Eliminate tabs and trailing spaces
[oota-llvm.git] / utils / TableGen / Record.h
index 9b3fb2d827fa9a2cd34fed3df20f5db078ac1883..b318157e0b0d4d31f8768c162149186fb5fb9ccf 100644 (file)
@@ -1,5 +1,14 @@
 //===- Record.h - Classes to represent Table Records ------------*- C++ -*-===//
 //
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the main TableGen data structures, including the TableGen
+// types, values, and high-level data structures.
 //
 //===----------------------------------------------------------------------===//
 
 #include <vector>
 #include <map>
 #include <iostream>
-class Init;
+#include <cassert>
+
+namespace llvm {
+
+// RecTy subclasses.
+class BitRecTy;
+class BitsRecTy;
+class IntRecTy;
+class StringRecTy;
+class ListRecTy;
+class CodeRecTy;
+class DagRecTy;
+class RecordRecTy;
+
+// Init subclasses.
+struct Init;
 class UnsetInit;
 class BitInit;
 class BitsInit;
 class IntInit;
 class StringInit;
+class CodeInit;
 class ListInit;
-class VarInit;
-class VarBitInit;
 class DefInit;
+class DagInit;
+class TypedInit;
+class VarInit;
 class FieldInit;
+class VarBitInit;
+class VarListElementInit;
+
+// Other classes.
 class Record;
+class RecordVal;
 
 //===----------------------------------------------------------------------===//
 //  Type Classes
@@ -30,19 +61,43 @@ class Record;
 struct RecTy {
   virtual ~RecTy() {}
 
+  virtual void print(std::ostream &OS) const = 0;
+  void dump() const;
+
+  /// typeIsConvertibleTo - Return true if all values of 'this' type can be
+  /// converted to the specified type.
+  virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
+
+public:   // These methods should only be called from subclasses of Init
   virtual Init *convertValue( UnsetInit *UI) { return 0; }
   virtual Init *convertValue(   BitInit *BI) { return 0; }
   virtual Init *convertValue(  BitsInit *BI) { return 0; }
   virtual Init *convertValue(   IntInit *II) { return 0; }
   virtual Init *convertValue(StringInit *SI) { return 0; }
   virtual Init *convertValue(  ListInit *LI) { return 0; }
-  virtual Init *convertValue(   VarInit *VI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
-  virtual Init *convertValue( FieldInit *FI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI) { return 0; }
+  virtual Init *convertValue(   VarInit *VI) {
+    return convertValue((TypedInit*)VI);
+  }
+  virtual Init *convertValue( FieldInit *FI) {
+    return convertValue((TypedInit*)FI);
+  }
 
-  virtual void print(std::ostream &OS) const = 0;
-  void dump() const;
+public:   // These methods should only be called by subclasses of RecTy.
+  // baseClassOf - These virtual methods should be overloaded to return true iff
+  // all values of type 'RHS' can be converted to the 'this' type.
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
 };
 
 inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) {
@@ -53,18 +108,41 @@ inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) {
 
 /// BitRecTy - 'bit' - Represent a single bit
 ///
-struct BitRecTy : public RecTy {
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(BitInit *BI) { return (Init*)BI; }
-  Init *convertValue(BitsInit *BI);
-  Init *convertValue(IntInit *II);
-  Init *convertValue(VarInit *VI);
+class BitRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return (Init*)BI; }
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II);
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  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( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
   void print(std::ostream &OS) const { OS << "bit"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const;
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
 };
 
 
-/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
+// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
+/// BitsRecTy - 'bits&lt;n&gt;' - Represent a fixed number of bits
 ///
 class BitsRecTy : public RecTy {
   unsigned Size;
@@ -73,50 +151,224 @@ public:
 
   unsigned getNumBits() const { return Size; }
 
-  Init *convertValue(UnsetInit *UI);
-  Init *convertValue(BitInit *UI);
-  Init *convertValue(BitsInit *BI);
-  Init *convertValue(IntInit *II);
-  Init *convertValue(VarInit *VI);
+  virtual Init *convertValue( UnsetInit *UI);
+  virtual Init *convertValue(   BitInit *UI);
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II);
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { 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);}
+
 
   void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return Size == 1; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const {
+    return RHS->Size == Size;
+  }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
 };
 
 
 /// IntRecTy - 'int' - Represent an integer value of no particular size
 ///
