//== CallGraph.cpp - Call graph building ------------------------*- C++ -*--==// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defined the CallGraph and CallGraphNode classes. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH #define LLVM_CLANG_ANALYSIS_CALLGRAPH #include "clang/Index/ASTLocation.h" #include "clang/Index/Entity.h" #include "clang/Index/Program.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/STLExtras.h" #include #include namespace clang { class CallGraphNode { idx::Entity F; typedef std::pair CallRecord; std::vector CalledFunctions; public: CallGraphNode(idx::Entity f) : F(f) {} typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; iterator begin() { return CalledFunctions.begin(); } iterator end() { return CalledFunctions.end(); } const_iterator begin() const { return CalledFunctions.begin(); } const_iterator end() const { return CalledFunctions.end(); } void addCallee(idx::ASTLocation L, CallGraphNode *Node) { CalledFunctions.push_back(std::make_pair(L, Node)); } bool hasCallee() const { return begin() != end(); } std::string getName() const { return F.getPrintableName(); } Decl *getDecl(ASTContext &Ctx) const { return F.getDecl(Ctx); } }; class CallGraph { /// Program manages all Entities. idx::Program &Prog; typedef std::map FunctionMapTy; /// FunctionMap owns all CallGraphNodes. FunctionMapTy FunctionMap; /// CallerCtx maps a caller to its ASTContext. llvm::DenseMap CallerCtx; /// Root node is the 'main' function or 0. CallGraphNode *Root; /// ExternalCallingNode has edges to all external functions. CallGraphNode *ExternalCallingNode; public: CallGraph(idx::Program &P); ~CallGraph(); 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(); } CallGraphNode *getRoot() { return Root; } CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; } void addTU(ASTContext &AST); idx::Program &getProgram() { return Prog; } CallGraphNode *getOrInsertFunction(idx::Entity F); Decl *getDecl(CallGraphNode *Node); void print(raw_ostream &os); void dump(); void ViewCallGraph() const; }; } // end clang namespace namespace llvm { template <> struct GraphTraits { typedef clang::CallGraph GraphType; typedef clang::CallGraphNode NodeType; typedef std::pair CGNPairTy; typedef std::pointer_to_unary_function CGNDerefFun; typedef mapped_iterator ChildIteratorType; static NodeType *getEntryNode(GraphType *CG) { return CG->getExternalCallingNode(); } static ChildIteratorType child_begin(NodeType *N) { return map_iterator(N->begin(), CGNDerefFun(CGNDeref)); } static ChildIteratorType child_end(NodeType *N) { return map_iterator(N->end(), CGNDerefFun(CGNDeref)); } typedef std::pair PairTy; typedef std::pointer_to_unary_function DerefFun; typedef mapped_iterator nodes_iterator; static nodes_iterator nodes_begin(const GraphType &CG) { return map_iterator(CG.begin(), DerefFun(CGDeref)); } static nodes_iterator nodes_end(const GraphType &CG) { return map_iterator(CG.end(), DerefFun(CGDeref)); } static NodeType *CGNDeref(CGNPairTy P) { return P.second; } static NodeType *CGDeref(PairTy P) { return P.second; } }; } // end llvm namespace #endif