Clang MatchResult 没有绑定 AST 节点?

Clang MatchResult has no AST nodes bound?

我正在编写我的第一个 AST 匹配器来检测指针到整数的转换,但是 MatchResult 中的 BoundedNodes 的大小是 0。这怎么可能?为什么即使 MatchResult 为空,AST Matcher 也会调用我的回调?有没有可能一段代码匹配到某个Matcher而不作为节点出现在AST中?

这是我的全部代码:

class PtoICallback : public clang::ast_matchers::MatchFinder::MatchCallback {
    clang::Rewriter rewriter;

public:
    virtual void run(const clang::ast_matchers::MatchFinder::MatchResult& result) override final {
        llvm::outs() << result.Nodes.getMap().size() << " nodes matched\n";
    }
};

int main(int argc, const char** argv) {
    llvm::cl::OptionCategory findPtoICategory("find-ptoi options");

    clang::tooling::CommonOptionsParser options(argc, argv, findPtoICategory);

    clang::tooling::ClangTool tool(options.getCompilations(), options.getSourcePathList());


    auto matcher = clang::ast_matchers::castExpr(clang::ast_matchers::hasCastKind(clang::CastKind::CK_PointerToIntegral));
    PtoICallback callback;
    clang::ast_matchers::MatchFinder finder;
    finder.addMatcher(matcher, &callback);

    return tool.run(clang::tooling::newFrontendActionFactory(&finder).get());
}

这输出

0 nodes matched

在包含 1 个整数转换指针的文件上调用时:

#include <stdint.h>

int main() { 
    int i = 0;
    intptr_t a = reinterpret_cast<intptr_t>(&i);
    return 0; 
}

同样,我不明白为什么会检测到匹配,但找不到节点?如果我转储上面代码的 AST,它会给出:

`-FunctionDecl 0x55765ad54520 <example.cpp:5:1, line:9:1> line:5:5 main 'int ()'
  `-CompoundStmt 0x55765ad62010 <col:12, line:9:1>
    |-DeclStmt 0x55765ad61e40 <line:6:5, col:14>
    | `-VarDecl 0x55765ad54648 <col:5, col:13> col:9 used i 'int' cinit
    |   `-IntegerLiteral 0x55765ad61e20 <col:13> 'int' 0
    |-DeclStmt 0x55765ad61fc8 <line:7:5, col:48>
    | `-VarDecl 0x55765ad61e90 <col:5, col:47> col:14 a 'intptr_t':'long' cinit
    |   `-CXXReinterpretCastExpr 0x55765ad61f98 <col:18, col:47> 'intptr_t':'long' reinterpret_cast<intptr_t> <PointerToIntegral>
    |     `-UnaryOperator 0x55765ad61f48 <col:45, col:46> 'int *' prefix '&' cannot overflow
    |       `-DeclRefExpr 0x55765ad61ef8 <col:46> 'int' lvalue Var 0x55765ad54648 'i' 'int'
    `-ReturnStmt 0x55765ad62000 <line:8:5, col:12>
      `-IntegerLiteral 0x55765ad61fe0 <col:12> 'int' 0

所以我想 result.Nodes.getMap() 至少会产生 AST 转储中显示的 CXXReinterpretCastExpr?然而它是空的。

找到了。显然你必须 bind 你的匹配器到一些字符串,否则它匹配的节点将不会出现在绑定节点中。这么说还挺有道理的,不过我也找了很久。

对于阅读本文的任何人,如果您在匹配器的末尾调用 bind 方法,您基本上可以指定一个由您定义的字符串,该字符串将标识您发现的匹配节点那个特定的匹配器。似乎没有通配符字符串之类的东西,这就是为什么如果您不将匹配器绑定到某些东西,它就不会将 AST 节点绑定到您的结果。

我认为这是一种区分匹配器的方法,如果多个匹配器要查找结果并且它们使用相同的回调并且 MatchResults 以某种方式包含同时匹配的多个节点?我还不太清楚匹配是如何工作的。它是否将多个 'matchings' 批处理在一起以避免调用 run() 太多?我不知道。对我来说,节点中一次总是只有一个条目。