-struct IntRecTy : public RecTy {
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(IntInit *II) { return (Init*)II; }
-  Init *convertValue(BitsInit *BI);
-  Init *convertValue(VarInit *VI);
+class IntRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI);
+  virtual Init *convertValue(  BitsInit *BI);
+  virtual Init *convertValue(   IntInit *II) { return (Init*)II; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { 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);}
+
 
   void print(std::ostream &OS) const { OS << "int"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return true; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+
 };
 
 /// StringRecTy - 'string' - Represent an string value
 ///
-struct StringRecTy : public RecTy {
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(StringInit *SI) { return (Init*)SI; }
-  Init *convertValue(VarInit *VI);
+class StringRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  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(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { 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);}
+
   void print(std::ostream &OS) const { OS << "string"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
 };
 
-/// ListRecTy - 'list<class>' - Represent a list defs, all of which must be
-/// derived from the specified class.
+// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
+// the specified type.
+/// ListRecTy - 'list&lt;Ty&gt;' - Represent a list of values, all of which must
+/// be of the specified type.
 ///
 class ListRecTy : public RecTy {
-  Record *Class;
+  RecTy *Ty;
 public:
-  ListRecTy(Record *C) : Class(C) {}
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(ListInit *LI);
-  
+  ListRecTy(RecTy *T) : Ty(T) {}
+
+  RecTy *getElementType() const { return Ty; }
+
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI);
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { 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);}
+
   void print(std::ostream &OS) const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const {
+    return RHS->getElementType()->typeIsConvertibleTo(Ty);
+  }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+};
+
+/// CodeRecTy - 'code' - Represent an code fragment, function or method.
+///
+class CodeRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return (Init*)CI; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *DI) { 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);}
+
+
+  void print(std::ostream &OS) const { OS << "code"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return true; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+};
+
+/// DagRecTy - 'dag' - Represent a dag fragment
+///
+class DagRecTy : public RecTy {
+public:
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI) { return 0; }
+  virtual Init *convertValue(   DagInit *CI) { return (Init*)CI; }
+  virtual Init *convertValue( TypedInit *TI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+  void print(std::ostream &OS) const { OS << "dag"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return true; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
 };
 
-/// RecordRecTy - '<classname>' - Represent an instance of a class, such as:
+
+/// RecordRecTy - '[classname]' - Represent an instance of a class, such as:
 /// (R32 X = EAX).
 ///
 class RecordRecTy : public RecTy {
@@ -126,10 +378,33 @@ public:
 
   Record *getRecord() const { return Rec; }
 
-  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(   DefInit *DI);
+  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+  virtual Init *convertValue(   BitInit *BI) { return 0; }
+  virtual Init *convertValue(  BitsInit *BI) { return 0; }
+  virtual Init *convertValue(   IntInit *II) { return 0; }
+  virtual Init *convertValue(StringInit *SI) { return 0; }
+  virtual Init *convertValue(  ListInit *LI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
+  virtual Init *convertValue(VarBitInit *VB) { return 0; }
+  virtual Init *convertValue(   DefInit *DI);
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( TypedInit *VI);
+  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
+  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
   void print(std::ostream &OS) const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const;
 };
 
 
@@ -141,22 +416,68 @@ public:
 struct Init {
   virtual ~Init() {}
 
-  virtual bool isComplete() const = 0;
+  /// isComplete - This virtual method should be overridden by values that may
+  /// not be completely specified yet.
+  virtual bool isComplete() const { return true; }
+
+  /// print - Print out this value.
   virtual void print(std::ostream &OS) const = 0;
+
+  /// dump - Debugging method that may be called through a debugger, just
+  /// invokes print on cerr.
   void dump() const;
 
+  /// convertInitializerTo - This virtual function is a simple call-back
+  /// function that should be overridden to call the appropriate
+  /// RecTy::convertValue method.
+  ///
   virtual Init *convertInitializerTo(RecTy *Ty) = 0;
+
+  /// convertInitializerBitRange - This method is used to implement the bitrange
+  /// selection operator.  Given an initializer, it selects the specified bits
+  /// out, returning them as a new init of bits type.  If it is not legal to use
+  /// the bit subscript operator on this initializer, return null.
+  ///
   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits) {
     return 0;
   }
 
+  /// convertInitListSlice - This method is used to implement the list slice
+  /// selection operator.  Given an initializer, it selects the specified list
+  /// elements, returning them as a new init of list type.  If it is not legal
+  /// to take a slice of this, return null.
+  ///
+  virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements) {
+    return 0;
+  }
+
   /// getFieldType - This method is used to implement the FieldInit class.
   /// Implementors of this method should return the type of the named field if
   /// they are of record type.
   ///
   virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; }
 
