ROSE 0.11.145.147
CallGraph.h
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
19class FunctionData;
20
21typedef Rose_STL_Container<SgFunctionDeclaration *> SgFunctionDeclarationPtrList;
22typedef 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
31namespace CallTargetSet
32{
33 typedef Rose_STL_Container<SgFunctionDeclaration *> SgFunctionDeclarationPtrList;
34 typedef Rose_STL_Container<SgClassDefinition *> SgClassDefinitionPtrList;
47 std::vector<SgFunctionDeclaration*> solveFunctionPointerCall ( SgPointerDerefExp *);
48
49 // returns the list of declarations of all functions that may get called via a member function pointer
50 std::vector<SgFunctionDeclaration*> solveMemberFunctionPointerCall ( SgExpression *,ClassHierarchyWrapper * );
51
66 Rose_STL_Container<SgFunctionDeclaration*> solveFunctionPointerCallsFunctional(SgNode* node, SgFunctionType* functionType );
67
68 // returns the list of declarations of all functions that may get called via a
69 // member function (non/polymorphic) call
70 std::vector<SgFunctionDeclaration*> solveMemberFunctionCall (
71 SgClassType *, ClassHierarchyWrapper *, SgMemberFunctionDeclaration *, bool , bool includePureVirtualFunc = false );
72
74 std::vector<SgFunctionDeclaration*> solveConstructorInitializer ( SgConstructorInitializer* sgCtorInit);
75
76 // Populates functionList with Properties of all functions that may get called.
77 ROSE_DLL_API void getPropertiesForExpression(SgExpression* exp,
78 ClassHierarchyWrapper* classHierarchy,
79 Rose_STL_Container<SgFunctionDeclaration*>& propList,
80 bool includePureVirtualFunc = false);
81
86 void getDefinitionsForExpression(SgExpression* exp,
87 ClassHierarchyWrapper* classHierarchy,
88 Rose_STL_Container<SgFunctionDefinition*>& calleeList);
89
92 void getDeclarationsForExpression(SgExpression* exp,
93 ClassHierarchyWrapper* classHierarchy,
94 Rose_STL_Container<SgFunctionDeclaration*>& calleeList,
95 bool includePureVirtualFunc = false);
96
97 // Gets a vector of SgExpressions that are associated with the current SgFunctionDefinition.
98 // This functionality is necessary for virtual, interprocedural control flow graphs. However,
99 // it is costly and should be used infrequently (or optimized!).
100 void getExpressionsForDefinition(SgFunctionDefinition* targetDef,
101 ClassHierarchyWrapper* classHierarchy,
102 Rose_STL_Container<SgExpression*>& exps);
103
104 // Gets the latest implementation of the member function from the ancestor hierarchy
105 SgFunctionDeclaration * getFirstVirtualFunctionDefinitionFromAncestors(SgClassType *crtClass,
106 SgMemberFunctionDeclaration *memberFunctionDeclaration,
107 ClassHierarchyWrapper *classHierarchy);
108
109};
110
111class ROSE_DLL_API FunctionData
112{
113 public:
114
115 bool hasDefinition;
116
117 bool isDefined ();
118
119 FunctionData(SgFunctionDeclaration* functionDeclaration, SgProject *project, ClassHierarchyWrapper * );
120
122 Rose_STL_Container<SgFunctionDeclaration *> functionList;
123
124 SgFunctionDeclaration* functionDeclaration;
125
126 Rose_STL_Container<SgMemberFunctionDeclaration*> *findPointsToVirtualFunctions ( SgMemberFunctionDeclaration * );
127 bool compareFunctionDeclarations( SgFunctionDeclaration *f1, SgFunctionDeclaration *f2 );
128};
129
132{
133 using result_type = bool;
134 result_type operator() (SgFunctionDeclaration* node) const; // always return true
135};
136
138// Liao, 6/17/2012
139struct ROSE_DLL_API builtinFilter
140{
141 using result_type = bool;
142 result_type operator() (SgFunctionDeclaration* node) const;
143};
144
145class ROSE_DLL_API CallGraphBuilder
146{
147 public:
152 template<typename Predicate>
153 void buildCallGraph(Predicate pred);
156 //void classifyCallGraph();
157
158 //We map each function to the corresponding graph node
159 boost::unordered_map<SgFunctionDeclaration*, SgGraphNode*>& getGraphNodesMapping(){ return graphNodes; }
160
165
166 private:
167 SgProject *project;
169 //We map each function to the corresponding graph node
170 typedef boost::unordered_map<SgFunctionDeclaration*, SgGraphNode*> GraphNodes;
171 GraphNodes graphNodes;
172
173};
175//TODO this function is not defined? If so, need to be removed.
176// AstDOTGeneration::writeIncidenceGraphToDOTFile() is used instead in the tutorial. Liao 6/17/2012
177void GenerateDotGraph ( SgIncidenceDirectedGraph *graph, std::string fileName );
178
180{
181 using result_type = Rose_STL_Container<SgNode*>;
182 result_type operator()(SgNode* node);
183};
184
185template<typename Predicate>
186void
188{
189 // Adds additional constraints to the predicate. It makes no sense to analyze non-instantiated templates.
190 struct isSelected {
191 Predicate &pred;
192 isSelected(Predicate &pred): pred(pred) {}
193 bool operator()(SgNode *node) {
194 SgFunctionDeclaration *f = isSgFunctionDeclaration(node);
195 // TV (10/26/2018): FIXME ROSE-1487
196 // assert(!f || f==f->get_firstNondefiningDeclaration()); // node uniqueness test
197#if 0
198 // DQ (8/25/2016): This is not a meaningful test since all functions will be in the memory pool, including template functions and template member functions.
199 if(isSgTemplateFunctionDeclaration(f)||isSgTemplateMemberFunctionDeclaration(f)) {
200 std::cerr<<"Error: CallGraphBuilder: call referring to node "<<f->class_name()<<" :: function-name:"<<f->get_qualified_name()<<std::endl;
201 }
202#endif
203 return f && f==f->get_firstNondefiningDeclaration() && !isSgTemplateMemberFunctionDeclaration(f) && !isSgTemplateFunctionDeclaration(f) && pred(f);
204 }
205 };
206
207 // Add nodes to the graph by querying the memory pool for function declarations, mapping them to unique declarations
208 // that can be used as keys in a map (using get_firstNondefiningDeclaration()), and filtering according to the predicate.
209 graph = new SgIncidenceDirectedGraph();
210 std::vector<FunctionData> callGraphData;
211 ClassHierarchyWrapper classHierarchy(project);
212 graphNodes.clear();
213 VariantVector vv(V_SgFunctionDeclaration);
215 std::vector<SgNode*> fdecl_nodes = NodeQuery::queryMemoryPool(defFunc, &vv);
216 BOOST_FOREACH(SgNode *node, fdecl_nodes) {
217 SgFunctionDeclaration *fdecl = isSgFunctionDeclaration(node);
218 SgFunctionDeclaration *unique = isSgFunctionDeclaration(fdecl->get_firstNondefiningDeclaration());
219#if 0 //debug
220 printf ("In buildCallGraph(): loop over functions from memory pool: fdecl = %p = %s name = %s \n",fdecl,fdecl->class_name().c_str(),fdecl->get_name().str());
221 printf ("In buildCallGraph(): loop over functions from memory pool: unique = %p = %s name = %s \n",unique,unique->class_name().c_str(),unique->get_name().str());
222#endif
223 if (isSelected(pred)(unique) && hasGraphNodeFor(unique) == NULL)
224 {
225#if 0 //debug
226 printf ("Collect function calls in unique function: unique = %p \n",unique);
227#endif
228 FunctionData fdata(unique, project, &classHierarchy); // computes functions called by unique
229 callGraphData.push_back(fdata);
230 std::string functionName = unique->get_qualified_name().getString();
231 SgGraphNode *graphNode = new SgGraphNode(functionName);
232 graphNode->set_SgNode(unique);
233 graphNodes[unique] = graphNode;
234 graph->addNode(graphNode);
235 printf("Added function %s %p\n", functionName.c_str(), unique);
236 }
237 else
238 {
239#if 0 //debug
240 printf ("Function not selected for processing: unique = %p \n",unique);
241 printf (" --- isSelected(pred)(unique) = %s \n",isSelected(pred)(unique) ? "true" : "false");
242 printf (" --- graphNodes.find(unique)==graphNodes.end() = %s \n",graphNodes.find(unique)==graphNodes.end() ? "true" : "false");
243#endif
244 }
245 }
246
247 // Add edges to the graph
248 BOOST_FOREACH(FunctionData &currentFunction, callGraphData) {
249 SgFunctionDeclaration* curFuncDecl = currentFunction.functionDeclaration;
250 std::string curFuncName = curFuncDecl->get_qualified_name().getString();
251 SgGraphNode * srcNode = hasGraphNodeFor(currentFunction.functionDeclaration);
252 ROSE_ASSERT(srcNode != NULL);
253 std::vector<SgFunctionDeclaration*> & callees = currentFunction.functionList;
254 BOOST_FOREACH(SgFunctionDeclaration * callee, callees) {
255 if (isSelected(pred)(callee)) {
256 SgGraphNode * dstNode = getGraphNodeFor(callee); //getGraphNode here, see function comment
257 ROSE_ASSERT(dstNode != NULL);
258 if (graph->checkIfDirectedGraphEdgeExists(srcNode, dstNode) == false)
259 graph->addDirectedEdge(srcNode, dstNode);
260 }
261 }
262 }
263}
264
265// endif for CALL_GRAPH_H
266#endif
267
SgIncidenceDirectedGraph * getGraph()
Grab the call graph built.
SgGraphNode * hasGraphNodeFor(SgFunctionDeclaration *fdecl) const
Retrieve the node matching a function declaration using firstNondefiningDeclaration (does not work ac...
void buildCallGraph()
Default builder filtering nothing in the call graph.
SgGraphNode * getGraphNodeFor(SgFunctionDeclaration *fdecl) const
Retrieve the node matching a function declaration (using mangled name to resolve across translation u...
Rose_STL_Container< SgFunctionDeclaration * > functionList
All the callees of this function.
Definition CallGraph.h:122
This class represents the call of a class constructor to initialize a variable. For example "Foo foo;...
SgDeclarationStatement * get_firstNondefiningDeclaration() const
This is an access function for the SgDeclarationStatement::p_firstNondefiningDeclaration data member ...
This class represents the notion of an expression. Expressions are derived from SgLocatedNodes,...
This class represents the concept of a function declaration statement.
virtual std::string class_name() const override
returns a string representing the class name
This class represents the concept of a scope in C++ (e.g. global scope, fuction scope,...
This class represents a type for all functions.
SgGraphNode * addNode(const std::string &name="", SgNode *sg_node=NULL)
Support for adding SgGraphNode to SgGraph.
SgDirectedGraphEdge * addDirectedEdge(SgGraphNode *a, SgGraphNode *b, const std::string &name="")
Support for adding SgGraphEdge to SgGraph.
This class represents the concept of a member function declaration statement.
This class represents the base class for all IR nodes within Sage III.
This class represents a source project, with a list of SgFile objects and global information about th...
A function object to filter out builtin functions in a call graph (only non-builtin functions will be...
Definition CallGraph.h:140
A function object to be used as a predicate to filter out functions in a call graph: it does not filt...
Definition CallGraph.h:132