clang plugin registry

Hi ,
I wrote my callgraph plugin code as following…

#include “clang/AST/DeclBase.h”
#include “llvm/ADT/DenseMap.h”
#include “llvm/ADT/SetVector.h”

#include “clang/AST/ASTContext.h”
#include “clang/AST/Decl.h”
#include “clang/AST/RecursiveASTVisitor.h”
#include “clang/AST/StmtVisitor.h”

#include “clang/Frontend/FrontendPluginRegistry.h”
#include “clang/AST/ASTConsumer.h”
#include “clang/AST/AST.h”
#include “clang/Frontend/CompilerInstance.h”
#include “llvm/Support/raw_ostream.h”

// call graph structure method

namespace clang{
class CallGraphNode;

class CallGraph{

public:

typedef llvm::DenseMap<Decl *, CallGraphNode *> FunctionMapTy;
FunctionMapTy FunctionMap;

CallGraphNode *Root;

CallGraph();
~CallGraph();

llvm::SetVector<CallGraphNode *> ParentlessNodes;

void addToCallGraph(Decl *D, bool isGlobal);
void addToCallGraph(TranslationUnitDecl *TU);

CallGraphNode *getNode(const Decl * ) const ;
CallGraphNode *getOrInsertNode(Decl *);

typedef FunctionMapTy::iterator iterator;
typedef FunctionMapTy::const_iterator const_iterator;

iterator begin() { return FunctionMap.begin(); }
iterator end() { return FunctionMap.end(); }
const_iterator begin() const { return FunctionMap.begin(); }
const_iterator end() const { return FunctionMap.end(); }

typedef llvm::SetVector<CallGraphNode *>::iterator Nodes_iterator;
typedef llvm::SetVector<CallGraphNode *>::const_iterator const_Nodes_iterator;

Nodes_iterator parentless_begin() { return ParentlessNodes.begin(); }
Nodes_iterator parentless_end() { return ParentlessNodes.end(); }
const_Nodes_iterator parentless_begin() const { return ParentlessNodes.begin(); }
const_Nodes_iterator parentless_end() const { return ParentlessNodes.end(); }

CallGraphNode *getRoot() const { return Root; }

}; // end of class CallGraph

class CallGraphNode{
public:
typedef CallGraphNode *CallRecord;

private:
Decl *FD;
llvm::SmallVector<CallRecord , 5> CalledFunctions;
public:

CallGraphNode(Decl *D):FD(D) {} // constructor

typedef llvm::SmallVector<CallRecord , 5>::iterator iterator;
typedef llvm::SmallVector<CallRecord , 5>::const_iterator const_iterator;

inline iterator begin() { return CalledFunctions.begin(); }
inline iterator end() { return CalledFunctions.end(); }
inline const_iterator begin() const { return CalledFunctions.begin(); }
inline const_iterator end() const { return CalledFunctions.end(); }

inline bool empty() const { return CalledFunctions.empty(); }
inline unsigned size() const { return CalledFunctions.size(); }

void addCallee(CallGraphNode *N , CallGraph *CG)
{
CalledFunctions.push_back(N);
CG->ParentlessNodes.remove(N);
}

Decl *getDecl() const { return FD; }
StringRef getName() const ;

}; // end of CallGrsphNode class

} //end of namespace clang

using namespace clang;

static bool includeInGraph(const Decl *D)
{
if(const FunctionDecl *FD = dyn_cast(D)){

if(!FD->isThisDeclarationADefinition() || FD->isDependentContext())
return false;

IdentifierInfo *II = FD->getIdentifier();

if(II && II->getName().startswith("__inline"))
return false;
}

return true;
}

