将内存文件添加到 clang CompilerInstance
Add memory file to clang CompilerInstance
我正在尝试使用 clang 创建一个工具,想知道是否可以将包含文件从内存注入 CompilerInstance
预处理器。
我的目标是将 #include <my_globals.hpp>
添加到我的文件中,并动态地包含具有适当内容的该文件。
所以我有一个像这样的 ASTFrontendAction
:
class MyFrontendAction : public ASTFrontendAction
{
virtual bool BeginInvocation(CompilerInstance &ci) override{
auto buffer = llvm::MemoryBuffer::getMemBufferCopy(...);
ci.createFileManager();
ci.createSourceManager(ci.getFileManager());
ci.createPreprocessor(clang::TU_Complete);
auto& pp = ci.getPreprocessor();
auto& preprocessorOpts = pp.getPreprocessorOpts();
preprocessorOpts.clearRemappedFiles();
preprocessorOpts.addRemappedFile("my_globals.hpp", buffer.release());
// this seams not to work
auto& hsi = pp.getHeaderSearchInfo();
auto& headerSearchOptions = hsi.getHeaderSearchOpts();
headerSearchOptions.Verbose = true; // this option is used during job
}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance& ci, StringRef file) override{/* do my parsing */}
};
只要我不包含我的头文件,解析就可以进行。如果我这样做,我会得到一个 my_globals.hpp file not found
.
所以 addRemappedFile
不会让这个文件对预处理器可见。我可以添加一些搜索路径,但我如何指示该文件没有路径?
谁能告诉我如何解决这个问题。
我会回答我自己的问题,也许会有帮助。
虽然 PPCallbacks
每当预处理器接触文件时都会被调用,但我发现无法更改内容。
所以我的解决方案是提供我自己的 FileSystem
class MyFs : public FileSystem{
... openFileForRead(const Twine& Path) overwrite
{
// in here I create my own File that will contain the data
// all other functions and when the path is not what I expect I forward it to a FileSystrem
}
};
class MyFrontendAction : public ASTFrontendAction
{
virtual bool BeginInvocation(CompilerInstance &ci) override{
ci.createFileManager(); // now I have a default FS
llvm::IntrusiveRefCntPtr<vfs::FileSystem> fs(new MyFs(ci.getFileManager().getVirtualFileSystem()));
ci.setVirtualFileSystem(fs);
ci.setFileManager(new clang::FileManager(clang::FileSystemOptions{}, fs));
auto& fm = ci.getFileManager();
ci.createSourceManager(fm);
return true;
}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance& ci, StringRef file) override{/* do my parsing */}
};
我正在尝试使用 clang 创建一个工具,想知道是否可以将包含文件从内存注入 CompilerInstance
预处理器。
我的目标是将 #include <my_globals.hpp>
添加到我的文件中,并动态地包含具有适当内容的该文件。
所以我有一个像这样的 ASTFrontendAction
:
class MyFrontendAction : public ASTFrontendAction
{
virtual bool BeginInvocation(CompilerInstance &ci) override{
auto buffer = llvm::MemoryBuffer::getMemBufferCopy(...);
ci.createFileManager();
ci.createSourceManager(ci.getFileManager());
ci.createPreprocessor(clang::TU_Complete);
auto& pp = ci.getPreprocessor();
auto& preprocessorOpts = pp.getPreprocessorOpts();
preprocessorOpts.clearRemappedFiles();
preprocessorOpts.addRemappedFile("my_globals.hpp", buffer.release());
// this seams not to work
auto& hsi = pp.getHeaderSearchInfo();
auto& headerSearchOptions = hsi.getHeaderSearchOpts();
headerSearchOptions.Verbose = true; // this option is used during job
}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance& ci, StringRef file) override{/* do my parsing */}
};
只要我不包含我的头文件,解析就可以进行。如果我这样做,我会得到一个 my_globals.hpp file not found
.
所以 addRemappedFile
不会让这个文件对预处理器可见。我可以添加一些搜索路径,但我如何指示该文件没有路径?
谁能告诉我如何解决这个问题。
我会回答我自己的问题,也许会有帮助。
虽然 PPCallbacks
每当预处理器接触文件时都会被调用,但我发现无法更改内容。
所以我的解决方案是提供我自己的 FileSystem
class MyFs : public FileSystem{
... openFileForRead(const Twine& Path) overwrite
{
// in here I create my own File that will contain the data
// all other functions and when the path is not what I expect I forward it to a FileSystrem
}
};
class MyFrontendAction : public ASTFrontendAction
{
virtual bool BeginInvocation(CompilerInstance &ci) override{
ci.createFileManager(); // now I have a default FS
llvm::IntrusiveRefCntPtr<vfs::FileSystem> fs(new MyFs(ci.getFileManager().getVirtualFileSystem()));
ci.setVirtualFileSystem(fs);
ci.setFileManager(new clang::FileManager(clang::FileSystemOptions{}, fs));
auto& fm = ci.getFileManager();
ci.createSourceManager(fm);
return true;
}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance& ci, StringRef file) override{/* do my parsing */}
};