[cfe-dev] clang plugin registry
akshay ratnaparkhi
ackk007 at gmail.com
Fri Apr 6 02:18:21 PDT 2012
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<FunctionDecl>(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<CGBuilder>,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<CGDeclVisitor>{
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<CGBuilderAction>
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::RegistryTraits<clang::PluginASTAction>
>::Add<<anonymous>::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::RegistryTraits<clang::PluginASTAction>
>::Add<<anonymous>::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?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120406/a3e86b9f/attachment.html>
More information about the cfe-dev
mailing list