clang API Documentation

CallGraph.h
Go to the documentation of this file.
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