Program Listing for File staticCFG.h

Program Listing for File staticCFG.h#

Return to documentation for file (src/frontend/SageIII/virtualCFG/staticCFG.h)

#ifndef STATIC_CFG_H
#define STATIC_CFG_H

#include <sage3basic.h>
#include "AstAttributeMechanism.h"
#include "virtualCFG.h"
#include <map>
#include <set>
#include <string>


class SgIncidenceDirectedGraph;
class SgGraphNode;
class SgDirectedGraphEdge;


namespace StaticCFG
{

using VirtualCFG::CFGNode;
using VirtualCFG::CFGEdge;


class ROSE_DLL_API CFG
{
protected:
    SgIncidenceDirectedGraph* graph_;

    std::map<CFGNode, SgGraphNode*> all_nodes_;

    SgNode* start_;

    SgGraphNode* entry_;

    SgGraphNode* exit_;

    bool is_filtered_;

public:
    CFG() : graph_(NULL), start_(NULL), entry_(NULL), exit_(NULL) {}

    CFGNode toCFGNode(SgGraphNode* node);

    SgGraphNode *toGraphNode(CFGNode &n) { return ((all_nodes_.count(n)==0) ?  NULL : all_nodes_[n]);}


#if 0
    CFG(SgNode* node, bool is_filtered = false)
        : graph_(NULL), start_(node), entry_(NULL), exit_(NULL), is_filtered_(is_filtered)
    { buildCFG(); }
#else
    CFG(SgNode* node, bool is_filtered = false);
#endif

    SgIncidenceDirectedGraph* getGraph() const
    { return graph_; }

    virtual ~CFG()
    { clearNodesAndEdges(); }


    void setStart(SgNode* node) { start_ = node; }

    SgGraphNode* getEntry() const
    { return entry_; }

    SgGraphNode* getExit() const
    { return exit_; }

    bool isFilteredCFG() const { return is_filtered_; }
    void setFiltered(bool flag) { is_filtered_ = flag; }


    virtual void buildCFG()
    {
        if (is_filtered_) buildFilteredCFG();
        else buildFullCFG();
    }

    virtual void buildFullCFG();

    virtual void buildFilteredCFG();


#if 0
    std::vector<SgDirectedGraphEdge*> getOutEdges(SgNode* node, int index);
    std::vector<SgDirectedGraphEdge*> getInEdges(SgNode* node, int index);
#endif

    // The following four functions are for getting in/out edges of a given node.
    std::vector<SgDirectedGraphEdge*> getOutEdges(SgGraphNode* node);
    std::vector<SgDirectedGraphEdge*> getInEdges(SgGraphNode* node);

    // Provide the same interface to get the beginning/end graph node for a SgNode
    SgGraphNode* cfgForBeginning(SgNode* node);
    SgGraphNode* cfgForEnd(SgNode* node);

    static int getIndex(SgGraphNode* node);

    void cfgToDot(SgNode* node, const std::string& file_name);

protected:
    //void buildCFG(CFGNode n);
    template <class NodeT, class EdgeT>
    void buildCFG(NodeT n, std::map<NodeT, SgGraphNode*>& all_nodes, std::set<NodeT>& explored);

    void clearNodesAndEdges();



    // The following methods are used to build a DOT file.
    virtual void processNodes(std::ostream & o, SgGraphNode* n, std::set<SgGraphNode*>& explored);
    virtual void printNodePlusEdges(std::ostream & o, SgGraphNode* node);
    virtual void printNode(std::ostream & o, SgGraphNode* node);
    virtual void printEdge(std::ostream & o, SgDirectedGraphEdge* edge, bool isInEdge);
};


class CFGNodeAttribute : public AstAttribute
{
    int index_;
    SgIncidenceDirectedGraph* graph_;

public:
    CFGNodeAttribute(int idx = 0, SgIncidenceDirectedGraph* graph = NULL)
        : index_(idx), graph_(graph) {}

    int getIndex() const { return index_; }

    void setIndex(int idx) { index_ = idx; }

    const SgIncidenceDirectedGraph* getGraph() const { return graph_; }
    SgIncidenceDirectedGraph* getGraph() { return graph_; }

    void setGraph(SgIncidenceDirectedGraph* graph)
    { graph_ = graph; }
};

template <class EdgeT>
class CFGEdgeAttribute : public AstAttribute
{
    EdgeT edge_;
public:
    CFGEdgeAttribute(const EdgeT& e) : edge_(e) {}

    void setEdge(const EdgeT& e)
    { edge_ = e; }

    EdgeT getEdge() const
    { return edge_; }
};

// The following are some auxiliary functions, since SgGraphNode cannot provide them.
std::vector<SgDirectedGraphEdge*> outEdges(SgGraphNode* node);
std::vector<SgDirectedGraphEdge*> inEdges(SgGraphNode* node);

} // end of namespace StaticCFG

#endif