ROSE  0.9.10.54
virtualCFG.h
1 #ifndef VIRTUAL_CFG_H
2 #define VIRTUAL_CFG_H
3 
4 #include <string>
5 #include <vector>
6 #include <assert.h>
7 #include "rosedll.h"
8 
9 
14 class SgNode;
15 class SgExpression;
16 class SgInitializedName;
17 class SgLabelSymbol;
18 class SgLabelRefExp;
19 class SgStatement;
20 
21 #ifndef _MSC_VER
23 const SgStatement* isSgStatement(const SgNode* node);
24 SgExpression* isSgExpression(SgNode* node);
25 const SgExpression* isSgExpression(const SgNode* node);
26 SgInitializedName* isSgInitializedName(SgNode* node);
27 const SgInitializedName* isSgInitializedName(const SgNode* node);
28 #endif
29 
30 // DQ (9/1/2012): Debugging code to trace haskell_port error.
31 extern int abcd;
32 
33 namespace VirtualCFG {
34 
35 // DQ (9/1/2012): Debugging code to trace haskell_port error.
36 extern int efgh;
37 
38  class CFGEdge;
39 
47  enum EdgeConditionKind
48  {
49  eckUnconditional,
50  eckTrue,
51  eckFalse,
52  eckCaseLabel,
53  eckDefault,
54  eckDoConditionPassed,
55  eckDoConditionFailed,
56  eckForallIndicesInRange,
57  eckForallIndicesNotInRange,
58  eckComputedGotoCaseLabel,
59  eckArithmeticIfLess,
60  eckArithmeticIfEqual,
61  eckArithmeticIfGreater,
62  eckInterprocedural,
63 
64  // DQ (1/19/2018): Allow an error value to use for debugging.
65  eckError
66  };
67 
70  class ROSE_DLL_API CFGNode {
72  SgNode* node; // Must be either a SgStatement, SgExpression, or SgInitializedName (FIXME: change this to just SgLocatedNode if SgInitializedName becomes a subclass of that)
73 
76  unsigned int index;
77 
78  public:
79  CFGNode(): node(0), index(0) {}
80  CFGNode(SgNode* node, unsigned int index = 0);
81 
83  std::string toString() const;
85  std::string toStringForDebugging() const;
87  std::string id() const;
89  SgNode* getNode() const {return node;}
91  unsigned int getIndex() const {return index;}
93  std::vector<CFGEdge> outEdges() const;
95  std::vector<CFGEdge> inEdges() const;
100  bool isInteresting() const;
102  bool operator==(const CFGNode& o) const {return node == o.node && index == o.index;}
104  bool operator!=(const CFGNode& o) const {return !(*this == o);}
106  bool operator<(const CFGNode& o) const {return node < o.node || (node == o.node && index < o.index);}
107  }; // end class CFGNode
108 
111  class ROSE_DLL_API CFGEdge {
112  CFGNode src, tgt;
113  public:
115  CFGEdge(CFGNode src, CFGNode tgt): src(src), tgt(tgt) { assert(src.getNode() != NULL && tgt.getNode() != NULL); }
116 
118  CFGEdge() {}
119 
121  std::string toString() const;
123  std::string toStringForDebugging() const;
125  std::string id() const;
127  CFGNode source() const {return src;}
129  CFGNode target() const {return tgt;}
131  EdgeConditionKind condition() const;
133  SgExpression* caseLabel() const;
135  unsigned int computedGotoCaseIndex() const;
137  SgExpression* conditionBasedOn() const;
139  std::vector<SgInitializedName*> scopesBeingExited() const;
141  std::vector<SgInitializedName*> scopesBeingEntered() const;
143  bool operator==(const CFGEdge& o) const {return src == o.src && tgt == o.tgt;}
145  bool operator!=(const CFGEdge& o) const {return src != o.src || tgt != o.tgt;}
146 
148  bool operator<(const CFGEdge& o) const {return src < o.src || (src == o.src && tgt < o.tgt);}
149 
150  }; // end CFGEdge
151 
157  class CFGPath {
158  std::vector<CFGEdge> edges;
159  public:
160  // DQ (8/28/2006): This constructor causes a bug to be brought out in ROSE
161  // (in compiling this file using ROSE) see test2006_124.C for a smaller example.
162  CFGPath(CFGEdge e): edges(1, e) {}
163  // Merge two CFG paths
164  CFGPath(const CFGPath& a, const CFGPath& b): edges(a.edges) {
165  assert (!a.edges.empty());
166  assert (!b.edges.empty());
167  assert (a.edges.back().target() == b.edges.front().source());
168  edges.insert(edges.end(),b.edges.begin(),b.edges.end());
169  }
170 
171  //George Vulov 12/1/2010: We need a default constructor
172  CFGPath()
173  {
174  }
175 
176  std::string toString() const;
177  std::string toStringForDebugging() const;
178  std::string id() const;
179  // Get the head CFG node of the path
180  CFGNode source() const {assert (!edges.empty()); return edges.front().source();}
181  // Get the tail CFG node of the path
182  CFGNode target() const {assert (!edges.empty()); return edges.back().target();}
183  //Return the first non-unconditional edge's condition
184  EdgeConditionKind condition() const {
185  for (unsigned int i = 0; i < edges.size(); ++i) {
186  EdgeConditionKind kind = edges[i].condition();
187  if (kind != eckUnconditional) return kind;
188  }
189  return eckUnconditional;
190  }
191  // Return the case label of its first edge representing a case
192  SgExpression* caseLabel() const {
193  for (unsigned int i = 0; i < edges.size(); ++i) {
194  SgExpression* label = edges[i].caseLabel();
195  if (label != NULL) return label;
196  }
197  return NULL;
198  }
199  SgExpression* conditionBasedOn() const {
200  for (unsigned int i = 0; i < edges.size(); ++i) {
201  SgExpression* base = edges[i].conditionBasedOn();
202  if (base != NULL) return base;
203  }
204  return NULL;
205  }
206  std::vector<SgInitializedName*> scopesBeingExited() const {
207  std::vector<SgInitializedName*> result;
208  for (unsigned int i = 0; i < edges.size(); ++i) {
209  std::vector<SgInitializedName*> s_i = edges[i].scopesBeingExited();
210  result.insert(result.end(), s_i.begin(), s_i.end());
211  }
212  return result;
213  }
214  std::vector<SgInitializedName*> scopesBeingEntered() const {
215  std::vector<SgInitializedName*> result;
216  for (unsigned int i = 0; i < edges.size(); ++i) {
217  std::vector<SgInitializedName*> s_i = edges[i].scopesBeingEntered();
218  result.insert(result.end(), s_i.begin(), s_i.end());
219  }
220  return result;
221  }
222  bool operator==(const CFGPath& o) const {return edges == o.edges;}
223  bool operator!=(const CFGPath& o) const {return edges != o.edges;}
224 
226  bool operator<(const CFGPath& o) const {
227  if (edges.size() != o.edges.size()) {
228  return edges.size() < o.edges.size();
229  }
230  for (unsigned int i = 0; i < edges.size(); ++i) {
231  if (edges[i] != o.edges[i]) {
232  return edges[i] < o.edges[i];
233  }
234  }
235  return false;
236  }
237 
239  const std::vector<CFGEdge>& getEdges() const
240  {
241  return edges;
242  }
243  }; // end CFGPath
244 
246  inline CFGPath mergePaths(const CFGPath& hd, const CFGPath& tl) {
247  // Assumes the edges don't do anything too complicated with scopes
248  return CFGPath(hd, tl);
249  }
250 
252  inline CFGPath mergePathsReversed(const CFGPath& tl, const CFGPath& hd) {
253  return mergePaths(hd, tl);
254  }
255 
258  inline CFGNode cfgBeginningOfConstruct(SgNode* c) {
259  return CFGNode(c, 0);
260  }
261 
264  unsigned int cfgIndexForEndWrapper(SgNode* n);
265 
269  inline CFGNode cfgEndOfConstruct(SgNode* c) {
270  return CFGNode(c, cfgIndexForEndWrapper(c));
271  }
272 
274  inline CFGNode makeCfg(SgNode* start) {
275  return cfgBeginningOfConstruct(start);
276  }
277 
279  class InterestingEdge;
280 
282  CFGNode n;
283 
284  public:
285  InterestingNode(CFGNode n): n(n) {}
286  std::string toString() const {return n.toString();}
287  std::string toStringForDebugging() const {return n.toStringForDebugging();}
288  std::string id() const {return n.id();}
289  SgNode* getNode() const {return n.getNode();}
290  const CFGNode& toNode() const { return n; }
291  unsigned int getIndex() const {return n.getIndex();}
292  std::vector<InterestingEdge> outEdges() const;
293  std::vector<InterestingEdge> inEdges() const;
294  bool isInteresting() const {return true;}
295  bool operator==(const InterestingNode& o) const {return n == o.n;}
296  bool operator!=(const InterestingNode& o) const {return !(*this == o);}
297  bool operator<(const InterestingNode& o) const {return n < o.n;}
298  };
299 
301  CFGPath p;
302 
303  public:
304  InterestingEdge(CFGPath p): p(p) {}
305  std::string toString() const {return p.toString();}
306  std::string toStringForDebugging() const {return p.toStringForDebugging();}
307  std::string id() const {return p.id();}
308  InterestingNode source() const {return InterestingNode(p.source());}
309  InterestingNode target() const {return InterestingNode(p.target());}
310  EdgeConditionKind condition() const {return p.condition();}
311  SgExpression* caseLabel() const {return p.caseLabel();}
312  SgExpression* conditionBasedOn() const {return p.conditionBasedOn();}
313  std::vector<SgInitializedName*> scopesBeingExited() const {return p.scopesBeingExited();}
314  std::vector<SgInitializedName*> scopesBeingEntered() const {return p.scopesBeingEntered();}
315  bool operator==(const InterestingEdge& o) const {return p == o.p;}
316  bool operator!=(const InterestingEdge& o) const {return p != o.p;}
317  bool operator<(const InterestingEdge& o) const {return p < o.p;}
318  };
319 
320  inline InterestingNode makeInterestingCfg(SgNode* start) {
321  // Returns CFG node for just before start
322  return InterestingNode(cfgBeginningOfConstruct(start));
323  }
324 
326  CFGNode getCFGTargetOfFortranLabelSymbol(SgLabelSymbol* sym);
328  CFGNode getCFGTargetOfFortranLabelRef(SgLabelRefExp* lRef);
329 
331  template <class Node1T, class Node2T, class EdgeT>
332  void makeEdge(Node1T from, Node2T to, std::vector<EdgeT>& result);
333 
334 } // end namespace VirtualCFG
335 
336 #define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
337 #define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
338 #define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
339 
340 #define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
341 #define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
342 #define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
343 
345 template <class NodeT1, class NodeT2, class EdgeT>
346 void makeEdge(NodeT1 from, NodeT2 to, std::vector<EdgeT>& result);
347 
348 #endif // VIRTUAL_CFG_H
unsigned int getIndex() const
An identifying index within the AST node given by getNode()
Definition: virtualCFG.h:91
bool operator!=(const CFGEdge &o) const
Compare disequality of edges.
Definition: virtualCFG.h:145
This class represents the notion of a declared variable.
bool operator<(const CFGNode &o) const
Less-than operator.
Definition: virtualCFG.h:106
const std::vector< CFGEdge > & getEdges() const
Returns the edges in the path, starting at the source and ending at the target.
Definition: virtualCFG.h:239
std::string id() const
ID to use for Dot, etc.
A control flow edge connecting two CFG nodes, with an edge condition to indicate edge types...
Definition: virtualCFG.h:111
This class represents the notion of an expression. Expressions are derived from SgLocatedNodes, since similar to statement, expressions have a concrete location within the user's source code.
CFGEdge()
Default constructor. Used for compatibility with containers.
Definition: virtualCFG.h:118
bool operator!=(const CFGNode &o) const
Disequality operator.
Definition: virtualCFG.h:104
CFGNode source() const
The source (beginning) CFG node.
Definition: virtualCFG.h:127
A node in the control flow graph.
Definition: virtualCFG.h:70
This class represents the base class for all IR nodes within Sage III.
Definition: Cxx_Grammar.h:8672
bool operator==(const CFGEdge &o) const
Compare equality of edges.
Definition: virtualCFG.h:143
CFGEdge(CFGNode src, CFGNode tgt)
Constructor.
Definition: virtualCFG.h:115
std::string toStringForDebugging() const
String for debugging graphs.
This class represents the notion of a statement.
SgNode * getNode() const
The underlying AST node.
Definition: virtualCFG.h:89
ROSE_DLL_API friend SgStatement * isSgStatement(SgNode *s)
Casts pointer from base class to derived class.
bool operator<(const CFGEdge &o) const
operator<() has an arbitrary ordering, but allows these objects to be used with std::set and std::map...
Definition: virtualCFG.h:148
bool operator==(const CFGNode &o) const
Equality operator.
Definition: virtualCFG.h:102
CFGNode target() const
The target (ending) CFG node.
Definition: virtualCFG.h:129
std::string toString() const
Pretty string for Dot node labels, etc.
bool operator<(const CFGPath &o) const
An arbitrary order, so we can use this in std::set and std::map.
Definition: virtualCFG.h:226