使用Clang的libtooling匹配#includes(或#defines)的正确方法是什么?

sag*_*rgp 8 c++ clang libtooling

我正在编写一个libtooling重构工具.我有一个类,比方说Foo,在一个标题中定义foo.h.我想看看是否foo.h包含在文件中.目前,要检查是否bar.cc包含foo.h,我只是匹配使用recordDecl(hasName("Foo")).这是有效的,因为预处理class Foo { ... };后将存在于bar.ccAST 内部,如果bar.cc包含foo.h.

但是,如果,例如,bar.cc包括cat.h哪些包括,则这不起作用foo.h.我想bar.cc明确包括foo.h.

此外,我希望能够匹配#define宏.

我编写工具的方式使得这两个目标无法实现,因为我匹配的AST已经过预处理.我正在努力做甚么可能吗?我Preprocessor在Clang的Doxygen页面上找到了类参考,但我还没有找到我正在寻找的东西.

sag*_*rgp 11

我在Clang的Doxygen和代码中挖掘后想出了这个.我需要和PPCallbacks班级一起使用Preprocessor班级.一个例子如下.请注意,这不能保证是功能代码段,但它说明了一般用法.欲了解更多信息,请参阅锵的PPCallbacks文档,同时还为文档addPPCallbacksgetPPCallbacks铿锵::预处理.

class Find_Includes : public PPCallbacks
{
public:
  bool has_include;

  void InclusionDirective(
    SourceLocation hash_loc,
    const Token &include_token,
    StringRef file_name,
    bool is_angled,
    CharSourceRange filename_range,
    const FileEntry *file,
    StringRef search_path,
    StringRef relative_path,
    const Module *imported)
  {
    // do something with the include
    has_include = true;
  }
};

class Include_Matching_Action : public ASTFrontendAction
{
  bool BeginSourceFileAction(CompilerInstance &ci, StringRef)
  {
    std::unique_ptr<Find_Includes> find_includes_callback(new Find_Includes());

    Preprocessor &pp = ci.getPreprocessor();
    pp.addPPCallbacks(std::move(find_includes_callback));

    return true;
  }

  void EndSourceFileAction()
  {
    CompilerInstance &ci = getCompilerInstance();
    Preprocessor &pp = ci.getPreprocessor();
    Find_Includes *find_includes_callback = static_cast<Find_Includes>(pp.getPPCallbacks());

    // do whatever you want with the callback now
    if (find_includes_callback->has_include)
      std::cout << "Found at least one include" << std::endl;
  }
};
Run Code Online (Sandbox Code Playgroud)