0

我正在编写我的第一个 AST 匹配器来检测指针到积分的转换,但BoundedNodesin 的大小MatchResult为 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()至少会产生我在CXXReinterpretCastExprAST 转储中显示的内容?然而它是空的。

4

1 回答 1

0

找到了。显然,您必须将bind匹配器匹配到某个字符串,否则它匹配的节点将不会出现在绑定节点中。如果你这样说是有道理的,但我不得不搜索太久。

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

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

于 2020-12-24T16:39:30.300 回答