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