2014-01-24 30 views
1

我想查找Clang libtool使用的每個函數的類型信息。如何通過Clang的VisitReturnStmt找到真實的回報類型

但是,VisitReturnStmt有時找不到任何返回語句。 此外,類類型返回(例如「CreateASTConsumer」方法中的ASTConsumer *)被轉換爲「int *」類型。 (另一種情況:bool - > _Bool)

如何才能找到每種功能的實際返回類型?

在此先感謝您的幫助。

工具來源和輸入cpp來源相同如下。

#include "clang/Driver/Options.h" 
    #include "clang/AST/AST.h" 
    #include "clang/AST/ASTContext.h" 
    #include "clang/AST/ASTConsumer.h" 
    #include "clang/AST/RecursiveASTVisitor.h" 
    #include "clang/Frontend/ASTConsumers.h" 
    #include "clang/Frontend/FrontendActions.h" 
    #include "clang/Frontend/CompilerInstance.h" 
    #include "clang/Tooling/CommonOptionsParser.h" 
    #include "clang/Tooling/Tooling.h" 

    using namespace std; 
    using namespace clang; 
    using namespace clang::driver; 
    using namespace clang::tooling; 
    using namespace llvm; 

    Rewriter TheRewriter; 

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

    public: 
     explicit ExampleVisitor(CompilerInstance *CI) 
      : astContext(&(CI->getASTContext())) // initialize private members 
     { 
      TheRewriter.setSourceMgr(astContext->getSourceManager(), astContext->getLangOpts()); 
     } 

     virtual bool VisitReturnStmt(ReturnStmt *ReturnStatement) { 

      ReturnStatement->getRetValue()->dump(TheRewriter.getSourceMgr()); 
      return true; 
     } 

     virtual bool VisitStmt(Stmt *S) { 
      S->dump(TheRewriter.getSourceMgr()); 
      return true; 
     } 
    }; 



    class ExampleASTConsumer : public ASTConsumer { 
    private: 
     ExampleVisitor *visitor; // doesn't have to be private 

    public: 
     // override the constructor in order to pass CI 
     explicit ExampleASTConsumer(CompilerInstance *CI) 
      : visitor(new ExampleVisitor(CI)) // initialize the visitor 
     { } 

     // override this to call our ExampleVisitor on the entire source file 
     virtual void HandleTranslationUnit(ASTContext &Context) { 
      /* we can use ASTContext to get the TranslationUnitDecl, which is 
       a single Decl that collectively represents the entire source file */ 
      visitor->TraverseDecl(Context.getTranslationUnitDecl()); 
     } 

    }; 



    class ExampleFrontendAction : public ASTFrontendAction { 
    public: 
     virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef file) { 
      return new ExampleASTConsumer(&CI); // pass CI pointer to ASTConsumer 
     } 
    }; 



    int main(int argc, const char **argv) { 
     // parse the command-line args passed to your code 
     CommonOptionsParser op(argc, argv); 
     // create a new Clang Tool instance (a LibTooling environment) 
     ClangTool Tool(op.getCompilations(), op.getSourcePathList()); 

     // run the Clang Tool, creating a new FrontendAction (explained below) 
     int result = Tool.run(newFrontendActionFactory<ExampleFrontendAction>()); 
     return result; 
    } 
+0

的returnstmt問題解決呼叫FunctionDecl::getReturnType()。解決方法是運行libtool需要所有包含路徑。 – happybrown

回答

2

如果我正確地解釋the clang docs

注意,GCC允許在聲明爲返回一個值的函數沒有參數返回,並且允許返回在聲明返回void函數的值。我們在AST中明確地對此進行了建模,這意味着您不能依賴函數的返回類型和參數的存在。

這意味着你不能從其return語句中可靠地推斷函數的返回類型。

如果你想找到一個函數的返回類型,你可以參觀FunctionDecl節點和他們

+0

感謝您的回覆。我已經嘗試通過getReturnType()來查找返回類型。 Stmt * FuncBody = f-> getBody(); QualType QT = f-> getResultType(); std :: string TypeStr = QT.getAsString(); 結果顯示「CreateASTConsumer」是「int *」。 – happybrown

相關問題