diff --git a/test/TableGen/FieldAccess.td b/test/TableGen/FieldAccess.td new file mode 100644 index 00000000000..ad652e79ea7 --- /dev/null +++ b/test/TableGen/FieldAccess.td @@ -0,0 +1,14 @@ +// RUN: tblgen %s +class Bla<string t> +{ + string blu = t; +} + +class Bli<Bla t> +{ + Bla bla = t; +} + +def a : Bli<Bla<"">>; +def b : Bla<!cast<Bla>(a.bla).blu>; // works +def c : Bla<a.bla.blu>; // doesn't work: Cannot access field 'blu' of value 'a.bla' diff --git a/test/TableGen/ListManip.td b/test/TableGen/ListManip.td new file mode 100644 index 00000000000..c221bb1335b --- /dev/null +++ b/test/TableGen/ListManip.td @@ -0,0 +1,10 @@ +// RUN: tblgen %s +class Bli<string _t> +{ + string t = _t; +} + +class Bla<list<Bli> _bli> +: Bli<!car(_bli).t> +{ +} diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index d2cf379907f..dc793586fbe 100644 --- a/utils/TableGen/Record.cpp +++ b/utils/TableGen/Record.cpp @@ -628,23 +628,6 @@ std::string UnOpInit::getAsString() const { return Result + "(" + LHS->getAsString() + ")"; } -RecTy *UnOpInit::getFieldType(const std::string &FieldName) const { - switch (getOpcode()) { - default: assert(0 && "Unknown unop"); - case CAST: { - RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType()); - if (RecordType) { - RecordVal *Field = RecordType->getRecord()->getValue(FieldName); - if (Field) { - return Field->getType(); - } - } - break; - } - } - return 0; -} - Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { switch (getOpcode()) { default: assert(0 && "Unknown binop"); @@ -1046,6 +1029,17 @@ std::string TernOpInit::getAsString() const { + RHS->getAsString() + ")"; } +RecTy *TypedInit::getFieldType(const std::string &FieldName) const { + RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType()); + if (RecordType) { + RecordVal *Field = RecordType->getRecord()->getValue(FieldName); + if (Field) { + return Field->getType(); + } + } + return 0; +} + Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) { BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType()); if (T == 0) return 0; // Cannot subscript a non-bits variable... diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index 8f9fd950bb0..d6f37eec749 100644 --- a/utils/TableGen/Record.h +++ b/utils/TableGen/Record.h @@ -535,6 +535,12 @@ public: virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits); virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements); + /// getFieldType - This method is used to implement the FieldInit class. + /// Implementors of this method should return the type of the named field if + /// they are of record type. + /// + virtual RecTy *getFieldType(const std::string &FieldName) const; + /// resolveBitReference - This method is used to implement /// VarBitInit::resolveReferences. If the bit is able to be resolved, we /// simply return the resolved value, otherwise we return null. @@ -835,12 +841,6 @@ public: virtual Init *resolveReferences(Record &R, const RecordVal *RV); - /// getFieldType - This method is used to implement the FieldInit class. - /// Implementors of this method should return the type of the named field if - /// they are of record type. - /// - virtual RecTy *getFieldType(const std::string &FieldName) const; - virtual std::string getAsString() const; };