CallGraph.h revision 16a705f26d069a0c9e391bf064bcd1bc3496ca83
1//== CallGraph.cpp - Call graph building ------------------------*- C++ -*--==// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defined the CallGraph and CallGraphNode classes. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH 15#define LLVM_CLANG_ANALYSIS_CALLGRAPH 16 17#include "clang/Index/ASTLocation.h" 18#include "clang/Index/Entity.h" 19#include "clang/Index/Program.h" 20#include "clang/Frontend/ASTUnit.h" 21#include "llvm/ADT/DenseMap.h" 22#include "llvm/ADT/GraphTraits.h" 23#include "llvm/ADT/STLExtras.h" 24#include <vector> 25#include <map> 26 27namespace clang { 28 29class CallGraphNode { 30 idx::Entity F; 31 typedef std::pair<idx::ASTLocation, CallGraphNode*> CallRecord; 32 std::vector<CallRecord> CalledFunctions; 33 34public: 35 CallGraphNode(idx::Entity f) : F(f) {} 36 37 typedef std::vector<CallRecord>::iterator iterator; 38 typedef std::vector<CallRecord>::const_iterator const_iterator; 39 40 iterator begin() { return CalledFunctions.begin(); } 41 iterator end() { return CalledFunctions.end(); } 42 const_iterator begin() const { return CalledFunctions.begin(); } 43 const_iterator end() const { return CalledFunctions.end(); } 44 45 void addCallee(idx::ASTLocation L, CallGraphNode *Node) { 46 CalledFunctions.push_back(std::make_pair(L, Node)); 47 } 48 49 bool hasCallee() const { return begin() != end(); } 50 51 std::string getName() const { return F.getPrintableName(); } 52}; 53 54class CallGraph { 55 /// Program manages all Entities. 56 idx::Program Prog; 57 58 typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy; 59 60 /// FunctionMap owns all CallGraphNodes. 61 FunctionMapTy FunctionMap; 62 63 /// CallerCtx maps a caller to its ASTContext. 64 llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx; 65 66 /// Entry node of the call graph. 67 // FIXME: find the entry of the graph. 68 CallGraphNode *Entry; 69 70public: 71 ~CallGraph(); 72 73 typedef FunctionMapTy::iterator iterator; 74 typedef FunctionMapTy::const_iterator const_iterator; 75 76 iterator begin() { return FunctionMap.begin(); } 77 iterator end() { return FunctionMap.end(); } 78 const_iterator begin() const { return FunctionMap.begin(); } 79 const_iterator end() const { return FunctionMap.end(); } 80 81 CallGraphNode *getEntry() { return Entry; } 82 83 void addTU(ASTUnit &AST); 84 85 idx::Program &getProgram() { return Prog; } 86 87 CallGraphNode *getOrInsertFunction(idx::Entity F); 88 89 void print(llvm::raw_ostream &os); 90 void dump(); 91 92 void ViewCallGraph() const; 93}; 94 95} // end clang namespace 96 97namespace llvm { 98 99template <> struct GraphTraits<clang::CallGraph> { 100 typedef clang::CallGraph GraphType; 101 typedef clang::CallGraphNode NodeType; 102 103 typedef std::pair<clang::idx::ASTLocation, NodeType*> CGNPairTy; 104 typedef std::pointer_to_unary_function<CGNPairTy, NodeType*> CGNDerefFun; 105 106 typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType; 107 108 static NodeType *getEntryNode(GraphType *CG) { 109 return CG->getEntry(); 110 } 111 112 static ChildIteratorType child_begin(NodeType *N) { 113 return map_iterator(N->begin(), CGNDerefFun(CGNDeref)); 114 } 115 static ChildIteratorType child_end(NodeType *N) { 116 return map_iterator(N->end(), CGNDerefFun(CGNDeref)); 117 } 118 119 typedef std::pair<clang::idx::Entity, NodeType*> PairTy; 120 typedef std::pointer_to_unary_function<PairTy, NodeType*> DerefFun; 121 122 typedef mapped_iterator<GraphType::const_iterator, DerefFun> nodes_iterator; 123 124 static nodes_iterator nodes_begin(const GraphType &CG) { 125 return map_iterator(CG.begin(), DerefFun(CGDeref)); 126 } 127 static nodes_iterator nodes_end(const GraphType &CG) { 128 return map_iterator(CG.end(), DerefFun(CGDeref)); 129 } 130 131 static NodeType *CGNDeref(CGNPairTy P) { return P.second; } 132 133 static NodeType *CGDeref(PairTy P) { return P.second; } 134}; 135 136} // end llvm namespace 137 138#endif 139