diff options
-rw-r--r-- | llvm/docs/TableGenFundamentals.html | 3 | ||||
-rw-r--r-- | llvm/utils/TableGen/Record.cpp | 117 | ||||
-rw-r--r-- | llvm/utils/TableGen/Record.h | 6 |
3 files changed, 89 insertions, 37 deletions
diff --git a/llvm/docs/TableGenFundamentals.html b/llvm/docs/TableGenFundamentals.html index 05b2b233e6a..ec87f2967cb 100644 --- a/llvm/docs/TableGenFundamentals.html +++ b/llvm/docs/TableGenFundamentals.html @@ -411,7 +411,8 @@ which case the user must specify it explicitly.</dd> <dt><tt>!cast<type>(a)</tt></dt> <dd>A symbol of type <em>type</em> obtained by looking up the string 'a' in the symbol table. If the type of 'a' does not match <em>type</em>, TableGen -aborts with an error. </dd> +aborts with an error. !cast<string> is a special case in that the argument must +be an object defined by a 'def' construct.</dd> <dt><tt>!nameconcat<type>(a, b)</tt></dt> <dd>Shorthand for !cast<type>(!strconcat(a, b))</dd> <dt><tt>!subst(a, b, c)</tt></dt> diff --git a/llvm/utils/TableGen/Record.cpp b/llvm/utils/TableGen/Record.cpp index c62e21b3aa1..92ba62879ee 100644 --- a/llvm/utils/TableGen/Record.cpp +++ b/llvm/utils/TableGen/Record.cpp @@ -537,52 +537,80 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { switch (getOpcode()) { default: assert(0 && "Unknown unop"); case CAST: { - StringInit *LHSs = dynamic_cast<StringInit*>(LHS); - if (LHSs) { - std::string Name = LHSs->getValue(); + if (getType()->getAsString() == "string") { + StringInit *LHSs = dynamic_cast<StringInit*>(LHS); + if (LHSs) { + return LHSs; + } - // From TGParser::ParseIDValue - if (CurRec) { - if (const RecordVal *RV = CurRec->getValue(Name)) { - if (RV->getType() != getType()) { - throw "type mismatch in nameconcat"; - } - return new VarInit(Name, RV->getType()); - } - - std::string TemplateArgName = CurRec->getName()+":"+Name; - if (CurRec->isTemplateArg(TemplateArgName)) { - const RecordVal *RV = CurRec->getValue(TemplateArgName); - assert(RV && "Template arg doesn't exist??"); + DefInit *LHSd = dynamic_cast<DefInit*>(LHS); + if (LHSd) { + return new StringInit(LHSd->getDef()->getName()); + } - if (RV->getType() != getType()) { - throw "type mismatch in nameconcat"; +// VarInit *LHSv = dynamic_cast<VarInit*>(LHS); +// if (LHSv) { +// // If this is not a template arg, cast it +// if (!CurRec->isTemplateArg(LHSv->getName()) +// && !CurMultiClass) { +// return new StringInit(LHSv->getName()); +// } +// break; +// } + +// OpInit *LHSo = dynamic_cast<OpInit*>(LHS); +// if (!LHSo) { +// return new StringInit(LHS->getAsString()); +// } + } + else { + StringInit *LHSs = dynamic_cast<StringInit*>(LHS); + if (LHSs) { + std::string Name = LHSs->getValue(); + + // From TGParser::ParseIDValue + if (CurRec) { + if (const RecordVal *RV = CurRec->getValue(Name)) { + if (RV->getType() != getType()) { + throw "type mismatch in nameconcat"; + } + return new VarInit(Name, RV->getType()); } - return new VarInit(TemplateArgName, RV->getType()); - } - } + std::string TemplateArgName = CurRec->getName()+":"+Name; + if (CurRec->isTemplateArg(TemplateArgName)) { + const RecordVal *RV = CurRec->getValue(TemplateArgName); + assert(RV && "Template arg doesn't exist??"); - if (CurMultiClass) { - std::string MCName = CurMultiClass->Rec.getName()+"::"+Name; - if (CurMultiClass->Rec.isTemplateArg(MCName)) { - const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); - assert(RV && "Template arg doesn't exist??"); + if (RV->getType() != getType()) { + throw "type mismatch in nameconcat"; + } - if (RV->getType() != getType()) { - throw "type mismatch in nameconcat"; + return new VarInit(TemplateArgName, RV->getType()); } - - return new VarInit(MCName, RV->getType()); } - } - if (Record *D = Records.getDef(Name)) - return new DefInit(D); + if (CurMultiClass) { + std::string MCName = CurMultiClass->Rec.getName()+"::"+Name; + if (CurMultiClass->Rec.isTemplateArg(MCName)) { + const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); + assert(RV && "Template arg doesn't exist??"); + + if (RV->getType() != getType()) { + throw "type mismatch in nameconcat"; + } + + return new VarInit(MCName, RV->getType()); + } + } + + if (Record *D = Records.getDef(Name)) + return new DefInit(D); - cerr << "Variable not defined: '" + Name + "'\n"; - assert(0 && "Variable not found"); - return 0; + cerr << "Variable not defined: '" + Name + "'\n"; + assert(0 && "Variable not found"); + return 0; + } } break; } @@ -654,6 +682,23 @@ 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"); diff --git a/llvm/utils/TableGen/Record.h b/llvm/utils/TableGen/Record.h index 5f45ea09caf..2254dd84e08 100644 --- a/llvm/utils/TableGen/Record.h +++ b/llvm/utils/TableGen/Record.h @@ -834,6 +834,12 @@ 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; }; |