c++ - 将内存文件添加到 clang CompilerInstance

标签 c++ clang libtooling

我正在尝试使用 clang 创建一个工具,并且想知道是否可以将包含文件从内存注入(inject)到 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 */}

};

关于c++ - 将内存文件添加到 clang CompilerInstance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44943663/

相关文章:

c++ - Linux。不打印到文件

c++ - 为什么这段 C++ 代码可以用某些编译器编译,而不能用其他编译器编译?

c - 解释 `_Generic`错误消息: error: invalid type argument of unary '` *`' (have '` int`')

c++11 - 如何通过 clang 工具访问解析的 C++11 属性

c++ - 使用 libtooling 获取完全限定的模板模板参数名称

c++ - 从 clang 中的 FunctionDecl 类获取参数信息

c++ - 没有错误,但没有输出

c++ - 为什么 G++12 vector 插入优化会破坏代码?

cmake - 如何在 CMake 中将组合编译器选项与 target_compile_options 一起传递?

c++ - CLang Libtooling:获取 clang::VarDecl、clang::FieldDecl 或 clang::ParmVarDecl 内变量的数据类型