CallGraph.h revision f20288c91601dd3fbab6362a3400a0e6c472795f
1f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//== CallGraph.cpp - Call graph building ------------------------*- C++ -*--==//
2f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//
3f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//                     The LLVM Compiler Infrastructure
4f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//
5f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org// This file is distributed under the University of Illinois Open Source
6f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org// License. See LICENSE.TXT for details.
7f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//
8f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//===----------------------------------------------------------------------===//
9f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//
10f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//  This file defined the CallGraph and CallGraphNode classes.
11f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//
12f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org//===----------------------------------------------------------------------===//
13f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
14f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
15f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#define LLVM_CLANG_ANALYSIS_CALLGRAPH
16f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
17f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#include "clang/Index/ASTLocation.h"
18f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#include "clang/Index/Entity.h"
19f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#include "clang/Index/Program.h"
20f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#include "llvm/ADT/DenseMap.h"
21f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#include "llvm/ADT/GraphTraits.h"
22f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#include "llvm/ADT/STLExtras.h"
23f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#include <vector>
24f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org#include <map>
25f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
26f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.orgnamespace clang {
27f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
28f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.orgclass CallGraphNode {
29f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  idx::Entity F;
30f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef std::pair<idx::ASTLocation, CallGraphNode*> CallRecord;
31f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  std::vector<CallRecord> CalledFunctions;
32f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
33f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.orgpublic:
3483a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org  CallGraphNode(idx::Entity f) : F(f) {}
35f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
36f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef std::vector<CallRecord>::iterator iterator;
37f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef std::vector<CallRecord>::const_iterator const_iterator;
38f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
39f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  iterator begin() { return CalledFunctions.begin(); }
40f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  iterator end()   { return CalledFunctions.end(); }
41f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  const_iterator begin() const { return CalledFunctions.begin(); }
42f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  const_iterator end()   const { return CalledFunctions.end();   }
43f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
44f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  void addCallee(idx::ASTLocation L, CallGraphNode *Node) {
45f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org    CalledFunctions.push_back(std::make_pair(L, Node));
46f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  }
47f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
48f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  bool hasCallee() const { return begin() != end(); }
49f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
50f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  std::string getName() const { return F.getPrintableName(); }
51f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
52f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  Decl *getDecl(ASTContext &Ctx) const { return F.getDecl(Ctx); }
53f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org};
54f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
55f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.orgclass CallGraph {
56f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  /// Program manages all Entities.
57f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  idx::Program Prog;
58f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
59f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy;
60f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
61f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  /// FunctionMap owns all CallGraphNodes.
62f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  FunctionMapTy FunctionMap;
63f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
64f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  /// CallerCtx maps a caller to its ASTContext.
65f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx;
66f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
67f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  /// Root node is the 'main' function or 0.
68f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  CallGraphNode *Root;
69f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
70f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  /// ExternalCallingNode has edges to all external functions.
71f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  CallGraphNode *ExternalCallingNode;
72f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
73f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.orgpublic:
74f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  CallGraph();
75f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  ~CallGraph();
76f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
77f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef FunctionMapTy::iterator iterator;
78f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef FunctionMapTy::const_iterator const_iterator;
79f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
80f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  iterator begin() { return FunctionMap.begin(); }
81f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  iterator end()   { return FunctionMap.end();   }
82f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  const_iterator begin() const { return FunctionMap.begin(); }
83f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  const_iterator end()   const { return FunctionMap.end();   }
84f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
85f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  CallGraphNode *getRoot() { return Root; }
86f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
87f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; }
88f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
89f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  void addTU(ASTContext &AST);
90f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
91f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  idx::Program &getProgram() { return Prog; }
92f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
93f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  CallGraphNode *getOrInsertFunction(idx::Entity F);
94f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
95f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  Decl *getDecl(CallGraphNode *Node);
96f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
97f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  void print(llvm::raw_ostream &os);
98f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  void dump();
99f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
100f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  void ViewCallGraph() const;
101f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org};
102f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
103f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org} // end clang namespace
104f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
105f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.orgnamespace llvm {
106f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
107f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.orgtemplate <> struct GraphTraits<clang::CallGraph> {
108f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef clang::CallGraph GraphType;
109f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef clang::CallGraphNode NodeType;
110f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org
111f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef std::pair<clang::idx::ASTLocation, NodeType*> CGNPairTy;
112f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org  typedef std::pointer_to_unary_function<CGNPairTy, NodeType*> CGNDerefFun;
113
114  typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
115
116  static NodeType *getEntryNode(GraphType *CG) {
117    return CG->getExternalCallingNode();
118  }
119
120  static ChildIteratorType child_begin(NodeType *N) {
121    return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
122  }
123  static ChildIteratorType child_end(NodeType *N) {
124    return map_iterator(N->end(), CGNDerefFun(CGNDeref));
125  }
126
127  typedef std::pair<clang::idx::Entity, NodeType*> PairTy;
128  typedef std::pointer_to_unary_function<PairTy, NodeType*> DerefFun;
129
130  typedef mapped_iterator<GraphType::const_iterator, DerefFun> nodes_iterator;
131
132  static nodes_iterator nodes_begin(const GraphType &CG) {
133    return map_iterator(CG.begin(), DerefFun(CGDeref));
134  }
135  static nodes_iterator nodes_end(const GraphType &CG) {
136    return map_iterator(CG.end(), DerefFun(CGDeref));
137  }
138
139  static NodeType *CGNDeref(CGNPairTy P) { return P.second; }
140
141  static NodeType *CGDeref(PairTy P) { return P.second; }
142};
143
144} // end llvm namespace
145
146#endif
147