ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
virtualCFG.h
Go to the documentation of this file.
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);
25 const SgExpression* isSgExpression(const 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 
48  {
63  };
64 
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 
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
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
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
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  }
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 
256  return CFGNode(c, 0);
257  }
258 
261  unsigned int cfgIndexForEndWrapper(SgNode* n);
262 
267  return CFGNode(c, cfgIndexForEndWrapper(c));
268  }
269 
271  inline CFGNode makeCfg(SgNode* start) {
272  return cfgBeginningOfConstruct(start);
273  }
274 
276  class InterestingEdge;
277 
280 
281  public:
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 
299 
300  public:
302  std::string toString() const {return p.toString();}
303  std::string toStringForDebugging() const {return p.toStringForDebugging();}
304  std::string id() const {return p.id();}
308  SgExpression* caseLabel() const {return p.caseLabel();}
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 
318  // Returns CFG node for just before start
320  }
321 
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