-  virtual Init *resolveReferences(Record &R) { return this; }
+  /// getFieldInit - This method complements getFieldType to return the
+  /// initializer for the specified field.  If getFieldType returns non-null
+  /// this method should return non-null, otherwise it returns null.
+  ///
+  virtual Init *getFieldInit(Record &R, const std::string &FieldName) const {
+    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
+  /// users of the value to allow the value to propagate out.
+  ///
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV) {
+    return this;
+  }
 };
 
 inline std::ostream &operator<<(std::ostream &OS, const Init &I) {
@@ -166,7 +487,8 @@ inline std::ostream &operator<<(std::ostream &OS, const Init &I) {
 
 /// UnsetInit - ? - Represents an uninitialized value
 ///
-struct UnsetInit : public Init {
+class UnsetInit : public Init {
+public:
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
@@ -189,7 +511,6 @@ public:
     return Ty->convertValue(this);
   }
 
-  virtual bool isComplete() const { return true; }
   virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); }
 };
 
@@ -209,6 +530,7 @@ public:
   }
   void setBit(unsigned Bit, Init *V) {
     assert(Bit < Bits.size() && "Bit index out of range!");
+    assert(Bits[Bit] == 0 && "Bit already set!");
     Bits[Bit] = V;
   }
 
@@ -224,7 +546,7 @@ public:
   }
   virtual void print(std::ostream &OS) const;
 
-  virtual Init *resolveReferences(Record &R);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 
   // printXX - Print this bitstream with the specified format, returning true if
   // it is not possible.
@@ -248,7 +570,8 @@ public:
   }
   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
 
-  virtual bool isComplete() const { return true; }
+  virtual Init *getBinaryOp(BinaryOp Op, Init *RHS);
+
   virtual void print(std::ostream &OS) const { OS << Value; }
 };
 
@@ -260,83 +583,181 @@ class StringInit : public Init {
 public:
   StringInit(const std::string &V) : Value(V) {}
 
+  const std::string &getValue() const { return Value; }
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
 
-  virtual bool isComplete() const { return true; }
   virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; }
 };
 
