1 //== CallGraph.cpp - Call graph building ------------------------*- 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 defined the CallGraph and CallGraphNode classes.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
15 #define LLVM_CLANG_ANALYSIS_CALLGRAPH
17 #include "clang/Index/ASTLocation.h"
18 #include "clang/Index/Entity.h"
19 #include "clang/Index/Program.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/GraphTraits.h"
22 #include "llvm/ADT/STLExtras.h"
30 typedef std::pair<idx::ASTLocation, CallGraphNode*> CallRecord;
31 std::vector<CallRecord> CalledFunctions;
34 CallGraphNode(idx::Entity f) : F(f) {}
36 typedef std::vector<CallRecord>::iterator iterator;
37 typedef std::vector<CallRecord>::const_iterator const_iterator;
39 iterator begin() { return CalledFunctions.begin(); }
40 iterator end() { return CalledFunctions.end(); }
41 const_iterator begin() const { return CalledFunctions.begin(); }
42 const_iterator end() const { return CalledFunctions.end(); }
44 void addCallee(idx::ASTLocation L, CallGraphNode *Node) {
45 CalledFunctions.push_back(std::make_pair(L, Node));
48 bool hasCallee() const { return begin() != end(); }
50 std::string getName() const { return F.getPrintableName(); }
52 Decl *getDecl(ASTContext &Ctx) const { return F.getDecl(Ctx); }
56 /// Program manages all Entities.
59 typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy;
61 /// FunctionMap owns all CallGraphNodes.
62 FunctionMapTy FunctionMap;
64 /// CallerCtx maps a caller to its ASTContext.
65 llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx;
67 /// Root node is the 'main' function or 0.
70 /// ExternalCallingNode has edges to all external functions.
71 CallGraphNode *ExternalCallingNode;
74 CallGraph(idx::Program &P);
77 typedef FunctionMapTy::iterator iterator;
78 typedef FunctionMapTy::const_iterator const_iterator;
80 iterator begin() { return FunctionMap.begin(); }
81 iterator end() { return FunctionMap.end(); }
82 const_iterator begin() const { return FunctionMap.begin(); }
83 const_iterator end() const { return FunctionMap.end(); }
85 CallGraphNode *getRoot() { return Root; }
87 CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; }
89 void addTU(ASTContext &AST);
91 idx::Program &getProgram() { return Prog; }
93 CallGraphNode *getOrInsertFunction(idx::Entity F);
95 Decl *getDecl(CallGraphNode *Node);
97 void print(llvm::raw_ostream &os);
100 void ViewCallGraph() const;
103 } // end clang namespace
107 template <> struct GraphTraits<clang::CallGraph> {
108 typedef clang::CallGraph GraphType;
109 typedef clang::CallGraphNode NodeType;
111 typedef std::pair<clang::idx::ASTLocation, NodeType*> CGNPairTy;
112 typedef std::pointer_to_unary_function<CGNPairTy, NodeType*> CGNDerefFun;
114 typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
116 static NodeType *getEntryNode(GraphType *CG) {
117 return CG->getExternalCallingNode();
120 static ChildIteratorType child_begin(NodeType *N) {
121 return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
123 static ChildIteratorType child_end(NodeType *N) {
124 return map_iterator(N->end(), CGNDerefFun(CGNDeref));
127 typedef std::pair<clang::idx::Entity, NodeType*> PairTy;
128 typedef std::pointer_to_unary_function<PairTy, NodeType*> DerefFun;
130 typedef mapped_iterator<GraphType::const_iterator, DerefFun> nodes_iterator;
132 static nodes_iterator nodes_begin(const GraphType &CG) {
133 return map_iterator(CG.begin(), DerefFun(CGDeref));
135 static nodes_iterator nodes_end(const GraphType &CG) {
136 return map_iterator(CG.end(), DerefFun(CGDeref));
139 static NodeType *CGNDeref(CGNPairTy P) { return P.second; }
141 static NodeType *CGDeref(PairTy P) { return P.second; }
144 } // end llvm namespace