RecTy *Ty;
Init *Initializer;
std::vector<Init*> *FieldList;
- std::vector<Record*> *RecPtr;
std::vector<unsigned>*BitList;
Record *Rec;
SubClassRefTy *SubClassRef;
%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
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
$$ = 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();
$$ = 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);
abort();
}
delete $3;
- } | '[' DefList ']' {
+ } | '[' ValueList ']' {
$$ = new ListInit(*$2);
delete $2;
} | Value '.' ID {
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);
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!
}
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;
}
return 0;
}
+bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
+ return Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec);
+}
+
+
//===----------------------------------------------------------------------===//
// Initializer implementations
//===----------------------------------------------------------------------===//
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 << "]";
}
#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;
class VarInit;
class FieldInit;
class VarBitInit;
+
+// Other classes...
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; }
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) {
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; }
};
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;
+ }
};
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
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.
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; }
};
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;
};
/// 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) {
RecTy *Ty;
Init *Initializer;
std::vector<Init*> *FieldList;
- std::vector<Record*> *RecPtr;
std::vector<unsigned>*BitList;
Record *Rec;
SubClassRefTy *SubClassRef;
%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
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
$$ = 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();
$$ = 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);
abort();
}
delete $3;
- } | '[' DefList ']' {
+ } | '[' ValueList ']' {
$$ = new ListInit(*$2);
delete $2;
} | Value '.' ID {
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);
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!
}
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;
}
return 0;
}
+bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
+ return Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec);
+}
+
+
//===----------------------------------------------------------------------===//
// Initializer implementations
//===----------------------------------------------------------------------===//
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 << "]";
}
#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;
class VarInit;
class FieldInit;
class VarBitInit;
+
+// Other classes...
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; }
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) {
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; }
};
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;
+ }
};
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
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.
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; }
};
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;
};
/// 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) {