Clang AST visitor, avoid traversing include files

2020-07-17 04:25发布

Hello I am trying to implement an AST Clang visitor and this is my code.

class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {
private:
    ASTContext *astContext; // used for getting additional AST info

public:
    virtual bool VisitVarDecl(VarDecl *var) 
    {
        numVariables++;
        string varName = var->getQualifiedNameAsString();
        string varType = var->getType().getAsString();
        cout << "Found variable declaration: " << varName << " of type " << varType << "\n";
        APIs << varType << ", ";
        return true;
    }

    virtual bool VisitFunctionDecl(FunctionDecl *func)
    {
        numFunctions++;
        string funcName = func->getNameInfo().getName().getAsString();
        string funcType = func->getResultType().getAsString();
        cout << "Found function declaration: " << funcName << " of type " << funcType << "\n";
        APIs << "\n\n" << funcName <<": ";
        APIs << funcType << ", ";
        return true;
    }

    virtual bool VisitStmt(Stmt *st) 
    {
        if (CallExpr *call = dyn_cast<CallExpr>(st)) 
        {
            numFuncCalls++;
            FunctionDecl *func_decl = call->getDirectCallee();
            string funcCall = func_decl->getNameInfo().getName().getAsString();
            cout << "Found function call: " << funcCall << " with arguments ";
            APIs << funcCall << ", ";
            for(int i=0, j = call->getNumArgs(); i<j; i++)
            {
                string TypeS;
                raw_string_ostream s(TypeS);
                call->getArg(i)->printPretty(s, 0, Policy);
                cout<< s.str() << ", ";
                APIs<< s.str() << ", ";
           }
            cout << "\n";
        }
        return true;
    }
};

How can I avoid traversing the included header files, but without loosing their information. I just dont want to print any information about this files but I want clang to know about these files

Thank you

1条回答
在下西门庆
2楼-- · 2020-07-17 04:49

By using AST context you can get all the nescecarry information for the code you are parsing. The function which distinguish between AST nodes being in the main file or the header files is called isInMainFile() and can be used as follows.

bool VisitVarDecl(VarDecl *var)
{
    if (astContext->getSourceManager().isInMainFile(var->getLocStart())) //checks if the node is in the main = input file.
    {
        if(var->hasLocalStorage() || var->isStaticLocal())
        {
            //var->dump(); //prints the corresponding line of the AST.
            FullSourceLoc FullLocation = astContext->getFullLoc(var->getLocStart());
            numVariables++;
            string varName = var->getQualifiedNameAsString();
            string varType = var->getType().getAsString();
            REPORT << "Variable Declaration [" << FullLocation.getSpellingLineNumber() << "," << FullLocation.getSpellingColumnNumber() << "]: " << varName << " of type " << varType << "\n";
            APIs << varType << ",";
        }
    }
    return true;
}

For more information on how to use astContext follow the official recursive ASTvisitor tutorial in clang website.

查看更多
登录 后发表回答