Program Listing for File AstInterface.h

Program Listing for File AstInterface.h#

↰ Return to documentation for file (src/midend/astUtil/astInterface/AstInterface.h)

#ifndef AST_TREE_INTERFACE_H
#define AST_TREE_INTERFACE_H

#include <iostream>
#include <vector>
#include <string>
#include <typeinfo>
#include "ObserveObject.h"
#include <rosedll.h>

class AstNodePtr;
class SgNode;

class AST_Error {
   std::string msg;
  public:
   AST_Error(const std::string& _msg) : msg(_msg) {}
   std::string get_msg() { return msg; }
};

class AstInterfaceImpl;
class AstNodePtr {
 protected:
  void* repr;
 public:
  AstNodePtr(void* _repr=0) : repr(_repr) {}
  AstNodePtr( const AstNodePtr& that) : repr(that.repr) {}
  ~AstNodePtr() {}
  AstNodePtr& operator = (const AstNodePtr &that)
      { repr = that.repr; return *this; }
  bool operator != (const AstNodePtr &that) const
    { return repr != that.repr; }
  bool operator == (const AstNodePtr &that) const
    { return repr == that.repr; }
  bool operator == (void *p) const
    { return repr == p; }
  bool operator != (void *p) const
    { return repr != p; }
  bool operator < (const AstNodePtr &that) const
    { return repr < that.repr; }
  void * get_ptr() const { return repr; }
  void *& get_ptr() { return repr; }
};
#define AST_NULL AstNodePtr()

class AstNodeType {
 protected:
  void* repr;
 public:
  AstNodeType() : repr(0) {}
  AstNodeType( const AstNodeType& that) : repr(that.repr) {}
  AstNodeType& operator = (const AstNodeType &that)
      { repr = that.repr; return *this; }
  ~AstNodeType() {}
  void * get_ptr() const { return repr; }
  void *& get_ptr() { return repr; }
};

class AstObserver {
  public:
   virtual void ObserveCopyAst( AstInterfaceImpl& fa, const AstNodePtr& orig, const AstNodePtr& n) = 0;
};

class CopyAstRecord : public ObserveInfo< AstObserver>
{
  AstNodePtr orig, n;
  AstInterfaceImpl& fa;
 public:
  CopyAstRecord(AstInterfaceImpl& _fa, const AstNodePtr& o, const AstNodePtr& _n)
      : orig(o), n(_n), fa(_fa) {}
  virtual void UpdateObserver( AstObserver& o) const
         {  o.ObserveCopyAst(fa, orig, n); }
  virtual ~CopyAstRecord() {}
};


// AstInterface
class AstInterface
{
protected:
  AstInterfaceImpl *impl;

public:
  // Types:
  typedef enum {OP_NONE = 0,
           UOP_MINUS, UOP_ADDR, UOP_DEREF, UOP_ALLOCATE, UOP_NOT,
           UOP_CAST, UOP_INCR1, UOP_DECR1, UOP_BIT_COMPLEMENT,
           BOP_DOT_ACCESS, BOP_ARROW_ACCESS,
           BOP_TIMES, BOP_DIVIDE, BOP_MOD, BOP_PLUS, BOP_MINUS,
           BOP_EQ, BOP_LE, BOP_LT, BOP_NE, BOP_GT, BOP_GE,
           BOP_AND, BOP_OR,
           BOP_BIT_AND,BOP_BIT_OR, BOP_BIT_RSHIFT, BOP_BIT_LSHIFT,
           OP_ARRAY_ACCESS, OP_ASSIGN, OP_UNKNOWN} OperatorEnum;
  // convert the enum type to a string
  static std::string toString (OperatorEnum op);
  typedef void* Ast;
  typedef std::vector<Ast>  AstList;
  typedef std::vector<Ast>  AstNodeList;
  typedef std::vector<AstNodeType> AstTypeList;

  AstInterface(AstInterfaceImpl* __impl) : impl(__impl) {}
  ~AstInterface() {}
  AstInterfaceImpl* get_impl() { return impl; }

