Changes to allow lists of any type

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7519 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2003-08-03 18:17:22 +00:00
parent bc1f0dc7eb
commit 7cf0ce4b8d
6 changed files with 230 additions and 110 deletions

View 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);

View 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 << "]";
}

View File

@ -14,6 +14,16 @@
#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) {

View 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);

View 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 << "]";
}

View File

@ -14,6 +14,16 @@
#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) {