mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
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:
parent
bc1f0dc7eb
commit
7cf0ce4b8d
@ -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);
|
||||
|
@ -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 << "]";
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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 << "]";
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user