1 //== CallGraph.h - AST-based Call graph ------------------------*- C++ -*--==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the AST-based CallGraph.
12 // A call graph for functions whose definitions/bodies are available in the
13 // current translation unit. The graph has a "virtual" root node that contains
14 // edges to all externally available functions.
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
18 #define LLVM_CLANG_ANALYSIS_CALLGRAPH
20 #include "clang/AST/DeclBase.h"
21 #include "clang/AST/RecursiveASTVisitor.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/GraphTraits.h"
24 #include "llvm/ADT/SetVector.h"
29 /// \brief The AST-based call graph.
31 /// The call graph extends itself with the given declarations by implementing
32 /// the recursive AST visitor, which constructs the graph by visiting the given
34 class CallGraph : public RecursiveASTVisitor<CallGraph> {
35 friend class CallGraphNode;
37 typedef llvm::DenseMap<const Decl *, CallGraphNode *> FunctionMapTy;
39 /// FunctionMap owns all CallGraphNodes.
40 FunctionMapTy FunctionMap;
42 /// This is a virtual root node that has edges to all the global functions -
43 /// 'main' or functions accessible from other translation units.
46 /// The list of nodes that have no parent. These are unreachable from Root.
47 /// Declarations can get to this list due to impressions in the graph, for
48 /// example, we do not track functions whose addresses were taken.
49 llvm::SetVector<CallGraphNode *> ParentlessNodes;
55 /// \brief Populate the call graph with the functions in the given
58 /// Recursively walks the declaration to find all the dependent Decls as well.
59 void addToCallGraph(Decl *D) {
63 /// \brief Determine if a declaration should be included in the graph.
64 static bool includeInGraph(const Decl *D);
66 /// \brief Lookup the node for the given declaration.
67 CallGraphNode *getNode(const Decl *) const;
69 /// \brief Lookup the node for the given declaration. If none found, insert
70 /// one into the graph.
71 CallGraphNode *getOrInsertNode(Decl *);
73 /// Iterators through all the elements in the graph. Note, this gives
74 /// non-deterministic order.
75 typedef FunctionMapTy::iterator iterator;
76 typedef FunctionMapTy::const_iterator const_iterator;
77 iterator begin() { return FunctionMap.begin(); }
78 iterator end() { return FunctionMap.end(); }
79 const_iterator begin() const { return FunctionMap.begin(); }
80 const_iterator end() const { return FunctionMap.end(); }
82 /// \brief Get the number of nodes in the graph.
83 unsigned size() const { return FunctionMap.size(); }
85 /// \ brief Get the virtual root of the graph, all the functions available
86 /// externally are represented as callees of the node.
87 CallGraphNode *getRoot() const { return Root; }
89 /// Iterators through all the nodes of the graph that have no parent. These
90 /// are the unreachable nodes, which are either unused or are due to us
91 /// failing to add a call edge due to the analysis imprecision.
92 typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator;
93 typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator;
94 nodes_iterator parentless_begin() { return ParentlessNodes.begin(); }
95 nodes_iterator parentless_end() { return ParentlessNodes.end(); }
97 parentless_begin() const { return ParentlessNodes.begin(); }
99 parentless_end() const { return ParentlessNodes.end(); }
101 void print(raw_ostream &os) const;
103 void viewGraph() const;
105 /// Part of recursive declaration visitation. We recursively visit all the
106 /// Declarations to collect the root functions.
107 bool VisitFunctionDecl(FunctionDecl *FD) {
108 // We skip function template definitions, as their semantics is
109 // only determined when they are instantiated.
110 if (includeInGraph(FD))
111 // If this function has external linkage, anything could call it.
112 // Note, we are not precise here. For example, the function could have
113 // its address taken.
114 addNodeForDecl(FD, FD->isGlobal());
118 /// Part of recursive declaration visitation.
119 bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
120 if (includeInGraph(MD))
121 addNodeForDecl(MD, true);
125 // We are only collecting the declarations, so do not step into the bodies.
126 bool TraverseStmt(Stmt *S) { return true; }
128 bool shouldWalkTypesOfTypeLocs() const { return false; }
131 /// \brief Add the given declaration to the call graph.
132 void addNodeForDecl(Decl *D, bool IsGlobal);
134 /// \brief Allocate a new node in the graph.
135 CallGraphNode *allocateNewNode(Decl *);
138 class CallGraphNode {
140 typedef CallGraphNode* CallRecord;
143 /// \brief The function/method declaration.
146 /// \brief The list of functions called from this node.
147 // Small vector might be more efficient since we are only tracking functions
148 // whose definition is in the current TU.
149 llvm::SmallVector<CallRecord, 5> CalledFunctions;
152 CallGraphNode(Decl *D) : FD(D) {}
154 typedef llvm::SmallVector<CallRecord, 5>::iterator iterator;
155 typedef llvm::SmallVector<CallRecord, 5>::const_iterator const_iterator;
157 /// Iterators through all the callees/children of the node.
158 inline iterator begin() { return CalledFunctions.begin(); }
159 inline iterator end() { return CalledFunctions.end(); }
160 inline const_iterator begin() const { return CalledFunctions.begin(); }
161 inline const_iterator end() const { return CalledFunctions.end(); }
163 inline bool empty() const {return CalledFunctions.empty(); }
164 inline unsigned size() const {return CalledFunctions.size(); }
166 void addCallee(CallGraphNode *N, CallGraph *CG) {
167 CalledFunctions.push_back(N);
168 CG->ParentlessNodes.remove(N);
171 Decl *getDecl() const { return FD; }
173 StringRef getName() const;
175 void print(raw_ostream &os) const;
179 } // end clang namespace
181 // Graph traits for iteration, viewing.
183 template <> struct GraphTraits<clang::CallGraphNode*> {
184 typedef clang::CallGraphNode NodeType;
185 typedef clang::CallGraphNode::CallRecord CallRecordTy;
186 typedef std::pointer_to_unary_function<CallRecordTy,
187 clang::CallGraphNode*> CGNDerefFun;
188 static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; }
189 typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
190 static inline ChildIteratorType child_begin(NodeType *N) {
191 return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
193 static inline ChildIteratorType child_end (NodeType *N) {
194 return map_iterator(N->end(), CGNDerefFun(CGNDeref));
196 static clang::CallGraphNode *CGNDeref(CallRecordTy P) {
201 template <> struct GraphTraits<const clang::CallGraphNode*> {
202 typedef const clang::CallGraphNode NodeType;
203 typedef NodeType::const_iterator ChildIteratorType;
204 static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; }
205 static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
206 static inline ChildIteratorType child_end (NodeType *N) { return N->end(); }
209 template <> struct GraphTraits<clang::CallGraph*>
210 : public GraphTraits<clang::CallGraphNode*> {
212 static NodeType *getEntryNode(clang::CallGraph *CGN) {
213 return CGN->getRoot(); // Start at the external node!
215 typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
216 typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
217 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
218 typedef mapped_iterator<clang::CallGraph::iterator, DerefFun> nodes_iterator;
220 static nodes_iterator nodes_begin(clang::CallGraph *CG) {
221 return map_iterator(CG->begin(), DerefFun(CGdereference));
223 static nodes_iterator nodes_end (clang::CallGraph *CG) {
224 return map_iterator(CG->end(), DerefFun(CGdereference));
226 static clang::CallGraphNode &CGdereference(PairTy P) {
230 static unsigned size(clang::CallGraph *CG) {
235 template <> struct GraphTraits<const clang::CallGraph*> :
236 public GraphTraits<const clang::CallGraphNode*> {
237 static NodeType *getEntryNode(const clang::CallGraph *CGN) {
238 return CGN->getRoot();
240 typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
241 typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
242 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
243 typedef mapped_iterator<clang::CallGraph::const_iterator,
244 DerefFun> nodes_iterator;
246 static nodes_iterator nodes_begin(const clang::CallGraph *CG) {
247 return map_iterator(CG->begin(), DerefFun(CGdereference));
249 static nodes_iterator nodes_end(const clang::CallGraph *CG) {
250 return map_iterator(CG->end(), DerefFun(CGdereference));
252 static clang::CallGraphNode &CGdereference(PairTy P) {
256 static unsigned size(const clang::CallGraph *CG) {
261 } // end llvm namespace