Search code examples
clanglibtooling

How can I get the name of a statement in Clang LibTooling?


I am playing around with LibTooling: What I want to do is output all the locations of all variables in a source file.

To find all occurences of variables, I overloaded the RecursiveASTVisitor and the method "bool VisitStmt(Stmt)" (see below), but now I don't know how to output the name of the variable. At the moment, my code only outputs "DeclRefExpr", but I want something like "myNewVariable" or whatever I defined in my input file.

class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor>
{
public:
    explicit MyASTVisitor(ASTContext *Context_passed) : Context(Context_passed) {}

    bool VisitStmt(Stmt *sta)
    {
        FullSourceLoc FullLocation = Context->getFullLoc(sta->getLocStart());
        SourceManager &srcMgr = Context->getSourceManager();
        if
        (
            FullLocation.isValid() &&
            strcmp(sta->getStmtClassName(), "DeclRefExpr") == 0
        )
        {
            // Print function name
            printf("stm: %-23s at %3u:%-3u in %-15s\n",
                sta->getStmtClassName(),
                FullLocation.getSpellingLineNumber(),
                FullLocation.getSpellingColumnNumber(),
                srcMgr.getFilename(FullLocation).data());
        }
        return true;
    }

private:
    ASTContext *Context;
};

How can I get the name, i.e. the statement itself? By using the Source Manager and extracting it from the original source code?


Solution

  • Using the method getFoundDecl(), an instance of the class "NamedDecl" can be acquired and then, using the method getNameAsString(), the name can be acquired as a string, so the code now looks like this:

    class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor>
    {
    public:
        explicit MyASTVisitor(ASTContext *Context_passed) : Context(Context_passed) {}
    
        bool VisitDeclRefExpr(DeclRefExpr *sta)
        {
            FullSourceLoc FullLocation = Context->getFullLoc(sta->getLocStart());
            SourceManager &srcMgr = Context->getSourceManager();
            if ( FullLocation.isValid() )
            {
                // Print function or variable name
                printf("stm: %-23s at %3u:%-3u in %-15s\n",
                    (sta->getFoundDecl())->getNameAsString().c_str(),
                    FullLocation.getSpellingLineNumber(),
                    FullLocation.getSpellingColumnNumber(),
                    srcMgr.getFilename(FullLocation).data());
            }
            return true;
        }
    
    private:
        ASTContext *Context;
    };