ROSE  0.9.9.139
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 
67  class ROSE_DLL_API CFGNode {
69  SgNode* node; // Must be either a SgStatement, SgExpression, or SgInitializedName (FIXME: change this to just SgLocatedNode if SgInitializedName becomes a subclass of that)
70 
73  unsigned int index;
74 
75  public:
76  CFGNode(): node(0), index(0) {}
77  CFGNode(SgNode* node, unsigned int index = 0);
78 
80  std::string toString() const;
82  std::string toStringForDebugging() const;
84  std::string id() const;
86  SgNode* getNode() const {return node;}
88  unsigned int getIndex() const {return index;}
90  std::vector<CFGEdge> outEdges() const;
92  std::vector<CFGEdge> inEdges() const;
97  bool isInteresting() const;
99  bool operator==(const CFGNode& o) const {return node == o.node && index == o.index;}
101  bool operator!=(const CFGNode& o) const {return !(*this == o);}
103  bool operator<(const CFGNode& o) const {return node < o.node || (node == o.node && index < o.index);}
104  }; // end class CFGNode
105 
108  class ROSE_DLL_API CFGEdge {
109  CFGNode src, tgt;
110  public:
112  CFGEdge(CFGNode src, CFGNode tgt): src(src), tgt(tgt) { assert(src.getNode() != NULL && tgt.getNode() != NULL); }
113 
115  CFGEdge() {}
116 
118  std::string toString() const;
120  std::string toStringForDebugging() const;
122  std::string id() const;
124  CFGNode source() const {return src;}
126  CFGNode target() const {return tgt;}
128  EdgeConditionKind condition() const;
130  SgExpression* caseLabel() const;
132  unsigned int computedGotoCaseIndex() const;
134  SgExpression* conditionBasedOn() const;
136  std::vector<SgInitializedName*> scopesBeingExited() const;
138  std::vector<SgInitializedName*> scopesBeingEntered() const;
140  bool operator==(const CFGEdge& o) const {return src == o.src && tgt == o.tgt;}
142  bool operator!=(const CFGEdge& o) const {return src != o.src || tgt != o.tgt;}
143 
145  bool operator<(const CFGEdge& o) const {return src < o.src || (src == o.src && tgt < o.tgt);}
146 
147  }; // end CFGEdge
148 
154  class CFGPath {
155  std::vector<CFGEdge> edges;
156  public:
157  // DQ (8/28/2006): This constructor causes a bug to be brought out in ROSE
158  // (in compiling this file using ROSE) see test2006_124.C for a smaller example.
159  CFGPath(CFGEdge e): edges(1, e) {}
160  // Merge two CFG paths
161  CFGPath(const CFGPath& a, const CFGPath& b): edges(a.edges) {
162  assert (!a.edges.empty());
163  assert (!b.edges.empty());
164  assert (a.edges.back().target() == b.edges.front().source());
165  edges.insert(edges.end(),b.edges.begin(),b.edges.end());
166  }
167 
168  //George Vulov 12/1/2010: We need a default constructor
169  CFGPath()
170  {
171  }
172 
173  std::string toString() const;
174  std::string toStringForDebugging() const;
175  std::string id() const;
176  // Get the head CFG node of the path
177  CFGNode source() const {assert (!edges.empty()); return edges.front().source();}
178  // Get the tail CFG node of the path
179  CFGNode target() const {assert (!edges.empty()); return edges.back().target();}
180  //Return the first non-unconditional edge's condition
181  EdgeConditionKind condition() const {
182  for (unsigned int i = 0; i < edges.size(); ++i) {
183  EdgeConditionKind kind = edges[i].condition();
184  if (kind != eckUnconditional) return kind;
185  }
186  return eckUnconditional;
187  }
188  // Return the case label of its first edge representing a case
189  SgExpression* caseLabel() const {
190  for (unsigned int i = 0; i < edges.size(); ++i) {
191  SgExpression* label = edges[i].caseLabel();
192  if (label != NULL) return label;
193  }
194  return NULL;
195  }
196  SgExpression* conditionBasedOn() const {
197  for (unsigned int i = 0; i < edges.size(); ++i) {
198  SgExpression* base = edges[i].conditionBasedOn();
199  if (base != NULL) return base;
200  }
201  return NULL;
202  }
203  std::vector<SgInitializedName*> scopesBeingExited() const {
204  std::vector<SgInitializedName*> result;
205  for (unsigned int i = 0; i < edges.size(); ++i) {
206  std::vector<SgInitializedName*> s_i = edges[i].scopesBeingExited();
207  result.insert(result.end(), s_i.begin(), s_i.end());
208  }
209  return result;
210  }
211  std::vector<SgInitializedName*> scopesBeingEntered() const {
212  std::vector<SgInitializedName*> result;
213  for (unsigned int i = 0; i < edges.size(); ++i) {
214  std::vector<SgInitializedName*> s_i = edges[i].scopesBeingEntered();
215  result.insert(result.end(), s_i.begin(), s_i.end());
216  }
217  return result;
218  }
219  bool operator==(const CFGPath& o) const {return edges == o.edges;}
220  bool operator!=(const CFGPath& o) const {return edges != o.edges;}
221 
223  bool operator<(const CFGPath& o) const {
224  if (edges.size() != o.edges.size()) {
225  return edges.size() < o.edges.size();
226  }
227  for (unsigned int i = 0; i < edges.size(); ++i) {
228  if (edges[i] != o.edges[i]) {
229  return edges[i] < o.edges[i];
230  }
231  }
232  return false;
233  }
234 
236  const std::vector<CFGEdge>& getEdges() const
237  {
238  return edges;
239  }
240  }; // end CFGPath
241 
243  inline CFGPath mergePaths(const CFGPath& hd, const CFGPath& tl) {
244  // Assumes the edges don't do anything too complicated with scopes
245  return CFGPath(hd, tl);
246  }
247 
249  inline CFGPath mergePathsReversed(const CFGPath& tl, const CFGPath& hd) {
250  return mergePaths(hd, tl);
251  }
252 
255  inline CFGNode cfgBeginningOfConstruct(SgNode* c) {
256  return CFGNode(c, 0);
257  }
258 
261  unsigned int cfgIndexForEndWrapper(SgNode* n);
262 
266  inline CFGNode cfgEndOfConstruct(SgNode* c) {
267  return CFGNode(c, cfgIndexForEndWrapper(c));
268  }
269 
271  inline CFGNode makeCfg(SgNode* start) {
272  return cfgBeginningOfConstruct(start);
273  }
274 
276  class InterestingEdge;
277 
279  CFGNode n;
280 
281  public:
282  InterestingNode(CFGNode n): n(n) {}
283  std::string toString() const {return n.toString();}
284  std::string toStringForDebugging() const {return n.toStringForDebugging();}
285  std::string id() const {return n.id();}
286  SgNode* getNode() const {return n.getNode();}
287  const CFGNode& toNode() const { return n; }
288  unsigned int getIndex() const {return n.getIndex();}
289  std::vector<InterestingEdge> outEdges() const;
290  std::vector<InterestingEdge> inEdges() const;
291  bool isInteresting() const {return true;}
292  bool operator==(const InterestingNode& o) const {return n == o.n;}
293  bool operator!=(const InterestingNode& o) const {return !(*this == o);}
294  bool operator<(const InterestingNode& o) const {return n < o.n;}
295  };
296 
298  CFGPath p;
299 
300  public:
301  InterestingEdge(CFGPath p): p(p) {}
302  std::string toString() const {return p.toString();}
303  std::string toStringForDebugging() const {return p.toStringForDebugging();}
304  std::string id() const {return p.id();}
305  InterestingNode source() const {return InterestingNode(p.source());}
306  InterestingNode target() const {return InterestingNode(p.target());}
307  EdgeConditionKind condition() const {return p.condition();}
308  SgExpression* caseLabel() const {return p.caseLabel();}
309  SgExpression* conditionBasedOn() const {return p.conditionBasedOn();}
310  std::vector<SgInitializedName*> scopesBeingExited() const {return p.scopesBeingExited();}
311  std::vector<SgInitializedName*> scopesBeingEntered() const {return p.scopesBeingEntered();}
312  bool operator==(const InterestingEdge& o) const {return p == o.p;}
313  bool operator!=(const InterestingEdge& o) const {return p != o.p;}
314  bool operator<(const InterestingEdge& o) const {return p < o.p;}
315  };
316 
317  inline InterestingNode makeInterestingCfg(SgNode* start) {
318  // Returns CFG node for just before start
319  return InterestingNode(cfgBeginningOfConstruct(start));
320  }
321 
323  CFGNode getCFGTargetOfFortranLabelSymbol(SgLabelSymbol* sym);
325  CFGNode getCFGTargetOfFortranLabelRef(SgLabelRefExp* lRef);
326 
328  template <class Node1T, class Node2T, class EdgeT>
329  void makeEdge(Node1T from, Node2T to, std::vector<EdgeT>& result);
330 
331 } // end namespace VirtualCFG
332 
333 #define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
334 #define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
335 #define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
336 
337 #define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
338 #define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
339 #define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
340 
342 template <class NodeT1, class NodeT2, class EdgeT>
343 void makeEdge(NodeT1 from, NodeT2 to, std::vector<EdgeT>& result);
344 
345 #endif // VIRTUAL_CFG_H
unsigned int getIndex() const
An identifying index within the AST node given by getNode()
Definition: virtualCFG.h:88
bool operator!=(const CFGEdge &o) const
Compare disequality of edges.
Definition: virtualCFG.h:142
This class represents the notion of a declared variable.
bool operator<(const CFGNode &o) const
Less-than operator.
Definition: virtualCFG.h:103
const std::vector< CFGEdge > & getEdges() const
Returns the edges in the path, starting at the source and ending at the target.
Definition: virtualCFG.h:236
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:108
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:115
bool operator!=(const CFGNode &o) const
Disequality operator.
Definition: virtualCFG.h:101
CFGNode source() const
The source (beginning) CFG node.
Definition: virtualCFG.h:124
A node in the control flow graph.
Definition: virtualCFG.h:67
This class represents the base class for all IR nodes within Sage III.
Definition: Cxx_Grammar.h:8322
bool operator==(const CFGEdge &o) const
Compare equality of edges.
Definition: virtualCFG.h:140
CFGEdge(CFGNode src, CFGNode tgt)
Constructor.
Definition: virtualCFG.h:112
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:86
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:145
bool operator==(const CFGNode &o) const
Equality operator.
Definition: virtualCFG.h:99
CFGNode target() const
The target (ending) CFG node.
Definition: virtualCFG.h:126
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:223