使用Clang的libtooling匹配#includes(或#defines)的正确方法是什么? [英] What's the right way to match #includes (or #defines) using Clang's libtooling?

查看:166
本文介绍了使用Clang的libtooling匹配#includes(或#defines)的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个libtooling重构工具。我有一个类,例如 Foo ,在一个名为 foo.h 的标头中定义。我想查看 foo.h 是否包含在文件中。目前,要检查 bar.cc 是否包含 foo.h ,我只是使用 recordDecl(hasName( Foo))。之所以可以这样,是因为 class Foo {...}; 在预处理后将存在于 bar.cc 的AST中,如果 bar.cc 包括 foo.h

I'm writing a libtooling refactoring tool. I have a class, let's say Foo, defined in a header called foo.h. I want to see if foo.h is included in a file. Currently, to check if bar.cc includes foo.h, I'm just matching using recordDecl(hasName("Foo")). This works because class Foo { ... }; will exist inside of bar.cc's AST after preprocessing, if bar.cc includes foo.h.

但是,例如如果 bar.cc 包含 cat.h 其中包括 foo.h 。我希望 bar.cc 明确包含 foo.h

But this doesn't work if, for example, bar.cc includes cat.h which includes foo.h. I want bar.cc to EXPLICITLY include foo.h.

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

Further, I'd like to be able to match #define macros.

我的方式我一直在写我的工具,使这两个目标无法实现,因为与我匹配的AST已经过预处理。我想做的事甚至可能吗?我在Clang的Doxygen页面上浏览了 Preprocessor 类引用,但是我没有找到我想要的东西。

The way I've been writing my tool has made these two goals impossible because the AST I'm matching on has already been preprocessed. Is what I'm trying to do even possible? I dug around the Preprocessor class reference on Clang's Doxygen pages, but I haven't quite found what I'm looking for.

推荐答案

在研究了Clang的Doxygen和代码后,我发现了这一点。我需要使用 PPCallbacks 类和 Preprocessor 类。下面是一个示例。请注意,这不能保证是功能代码段,但可以说明一般用法。有关更多信息,请参见Clang的 PPCallbacks 文档以及addPPCallbacks a href = http://clang.llvm.org/doxygen/classclang_1_1Preprocessor.html> clang :: Preprocessor

I figured this out after digging around in Clang's Doxygen and code. I needed to be using the PPCallbacks class along with the Preprocessor class. An example is below. Note, this isn't guaranteed to be a functional code snippet, but it illustrates general usage. For more info, see Clang's PPCallbacks documentation and also the documentation for addPPCallbacks and getPPCallbacks in clang::Preprocessor.

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;
  }
};

这篇关于使用Clang的libtooling匹配#includes(或#defines)的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