2016-11-29 53 views
4

我正在使用基于示例Clang ASTFrontendActions sample的LibTooling编写叮当4.0工具。鉴于目前的声明stmt,我想在AST中获得它的直接父母。因此,我想下面的代码转储语句的所有家长(用于测试目的):叮当ASTContext.getParents总是返回一个空列表

bool VisitStmt(Stmt *s) { 
    cout <<"Trying to get parents \n"; 
    const Stmt currentStmt = *s; 
    const auto& parents = Context->getParents(currentStmt); 
    auto it = Context->getParents(currentStmt).begin(); 
    if(it == Context->getParents(currentStmt).end()) 
     cout<< "parents not found\n"; 
    cout<<"parents size "<< parents.size() <<": \n"; 
    if (!parents.empty()){ 
     for (int i = 0; i< parents.size(); i++){ 
      cout<<"parent at "<< i <<": \n"; 
      const Stmt* parentStmt = parents[i].get<Stmt>(); 
      parentStmt->dump(); 
     } 

    } 
} 

ContextASTContext和精细的工作时,我使用它的其他功能,如:Context->getSourceManager()
对于所有访问过的语句,结果总是(不管我输入什么):

Trying to get parents 
parents not found 
parents size 0: 

我是否错过任何(初始化,设置)使用getParents?

+1

我对'const stmt currentStmt = * s;'感到困惑。我认为你的意思是'const stmt&currentStmt = * s;'我不确定这是否是你的问题的原因,但是这可能会愚蠢地认为它是一个类似但不同的声明,它没有父母。 – Frank

+1

我从来没有与铿锵合作,但已与其他几个解析/ AST库一起工作。尽管节点的API仍然保持相同(基本上是因为在每次处理时重新创建新节点对象会花费太多的代价),但在处理的一些(通常是早期)阶段,某些信息是不可用的阶段)。你确定API没有在getParents()函数中指定这样的限制吗? – jwatkins

+0

@Frank'const stmt&currentStmt = * s;'做了诡计,谢谢。如果您有很好的解释,请在下面回答,以便我可以将您的答案标记为正确答案 – minhhn2910

回答

3

的问题来自于以下行:

const Stmt currentStmt = *s; 

这样做是使陈述的副本。 Context->getParents()通过查找具有作为孩子传递参数的节点来工作。但由于currentStmt只存在于您的堆栈上,而不在上下文中,因此无法找到任何此类节点。

通过使currentStmt到由s指向的节点的引用:

const Stmt& currentStmt = *s; 

然后你会被传递到上下文的实际节点实例,它有自身内部,和铛将设法成功地找到父母。