在使用Clang LibTooling的RecursiveASTVisitor时,如何告诉库中止当前访问的AST节点下的子树扫描?
RecursiveASTVisitor在AST上使用深度优先遍历,可以很容易地中止某些子树并继续遍历。
例如(请阅读代码中的注释):
virtual bool VisitCXXRecordDecl(CXXRecordDecl *decl) {
//some code to tell the lib not to traverse the subtree
//under the currently visited node i.e. decl
//but still continue the traversal
//so that the scan process will skip all AST nodes under any
//CXXRecordDecl in the AST
}
我以为从Visit ***方法返回false会达到这个目标,但是它确实告诉lib一起结束遍历,而不是跳过子树。
由于目标只是标题中所述的目标,因此不考虑使用ASTMatchers。
最佳答案
实际上,从false
函数之一返回VisitXXX
将终止整个遍历。
要跳过AST节点,您可以覆盖TraverseXXX
并有选择地回退到父类(super class)型(即RecursiveASTVisitor
)实现:
class ASTVisitor : public RecursiveASTVisitor<ASTVisitor> {
public:
bool TraverseCXXRecordDecl(CXXRecordDecl *decl) {
// Don't traverse skip_me
if (auto name = decl->getName(); name.equals("skip_me")) {
std::cout << "Skipping " << name.str() << '\n';
// Return true to continue AST traversal,
// but don't visit the node
return true;
}
// Call RecursiveASTVisitor's implementation to visit this node
return RecursiveASTVisitor::TraverseCXXRecordDecl(decl);
}
bool VisitFieldDecl(FieldDecl *decl) {
std::cout << "Visited field " << decl->getName().str() << '\n';
return true;
}
};
在此翻译单元上测试此访客:
struct skip_me {
int skipped;
};
struct dont_skip_me {
int not_skipped;
};
产生以下输出:
Skipping skip_me
Visited field not_skipped