  static std::string AstToString( const AstNodePtr& s, bool unparseClassName=true);
  static std::string getAstLocation( const AstNodePtr& s);
  static std::string unparseToString( const AstNodePtr& s);
  AstNodePtr GetRoot() const;
  AstNodePtr getNULL() const { return AstNodePtr(); }
  void SetRoot( const AstNodePtr& root);

  typedef enum { PreOrder, PostOrder, ReversePreOrder, ReversePostOrder,
                 PreAndPostOrder } TraversalOrderType;
  typedef enum {PreVisit, PostVisit} TraversalVisitType;

  void AttachObserver(AstObserver* ob);
  void DetachObserver(AstObserver* ob);

  bool get_fileInfo(const AstNodePtr& n, std:: string* fname= 0, int* lineno = 0);

  void InsertStmt( const AstNodePtr& orig, const AstNodePtr& n,
                   bool before = true, bool extractFromBlock = false);
  void InsertAnnot( const AstNodePtr& n, const std::string& annot,
                   bool before = true);
  bool ReplaceAst( const AstNodePtr& orig, const AstNodePtr& n);
  bool RemoveStmt( const AstNodePtr& n);
  void FreeAstTree( const AstNodePtr& n);
  AstNodePtr CopyAstTree( const AstNodePtr& n);

  void SetParent(const AstNodePtr& n, const AstNodePtr& p);
  AstNodePtr GetParent( const AstNodePtr &n);
  AstNodePtr GetPrevStmt( const AstNodePtr& s);
  AstNodePtr GetNextStmt( const AstNodePtr& s);
  static AstList GetChildrenList( const AstNodePtr &n);

  bool IsDecls( const AstNodePtr& s) ;
  bool IsVariableDecl( const AstNodePtr& exp, AstList* vars = 0,
                                 AstList* inits = 0);
  bool IsExecutableStmt( const AstNodePtr& s) ;
  static bool IsStatement( const AstNodePtr& s);
  static bool IsExprStmt(const AstNodePtr& n, AstNodePtr* exp = 0);

  static bool IsBlock( const AstNodePtr& exp);
  static AstList GetBlockStmtList( const AstNodePtr& n);
  AstNodePtr GetBlockFirstStmt( const AstNodePtr& n);
  AstNodePtr GetBlockLastStmt( const AstNodePtr& n);
  int GetBlockSize( const AstNodePtr& n);
  AstNodePtr CreateBlock( const AstNodePtr& orig = AstNodePtr()) ;
  /* if flatter_s == true, always flatten s if it is a block*/
  void BlockAppendStmt( AstNodePtr& b, const AstNodePtr& s, bool flatten_s=false);
  void BlockPrependStmt( AstNodePtr& b, const AstNodePtr& s);

  static bool IsLoop( const AstNodePtr& s,
                          AstNodePtr* init=0, AstNodePtr* cond=0,
                         AstNodePtr* incr = 0, AstNodePtr* body = 0) ;
  bool IsPostTestLoop( const AstNodePtr& s);

  static bool IsFortranLoop( const AstNodePtr& s, AstNodePtr* ivar = 0,
                       AstNodePtr* lb = 0, AstNodePtr* ub=0,
                       AstNodePtr* step =0, AstNodePtr* body=0);
  AstNodePtr CreateLoop( const AstNodePtr& cond, const AstNodePtr& body);
  AstNodePtr CreateLoop( const AstNodePtr& ivar, const AstNodePtr& lb,
                         const AstNodePtr& ub, const AstNodePtr& step,
                         const AstNodePtr& stmts, bool negativeStep);

  static bool IsIf( const AstNodePtr& s, AstNodePtr* cond = 0,
                       AstNodePtr* truebody = 0, AstNodePtr* falsebody = 0);

  AstNodePtr
  CreateIf(const AstNodePtr& __cond, const AstNodePtr& __if_stmt, const AstNodePtr& __else_stmt = AST_NULL)  const;