+/// CodeInit - "[{...}]" - Represent a code fragment.
+///
+class CodeInit : public Init {
+  std::string Value;
+public:
+  CodeInit(const std::string &V) : Value(V) {}
+
+  const std::string getValue() const { return Value; }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual void print(std::ostream &OS) const { OS << "[{" << Value << "}]"; }
+};
+
 /// ListInit - [AL, AH, CL] - Represent a list of defs
 ///
 class ListInit : public Init {
-  std::vector<Record*> Records;
+  std::vector<Init*> Values;
 public:
-  ListInit(std::vector<Record*> &Rs) {
-    Records.swap(Rs);
+  ListInit(std::vector<Init*> &Vs) {
+    Values.swap(Vs);
   }
 
-  unsigned getSize() const { return Records.size(); }
-  Record  *getElement(unsigned i) const {
-    assert(i < Records.size() && "List element index out of range!");
-    return Records[i];
+  unsigned getSize() const { return Values.size(); }
+  Init *getElement(unsigned i) const {
+    assert(i < Values.size() && "List element index out of range!");
+    return Values[i];
   }
 
+  Init *convertInitListSlice(const std::vector<unsigned> &Elements);
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
 
-  virtual bool isComplete() const { return true; }
+  /// 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
+  /// users of the value to allow the value to propagate out.
+  ///
+  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.
+///
+class TypedInit : public Init {
+  RecTy *Ty;
+public:
+  TypedInit(RecTy *T) : Ty(T) {}
+
+  RecTy *getType() const { return Ty; }
+
+  virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+  virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements);
+
+  /// resolveBitReference - This method is used to implement
+  /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
+  /// simply return the resolved value, otherwise we return null.
+  ///
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit) = 0;
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt) = 0;
+};
+
 /// VarInit - 'Opcode' - Represent a reference to an entire variable object.
 ///
-class VarInit : public Init {
+class VarInit : public TypedInit {
   std::string VarName;
-  RecTy *Ty;
 public:
-  VarInit(const std::string &VN, RecTy *T) : VarName(VN), Ty(T) {}
-  
+  VarInit(const std::string &VN, RecTy *T) : TypedInit(T), VarName(VN) {}
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
 
   const std::string &getName() const { return VarName; }
-  RecTy *getType() const { return Ty; }
 
-  virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
 
   virtual RecTy *getFieldType(const std::string &FieldName) const;
-  
-  virtual bool isComplete() const { return true; }
+  virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
+
+  /// 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
+  /// users of the value to allow the value to propagate out.
+  ///
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
   virtual void print(std::ostream &OS) const { OS << VarName; }
 };
 
 
-/// VarBitInit - Opcode{0} - Represent access to one bit of a variable
+/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field.
 ///
 class VarBitInit : public Init {
-  VarInit *VI;
+  TypedInit *TI;
   unsigned Bit;
 public:
-  VarBitInit(VarInit *V, unsigned B) : VI(V), Bit(B) {}
+  VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) {
+    assert(T->getType() && dynamic_cast<BitsRecTy*>(T->getType()) &&
+           ((BitsRecTy*)T->getType())->getNumBits() > B &&
+           "Illegal VarBitInit expression!");
+  }
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
 
-  VarInit *getVariable() const { return VI; }
+  TypedInit *getVariable() const { return TI; }
   unsigned getBitNum() const { return Bit; }
-  
-  virtual bool isComplete() const { return true; }
+
   virtual void print(std::ostream &OS) const {
-    VI->print(OS); OS << "{" << Bit << "}";
+    TI->print(OS); OS << "{" << Bit << "}";
   }
-  virtual Init *resolveReferences(Record &R);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 };
 
+/// VarListElementInit - List[4] - Represent access to one element of a var or
+/// field.
+class VarListElementInit : public TypedInit {
+  TypedInit *TI;
+  unsigned Element;
+public:
+  VarListElementInit(TypedInit *T, unsigned E)
+    : TypedInit(dynamic_cast<ListRecTy*>(T->getType())->getElementType()),
+                TI(T), Element(E) {
+    assert(T->getType() && dynamic_cast<ListRecTy*>(T->getType()) &&
+           "Illegal VarBitInit expression!");
+  }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  TypedInit *getVariable() const { return TI; }
+  unsigned getElementNum() const { return Element; }
+
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+
+  /// resolveListElementReference - This method is used to implement
+  /// VarListElementInit::resolveReferences.  If the list element is resolvable
+  /// now, we return the resolved value, otherwise we return null.
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
+
+  virtual void print(std::ostream &OS) const {
+    TI->print(OS); OS << "[" << Element << "]";
+  }
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+};
 
 /// DefInit - AL - Represent a reference to a 'def' in the description
 ///
