I am compiling my program which uses Clang 3.5
on Ubuntu 13.04 x86
machine. I wanted to get all the variables declared in a cpp project. Here is what I wrote:-
// 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));
}
When I try running this program, I get segmentation fault (possibly when I am casting var->getParentFunctionOrMethod()
to CXXMethodDecl*
). I wanted the method name where this variable is declared if it is a local variable. Can anybody tell me what may be the reasons for the error? Or what could be a better way to get method name of the variable?
I got the solution. It was because I was trying to fetch method name even if var
is not inside method. Here is the solution:-
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";
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments