clangabstract-syntax-treeclang-static-analyzer

clang-8: getting typedef information from DeclRefExpr node in AST


I have below test code:

typedef void (*funcPtrType)()
funcPtrType FPT;

void myFunc(){
    
}

int main(){
    FPT = myFunc;
    FPT();
    return 0;
}

And following is the part of AST dump of this code:

ASTDump

My question is, from which API can I get the 'void (*)()' information from DeclRefExpr node?

dclrfxpr

Already tried dynamic casting this node to VarDecl but from it I could not reach the information I mentioned.

Thanks in advance.


Solution

  • If you have a DeclRefExpr, that is an expression that refers to a declared entity. Call the getDecl method to get the associated ValueDecl, which is the declaration itself. On that object, call getType to get the QualType, which is the type, possibly including cv-qualifiers.

    For example:

    DeclRefExpr const *dre = ...;      // wherever you got it
    ValueDecl const *decl = dre->getDecl();
    QualType type = decl->getType();
    

    In this case, the type is a typedef. To inspect the underlying type, call getTypePtr to get the unqualified type, then getUnqualifiedDesugaredType to skip typedefs:

    clang::Type const *underType = type.getTypePtr()->getUnqualifiedDesugaredType();
    

    You can then call, for example, underType->isPointerType() to find out if it is a pointer type, etc. See the documentation for clang::Type for other ways to query it.

    If you want to get a string representation of underType, use the static QualType::print method, something like this:

    LangOptions lo;
    PrintingPolicy pp(lo);
    std::string s;
    llvm::raw_string_ostream rso(s);
    QualType::print(underType, Qualifiers(), rso, lo, llvm::Twine());
    errs() << "type as string: \"" << rso.str() << "\"\n";
    

    For your example, this will print:

    type as string: "void (*)()"