diff --git a/support/tools/TableGen/FileParser.y b/support/tools/TableGen/FileParser.y index 7144c915c3b..4025d4e2315 100644 --- a/support/tools/TableGen/FileParser.y +++ b/support/tools/TableGen/FileParser.y @@ -162,7 +162,6 @@ static void addSubClass(Record *SC, const std::vector &TemplateArgs) { RecTy *Ty; Init *Initializer; std::vector *FieldList; - std::vector *RecPtr; std::vector*BitList; Record *Rec; SubClassRefTy *SubClassRef; @@ -174,8 +173,7 @@ static void addSubClass(Record *SC, const std::vector &TemplateArgs) { %token ID STRVAL CODEFRAGMENT %type Type -%type DefList DefListNE -%type ClassInst DefInst Object ObjectBody ClassID DefID +%type ClassInst DefInst Object ObjectBody ClassID %type SubClassRef %type 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 type + } | LIST '<' Type '>' { // list 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(); - } | DefListNE { - $$ = $1; - }; -DefListNE : DefID { - $$ = new std::vector(); - $$->push_back($1); - } | DefListNE ',' DefID { - ($$=$1)->push_back($3); - }; - - RBitList : INTVAL { $$ = new std::vector(); $$->push_back($1); diff --git a/support/tools/TableGen/Record.cpp b/support/tools/TableGen/Record.cpp index 309f386e78c..ef7d9a044ae 100644 --- a/support/tools/TableGen/Record.cpp +++ b/support/tools/TableGen/Record.cpp @@ -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 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(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 &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 << "]"; } diff --git a/support/tools/TableGen/Record.h b/support/tools/TableGen/Record.h index 1eedf43a18a..4c4ad5a6b8c 100644 --- a/support/tools/TableGen/Record.h +++ b/support/tools/TableGen/Record.h @@ -14,6 +14,16 @@ #include #include +// 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' - Represent a list defs, all of which must be -/// derived from the specified class. +/// ListRecTy - 'list' - 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 Records; + std::vector Values; public: - ListInit(std::vector &Rs) { - Records.swap(Rs); + ListInit(std::vector &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) { diff --git a/utils/TableGen/FileParser.y b/utils/TableGen/FileParser.y index 7144c915c3b..4025d4e2315 100644 --- a/utils/TableGen/FileParser.y +++ b/utils/TableGen/FileParser.y @@ -162,7 +162,6 @@ static void addSubClass(Record *SC, const std::vector &TemplateArgs) { RecTy *Ty; Init *Initializer; std::vector *FieldList; - std::vector *RecPtr; std::vector*BitList; Record *Rec; SubClassRefTy *SubClassRef; @@ -174,8 +173,7 @@ static void addSubClass(Record *SC, const std::vector &TemplateArgs) { %token ID STRVAL CODEFRAGMENT %type Type -%type DefList DefListNE -%type ClassInst DefInst Object ObjectBody ClassID DefID +%type ClassInst DefInst Object ObjectBody ClassID %type SubClassRef %type 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 type + } | LIST '<' Type '>' { // list 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(); - } | DefListNE { - $$ = $1; - }; -DefListNE : DefID { - $$ = new std::vector(); - $$->push_back($1); - } | DefListNE ',' DefID { - ($$=$1)->push_back($3); - }; - - RBitList : INTVAL { $$ = new std::vector(); $$->push_back($1); diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index 309f386e78c..ef7d9a044ae 100644 --- a/utils/TableGen/Record.cpp +++ b/utils/TableGen/Record.cpp @@ -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 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(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 &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 << "]"; } diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index 1eedf43a18a..4c4ad5a6b8c 100644 --- a/utils/TableGen/Record.h +++ b/utils/TableGen/Record.h @@ -14,6 +14,16 @@ #include #include +// 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' - Represent a list defs, all of which must be -/// derived from the specified class. +/// ListRecTy - 'list' - 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 Records; + std::vector Values; public: - ListInit(std::vector &Rs) { - Records.swap(Rs); + ListInit(std::vector &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) {