namespace{
class CGBuilder:public StmtVisitor,public ASTConsumer{

CallGraph *G;
const Decl *FD;
CallGraphNode *callernode;

protected:
virtual bool HandleTopLevelDecl(DeclGroupRef DG) {return true;}
public:

CGBuilder() {}
CGBuilder(CallGraph *g, const Decl *D, CallGraphNode *N ):G(g),FD(D),callernode(N) {}
void VisitStmt(Stmt *S){ VisitChildren(S); }

void VisitCallExpr(CallExpr *CE){
if(FunctionDecl *calleeDecl = CE->getDirectCallee())
{
if(includeInGraph(calleeDecl))
{
CallGraphNode *calleenode = G->getOrInsertNode(calleeDecl);
callernode->addCallee(calleenode,G);
}
}
}

void VisitChildren(Stmt *S)
{
for(Stmt::child_range I = S->children() ; I ; ++I)
if(I)
static_cast<CGBuilder
>(this)->Visit(*I);
}

};//end of class CGBuilder

class CGDeclVisitor:public RecursiveASTVisitor{
CallGraph *CG;
public:
CGDeclVisitor(CallGraph *inCG):CG(inCG) {}

bool VisitFunctionDecl(FunctionDecl *FD)
{
if(includeInGraph(FD))
CG->addToCallGraph(FD,FD->isGlobal());
return true;
}

};//end of CGDeclVisitor class

class CGBuilderAction : public PluginASTAction {
protected:
ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
return new CGBuilder();
}

};

static FrontendPluginRegistry::Add
X(“print-cgp”, “print callgraph”);

}//end of namespace

CallGraph::CallGraph()
{
Root = getOrInsertNode(0);
}

CallGraph::~CallGraph()
{
if(!FunctionMap.empty())
{
for(FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end() ; I != E ; ++I)
delete I->second;
FunctionMap.clear();
}
}

CallGraphNode *CallGraph::getOrInsertNode(Decl *F)
{
CallGraphNode *&Node = FunctionMap[F];
if(Node)
return Node;

Node = new CallGraphNode(F);
if(F!=0)
ParentlessNodes.insert(Node);
return Node;
}

void CallGraph::addToCallGraph( Decl *D , bool isGlobal)
{
assert(D);
CallGraphNode *Node = getOrInsertNode(D);

if(isGlobal)
Root->addCallee(Node,this);

CGBuilder builder(this,D,Node);
if(Stmt *Body = D->getBody())
builder.Visit(Body);
}

void CallGraph::addToCallGraph(TranslationUnitDecl *TU)
{
CGDeclVisitor(this).TraverseDecl(TU);
}

after compiling plugin it will give me error as following…

In file included from /home/akshay/llvmsrc/llvm/tools/clang/examples/CallGraph/…/…/include/clang/Frontend/FrontendPluginRegistry.h:14:
/home/akshay/llvmsrc/llvm/include/llvm/Support/Registry.h:195:39: error: allocating an object of abstract class type ‘CGBuilderAction’
static T *CtorFn() { return new V(); }
^
/home/akshay/llvmsrc/llvm/include/llvm/Support/Registry.h:199:29: note: in instantiation of member function
‘llvm::Registry<clang::PluginASTAction, llvm::RegistryTraitsclang::PluginASTAction >::Add<::CGBuilderAction>::CtorFn’
requested here
: Entry(Name, Desc, CtorFn), Node(Entry) {}
^
/home/akshay/llvmsrc/llvm/tools/clang/examples/CallGraph/callgraph.cpp:190:1: note: in instantiation of member function
‘llvm::Registry<clang::PluginASTAction, llvm::RegistryTraitsclang::PluginASTAction >::Add<::CGBuilderAction>::Add’
requested here
X(“print-cgp”, “print callgraph”);
^
/home/akshay/llvmsrc/llvm/tools/clang/examples/CallGraph/…/…/include/clang/Frontend/FrontendAction.h:228:16: note: unimplemented pure
virtual method ‘ParseArgs’ in ‘CGBuilderAction’
virtual bool ParseArgs(const CompilerInstance &CI,

can anyone tell me what is going on here?