DynAST.h

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #if !defined(AST_H)
00032 #define AST_H
00033 
00034 #include <vector>
00035 #include <string>
00036 #include <sstream>
00037 #include <iostream>
00038 #include "util.h"
00039 #include "boost/enable_shared_from_this.hpp"
00040 
00041 namespace Dyninst {
00042 
00043 // We fully template the three types of nodes we have so that
00044 // users can specify their own. This basically makes the AST
00045 // a fully generic class. 
00046 //
00047 // TODO: do we want Variable and Constant to be different classes?
00048 // I'm using the Absloc case as the basis here; EAX and '5' are
00049 // very different things...
00050 //
00051 // Possible fourth template type: Type
00052 // though I'm currently arguing that Type is an artifact of the
00053 // Eval method you apply here. 
00054 // ... and are Eval methods independent of Operation/Variable/Constant?
00055 // I think they are...x
00056 
00057 class ASTVisitor;  
00058 
00059  // For this to work, the ASTVisitor has to have a virtual
00060  // visit() method for every instantiation of an AST-typed
00061  // class. Yes, this means that if you add an AST class
00062  // somewhere else you have to come back and put it in here. 
00063  // Well, if you want to run a visitor over it, that is.
00064  class AST;
00065 
00066  // SymEval...
00067  namespace DataflowAPI {
00068  class BottomAST;
00069  class ConstantAST;
00070  class VariableAST;
00071  class RoseAST;
00072  };
00073  // Stack analysis...
00074  class StackAST;
00075 
00076  // InsnAPI...
00077 
00078  // Codegen...
00079 
00080  // Concolic execution...
00081  class InputVariableAST;
00082  class ReferenceAST;
00083  class StpAST;
00084  class YicesAST;
00085  class SemanticsAST;
00086 
00087 #define DEF_AST_LEAF_TYPE(name, type)                   \
00088 class name : public AST {                       \
00089  public:                                \
00090  typedef boost::shared_ptr<name> Ptr;           \
00091  static Ptr create(type t) { return Ptr(new name(t)); }         \
00092  virtual ~name() {};                            \
00093  virtual const std::string format() const {             \
00094    std::stringstream ret;                       \
00095    ret << "<" << t_ << ">";                     \
00096    return ret.str();                            \
00097  }                                  \
00098  virtual AST::Ptr accept(ASTVisitor *v) { return v->visit(this); }  \
00099  virtual ID getID() const { return V_##name; }              \
00100   static Ptr convert(AST::Ptr a) {                  \
00101   return ((a->getID() == V_##name) ? boost::static_pointer_cast<name>(a) : Ptr()); \
00102   }                                 \
00103   const type &val() const { return t_; }                \
00104  private:                               \
00105  name(type t) : t_(t) {};                       \
00106  virtual bool isStrictEqual(const AST &rhs) const {         \
00107    const name &other(dynamic_cast<const name&>(rhs));           \
00108    return t_ == other.t_;                       \
00109  }                                  \
00110  const type t_;                             \
00111  };                                 \
00112 
00113 #define DEF_AST_INTERNAL_TYPE(name, type)               \
00114 class name : public AST {                       \
00115  public:                                \
00116   typedef boost::shared_ptr<name> Ptr;          \
00117   virtual ~name() {};                           \
00118   static Ptr create(type t, AST::Ptr a) { return Ptr(new name(t, a)); } \
00119   static Ptr create(type t, AST::Ptr a, AST::Ptr b) { return Ptr(new name(t, a, b)); } \
00120   static Ptr create(type t, AST::Ptr a, AST::Ptr b, AST::Ptr c) { return Ptr(new name(t, a, b, c)); } \
00121   static Ptr create(type t, Children c) { return Ptr(new name(t, c)); } \
00122   virtual const std::string format() const {                \
00123     std::stringstream ret;                      \
00124     ret << t_ << "(";                                                   \
00125     for (Children::const_iterator i = kids_.begin(); i != kids_.end(); ++i) {   \
00126       ret << (*i)->format() << ",";                 \
00127     }                                   \
00128     ret << ")";                             \
00129     return ret.str();                           \
00130   }                                 \
00131   virtual AST::Ptr child(unsigned i) const { return kids_[i];}      \
00132   virtual unsigned numChildren() const { return kids_.size();}      \
00133   virtual AST::Ptr accept(ASTVisitor *v) { return v->visit(this); } \
00134   virtual ID getID() const { return V_##name; }             \
00135   static Ptr convert(AST::Ptr a) {                  \
00136     return ((a->getID() == V_##name) ? boost::static_pointer_cast<name>(a) : Ptr()); \
00137   }                                 \
00138   const type &val() const { return t_; }                \
00139   void setChild(int i, AST::Ptr a) { kids_[i] = a; };           \
00140  private:                               \
00141  name(type t, AST::Ptr a) : t_(t) { kids_.push_back(a); };      \
00142  name(type t, AST::Ptr a, AST::Ptr b) : t_(t) {             \
00143     kids_.push_back(a);                         \
00144     kids_.push_back(b);                         \
00145   };                                    \
00146  name(type t, AST::Ptr a, AST::Ptr b, AST::Ptr c) : t_(t) {     \
00147     kids_.push_back(a);                         \
00148     kids_.push_back(b);                         \
00149     kids_.push_back(c);                         \
00150   };                                    \
00151  name(type t, Children kids) : t_(t), kids_(kids) {};           \
00152   virtual bool isStrictEqual(const AST &rhs) const {            \
00153     const name &other(dynamic_cast<const name&>(rhs));                  \
00154     if (!(t_ == other.t_)) return false;                \
00155     if (kids_.size() != other.kids_.size()) return false;               \
00156     for (unsigned i = 0; i < kids_.size(); ++i)                         \
00157       if (!(kids_[i]->equals(other.kids_[i]))) return false;            \
00158     return true;                                                        \
00159   }                                 \
00160   const type t_;                            \
00161   Children kids_;                           \
00162  };                                 \
00163 
00164 class COMMON_EXPORT AST : public boost::enable_shared_from_this<AST> {
00165  public:
00166 
00167   // This is a global list of all AST types, including those that are not
00168   // yet implemented. The format is a "V_" string prepending the class name.
00169   // If you add an AST type you should update this list.
00170 
00171   typedef enum {
00172     V_AST,
00173     // SymEval
00174     V_BottomAST,
00175     V_ConstantAST,
00176     V_VariableAST,
00177     V_RoseAST,
00178     // Stack analysis
00179     V_StackAST,
00180     // Concolic execution
00181     V_InputVariableAST,
00182     V_ReferenceAST,
00183     V_StpAST,
00184     V_YicesAST,
00185     V_SemanticsAST } ID;
00186 
00187   typedef boost::shared_ptr<AST> Ptr;
00188   typedef std::vector<AST::Ptr> Children;      
00189 
00190   AST() {};
00191   virtual ~AST() {};
00192   
00193   bool operator==(const AST &rhs) const {
00194     // make sure rhs and this have the same type
00195     return((typeid(*this) == typeid(rhs)) && isStrictEqual(rhs));
00196   }
00197 
00198   virtual unsigned numChildren() const { return 0; }               
00199 
00200   virtual AST::Ptr child(unsigned) const {              
00201     assert(0);                              
00202     return Ptr();                           
00203   }                                    
00204 
00205   bool equals(AST::Ptr rhs) {
00206     if (!rhs) return false;
00207     return *this == (*rhs);
00208   }
00209 
00210   virtual const std::string format() const = 0;
00211 
00212   // Substitutes every occurrence of a with b in
00213   // AST in. Returns a new AST. 
00214 
00215   static AST::Ptr substitute(AST::Ptr in, AST::Ptr a, AST::Ptr b); 
00216 
00217   virtual ID getID() const { return V_AST; };
00218 
00219   // VISITOR wooo....
00220   virtual Ptr accept(ASTVisitor *);
00221 
00222   Ptr ptr() { return shared_from_this(); }
00223 
00224   virtual void setChild(int, AST::Ptr) {
00225     assert(0);
00226   };
00227 
00228  protected:
00229   virtual bool isStrictEqual(const AST &rhs) const = 0;
00230 };
00231 
00232  class COMMON_EXPORT ASTVisitor {
00233  public:
00234    typedef boost::shared_ptr<AST> ASTPtr;
00235 
00236    virtual ASTPtr visit(AST *) {return AST::Ptr();};
00237    virtual ASTPtr visit(DataflowAPI::BottomAST *) {return AST::Ptr();};
00238    virtual ASTPtr visit(DataflowAPI::ConstantAST *) {return AST::Ptr();};
00239    virtual ASTPtr visit(DataflowAPI::VariableAST *) {return AST::Ptr();};
00240    virtual ASTPtr visit(DataflowAPI::RoseAST *) {return AST::Ptr();};
00241    virtual ASTPtr visit(StackAST *) {return AST::Ptr();};
00242    virtual ASTPtr visit(InputVariableAST *) {return AST::Ptr();};
00243    virtual ASTPtr visit(ReferenceAST *) {return AST::Ptr();};
00244    virtual ASTPtr visit(StpAST *) {return AST::Ptr();};
00245    virtual ASTPtr visit(YicesAST *) {return AST::Ptr();};
00246    virtual ASTPtr visit(SemanticsAST *) {return AST::Ptr();};
00247 
00248    virtual ~ASTVisitor() {};
00249  };
00250 
00251 }
00252 #endif // AST_H
00253 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1