#ifndef __CFG_IR_H__
#define __CFG_IR_H__
#include "suifkernel/suifkernel_forwarders.h"
#include "suifkernel/suif_object.h"
#include "common/suif_list.h"
#include "common/suif_vector.h"
#include "common/suif_indexed_list.h"
#ifdef PGI_BUILD
#include <new>
#else
#include <new.h>
#endif
#include "cfg_ir_forwarders.h"
#include "common/formatted.h"
#include "suifkernel/iter.h"
#include "common/i_integer.h"
#include <bit_vector/bit_vector.h>
#include <machine/machine.h>
#include "iokernel/meta_class.h"
extern "C" void EXPORT init_cfg_irnodes(SuifEnv* suif);
#ifdef SUIF_NAMESPACE
namespace SUIF_NAMESPACE {
#endif
class Cfg : public  AnyBody {
  public:
    
    virtual CfgNode*  get_entry_node () const;
    virtual void set_entry_node(CfgNode*  the_value);
    
    virtual CfgNode*  get_exit_node () const;
    virtual void set_exit_node(CfgNode*  the_value);
    
    
    virtual bool get_keep_layout () const;
    virtual void set_keep_layout(bool the_value);
    
    virtual bool get_break_at_call () const;
    virtual void set_break_at_call(bool the_value);
    
    virtual bool get_break_at_instr () const;
    virtual void set_break_at_instr(bool the_value);
    
    Iter<CfgNode* > get_node_iterator() const;
    virtual void append_node(CfgNode* sf_owned x);
    int get_node_count() const;
    virtual void insert_node(int pos,CfgNode* sf_owned x);
    CfgNode* sf_owned remove_node(int pos);
    CfgNode* sf_owned get_node (int pos) const;
    Iter<LabelSym* > get_noted_label_iterator() const;
    virtual void append_noted_label(LabelSym*  x);
    int get_noted_label_count() const;
    virtual void insert_noted_label(int pos,LabelSym*  x);
    LabelSym*  remove_noted_label(int pos);
    LabelSym*  get_noted_label (int pos) const;
    
    
    
    virtual ~Cfg();
    virtual void print(FormattedText &x) const;
    static const LString &get_class_name();
  protected:
    //use the factory to create objects
    friend class CfgIrObjectFactory;
    
    Cfg();
    static void constructor_function( Address address );
  private:
    list<CfgNode* > _nodes;
    CfgNode*  _entry_node;
    CfgNode*  _exit_node;
    list<LabelSym* > _noted_labels;
    bool _keep_layout;
    bool _break_at_call;
    bool _break_at_instr;
    public:
        list<CfgNode*>& nodes() { return _nodes; }
        InstrList* to_instr_list();
        list<LabelSym*>& noted_labels() { return _noted_labels; }
    
  }; 



class CfgNode : public  ScopedObject {
  public:
    virtual int get_number () const;
    virtual void set_number(int the_value);
    
    virtual Instr*  get_cti () const;
    virtual void set_cti(Instr*  the_value);
    
    
    
    
    virtual CfgNode*  get_layout_pred () const;
    virtual void set_layout_pred(CfgNode*  the_value);
    
    virtual CfgNode*  get_layout_succ () const;
    virtual void set_layout_succ(CfgNode*  the_value);
    
    virtual IInteger get_exc_succs () const;
    virtual void set_exc_succs(IInteger the_value);
    
    virtual IInteger get_imp_succs () const;
    virtual void set_imp_succs(IInteger the_value);
    
    Iter<Instr* > get_instr_iterator() const;
    virtual void append_instr(Instr* sf_owned x);
    int get_instr_count() const;
    virtual void insert_instr(int pos,Instr* sf_owned x);
    Instr* sf_owned remove_instr(int pos);
    Instr* sf_owned get_instr (int pos) const;
    Iter<CfgNode* > get_pred_iterator() const;
    virtual void append_pred(CfgNode*  x);
    int get_pred_count() const;
    virtual void insert_pred(int pos,CfgNode*  x);
    CfgNode*  remove_pred(int pos);
    CfgNode*  get_pred (int pos) const;
    Iter<CfgNode* > get_succ_iterator() const;
    virtual void append_succ(CfgNode*  x);
    int get_succ_count() const;
    virtual void insert_succ(int pos,CfgNode*  x);
    CfgNode*  remove_succ(int pos);
    CfgNode*  get_succ (int pos) const;
    
    
    
    virtual ~CfgNode();
    virtual void print(FormattedText &x) const;
    static const LString &get_class_name();
  protected:
    //use the factory to create objects
    friend class CfgIrObjectFactory;
    
    CfgNode();
    static void constructor_function( Address address );
  private:
    int _number;
    Instr*  _cti;
    list<Instr* > _instrs;
    list<CfgNode* > _preds;
    list<CfgNode* > _succs;
    CfgNode*  _layout_pred;
    CfgNode*  _layout_succ;
    IInteger _exc_succs;
    IInteger _imp_succs;
    public:
        list<Instr*>& instrs() { return _instrs; }
        list<CfgNode*>& succs() { return _succs; }
        list<CfgNode*>& preds() { return _preds; }

        IInteger& exc_succs() { return _exc_succs; }
        IInteger& imp_succs() { return _imp_succs; }
    
  }; 




#ifdef SUIF_NAMESPACE
}
#ifndef NO_IMPLICIT_USING
using namespace SUIF_NAMESPACE;
#endif
#endif
#endif
