2013-12-17 1 views
0

Ubuntu 13.04 x86 기계에서 Clang 3.5을 사용하는 프로그램을 컴파일 중입니다. 나는 cpp 프로젝트에서 선언 된 모든 변수를 얻고 싶었다. 여기에 내가 쓴 것입니다 : -이 프로그램을 실행하려고 할 때(CXXMethodDecl *) (VarDecl-> getParentFunctionOrMethod())에서 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)); 
} 

(내가 CXXMethodDecl*var->getParentFunctionOrMethod()을 캐스팅하고 가능한 경우), 나는 세그먼트 오류를 얻을. 이 변수가 로컬 변수 인 경우이 변수가 선언 된 메서드 이름을 원했습니다. 아무도 그 오류의 이유가 무엇인지 말해 줄 수 있습니까? 또는 변수의 메서드 이름을 얻는 더 좋은 방법은 무엇일까요?

+3

이것은 종종 디버깅 도구를 사용하는 방법을 배우는 좋은 시간입니다. 일반적인 디버깅을 위해서는 GDB를, 더 많은 메모리 문제는 Valgrind suite를 추천합니다. –

+0

GDB는 훌륭한 도구입니다. 제 경우에는 작동하지 않습니다. llvm의 cmake에'-DCMAKE_BUILD_TYPE = Debug'를 추가했습니다. 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"; 
} 
관련 문제