ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CallGraph.h
Go to the documentation of this file.
1 
2 #ifndef CALL_GRAPH_H
3 #define CALL_GRAPH_H
4 
5 #include <AstInterface.h>
6 #include <GraphDotOutput.h>
7 #include <VirtualGraphCreate.h>
8 
9 #include "AstDiagnostics.h"
10 
11 #include <sstream>
12 #include <iostream>
13 #include <string>
14 #include <functional>
15 #include <queue>
16 #include <boost/foreach.hpp>
17 #include <boost/unordered_map.hpp>
18 
20 
21 typedef Rose_STL_Container<SgFunctionDeclaration *> SgFunctionDeclarationPtrList;
22 typedef Rose_STL_Container<SgClassDefinition *> SgClassDefinitionPtrList;
23 
24 // DQ (1/31/2006): Changed name and made global function type symbol table a static data member.
25 // extern SgFunctionTypeTable Sgfunc_type_table;
26 // This header has to be here since it uses type SgFunctionDeclarationPtrList
27 #include "ClassHierarchyGraph.h"
28 
29 
30 //AS(090707) Added the CallTargetSet namespace to replace the CallGraphFunctionSolver class
31 namespace CallTargetSet
32 {
33  typedef Rose_STL_Container<SgFunctionDeclaration *> SgFunctionDeclarationPtrList;
34  typedef Rose_STL_Container<SgClassDefinition *> SgClassDefinitionPtrList;
35  // returns the list of declarations of all functions that may get called via the specified pointer
36  std::vector<SgFunctionDeclaration*> solveFunctionPointerCall ( SgPointerDerefExp *, SgProject * );
37 
38  // returns the list of declarations of all functions that may get called via a member function pointer
39  std::vector<SgFunctionDeclaration*> solveMemberFunctionPointerCall ( SgExpression *,ClassHierarchyWrapper * );
40  Rose_STL_Container<SgFunctionDeclaration*> solveFunctionPointerCallsFunctional(SgNode* node, SgFunctionType* functionType );
41 
42  // returns the list of declarations of all functions that may get called via a
43  // member function (non/polymorphic) call
44  std::vector<SgFunctionDeclaration*> solveMemberFunctionCall (
45  SgClassType *, ClassHierarchyWrapper *, SgMemberFunctionDeclaration *, bool , bool includePureVirtualFunc = false );
46 
51  std::vector<SgFunctionDeclaration*> solveConstructorInitializer ( SgConstructorInitializer* sgCtorInit);
52 
53  // Populates functionList with Properties of all functions that may get called.
55  ClassHierarchyWrapper* classHierarchy,
56  Rose_STL_Container<SgFunctionDeclaration*>& propList,
57  bool includePureVirtualFunc = false);
58 
64  ClassHierarchyWrapper* classHierarchy,
65  Rose_STL_Container<SgFunctionDefinition*>& calleeList);
66 
70  ClassHierarchyWrapper* classHierarchy,
71  Rose_STL_Container<SgFunctionDeclaration*>& calleeList,
72  bool includePureVirtualFunc = false);
73 
74  // Gets a vector of SgExpressions that are associated with the current SgFunctionDefinition.
75  // This functionality is necessary for virtual, interprocedural control flow graphs. However,
76  // it is costly and should be used infrequently (or optimized!).
78  ClassHierarchyWrapper* classHierarchy,
79  Rose_STL_Container<SgExpression*>& exps);
80 
81  // Gets the latest implementation of the member function from the ancestor hierarchy
83  SgMemberFunctionDeclaration *memberFunctionDeclaration,
84  ClassHierarchyWrapper *classHierarchy);
85 
86 };
87 
89 {
90  public:
91 
93 
94  bool isDefined ();
95 
97 
99  Rose_STL_Container<SgFunctionDeclaration *> functionList;
100 
102 
103  Rose_STL_Container<SgMemberFunctionDeclaration*> *findPointsToVirtualFunctions ( SgMemberFunctionDeclaration * );
104  bool compareFunctionDeclarations( SgFunctionDeclaration *f1, SgFunctionDeclaration *f2 );
105 };
106 
108 struct dummyFilter : public std::unary_function<bool,SgFunctionDeclaration*>
109 {
110  bool operator() (SgFunctionDeclaration* node) const; // always return true
111 };
112 
114 // Liao, 6/17/2012
115 struct ROSE_DLL_API builtinFilter : public std::unary_function<bool,SgFunctionDeclaration*>
116 {
117  bool operator() (SgFunctionDeclaration* node) const;
118 };
119 
121 {
122  public:
123  CallGraphBuilder( SgProject *proj);
125  void buildCallGraph();
127  template<typename Predicate>
128  void buildCallGraph(Predicate pred);
130  SgIncidenceDirectedGraph *getGraph();
131  //void classifyCallGraph();
132 
133  //We map each function to the corresponding graph node
134  boost::unordered_map<SgFunctionDeclaration*, SgGraphNode*>& getGraphNodesMapping(){ return graphNodes; }
135 
136  private:
139  //We map each function to the corresponding graph node
140  typedef boost::unordered_map<SgFunctionDeclaration*, SgGraphNode*> GraphNodes;
142 
143 };
145 //TODO this function is not defined? If so, need to be removed.
146 // AstDOTGeneration::writeIncidenceGraphToDOTFile() is used instead in the tutorial. Liao 6/17/2012
147 void GenerateDotGraph ( SgIncidenceDirectedGraph *graph, std::string fileName );
148 
149 class ROSE_DLL_API GetOneFuncDeclarationPerFunction : public std::unary_function<SgNode*, Rose_STL_Container<SgNode*> >
150 {
151  public:
152  result_type operator()(SgNode* node );
153 };
154 
155 template<typename Predicate>
156 void
158 {
159  // Adds additional constraints to the predicate. It makes no sense to analyze non-instantiated templates.
160  struct isSelected {
161  Predicate &pred;
162  isSelected(Predicate &pred): pred(pred) {}
163  bool operator()(SgNode *node) {
165  assert(!f || f==f->get_firstNondefiningDeclaration()); // node uniqueness test
167  }
168  };
169 
170  // Add nodes to the graph by querying the memory pool for function declarations, mapping them to unique declarations
171  // that can be used as keys in a map (using get_firstNondefiningDeclaration()), and filtering according to the predicate.
173  std::vector<FunctionData> callGraphData;
174  ClassHierarchyWrapper classHierarchy(project);
175  graphNodes.clear();
176  VariantVector vv(V_SgFunctionDeclaration);
178  std::vector<SgNode*> fdecl_nodes = NodeQuery::queryMemoryPool(defFunc, &vv);
179  BOOST_FOREACH(SgNode *node, fdecl_nodes) {
182  if (isSelected(pred)(unique) && graphNodes.find(unique)==graphNodes.end()) {
183  FunctionData fdata(unique, project, &classHierarchy); // computes functions called by unique
184  callGraphData.push_back(fdata);
185  std::string functionName = unique->get_qualified_name().getString();
186  SgGraphNode *graphNode = new SgGraphNode(functionName);
187  graphNode->set_SgNode(unique);
188  graphNodes[unique] = graphNode;
189  graph->addNode(graphNode);
190  }
191  }
192 
193  // Add edges to the graph
194  BOOST_FOREACH(FunctionData &currentFunction, callGraphData) {
195  SgGraphNode *srcNode = graphNodes.find(currentFunction.functionDeclaration)->second; // we inserted it above
196  std::vector<SgFunctionDeclaration*> &callees = currentFunction.functionList;
197  BOOST_FOREACH(SgFunctionDeclaration *callee, callees) {
198  if (isSelected(pred)(callee)) {
199  GraphNodes::iterator dstNodeFound = graphNodes.find(callee);
200  assert(dstNodeFound!=graphNodes.end()); // should have been added above
201  SgGraphNode *dstNode = dstNodeFound->second;
202  if (graph->checkIfDirectedGraphEdgeExists(srcNode, dstNode) == false)
203  graph->addDirectedEdge(srcNode, dstNode);
204  }
205  }
206  }
207 }
208 
209 // endif for CALL_GRAPH_H
210 #endif
211