我想用clang的RecursiveASTVisitor
遍历一个拥有巨大AST的项目。当我指定遍历整个AST时(如下所示),这需要花费大量时间:
void MyVisitor::HandleTranslationUnit(clang::ASTContext& context)
{
TraverseDecl(context.getTranslationUnitDecl());
}
字符串
出于这个原因,我想使用AST匹配器将AST缩小到我想要遍历的代码的相关部分。假设我只想遍历某些函数声明,那么我有沿着行的东西:
void MyVisitor::HandleTranslationUnit(clang::ASTContext& context)
{
auto decl = context.getTranslationUnitDecl();
auto relevantNodes = match(findAll(functionDecl(/* any matcher */).bind("function")), *decl, context);
for(auto &relevantNode : relevantNodes)
{
const clang::FunctionDecl *relevantFunctionDecl = relevantNode.getNodeAs<clang::FunctionDecl>("function");
if(relevantFunctionDecl)
{
TraverseDecl(relevantFunctionDecl);
//----------^ cannot pass const clang::FunctionDecl* to function accepting clang::Decl*
}
}
}
型
在我的代码中,getNodeAs<>
方法返回一个常量指针,但是TraverseDecl
接受非常量指针,即编译失败。
有没有办法只穿越AST的某些部分?
提前感谢!
1条答案
按热度按时间sulc1iza1#
是的,可以访问子树。只需按照代码片段中所示的操作,除了添加
const_cast
以允许从匹配器获得的指针传递给RecursiveASTVisitor
。C未定义行为没有问题,因为所有AST对象最初都是在没有const
限定符的情况下创建的。一般来说,Clang API在常量方面有点不一致。许多API,比如matchers,处理
const
指针,因为它们本身不修改AST。但是,虽然RecursiveASTVisitor
也是如此,但使用修改AST的指针编写transformer是很常见的,所以它的API不使用const
。参见Clang Discourse讨论Is it safe to cast-away constness to use Clang static analysis?,了解Clang开发人员的类似问题和评论。
(As另外,我认为这部分源于C没有“const polymorphism”的概念,如果它存在的话,可能会允许API在客户端的请求下选择性地统一处理
const
或非const
指针。由于语言强制做出选择,API设计者必须选择更适合通用用法的指针,因此客户端必须在某些边界处插入const_cast
)。