@@ -344,7 +765,7 @@ class DefInit : public Init {
   Record *Def;
 public:
   DefInit(Record *D) : Def(D) {}
-  
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
@@ -352,34 +773,83 @@ public:
   Record *getDef() const { return Def; }
 
   //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
-  
-  virtual bool isComplete() const { return true; }
+
+  virtual RecTy *getFieldType(const std::string &FieldName) const;
+  virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
+
   virtual void print(std::ostream &OS) const;
 };
 
 
 /// FieldInit - X.Y - Represent a reference to a subfield of a variable
 ///
-class FieldInit : public Init {
+class FieldInit : public TypedInit {
   Init *Rec;                // Record we are referring to
   std::string FieldName;    // Field we are accessing
-  RecTy *Ty;                // The type of this expression
 public:
   FieldInit(Init *R, const std::string &FN)
-    : Rec(R), FieldName(FN), Ty(R->getFieldType(FN)) {
-    assert(Ty && "FieldInit with non-record type!");
+    : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) {
+    assert(getType() && "FieldInit with non-record type!");
   }
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
 
-  virtual bool isComplete() const { return true; }
+  virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+                                    unsigned Bit);
+  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                            unsigned Elt);
+
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
   virtual void print(std::ostream &OS) const {
     Rec->print(OS); OS << "." << FieldName;
   }
 };
 
+/// 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.
+///
+class DagInit : public Init {
+  Record *NodeTypeDef;
+  std::vector<Init*> Args;
+  std::vector<std::string> ArgNames;
+public:
+  DagInit(Record *D, const std::vector<std::pair<Init*, std::string> > &args)
+    : NodeTypeDef(D) {
+    Args.reserve(args.size());
+    ArgNames.reserve(args.size());
+    for (unsigned i = 0, e = args.size(); i != e; ++i) {
+      Args.push_back(args[i].first);
+      ArgNames.push_back(args[i].second);
+    }
+  }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  Record *getNodeType() const { return NodeTypeDef; }
+
+  unsigned getNumArgs() const { return Args.size(); }
+  Init *getArg(unsigned Num) const {
+    assert(Num < Args.size() && "Arg number out of range!");
+    return Args[Num];
+  }
+  const std::string &getArgName(unsigned Num) const {
+    assert(Num < ArgNames.size() && "Arg number out of range!");
+    return ArgNames[Num];
+  }
+
+  void setArg(unsigned Num, Init *I) {
+    assert(Num < Args.size() && "Arg number out of range!");
+    Args[Num] = I;
+  }
+
+  virtual void print(std::ostream &OS) const;
+};
 
 //===----------------------------------------------------------------------===//
 //  High-Level Classes
@@ -392,7 +862,6 @@ class RecordVal {
   Init *Value;
 public:
   RecordVal(const std::string &N, RecTy *T, unsigned P);
-  ~RecordVal() { /*delete Ty; delete Value; Bad for copy ctor!*/ }
 
   const std::string &getName() const { return Name; }
 
@@ -418,7 +887,7 @@ inline std::ostream &operator<<(std::ostream &OS, const RecordVal &RV) {
   return OS;
 }
 
-struct Record {
+class Record {
   const std::string Name;
   std::vector<std::string> TemplateArgs;
   std::vector<RecordVal> Values;
@@ -462,10 +931,27 @@ public:
     Values.push_back(RV);
   }
 
+  void removeValue(const std::string &Name) {
+    assert(getValue(Name) && "Cannot remove an entry that does not exist!");
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].getName() == Name) {
+        Values.erase(Values.begin()+i);
+        return;
+      }
+    assert(0 && "Name does not exist in record!");
+  }
+
   bool isSubClassOf(Record *R) const {
     for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
       if (SuperClasses[i] == R)
-       return true;
+        return true;
+    return false;
+  }
+
+  bool isSubClassOf(const std::string &Name) const {
+    for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
+      if (SuperClasses[i]->getName() == Name)
+        return true;
     return false;
   }
 
