PredicateOperand related bug fix.
[oota-llvm.git] / utils / TableGen / Record.h
index b318157e0b0d4d31f8768c162149186fb5fb9ccf..0971e938baae5dfee6dd1f5fc89aa83e736c0aca 100644 (file)
@@ -18,7 +18,7 @@
 #include <string>
 #include <vector>
 #include <map>
-#include <iostream>
+#include <ostream>
 #include <cassert>
 
 namespace llvm {
@@ -42,6 +42,7 @@ class IntInit;
 class StringInit;
 class CodeInit;
 class ListInit;
+class BinOpInit;
 class DefInit;
 class DagInit;
 class TypedInit;
@@ -75,6 +76,7 @@ public:   // These methods should only be called from subclasses of Init
   virtual Init *convertValue(   IntInit *II) { return 0; }
   virtual Init *convertValue(StringInit *SI) { return 0; }
   virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
@@ -120,6 +122,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -161,6 +164,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -199,6 +203,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -231,6 +236,7 @@ public:
   virtual Init *convertValue(   IntInit *II) { return 0; }
   virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
   virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue( BinOpInit *BO);
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
@@ -277,6 +283,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -313,6 +320,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -346,6 +354,7 @@ public:
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue(   DagInit *CI) { return (Init*)CI; }
   virtual Init *convertValue( TypedInit *TI);
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
@@ -386,6 +395,7 @@ public:
   virtual Init *convertValue(  ListInit *LI) { return 0; }
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue( BinOpInit *UI) { return 0; }
   virtual Init *convertValue(   DefInit *DI);
   virtual Init *convertValue(   DagInit *DI) { return 0; }
   virtual Init *convertValue( TypedInit *VI);
@@ -465,11 +475,6 @@ struct Init {
     return 0;
   }
 
-  enum BinaryOp { SHL, SRA, SRL };
-  virtual Init *getBinaryOp(BinaryOp Op, Init *RHS) {
-    return 0;
-  }
-
   /// resolveReferences - This method is used by classes that refer to other
   /// variables which may not be defined at the time they expression is formed.
   /// If a value is set for the variable later, this method will be called on
@@ -570,8 +575,6 @@ public:
   }
   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
 
-  virtual Init *getBinaryOp(BinaryOp Op, Init *RHS);
-
   virtual void print(std::ostream &OS) const { OS << Value; }
 };
 
@@ -623,6 +626,8 @@ public:
     return Values[i];
   }
 
+  Record *getElementAsRecord(unsigned i) const;
+  
   Init *convertInitListSlice(const std::vector<unsigned> &Elements);
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
@@ -639,6 +644,36 @@ public:
   virtual void print(std::ostream &OS) const;
 };
 
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public Init {
+public:
+  enum BinaryOp { SHL, SRA, SRL, STRCONCAT };
+private:
+  BinaryOp Opc;
+  Init *LHS, *RHS;
+public:
+  BinOpInit(BinaryOp opc, Init *lhs, Init *rhs) : Opc(opc), LHS(lhs), RHS(rhs) {
+  }
+  
+  BinaryOp getOpcode() const { return Opc; }
+  Init *getLHS() const { return LHS; }
+  Init *getRHS() const { return RHS; }
+
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  Init *Fold();
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+  
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+  
+  virtual void print(std::ostream &OS) const;
+};
+
+
 
 /// TypedInit - This is the common super-class of types that have a specific,
 /// explicit, type.
@@ -808,17 +843,17 @@ public:
   }
 };
 
-/// DagInit - (def a, b) - Represent a DAG tree value.  DAG inits are required
-/// to have Records for their first value, after that, any legal Init is
-/// possible.
+/// DagInit - (v a, b) - Represent a DAG tree value.  DAG inits are required
+/// to have at least one value then a (possibly empty) list of arguments.  Each
+/// argument can have a name associated with it.
 ///
 class DagInit : public Init {
-  Record *NodeTypeDef;
+  Init *Val;
   std::vector<Init*> Args;
   std::vector<std::string> ArgNames;
 public:
-  DagInit(Record *D, const std::vector<std::pair<Init*, std::string> > &args)
-    : NodeTypeDef(D) {
+  DagInit(Init *V, const std::vector<std::pair<Init*, std::string> > &args)
+    : Val(V) {
     Args.reserve(args.size());
     ArgNames.reserve(args.size());
     for (unsigned i = 0, e = args.size(); i != e; ++i) {
@@ -826,12 +861,16 @@ public:
       ArgNames.push_back(args[i].second);
     }
   }
-
+  DagInit(Init *V, const std::vector<Init*> &args, 
+          const std::vector<std::string> &argNames)
+  : Val(V), Args(args), ArgNames(argNames) {
+  }
+  
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
 
-  Record *getNodeType() const { return NodeTypeDef; }
+  Init *getOperator() const { return Val; }
 
   unsigned getNumArgs() const { return Args.size(); }
   Init *getArg(unsigned Num) const {
@@ -847,6 +886,8 @@ public:
     assert(Num < Args.size() && "Arg number out of range!");
     Args[Num] = I;
   }
+  
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 
   virtual void print(std::ostream &OS) const;
 };
@@ -888,7 +929,7 @@ inline std::ostream &operator<<(std::ostream &OS, const RecordVal &RV) {
 }
 
 class Record {
-  const std::string Name;
+  std::string Name;
   std::vector<std::string> TemplateArgs;
   std::vector<RecordVal> Values;
   std::vector<Record*> SuperClasses;
@@ -898,6 +939,7 @@ public:
   ~Record() {}
 
   const std::string &getName() const { return Name; }
+  void setName(const std::string &Name);  // Also updates RecordKeeper.
   const std::vector<std::string> &getTemplateArgs() const {
     return TemplateArgs;
   }
@@ -999,6 +1041,12 @@ public:
   ///
   ListInit *getValueAsListInit(const std::string &FieldName) const;
 
+  /// getValueAsListOfDefs - This method looks up the specified field and
+  /// returnsits value as a vector of records, throwing an exception if the
+  /// field does not exist or if the value is not the right type.
+  ///
+  std::vector<Record*> getValueAsListOfDefs(const std::string &FieldName) const;
+
   /// getValueAsDef - This method looks up the specified field and returns its
   /// value as a Record, throwing an exception if the field does not exist or if
   /// the value is not the right type.
@@ -1022,6 +1070,12 @@ public:
   /// the value is not the right type.
   ///
   DagInit *getValueAsDag(const std::string &FieldName) const;
+  
+  /// getValueAsCode - This method looks up the specified field and returns
+  /// its value as the string data in a CodeInit, throwing an exception if the
+  /// field does not exist or if the value is not a code object.
+  ///
+  std::string getValueAsCode(const std::string &FieldName) const;
 };
 
 std::ostream &operator<<(std::ostream &OS, const Record &R);
@@ -1058,6 +1112,19 @@ public:
     Defs.insert(std::make_pair(R->getName(), R));
   }
 
+  /// removeClass - Remove, but do not delete, the specified record.
+  ///
+  void removeClass(const std::string &Name) {
+    assert(Classes.count(Name) && "Class does not exist!");
+    Classes.erase(Name);
+  }
+  /// removeDef - Remove, but do not delete, the specified record.
+  ///
+  void removeDef(const std::string &Name) {
+    assert(Defs.count(Name) && "Def does not exist!");
+    Defs.erase(Name);
+  }
+  
   //===--------------------------------------------------------------------===//
   // High-level helper methods, useful for tablegen backends...