  // I/O Statements (Fortran oriented, to be refined):

  AstNodePtr CreateReadStatement(const AstList& __refs) const;

  AstNodePtr CreateWriteStatement(const AstList& __vals) const;

  AstNodePtr CreatePrintStatement(const AstList& __vals) const;

  AstNodePtr CreateNullStatement() const;

  bool IsGoto( const AstNodePtr& s, AstNodePtr* dest = 0);
  bool IsGotoBefore( const AstNodePtr& s); // goto the point before destination
  bool IsGotoAfter( const AstNodePtr& s); // goto the point after destination
  bool IsLabelStatement( const AstNodePtr& s);
  bool IsReturn(const AstNodePtr& s, AstNodePtr* val=0);

  bool GetFunctionCallSideEffect( const AstNodePtr& fc,
                     CollectObject<AstNodePtr>& collectmod,
                     CollectObject<AstNodePtr>& collectread);
  bool IsFunctionCall( const AstNodePtr& s, AstNodePtr* f = 0,
                       AstList* args = 0, AstList* outargs = 0,
                       AstTypeList* paramtypes = 0, AstNodeType* returntype=0);
  bool IsMin(const AstNodePtr& exp);
  bool IsMax(const AstNodePtr& exp);
  AstNodePtr CreateFunctionCall(const std::string& func, AstList::const_iterator args_begin, AstList::const_iterator args_end);
  AstNodePtr CreateFunctionCall(const AstNodePtr& func, AstList::const_iterator args_begin, AstList::const_iterator args_end);

  AstNodePtr GetFunctionDefinition( const AstNodePtr &n, std::string* name=0);
  static bool IsFunctionDefinition(  const AstNodePtr& s, std::string* name = 0,
                    AstList* params = 0, AstList* outpars = 0,
                    AstNodePtr* body = 0,
                    AstTypeList* paramtypes = 0, AstNodeType* returntype=0);

  static bool IsAssignment( const AstNodePtr& s, AstNodePtr* lhs = 0,
                               AstNodePtr* rhs = 0, bool* readlhs = 0);
  AstNodePtr CreateAssignment( const AstNodePtr& lhs, const AstNodePtr& rhs);

  bool IsIOInputStmt( const AstNodePtr& s, AstList* varlist = 0);
  bool IsIOOutputStmt( const AstNodePtr& s, AstList* explist = 0);

  bool IsMemoryAccess( const AstNodePtr& s);
  static AstNodePtr IsExpression( const AstNodePtr& s, AstNodeType* exptype =0);
  AstNodeType GetExpressionType( const AstNodePtr& s);

  bool IsConstInt( const AstNodePtr& exp, int* value = 0) ;
  AstNodePtr CreateConstInt( int val)  ;

  bool IsConstant( const AstNodePtr& exp, std::string* valtype=0, std::string* value = 0) ;
  AstNodePtr CreateConstant( const std::string& valtype, const std::string& val);

  static SgNode* SkipCasting(SgNode*  exp);

  static bool IsVarRef( const AstNodePtr& exp, AstNodeType* vartype = 0,
                   std::string* varname = 0, AstNodePtr* scope = 0,
                    bool *isglobal = 0) ;

  static std::string GetVarName( const AstNodePtr& exp);
  static std::string GetScopeName( const AstNodePtr& scope);

  bool IsSameVarRef( const AstNodePtr& v1, const AstNodePtr& v2);

  /*QY: by default variable declarations are merely saved to be inserted later*/
  std::string NewVar (const AstNodeType& t, const std::string& name = "",
                bool makeunique = false, bool delayInsert=true,
                const AstNodePtr& declLoc=AstNodePtr(),
                const AstNodePtr& init = AstNodePtr());
  /*Invoke this function to add the list of new variable declarations*/
  void AddNewVarDecls();
  /* copy new var declarations to a new given basic block; by default, the new var declarations are removed from their original block*/
  void CopyNewVarDecls(const AstNodePtr& nblock, bool clearNewVars=true);

