[cfe-dev] Moving up the AST of a function from a CallExpr

Zaki, Ahmed via cfe-dev cfe-dev at lists.llvm.org
Wed Apr 7 03:30:45 PDT 2021


Hi,

I am trying to move up the AST from a CallExpr. I am using Recursive Visitors to match on the target CallExpr I am interested in.

The function AST I am trying to recurse upwards from looks like this

|-FunctionDecl 0x564865171688 prev 0x56486516d948 <line:101:1, line:110:1> line:101:6 used print_json_array 'void (json_t *, int)'
| |-ParmVarDecl 0x564865171580 <col:23, col:31> col:31 used element 'json_t *'
| |-ParmVarDecl 0x5648651715f8 <col:40, col:44> col:44 used indent 'int'
| `-CompoundStmt 0x564865172048 <col:52, line:110:1>
|   |-DeclStmt 0x5648651717c0 <line:102:5, col:13>
|   | `-VarDecl 0x564865171748 <col:5, col:12> col:12 used i 'size_t':'unsigned long'
|   |-DeclStmt 0x564865171910 <line:103:5, col:43>
|   | `-VarDecl 0x5648651717e8 <col:5, col:42> col:12 used size 'size_t':'unsigned long' cinit
|   |   `-CallExpr 0x5648651718b0 <col:19, col:42> 'size_t':'unsigned long'
|   |     |-ImplicitCastExpr 0x564865171898 <col:19> 'size_t (*)(const json_t *)' <FunctionToPointerDecay>
|   |     | `-DeclRefExpr 0x564865171848 <col:19> 'size_t (const json_t *)' Function 0x564865161cd8 'json_array_size' 'size_t (const json_t *)'
|   |     `-ImplicitCastExpr 0x5648651718f8 <col:35> 'const json_t *' <BitCast>
|   |       `-ImplicitCastExpr 0x5648651718e0 <col:35> 'json_t *' <LValueToRValue>
|   |         `-DeclRefExpr 0x564865171870 <col:35> 'json_t *' lvalue ParmVar 0x564865171580 'element' 'json_t *'



I am following the suggestion here http://clang-developers.42468.n3.nabble.com/acquiring-all-the-ancestors-or-descendants-of-a-matched-node-td4052601.html to get the functiondecl of the CallExpr.

This is what the upwards traversal looks like

const FunctionDecl* Visitor::getParentFunctionDecl(const clang::Stmt& stmt){

    auto it = astContext.getParents(stmt).begin();

    if(it == astContext.getParents(stmt).end()) return nullptr;



    outs() << "Current Node Kind: " << it->getNodeKind().asStringRef() << "\n";



    const FunctionDecl *fDecl = it->get<FunctionDecl>();

    if(fDecl){

        outs() << "Got function Decl!\n" ;

        return fDecl;

    }



    const Stmt *aStmt = it->get<Stmt>();

    if(aStmt){

        return getParentFunctionDecl(*aStmt);

    }

    //nothing worked

    errs() << "Nothing worked\n";

    return nullptr;

}

The problem I am running into is getting the parent of the VarDecl which is the DeclStmt in my function.

I tried something like

  const VarDecl *var = it->get<VarDecl>();

    if(var){

        outs() << "Got a VarDecl\n";

        auto decl = astContext.getParents(dyn_cast<Decl>(var)).begin();

        outs() << "Parent of VarDecl: " << decl->getNodeKind().asStringRef() << "\n";

        const DeclStmt *declStmt = decl->get<DeclStmt>();

        return getParentFunctionDecl(dyn_cast<Stmt>(decl));

    }

But I get problem with the creation of a Decl from a DynTypedNode.

An idea how can I move upwards from a VarDecl ?

What I am trying to achieve is if I find an interesting callexpr I want to check all declstmts and declrefexprs before the callexpr that reference the arguments of the call.

Thanks



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210407/cbc263ec/attachment.html>


More information about the cfe-dev mailing list