Program Listing for File virtualCFG.h#
↰ Return to documentation for file (src/frontend/SageIII/virtualCFG/virtualCFG.h)
#ifndef VIRTUAL_CFG_H
#define VIRTUAL_CFG_H
#include <string>
#include <vector>
#include <assert.h>
#include "rosedll.h"
class SgNode;
class SgExpression;
class SgInitializedName;
class SgLabelSymbol;
class SgLabelRefExp;
class SgStatement;
#ifndef _MSC_VER
SgStatement* isSgStatement(SgNode* node);
const SgStatement* isSgStatement(const SgNode* node);
SgExpression* isSgExpression(SgNode* node);
const SgExpression* isSgExpression(const SgNode* node);
SgInitializedName* isSgInitializedName(SgNode* node);
const SgInitializedName* isSgInitializedName(const SgNode* node);
#endif
// DQ (9/1/2012): Debugging code to trace haskell_port error.
extern int abcd;
namespace VirtualCFG {
// DQ (9/1/2012): Debugging code to trace haskell_port error.
extern int efgh;
class CFGEdge;
enum EdgeConditionKind
{
eckUnconditional,
eckTrue,
eckFalse,
eckCaseLabel,
eckDefault,
eckDoConditionPassed,
eckDoConditionFailed,
eckForallIndicesInRange,
eckForallIndicesNotInRange,
eckComputedGotoCaseLabel,
eckArithmeticIfLess,
eckArithmeticIfEqual,
eckArithmeticIfGreater,
eckInterprocedural,
// DQ (1/19/2018): Allow an error value to use for debugging.
eckError
};
class ROSE_DLL_API CFGNode {
SgNode* node; // Must be either a SgStatement, SgExpression, or SgInitializedName (FIXME: change this to just SgLocatedNode if SgInitializedName becomes a subclass of that)
unsigned int index;
public:
CFGNode(): node(0), index(0) {}
CFGNode(SgNode* node, unsigned int index = 0);
std::string toString() const;
std::string toStringForDebugging() const;
std::string id() const;
SgNode* getNode() const {return node;}
unsigned int getIndex() const {return index;}
std::vector<CFGEdge> outEdges() const;
std::vector<CFGEdge> inEdges() const;
bool isInteresting() const;
bool operator==(const CFGNode& o) const {return node == o.node && index == o.index;}
bool operator!=(const CFGNode& o) const {return !(*this == o);}
bool operator<(const CFGNode& o) const {return node < o.node || (node == o.node && index < o.index);}
}; // end class CFGNode
class ROSE_DLL_API CFGEdge {
CFGNode src, tgt;
public:
CFGEdge(CFGNode src, CFGNode tgt): src(src), tgt(tgt) { assert(src.getNode() != NULL && tgt.getNode() != NULL); }
CFGEdge() {}
std::string toString() const;
std::string toStringForDebugging() const;
std::string id() const;
CFGNode source() const {return src;}
CFGNode target() const {return tgt;}
EdgeConditionKind condition() const;
SgExpression* caseLabel() const;
unsigned int computedGotoCaseIndex() const;
SgExpression* conditionBasedOn() const;
std::vector<SgInitializedName*> scopesBeingExited() const;
std::vector<SgInitializedName*> scopesBeingEntered() const;
bool operator==(const CFGEdge& o) const {return src == o.src && tgt == o.tgt;}
bool operator!=(const CFGEdge& o) const {return src != o.src || tgt != o.tgt;}
bool operator<(const CFGEdge& o) const {return src < o.src || (src == o.src && tgt < o.tgt);}
}; // end CFGEdge
class CFGPath {
std::vector<CFGEdge> edges;
public:
// DQ (8/28/2006): This constructor causes a bug to be brought out in ROSE
// (in compiling this file using ROSE) see test2006_124.C for a smaller example.
CFGPath(CFGEdge e): edges(1, e) {}
// Merge two CFG paths
CFGPath(const CFGPath& a, const CFGPath& b): edges(a.edges) {
assert (!a.edges.empty());
assert (!b.edges.empty());
assert (a.edges.back().target() == b.edges.front().source());
edges.insert(edges.end(),b.edges.begin(),b.edges.end());
}
//George Vulov 12/1/2010: We need a default constructor
CFGPath()
{
}
std::string toString() const;
std::string toStringForDebugging() const;
std::string id() const;
// Get the head CFG node of the path
CFGNode source() const {assert (!edges.empty()); return edges.front().source();}
// Get the tail CFG node of the path
CFGNode target() const {assert (!edges.empty()); return edges.back().target();}
//Return the first non-unconditional edge's condition
EdgeConditionKind condition() const {
for (unsigned int i = 0; i < edges.size(); ++i) {
EdgeConditionKind kind = edges[i].condition();
if (kind != eckUnconditional) return kind;
}
return eckUnconditional;
}
// Return the case label of its first edge representing a case
SgExpression* caseLabel() const {
for (unsigned int i = 0; i < edges.size(); ++i) {
SgExpression* label = edges[i].caseLabel();
if (label != NULL) return label;
}
return NULL;
}
SgExpression* conditionBasedOn() const {
for (unsigned int i = 0; i < edges.size(); ++i) {
SgExpression* base = edges[i].conditionBasedOn();
if (base != NULL) return base;
}
return NULL;
}
std::vector<SgInitializedName*> scopesBeingExited() const {
std::vector<SgInitializedName*> result;
for (unsigned int i = 0; i < edges.size(); ++i) {
std::vector<SgInitializedName*> s_i = edges[i].scopesBeingExited();
result.insert(result.end(), s_i.begin(), s_i.end());
}
return result;
}
std::vector<SgInitializedName*> scopesBeingEntered() const {
std::vector<SgInitializedName*> result;
for (unsigned int i = 0; i < edges.size(); ++i) {
std::vector<SgInitializedName*> s_i = edges[i].scopesBeingEntered();
result.insert(result.end(), s_i.begin(), s_i.end());
}
return result;
}
bool operator==(const CFGPath& o) const {return edges == o.edges;}
bool operator!=(const CFGPath& o) const {return edges != o.edges;}
bool operator<(const CFGPath& o) const {
if (edges.size() != o.edges.size()) {
return edges.size() < o.edges.size();
}
for (unsigned int i = 0; i < edges.size(); ++i) {
if (edges[i] != o.edges[i]) {
return edges[i] < o.edges[i];
}
}
return false;
}
const std::vector<CFGEdge>& getEdges() const
{
return edges;
}
}; // end CFGPath
inline CFGPath mergePaths(const CFGPath& hd, const CFGPath& tl) {
// Assumes the edges don't do anything too complicated with scopes
return CFGPath(hd, tl);
}
inline CFGPath mergePathsReversed(const CFGPath& tl, const CFGPath& hd) {
return mergePaths(hd, tl);
}
inline CFGNode cfgBeginningOfConstruct(SgNode* c) {
return CFGNode(c, 0);
}
unsigned int cfgIndexForEndWrapper(SgNode* n);
inline CFGNode cfgEndOfConstruct(SgNode* c) {
return CFGNode(c, cfgIndexForEndWrapper(c));
}
inline CFGNode makeCfg(SgNode* start) {
return cfgBeginningOfConstruct(start);
}
class InterestingEdge;
class InterestingNode {
CFGNode n;
public:
InterestingNode(CFGNode n): n(n) {}
std::string toString() const {return n.toString();}
std::string toStringForDebugging() const {return n.toStringForDebugging();}
std::string id() const {return n.id();}
SgNode* getNode() const {return n.getNode();}
const CFGNode& toNode() const { return n; }
unsigned int getIndex() const {return n.getIndex();}
std::vector<InterestingEdge> outEdges() const;
std::vector<InterestingEdge> inEdges() const;
bool isInteresting() const {return true;}
bool operator==(const InterestingNode& o) const {return n == o.n;}
bool operator!=(const InterestingNode& o) const {return !(*this == o);}
bool operator<(const InterestingNode& o) const {return n < o.n;}
};
class InterestingEdge {
CFGPath p;
public:
InterestingEdge(CFGPath p): p(p) {}
std::string toString() const {return p.toString();}
std::string toStringForDebugging() const {return p.toStringForDebugging();}
std::string id() const {return p.id();}
InterestingNode source() const {return InterestingNode(p.source());}
InterestingNode target() const {return InterestingNode(p.target());}
EdgeConditionKind condition() const {return p.condition();}
SgExpression* caseLabel() const {return p.caseLabel();}
SgExpression* conditionBasedOn() const {return p.conditionBasedOn();}
std::vector<SgInitializedName*> scopesBeingExited() const {return p.scopesBeingExited();}
std::vector<SgInitializedName*> scopesBeingEntered() const {return p.scopesBeingEntered();}
bool operator==(const InterestingEdge& o) const {return p == o.p;}
bool operator!=(const InterestingEdge& o) const {return p != o.p;}
bool operator<(const InterestingEdge& o) const {return p < o.p;}
};
inline InterestingNode makeInterestingCfg(SgNode* start) {
// Returns CFG node for just before start
return InterestingNode(cfgBeginningOfConstruct(start));
}
CFGNode getCFGTargetOfFortranLabelSymbol(SgLabelSymbol* sym);
CFGNode getCFGTargetOfFortranLabelRef(SgLabelRefExp* lRef);
template <class Node1T, class Node2T, class EdgeT>
void makeEdge(Node1T from, Node2T to, std::vector<EdgeT>& result);
} // end namespace VirtualCFG
#define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
#define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
#define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
#define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
#define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
#define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
template <class NodeT1, class NodeT2, class EdgeT>
void makeEdge(NodeT1 from, NodeT2 to, std::vector<EdgeT>& result);
#endif // VIRTUAL_CFG_H