Changes to allow lists of any type
authorChris Lattner <sabre@nondot.org>
Sun, 3 Aug 2003 18:17:22 +0000 (18:17 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 3 Aug 2003 18:17:22 +0000 (18:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7519 91177308-0d34-0410-b5e6-96231b3b80d8

support/tools/TableGen/FileParser.y
support/tools/TableGen/Record.cpp
support/tools/TableGen/Record.h
utils/TableGen/FileParser.y
utils/TableGen/Record.cpp
utils/TableGen/Record.h

index 7144c915c3bbe720f128d03df8ef840cbb3edf37..4025d4e2315dea5f6686c0b0fff22cc121dbec2e 100644 (file)
@@ -162,7 +162,6 @@ static void addSubClass(Record *SC, const std::vector<Init*> &TemplateArgs) {
   RecTy                *Ty;
   Init                 *Initializer;
   std::vector<Init*>   *FieldList;
-  std::vector<Record*> *RecPtr;
   std::vector<unsigned>*BitList;
   Record               *Rec;
   SubClassRefTy        *SubClassRef;
@@ -174,8 +173,7 @@ static void addSubClass(Record *SC, const std::vector<Init*> &TemplateArgs) {
 %token <StrVal>      ID STRVAL CODEFRAGMENT
 
 %type <Ty>           Type
-%type <RecPtr>       DefList DefListNE
-%type <Rec>          ClassInst DefInst Object ObjectBody ClassID DefID
+%type <Rec>          ClassInst DefInst Object ObjectBody ClassID
 
 %type <SubClassRef>  SubClassRef
 %type <SubClassList> ClassList ClassListNE
@@ -197,15 +195,6 @@ ClassID : ID {
     delete $1;
   };
 
-DefID : ID {
-    $$ = Records.getDef(*$1);
-    if ($$ == 0) {
-      err() << "Couldn't find def '" << *$1 << "'!\n";
-      abort();
-    }
-    delete $1;
-  };
-
 
 // TableGen types...
 Type : STRING {                       // string type
@@ -216,7 +205,7 @@ Type : STRING {                       // string type
     $$ = new BitsRecTy($3);
   } | INT {                           // int type
     $$ = new IntRecTy();
-  } | LIST '<' ClassID '>' {          // list<x> type
+  } | LIST '<' Type '>'    {          // list<x> type
     $$ = new ListRecTy($3);
   } | CODE {                          // code type
     $$ = new CodeRecTy();
@@ -252,11 +241,7 @@ Value : INTVAL {
     $$ = Init;
     delete $2;
   } | ID {
-    if (CurRec == 0) {
-      err() << "Def/Class name '" << *$1 << "' not allowed here!\n";
-      abort();
-    }
-    if (const RecordVal *RV = CurRec->getValue(*$1)) {
+    if (const RecordVal *RV = (CurRec ? CurRec->getValue(*$1) : 0)) {
       $$ = new VarInit(*$1, RV->getType());
     } else if (Record *D = Records.getDef(*$1)) {
       $$ = new DefInit(D);
@@ -273,7 +258,7 @@ Value : INTVAL {
       abort();
     }
     delete $3;
-  } | '[' DefList ']' {
+  } | '[' ValueList ']' {
     $$ = new ListInit(*$2);
     delete $2;
   } | Value '.' ID {
@@ -285,19 +270,6 @@ Value : INTVAL {
     delete $3;
   };
 
-DefList : /*empty */ {
-    $$ = new std::vector<Record*>();
-  } | DefListNE {
-    $$ = $1;
-  };
-DefListNE : DefID {
-    $$ = new std::vector<Record*>();
-    $$->push_back($1);
-  } | DefListNE ',' DefID {
-    ($$=$1)->push_back($3);
-  };
-
-
 RBitList : INTVAL {
     $$ = new std::vector<unsigned>();
     $$->push_back($1);
index 309f386e78c094c033793dded27ab99119381cfb..ef7d9a044ae66e1ffad1448d40d3604ac9328744 100644 (file)
@@ -16,6 +16,10 @@ Init *BitRecTy::convertValue(BitsInit *BI) {
   return BI->getBit(0);
 }
 
+bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
+  return RHS->getNumBits() == 1;
+}
+
 Init *BitRecTy::convertValue(IntInit *II) {
   int Val = II->getValue();
   if (Val != 0 && Val != 1) return 0;  // Only accept 0 or 1 for a bit!
@@ -104,22 +108,27 @@ Init *StringRecTy::convertValue(TypedInit *TI) {
 }
 
 void ListRecTy::print(std::ostream &OS) const {
-  OS << "list<" << Class->getName() << ">";
+  OS << "list<" << *Ty << ">";
 }
 
 Init *ListRecTy::convertValue(ListInit *LI) {
+  std::vector<Init*> Elements;
+
   // Verify that all of the elements of the list are subclasses of the
-  // appopriate class!
+  // appropriate class!
   for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
-    if (!LI->getElement(i)->isSubClassOf(Class))
+    if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
+      Elements.push_back(CI);
+    else
       return 0;
-  return LI;
+
+  return new ListInit(Elements);
 }
 
 Init *ListRecTy::convertValue(TypedInit *TI) {
   // Ensure that TI is compatible with our class.
   if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
-    if (LRT->getElementClass() == getElementClass())
+    if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
       return TI;
   return 0;
 }
@@ -144,6 +153,11 @@ Init *RecordRecTy::convertValue(TypedInit *TI) {
   return 0;
 }
 
+bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
+  return Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec);
+}
+
+
 //===----------------------------------------------------------------------===//
 //    Initializer implementations
 //===----------------------------------------------------------------------===//
@@ -263,9 +277,9 @@ Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
 
 void ListInit::print(std::ostream &OS) const {
   OS << "[";
-  for (unsigned i = 0, e = Records.size(); i != e; ++i) {
+  for (unsigned i = 0, e = Values.size(); i != e; ++i) {
     if (i) OS << ", ";
-    OS << Records[i]->getName();
+    OS << *Values[i];
   }
   OS << "]";
 }
index 1eedf43a18a5f65e73983226523b12bc33eb7430..4c4ad5a6b8cfff380974a5e33bdb3c543c5b0992 100644 (file)
 #include <iostream>
 #include <cassert>
 
+// RecTy subclasses...
+class BitRecTy;
+class BitsRecTy;
+class IntRecTy;
+class StringRecTy;
+class ListRecTy;
+class CodeRecTy;
+class RecordRecTy;
+
+// Init subclasses...
 class Init;
 class UnsetInit;
 class BitInit;
@@ -27,6 +37,8 @@ class TypedInit;
 class VarInit;
 class FieldInit;
 class VarBitInit;
+
+// Other classes...
 class Record;
 
 //===----------------------------------------------------------------------===//
@@ -36,6 +48,14 @@ 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; }
@@ -53,8 +73,16 @@ struct RecTy {
     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 RecordRecTy *RHS) const { return false; }
 };
 
 inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) {
@@ -74,6 +102,13 @@ struct BitRecTy : public RecTy {
   Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
 
   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; }
 };
 
 
@@ -93,6 +128,15 @@ public:
   Init *convertValue(TypedInit *VI);
 
   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 IntRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy *RHS) const {
+    return RHS->Size == Size;
+  }
 };
 
 
@@ -105,6 +149,14 @@ struct IntRecTy : public RecTy {
   Init *convertValue(TypedInit *TI);
 
   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 IntRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; }
 };
 
 /// StringRecTy - 'string' - Represent an string value
@@ -114,25 +166,37 @@ struct StringRecTy : public RecTy {
   Init *convertValue(StringInit *SI) { return (Init*)SI; }
   Init *convertValue(TypedInit *TI);
   void print(std::ostream &OS) const { OS << "string"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
 };
 
-/// 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.
 ///
 class ListRecTy : public RecTy {
-  Record *Class;
+  RecTy *Ty;
 public:
-  ListRecTy(Record *C) : Class(C) {}
+  ListRecTy(RecTy *T) : Ty(T) {}
 
-  /// getElementClass - Return the class that the list contains.
-  ///
-  Record *getElementClass() const { return Class; }
+  RecTy *getElementType() const { return Ty; }
 
   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
   Init *convertValue(ListInit *LI);
   Init *convertValue(TypedInit *TI);
   
   void print(std::ostream &OS) const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const ListRecTy *RHS) const {
+    return RHS->getElementType()->typeIsConvertibleTo(Ty); 
+  }
 };
 
 /// CodeRecTy - 'code' - Represent an code fragment, function or method.
@@ -142,6 +206,11 @@ struct CodeRecTy : public RecTy {
   Init *convertValue( CodeInit *CI) { return (Init*)CI; }
 
   void print(std::ostream &OS) const { OS << "code"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; }
 };
 
 
@@ -160,6 +229,11 @@ public:
   Init *convertValue(TypedInit *VI); 
 
   void print(std::ostream &OS) const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const;
 };
 
 
@@ -347,16 +421,16 @@ public:
 /// 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];
   }
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
index 7144c915c3bbe720f128d03df8ef840cbb3edf37..4025d4e2315dea5f6686c0b0fff22cc121dbec2e 100644 (file)
@@ -162,7 +162,6 @@ static void addSubClass(Record *SC, const std::vector<Init*> &TemplateArgs) {
   RecTy                *Ty;
   Init                 *Initializer;
   std::vector<Init*>   *FieldList;
-  std::vector<Record*> *RecPtr;
   std::vector<unsigned>*BitList;
   Record               *Rec;
   SubClassRefTy        *SubClassRef;
@@ -174,8 +173,7 @@ static void addSubClass(Record *SC, const std::vector<Init*> &TemplateArgs) {
 %token <StrVal>      ID STRVAL CODEFRAGMENT
 
 %type <Ty>           Type
-%type <RecPtr>       DefList DefListNE
-%type <Rec>          ClassInst DefInst Object ObjectBody ClassID DefID
+%type <Rec>          ClassInst DefInst Object ObjectBody ClassID
 
 %type <SubClassRef>  SubClassRef
 %type <SubClassList> ClassList ClassListNE
@@ -197,15 +195,6 @@ ClassID : ID {
     delete $1;
   };
 
-DefID : ID {
-    $$ = Records.getDef(*$1);
-    if ($$ == 0) {
-      err() << "Couldn't find def '" << *$1 << "'!\n";
-      abort();
-    }
-    delete $1;
-  };
-
 
 // TableGen types...
 Type : STRING {                       // string type
@@ -216,7 +205,7 @@ Type : STRING {                       // string type
     $$ = new BitsRecTy($3);
   } | INT {                           // int type
     $$ = new IntRecTy();
-  } | LIST '<' ClassID '>' {          // list<x> type
+  } | LIST '<' Type '>'    {          // list<x> type
     $$ = new ListRecTy($3);
   } | CODE {                          // code type
     $$ = new CodeRecTy();
@@ -252,11 +241,7 @@ Value : INTVAL {
     $$ = Init;
     delete $2;
   } | ID {
-    if (CurRec == 0) {
-      err() << "Def/Class name '" << *$1 << "' not allowed here!\n";
-      abort();
-    }
-    if (const RecordVal *RV = CurRec->getValue(*$1)) {
+    if (const RecordVal *RV = (CurRec ? CurRec->getValue(*$1) : 0)) {
       $$ = new VarInit(*$1, RV->getType());
     } else if (Record *D = Records.getDef(*$1)) {
       $$ = new DefInit(D);
@@ -273,7 +258,7 @@ Value : INTVAL {
       abort();
     }
     delete $3;
-  } | '[' DefList ']' {
+  } | '[' ValueList ']' {
     $$ = new ListInit(*$2);
     delete $2;
   } | Value '.' ID {
@@ -285,19 +270,6 @@ Value : INTVAL {
     delete $3;
   };
 
-DefList : /*empty */ {
-    $$ = new std::vector<Record*>();
-  } | DefListNE {
-    $$ = $1;
-  };
-DefListNE : DefID {
-    $$ = new std::vector<Record*>();
-    $$->push_back($1);
-  } | DefListNE ',' DefID {
-    ($$=$1)->push_back($3);
-  };
-
-
 RBitList : INTVAL {
     $$ = new std::vector<unsigned>();
     $$->push_back($1);
index 309f386e78c094c033793dded27ab99119381cfb..ef7d9a044ae66e1ffad1448d40d3604ac9328744 100644 (file)
@@ -16,6 +16,10 @@ Init *BitRecTy::convertValue(BitsInit *BI) {
   return BI->getBit(0);
 }
 
+bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
+  return RHS->getNumBits() == 1;
+}
+
 Init *BitRecTy::convertValue(IntInit *II) {
   int Val = II->getValue();
   if (Val != 0 && Val != 1) return 0;  // Only accept 0 or 1 for a bit!
@@ -104,22 +108,27 @@ Init *StringRecTy::convertValue(TypedInit *TI) {
 }
 
 void ListRecTy::print(std::ostream &OS) const {
-  OS << "list<" << Class->getName() << ">";
+  OS << "list<" << *Ty << ">";
 }
 
 Init *ListRecTy::convertValue(ListInit *LI) {
+  std::vector<Init*> Elements;
+
   // Verify that all of the elements of the list are subclasses of the
-  // appopriate class!
+  // appropriate class!
   for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
-    if (!LI->getElement(i)->isSubClassOf(Class))
+    if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
+      Elements.push_back(CI);
+    else
       return 0;
-  return LI;
+
+  return new ListInit(Elements);
 }
 
 Init *ListRecTy::convertValue(TypedInit *TI) {
   // Ensure that TI is compatible with our class.
   if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
-    if (LRT->getElementClass() == getElementClass())
+    if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
       return TI;
   return 0;
 }
@@ -144,6 +153,11 @@ Init *RecordRecTy::convertValue(TypedInit *TI) {
   return 0;
 }
 
+bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
+  return Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec);
+}
+
+
 //===----------------------------------------------------------------------===//
 //    Initializer implementations
 //===----------------------------------------------------------------------===//
@@ -263,9 +277,9 @@ Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
 
 void ListInit::print(std::ostream &OS) const {
   OS << "[";
-  for (unsigned i = 0, e = Records.size(); i != e; ++i) {
+  for (unsigned i = 0, e = Values.size(); i != e; ++i) {
     if (i) OS << ", ";
-    OS << Records[i]->getName();
+    OS << *Values[i];
   }
   OS << "]";
 }
index 1eedf43a18a5f65e73983226523b12bc33eb7430..4c4ad5a6b8cfff380974a5e33bdb3c543c5b0992 100644 (file)
 #include <iostream>
 #include <cassert>
 
+// RecTy subclasses...
+class BitRecTy;
+class BitsRecTy;
+class IntRecTy;
+class StringRecTy;
+class ListRecTy;
+class CodeRecTy;
+class RecordRecTy;
+
+// Init subclasses...
 class Init;
 class UnsetInit;
 class BitInit;
@@ -27,6 +37,8 @@ class TypedInit;
 class VarInit;
 class FieldInit;
 class VarBitInit;
+
+// Other classes...
 class Record;
 
 //===----------------------------------------------------------------------===//
@@ -36,6 +48,14 @@ 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; }
@@ -53,8 +73,16 @@ struct RecTy {
     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 RecordRecTy *RHS) const { return false; }
 };
 
 inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) {
@@ -74,6 +102,13 @@ struct BitRecTy : public RecTy {
   Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
 
   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; }
 };
 
 
@@ -93,6 +128,15 @@ public:
   Init *convertValue(TypedInit *VI);
 
   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 IntRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy *RHS) const {
+    return RHS->Size == Size;
+  }
 };
 
 
@@ -105,6 +149,14 @@ struct IntRecTy : public RecTy {
   Init *convertValue(TypedInit *TI);
 
   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 IntRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; }
 };
 
 /// StringRecTy - 'string' - Represent an string value
@@ -114,25 +166,37 @@ struct StringRecTy : public RecTy {
   Init *convertValue(StringInit *SI) { return (Init*)SI; }
   Init *convertValue(TypedInit *TI);
   void print(std::ostream &OS) const { OS << "string"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
 };
 
-/// 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.
 ///
 class ListRecTy : public RecTy {
-  Record *Class;
+  RecTy *Ty;
 public:
-  ListRecTy(Record *C) : Class(C) {}
+  ListRecTy(RecTy *T) : Ty(T) {}
 
-  /// getElementClass - Return the class that the list contains.
-  ///
-  Record *getElementClass() const { return Class; }
+  RecTy *getElementType() const { return Ty; }
 
   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
   Init *convertValue(ListInit *LI);
   Init *convertValue(TypedInit *TI);
   
   void print(std::ostream &OS) const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const ListRecTy *RHS) const {
+    return RHS->getElementType()->typeIsConvertibleTo(Ty); 
+  }
 };
 
 /// CodeRecTy - 'code' - Represent an code fragment, function or method.
@@ -142,6 +206,11 @@ struct CodeRecTy : public RecTy {
   Init *convertValue( CodeInit *CI) { return (Init*)CI; }
 
   void print(std::ostream &OS) const { OS << "code"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; }
 };
 
 
@@ -160,6 +229,11 @@ public:
   Init *convertValue(TypedInit *VI); 
 
   void print(std::ostream &OS) const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const;
 };
 
 
@@ -347,16 +421,16 @@ public:
 /// 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];
   }
 
   virtual Init *convertInitializerTo(RecTy *Ty) {