在 Clang AST 中查找声明的父级

Find parent of a declaration in Clang AST

本文关键字:声明 查找 Clang AST      更新时间:2023-10-16

我正在使用 clang 进行一些分析,我需要在 AST 中找到声明的父级。例如,在下面的代码中,我int x了,我想获取它的父级,它应该是函数声明:

int main(int x) { return 0 }

我知道如此链接中所述 http://comments.gmane.org/gmane.comp.compilers.clang.devel/2152 有一个 ParentMap 类来跟踪父节点。但是,这只是来自 Stmt* -> Stmt* 的映射,我需要找到声明的父级。有谁知道我该怎么做?

你可以

使用 AstContext::getParents() 来查找 ast 节点的父节点。示例代码如下:

    const Stmt* ST = str;
    while (true) {
        //get parents
        const auto& parents = pContext->getParents(*ST);
        if ( parents.empty() ) {
            llvm::errs() << "Can not find parentn";
            return false;
        }
        llvm::errs() << "find parent size=" << parents.size() << "n";
        ST = parents[0].get<Stmt>();
        if (!ST)
            return false;
        ST->dump();
        if (isa<CompoundStmt>(ST))
            break;
    } 

AstContext::getParents() 可以接收 stmt 参数或 decl 参数。

它与您正在寻找的链接线程中所述完全ParentMap。在 clang 特定声明中,所有继承自 clang::Decl 它提供

virtual Stmt* getBody() const;

或者,您可能还对现成的 AST 匹配器感到满意,这使得在 AST 上创建查询变得更加容易。叮叮当当的检查大量使用它们并且很容易遵循,请参阅来源 [git]。

关于 FunctionDecl 的父级,需要注意的是:函数的声明可以是类的成员,也可以是"独立"声明。

如果 FunctionDecl 是

类的成员,那么 FunctionDecl 是 CXXMethodDecl 因此您可以检查:

isa<CXXMethodDecl>(FunctionDecl *FD).

然后你可以用getParent()方法获取CXXMethodDecl的父级。此方法在 FunctionDecl 中不存在。