[cfe-dev] Getting the parent of CallExpr that has a VarDecl.

Ahmed via cfe-dev cfe-dev at lists.llvm.org
Tue Jun 15 04:23:20 PDT 2021


Hi,

I am currently trying to get the parent statement of a CallExpr.


The statement looks like this


size_t size = json_array_size(element);


The AST looks like this


|-FunctionDecl 0x560eb8d9e5e8 prev 0x560eb8d9a8a8 <line:101:1,
line:110:1> line:101:6 used print_json_array 'void (json_t *, int)'
| |-ParmVarDecl 0x560eb8d9e4e0 <col:23, col:31> col:31 used element
'json_t *'
| |-ParmVarDecl 0x560eb8d9e558 <col:40, col:44> col:44 used indent 'int'
| `-CompoundStmt 0x560eb8d9efa8 <col:52, line:110:1>
|   |-DeclStmt 0x560eb8d9e870 <line:103:5, col:43>
|   | `-VarDecl 0x560eb8d9e748 <col:5, col:42> col:12 used size
'size_t':'unsigned long' cinit
|   |   `-CallExpr 0x560eb8d9e810 <col:19, col:42> 'size_t':'unsigned long'
|   |     |-ImplicitCastExpr 0x560eb8d9e7f8 <col:19> 'size_t (*)(const
json_t *)' <FunctionToPointerDecay>
|   |     | `-DeclRefExpr 0x560eb8d9e7a8 <col:19> 'size_t (const json_t
*)' Function 0x560eb8d8ec38 'json_array_size' 'size_t (const json_t *)'
|   |     `-ImplicitCastExpr 0x560eb8d9e858 <col:35> 'const json_t *'
<BitCast>
|   |       `-ImplicitCastExpr 0x560eb8d9e840 <col:35> 'json_t *'
<LValueToRValue>
|   |         `-DeclRefExpr 0x560eb8d9e7d0 <col:35> 'json_t *' lvalue
ParmVar 0x560eb8d9e4e0 'element' 'json_t *'

...


The way I try to get the parent of a CallExpr once it meets the criteria
I am looking for


const clang::Stmt* Visitor::getParentStmt(const clang::Stmt *stmt){
    auto it = astContext.getParents(*stmt).begin();
    if(it == astContext.getParents(*stmt).end()) return nullptr;

    const clang::Stmt *aStmt = it->get<clang::Stmt>();
    if(aStmt){
        auto parent = astContext.getParents(*aStmt).begin();
        const clang::Stmt *pStmt = parent->get<clang::Stmt>();
        if(llvm::dyn_cast_or_null<clang::CompoundStmt>(pStmt)){
            return aStmt;
        }
        else{
            return getParentStmt(aStmt);
        }
    }
    //nothing worked
    if(Debug){
        llvm::errs() << "Failed to get parent stmt for\n";
        stmt->dump();
    }
    return nullptr;
}


When a VarDecl is the direct ancestor of the CallExpr it fails to
traverse up. 


Any ideas how I can overcome that ?


Thanks

Ahmed



More information about the cfe-dev mailing list