2013-12-17 30 views
0

我正在編譯我的程序,該程序在Ubuntu 13.04 x86機器上使用Clang 3.5。我想獲得在cpp項目中聲明的所有變量。下面是我寫的: -CLang prog分段錯誤

// Declares clang::SyntaxOnlyAction. 
#include "clang/Frontend/FrontendActions.h" 
#include "clang/Tooling/CommonOptionsParser.h" 
#include "clang/Tooling/Tooling.h" 
#include "clang/ASTMatchers/ASTMatchers.h" 
#include "clang/ASTMatchers/ASTMatchFinder.h" 
// Declares llvm::cl::extrahelp. 
#include "llvm/Support/CommandLine.h" 
#include "clang/AST/DeclCXX.h" 
#include <iostream> 
#include <vector> 

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

static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); 

static cl::extrahelp MoreHelp("\nMore help text..."); 

static cl::OptionCategory MyToolCategory("My Tool Category"); 

internal::Matcher<Decl> fields = fieldDecl().bind("field"); 
internal::Matcher<Decl> params = parmVarDecl().bind("param"); 
internal::Matcher<Decl> vars = varDecl().bind("var"); 

class VarDeclPrinter : public MatchFinder::MatchCallback { 
    public: 
    int counter; 

    virtual void run(const MatchFinder::MatchResult &Result) { 
    const Decl* dec; 

    if(const FieldDecl* field = Result.Nodes.getNodeAs<FieldDecl>("field")) 
     llvm::outs() << "Member Variable: " << field->getName() << "\t\t" 
        << field->getParent()->getQualifiedNameAsString() << "\n"; 

    if(const ParmVarDecl* param = Result.Nodes.getNodeAs<ParmVarDecl>("param")) 
     llvm::outs() << "Argument Variable: " << param->getName() << "\t\t" 
        << ((CXXMethodDecl*)(param->getParentFunctionOrMethod()))->getQualifiedNameAsString() << "\n"; 

    if(const VarDecl* var = Result.Nodes.getNodeAs<VarDecl>("var")) 
     llvm::outs() << "Local Variable: " << var->getName() << "\t\t" 
        << ((CXXMethodDecl*)(var->getParentFunctionOrMethod()))->getQualifiedNameAsString() << "\n"; 

    counter++; 
    //llvm::outs() << "Variable count: " << counter << "\n"; 
    //ASTContext* Context = Result.Context; 
    } 
}; 

int main(int argc, const char **argv) { 
    CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); 
    ClangTool Tool(OptionsParser.getCompilations(), 
       OptionsParser.getSourcePathList()); 

    VarDeclPrinter VarDeclCallback; 
    MatchFinder Finder; 

    Finder.addMatcher(fields, &VarDeclCallback); 
    Finder.addMatcher(params, &VarDeclCallback); 
    Finder.addMatcher(vars, &VarDeclCallback); 
    return Tool.run(newFrontendActionFactory(&Finder)); 
} 

當我嘗試運行這個程序,我得到分段錯誤(可能是當我鑄造var->getParentFunctionOrMethod()CXXMethodDecl*)。如果它是一個局部變量,我想要聲明該變量的方法名稱。有人可以告訴我可能是什麼原因造成的錯誤?或者什麼可能是更好的方法來獲取變量的方法名稱?

+3

這往往是你生活中學習如何使用調試工具的好時機。我推薦GDB進行一般調試,而Valgrind套件則針對更加繁重的內存問題。 –

+0

GDB是一個很棒的工具。它只是不適合我的情況。我添加了-DCMAKE_BUILD_TYPE = Debug到llvm的cmake。在花了大量的編譯時間(比以前執行make時),現在它給了我'libclangStaticAnalyzerCheckers.a:文件格式不被識別;視爲鏈接腳本「。無論如何感謝您的評論。 –

回答

1

我得到了解決方案。這是因爲我試圖取方法名稱即使var不在裏面的方法。這裏是解決方案: -

if(const VarDecl* var = Result.Nodes.getNodeAs<VarDecl>("var")) { 
    llvm::outs() << "Local Variable: " << var->getName() << "\t\t"; 
    if(var->isFunctionOrMethodVarDecl()) 
    llvm::outs() << ((CXXMethodDecl*)(var->getParentFunctionOrMethod()))->getQualifiedNameAsString(); 
    llvm::outs() << "\n"; 
}