@@ -474,12 +960,68 @@ public:
     SuperClasses.push_back(R);
   }
 
-  // resolveReferences - If there are any field references that refer to fields
-  // that have been filled in, we can propagate the values now.
-  //
-  void resolveReferences();
+  /// resolveReferences - If there are any field references that refer to fields
+  /// that have been filled in, we can propagate the values now.
+  ///
+  void resolveReferences() { resolveReferencesTo(0); }
+
+  /// resolveReferencesTo - If anything in this record refers to RV, replace the
+  /// reference to RV with the RHS of RV.  If RV is null, we resolve all
+  /// possible references.
+  void resolveReferencesTo(const RecordVal *RV);
 
   void dump() const;
+
+  //===--------------------------------------------------------------------===//
+  // High-level methods useful to tablegen back-ends
+  //
+
+  /// getValueInit - Return the initializer for a value with the specified name,
+  /// or throw an exception if the field does not exist.
+  ///
+  Init *getValueInit(const std::string &FieldName) const;
+
+  /// getValueAsString - This method looks up the specified field and returns
+  /// its value as a string, throwing an exception if the field does not exist
+  /// or if the value is not a string.
+  ///
+  std::string getValueAsString(const std::string &FieldName) const;
+
+  /// getValueAsBitsInit - This method looks up the specified field and returns
+  /// its value as a BitsInit, throwing an exception if the field does not exist
+  /// or if the value is not the right type.
+  ///
+  BitsInit *getValueAsBitsInit(const std::string &FieldName) const;
+
+  /// getValueAsListInit - This method looks up the specified field and returns
+  /// its value as a ListInit, throwing an exception if the field does not exist
+  /// or if the value is not the right type.
+  ///
+  ListInit *getValueAsListInit(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.
+  ///
+  Record *getValueAsDef(const std::string &FieldName) const;
+
+  /// getValueAsBit - This method looks up the specified field and returns its
+  /// value as a bit, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  bool getValueAsBit(const std::string &FieldName) const;
+
+  /// getValueAsInt - This method looks up the specified field and returns its
+  /// value as an int, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  int getValueAsInt(const std::string &FieldName) const;
+
+  /// getValueAsDag - This method looks up the specified field and returns its
+  /// value as an Dag, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  DagInit *getValueAsDag(const std::string &FieldName) const;
 };
 
 std::ostream &operator<<(std::ostream &OS, const Record &R);
@@ -489,13 +1031,13 @@ class RecordKeeper {
 public:
   ~RecordKeeper() {
     for (std::map<std::string, Record*>::iterator I = Classes.begin(),
-          E = Classes.end(); I != E; ++I)
+           E = Classes.end(); I != E; ++I)
       delete I->second;
     for (std::map<std::string, Record*>::iterator I = Defs.begin(),
-          E = Defs.end(); I != E; ++I)
+           E = Defs.end(); I != E; ++I)
       delete I->second;
   }
-  
+
   const std::map<std::string, Record*> &getClasses() const { return Classes; }
   const std::map<std::string, Record*> &getDefs() const { return Defs; }
 
@@ -516,6 +1058,16 @@ public:
     Defs.insert(std::make_pair(R->getName(), R));
   }
 
+  //===--------------------------------------------------------------------===//
+  // High-level helper methods, useful for tablegen backends...
+
+  /// getAllDerivedDefinitions - This method returns all concrete definitions
+  /// that derive from the specified class name.  If a class with the specified
+  /// name does not exist, an exception is thrown.
+  std::vector<Record*>
+  getAllDerivedDefinitions(const std::string &ClassName) const;
+
+
   void dump() const;
 };
 
@@ -523,4 +1075,6 @@ std::ostream &operator<<(std::ostream &OS, const RecordKeeper &RK);
 
 extern RecordKeeper Records;
 
+} // End llvm namespace
+
 #endif