使用RecursiveASTVisitor访问Clang AST时确定Stmt的父函数节点

时间:2014-08-20 17:35:26

标签: c++ c++11 clang llvm-clang

我正在学习如何使用 clang libtooling 构建解析C的工具。

我正在使用RecursiveASTVisitor - 继承的类,因此它的所有遍历和访问者方法都可用。 我想知道在重写方法VisitStmt(Stmt *s)时是否可以确定语句的父函数节点。例如,我可以从FunctionDecl*获得s吗?

感谢。

4 个答案:

答案 0 :(得分:2)

我不具备铿锵声的专业知识,但您是否只能存储上次VisitDecl来电时收到的价值?

像:

class FooVisitor : public RecursiveASTVisitor<FooVisitor> {
 public:
  explicit FooVisitor(ASTContext* context)
    : context_(context), current_func_(nullptr) {}

  bool VisitDecl(Decl *decl) {
     if (decl->isFunctionOrFunctionTemplate())
        current_func_ = decl->getAsFunction();
     return true;
  }

  bool VisitStmt(Stmt* stmt) {
     do_something(current_func_, stmt);
     return true;
  }
 private:
  ASTContext* context_;
  FunctionDecl* current_func_;
};

我还没有编译它,所以可能需要一些修正,但它应该说明这个概念。

答案 1 :(得分:2)

我认为这段代码是你想要的:

    const Stmt* ST = str;

    while (true) {
        //get parents
        const auto& parents = pContext->getParents(*ST);
        if ( parents.empty() ) {
            llvm::errs() << "Can not find parent\n";
            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;
    } 

答案 2 :(得分:1)

由于您持有ASTContext,我认为您可以通过ASTContext :: getParent()访问Node的父级。

答案 3 :(得分:0)

可能有点晚了。 如果你在decls和Stmts上添加解析到@ xawi2000那么我猜你会到达顶级节点。 例如,你可能有

functionDecl

compoundStmt

VarDecl

语句

在这种情况下你需要解析stmt,然​​后decl来获取functionDecl。 只解析stmts,可能不会给出这种情况