【问题标题】:Clang MatchResult has no AST nodes bound?Clang MatchResult 没有绑定 AST 节点?
【发布时间】:2020-12-24 09:40:41
【问题描述】:

我正在编写我的第一个 AST 匹配器来检测指针到整数的转换,但 MatchResult 中 BoundedNodes 的大小为 0。这怎么可能?为什么 AST Matcher 会在 MatchResult 为空的情况下调用我的回调?一段代码是否可以匹配某个 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?然而它是空的。

【问题讨论】:

    标签: c++ clang clang-ast-matchers


    【解决方案1】:

    找到了。显然你必须bind你的匹配器到某个字符串,否则它匹配的节点将不会出现在绑定节点中。这么说倒是有道理,不过我找的时间太长了。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-28
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      • 2019-11-03
      相关资源
      最近更新 更多