  AstNodePtr CreateVarRef( std::string varname, const AstNodePtr& declLoc = AstNodePtr());

  bool IsScalarType(const AstNodeType& t);
  bool IsPointerType(const AstNodeType& t);
  static bool IsArrayType(const AstNodeType& t, int* dim = 0, AstNodeType* base = 0, std::string* annotation=0);

  AstNodeType GetType(const std::string& name);
  bool IsCompatibleType( const AstNodeType& t1, const AstNodeType& t2);
  static void GetTypeInfo( const AstNodeType& t, std::string* name = 0,
                           std::string* stripname = 0, int* size = 0);
  static std::string GetTypeName(const AstNodeType& t)
     { std::string r; GetTypeInfo(t, &r); return r; }
  static std::string GetBaseTypeName(const AstNodeType& t)
     { std::string r; GetTypeInfo(t, 0, &r); return r; }

  bool GetArrayBound( const AstNodePtr& arrayname, int dim, int &lb, int &ub) ;
  AstNodeType GetArrayType( const AstNodeType& base, const AstList& indexsize);

  AstNodePtr CreateAllocateArray( const AstNodePtr& arr, const AstNodeType& elemtype,
                                const AstList& indexsize);
  AstNodePtr CreateDeleteArray( const AstNodePtr& arr);
  static bool IsArrayAccess( const AstNodePtr& s, AstNodePtr* array = 0,
                                   AstList* index = 0)  ;
  static AstNodePtr CreateArrayAccess( const AstNodePtr& arr, const AstNodePtr& index);

  bool IsBinaryOp(  const AstNodePtr& exp, OperatorEnum* opr=0,
                    AstNodePtr* opd1 = 0, AstNodePtr* opd2 = 0);
  bool IsUnaryOp( const AstNodePtr& exp, OperatorEnum* op = 0,
                   AstNodePtr* opd = 0);
  AstNodePtr CreateBinaryOP( OperatorEnum op, const AstNodePtr& a0,
                                   const AstNodePtr& a2);
  AstNodePtr CreateUnaryOP( OperatorEnum op, const AstNodePtr& arg);

  AstNodePtr
  GetParentBlock(const AstNodePtr& __n)
  {
    if (__n == AST_NULL)
      return AST_NULL;

    AstNodePtr p = GetParent(__n);
    while (p != AST_NULL && !IsBlock(p))
      p = GetParent(p);
    return p;
  }

  AstNodePtr
  GetParentStatement(const AstNodePtr& __n)
  {
    if (__n == AST_NULL)
      return AST_NULL;

    AstNodePtr p = GetParent(__n);
    while (p != AST_NULL && !IsStatement(p))
      p = GetParent(p);
    return p;
  }

  static bool IsFortranLanguage();
};

typedef AstInterface::AstList AstNodeList;
typedef AstInterface::AstTypeList AstTypeList;

class ProcessAstNode
{
  public:
   virtual bool Traverse( AstInterface &fa, const AstNodePtr& n,
                             AstInterface::TraversalVisitType t) = 0;
};

bool ReadAstTraverse(AstInterface& fa, const AstNodePtr& root,
                        ProcessAstNode& op,
                        AstInterface::TraversalOrderType t = AstInterface::PreOrder);

class TransformAstTree
{
 public:
  virtual bool operator()( AstInterface& fa, const AstNodePtr& n,
                           AstNodePtr& result) = 0;
};

AstNodePtr TransformAstTraverse( AstInterface& fa, const AstNodePtr& r,
                    bool (*op)( AstInterface& fa, const AstNodePtr& head,
                                AstNodePtr& result),
                    AstInterface::TraversalVisitType t = AstInterface::PreVisit );
AstNodePtr TransformAstTraverse( AstInterface& fa, const AstNodePtr& r,
                              TransformAstTree& op,
                        AstInterface::TraversalVisitType t = AstInterface::PreVisit);

#endif