使用 RecursiveASTVisitor 访问 Clang AST 时确定 Stmt 的父函数节点
Posted
技术标签:
【中文标题】使用 RecursiveASTVisitor 访问 Clang AST 时确定 Stmt 的父函数节点【英文标题】:Determine parent function node of a Stmt when visiting Clang AST using RecursiveASTVisitor 【发布时间】:2014-08-20 17:35:25 【问题描述】:我正在学习如何使用 clang 的 libtooling 构建解析 C 的工具。
我正在使用RecursiveASTVisitor
-inherited 类,因此它的所有遍历和访问方法都可用。
我想知道在覆盖方法VisitStmt(Stmt *s)
时是否可以确定语句的父函数节点。例如这里,我可以从s
获得FunctionDecl*
吗?
谢谢。
【问题讨论】:
【参考方案1】:我没有clang方面的专业知识,但你不能只存储你在上次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_;
;
我还没有编译它,所以可能需要一些修正,但它应该能说明这个概念。
【讨论】:
谢谢,这可能是个主意。我只想知道 Clang AST 是如何连接的。 @TrúcNguyễnLâm:“Clang AST 的连接程度”是什么意思?【参考方案2】:由于你持有 ASTContext,我认为你可以通过 ASTContext::getParent() 访问 Node 的父母。
【讨论】:
【参考方案3】:我认为这段代码是你想要的:
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;
【讨论】:
【参考方案4】:可能有点晚了。 如果您将 decls 和 Stmts 的解析添加到@xawi2000,那么我想您会到达顶部节点。 例如,你可能有
函数声明
compoundStmt
变量声明
Stmt
在这种情况下,您需要通过 stmt 进行解析,然后通过 decl 来获取 functionDecl。 只解析过stmts,可能不会给出这种情况
【讨论】:
以上是关于使用 RecursiveASTVisitor 访问 Clang AST 时确定 Stmt 的父函数节点的主要内容,如果未能解决你的问题,请参考以下文章
将 json 库添加到 clang libtooling 项目
Groovy集合声明与访问 ( 使用 [] 创建 ArrayList 和 LinkedList 集合 | 集合赋初值 | 使用下标访问集合 | 使用 IntRange 作为下标访问集合 )
GroovyGroovy 方法调用 ( 使用 对象名.成员名 访问 Groovy 类的成员 | 使用 对象名.‘成员名‘ 访问类的成员 | 使用 对象名[‘成员名‘] 访问类成员 )