clang API Documentation
00001 //== CallGraph.h - AST-based Call graph ------------------------*- C++ -*--==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the AST-based CallGraph. 00011 // 00012 // A call graph for functions whose definitions/bodies are available in the 00013 // current translation unit. The graph has a "virtual" root node that contains 00014 // edges to all externally available functions. 00015 //===----------------------------------------------------------------------===// 00016 00017 #ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH 00018 #define LLVM_CLANG_ANALYSIS_CALLGRAPH 00019 00020 #include "clang/AST/DeclBase.h" 00021 #include "clang/AST/RecursiveASTVisitor.h" 00022 #include "llvm/ADT/DenseMap.h" 00023 #include "llvm/ADT/GraphTraits.h" 00024 #include "llvm/ADT/SetVector.h" 00025 00026 namespace clang { 00027 class CallGraphNode; 00028 00029 /// \class The AST-based call graph. 00030 /// 00031 /// The call graph extends itself with the given declarations by implementing 00032 /// the recursive AST visitor, which constructs the graph by visiting the given 00033 /// declarations. 00034 class CallGraph : public RecursiveASTVisitor<CallGraph> { 00035 friend class CallGraphNode; 00036 00037 typedef llvm::DenseMap<const Decl *, CallGraphNode *> FunctionMapTy; 00038 00039 /// FunctionMap owns all CallGraphNodes. 00040 FunctionMapTy FunctionMap; 00041 00042 /// This is a virtual root node that has edges to all the global functions - 00043 /// 'main' or functions accessible from other translation units. 00044 CallGraphNode *Root; 00045 00046 /// The list of nodes that have no parent. These are unreachable from Root. 00047 /// Declarations can get to this list due to impressions in the graph, for 00048 /// example, we do not track functions whose addresses were taken. 00049 llvm::SetVector<CallGraphNode *> ParentlessNodes; 00050 00051 public: 00052 CallGraph(); 00053 ~CallGraph(); 00054 00055 /// \brief Populate the call graph with the functions in the given 00056 /// declaration. 00057 /// 00058 /// Recursively walks the declaration to find all the dependent Decls as well. 00059 void addToCallGraph(Decl *D) { 00060 TraverseDecl(D); 00061 } 00062 00063 /// \brief Determine if a declaration should be included in the graph. 00064 static bool includeInGraph(const Decl *D); 00065 00066 /// \brief Lookup the node for the given declaration. 00067 CallGraphNode *getNode(const Decl *) const; 00068 00069 /// \brief Lookup the node for the given declaration. If none found, insert 00070 /// one into the graph. 00071 CallGraphNode *getOrInsertNode(Decl *); 00072 00073 /// Iterators through all the elements in the graph. Note, this gives 00074 /// non-deterministic order. 00075 typedef FunctionMapTy::iterator iterator; 00076 typedef FunctionMapTy::const_iterator const_iterator; 00077 iterator begin() { return FunctionMap.begin(); } 00078 iterator end() { return FunctionMap.end(); } 00079 const_iterator begin() const { return FunctionMap.begin(); } 00080 const_iterator end() const { return FunctionMap.end(); } 00081 00082 /// \brief Get the number of nodes in the graph. 00083 unsigned size() const { return FunctionMap.size(); } 00084 00085 /// \ brief Get the virtual root of the graph, all the functions available 00086 /// externally are represented as callees of the node. 00087 CallGraphNode *getRoot() const { return Root; } 00088 00089 /// Iterators through all the nodes of the graph that have no parent. These 00090 /// are the unreachable nodes, which are either unused or are due to us 00091 /// failing to add a call edge due to the analysis imprecision. 00092 typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator; 00093 typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator; 00094 nodes_iterator parentless_begin() { return ParentlessNodes.begin(); } 00095 nodes_iterator parentless_end() { return ParentlessNodes.end(); } 00096 const_nodes_iterator 00097 parentless_begin() const { return ParentlessNodes.begin(); } 00098 const_nodes_iterator 00099 parentless_end() const { return ParentlessNodes.end(); } 00100 00101 void print(raw_ostream &os) const; 00102 void dump() const; 00103 void viewGraph() const; 00104 00105 /// Part of recursive declaration visitation. 00106 bool VisitFunctionDecl(FunctionDecl *FD) { 00107 // We skip function template definitions, as their semantics is 00108 // only determined when they are instantiated. 00109 if (includeInGraph(FD)) 00110 // If this function has external linkage, anything could call it. 00111 // Note, we are not precise here. For example, the function could have 00112 // its address taken. 00113 addNodeForDecl(FD, FD->isGlobal()); 00114 return true; 00115 } 00116 00117 /// Part of recursive declaration visitation. 00118 bool VisitObjCMethodDecl(ObjCMethodDecl *MD) { 00119 if (includeInGraph(MD)) 00120 addNodeForDecl(MD, true); 00121 return true; 00122 } 00123 00124 private: 00125 /// \brief Add the given declaration to the call graph. 00126 void addNodeForDecl(Decl *D, bool IsGlobal); 00127 00128 /// \brief Allocate a new node in the graph. 00129 CallGraphNode *allocateNewNode(Decl *); 00130 }; 00131 00132 class CallGraphNode { 00133 public: 00134 typedef CallGraphNode* CallRecord; 00135 00136 private: 00137 /// \brief The function/method declaration. 00138 Decl *FD; 00139 00140 /// \brief The list of functions called from this node. 00141 // Small vector might be more efficient since we are only tracking functions 00142 // whose definition is in the current TU. 00143 llvm::SmallVector<CallRecord, 5> CalledFunctions; 00144 00145 public: 00146 CallGraphNode(Decl *D) : FD(D) {} 00147 00148 typedef llvm::SmallVector<CallRecord, 5>::iterator iterator; 00149 typedef llvm::SmallVector<CallRecord, 5>::const_iterator const_iterator; 00150 00151 /// Iterators through all the callees/children of the node. 00152 inline iterator begin() { return CalledFunctions.begin(); } 00153 inline iterator end() { return CalledFunctions.end(); } 00154 inline const_iterator begin() const { return CalledFunctions.begin(); } 00155 inline const_iterator end() const { return CalledFunctions.end(); } 00156 00157 inline bool empty() const {return CalledFunctions.empty(); } 00158 inline unsigned size() const {return CalledFunctions.size(); } 00159 00160 void addCallee(CallGraphNode *N, CallGraph *CG) { 00161 CalledFunctions.push_back(N); 00162 CG->ParentlessNodes.remove(N); 00163 } 00164 00165 Decl *getDecl() const { return FD; } 00166 00167 StringRef getName() const; 00168 00169 void print(raw_ostream &os) const; 00170 void dump() const; 00171 }; 00172 00173 } // end clang namespace 00174 00175 // Graph traits for iteration, viewing. 00176 namespace llvm { 00177 template <> struct GraphTraits<clang::CallGraphNode*> { 00178 typedef clang::CallGraphNode NodeType; 00179 typedef clang::CallGraphNode::CallRecord CallRecordTy; 00180 typedef std::pointer_to_unary_function<CallRecordTy, 00181 clang::CallGraphNode*> CGNDerefFun; 00182 static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; } 00183 typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType; 00184 static inline ChildIteratorType child_begin(NodeType *N) { 00185 return map_iterator(N->begin(), CGNDerefFun(CGNDeref)); 00186 } 00187 static inline ChildIteratorType child_end (NodeType *N) { 00188 return map_iterator(N->end(), CGNDerefFun(CGNDeref)); 00189 } 00190 static clang::CallGraphNode *CGNDeref(CallRecordTy P) { 00191 return P; 00192 } 00193 }; 00194 00195 template <> struct GraphTraits<const clang::CallGraphNode*> { 00196 typedef const clang::CallGraphNode NodeType; 00197 typedef NodeType::const_iterator ChildIteratorType; 00198 static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; } 00199 static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();} 00200 static inline ChildIteratorType child_end (NodeType *N) { return N->end(); } 00201 }; 00202 00203 template <> struct GraphTraits<clang::CallGraph*> 00204 : public GraphTraits<clang::CallGraphNode*> { 00205 00206 static NodeType *getEntryNode(clang::CallGraph *CGN) { 00207 return CGN->getRoot(); // Start at the external node! 00208 } 00209 typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy; 00210 typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun; 00211 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph 00212 typedef mapped_iterator<clang::CallGraph::iterator, DerefFun> nodes_iterator; 00213 00214 static nodes_iterator nodes_begin(clang::CallGraph *CG) { 00215 return map_iterator(CG->begin(), DerefFun(CGdereference)); 00216 } 00217 static nodes_iterator nodes_end (clang::CallGraph *CG) { 00218 return map_iterator(CG->end(), DerefFun(CGdereference)); 00219 } 00220 static clang::CallGraphNode &CGdereference(PairTy P) { 00221 return *(P.second); 00222 } 00223 00224 static unsigned size(clang::CallGraph *CG) { 00225 return CG->size(); 00226 } 00227 }; 00228 00229 template <> struct GraphTraits<const clang::CallGraph*> : 00230 public GraphTraits<const clang::CallGraphNode*> { 00231 static NodeType *getEntryNode(const clang::CallGraph *CGN) { 00232 return CGN->getRoot(); 00233 } 00234 typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy; 00235 typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun; 00236 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph 00237 typedef mapped_iterator<clang::CallGraph::const_iterator, 00238 DerefFun> nodes_iterator; 00239 00240 static nodes_iterator nodes_begin(const clang::CallGraph *CG) { 00241 return map_iterator(CG->begin(), DerefFun(CGdereference)); 00242 } 00243 static nodes_iterator nodes_end(const clang::CallGraph *CG) { 00244 return map_iterator(CG->end(), DerefFun(CGdereference)); 00245 } 00246 static clang::CallGraphNode &CGdereference(PairTy P) { 00247 return *(P.second); 00248 } 00249 00250 static unsigned size(const clang::CallGraph *CG) { 00251 return CG->size(); 00252 } 00253 }; 00254 00255 } // end llvm namespace 00256 00257 #endif