Search code examples
llvm-clang

acquiring all the ancestors or descendants of a matched node


I need to travel through all the ancestors or descendants of a matched AST node to later use that info to moodify parts of the input source code. I tried to look for ways to do that. I looked at the getParents member function of the ASTContext class. I could use that to just go up the AST hierarchy to visit all the ancestor nodes of my currently-matched node. but the problem with that is, when i get the parent node, i no longer have the context for that node to try and get its parent. I could try to rebuild the ASTContext for the new node but that seems to be another big task on its own, if possible. the lowest NodeKind (lowest in the C hierarchy) I'm looking for is a callExpr and the highest I'm looking for is a functionDecl. how can I obtain all the ancestors or descendants of a matched AST node after the match returns the control to run in MatchCallback?


Solution

  • It may be possible to keep reaching for a parent declaration recursively until you reach TranslationUnitDecl, however, I would instead suggest actually iterating over the declarations in TranslationUnitDecl and working your way toward the FunctionDecl instead.

    You can create a recursive function which finds all TagDecl in a translation unit, searches all methods in that class for the FunctionDecl you specify, and also recursively consumes TagDecls within that TagDecl, until you have nothing left to consume.

    This would allow you to more easily keep a complete record of the specific AST nodes you want, and would probably be less confusing to write.

    However, if you choose to work your way backward you can try something like this (untested)

    FunctionDecl *FD;
    DeclContext *PC = FD->getParent();
    while (!isa<TranslationUnitDecl>(Decl::castFromDeclContext(PC))) {
        //consume 
    
        PC = PC->getParent();
    }
    

    for descendants (children) you'll just have to cast to a type with children and iterate.