From 2c0266202dc10a1ff887a8829950b6548d7feee3 Mon Sep 17 00:00:00 2001 From: David Greene Date: Mon, 29 Jun 2009 20:05:29 +0000 Subject: [PATCH] Implement !cast. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74444 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/TableGenFundamentals.html | 3 +- utils/TableGen/Record.cpp | 125 ++++++++++++++++++++++----------- utils/TableGen/Record.h | 6 ++ 3 files changed, 93 insertions(+), 41 deletions(-) diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html index 05b2b233e6a..ec87f2967cb 100644 --- a/docs/TableGenFundamentals.html +++ b/docs/TableGenFundamentals.html @@ -411,7 +411,8 @@ which case the user must specify it explicitly.
!cast(a)
A symbol of type type obtained by looking up the string 'a' in the symbol table. If the type of 'a' does not match type, TableGen -aborts with an error.
+aborts with an error. !cast is a special case in that the argument must +be an object defined by a 'def' construct.
!nameconcat<type>(a, b)
Shorthand for !cast(!strconcat(a, b))
!subst(a, b, c)
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index c62e21b3aa1..92ba62879ee 100644 --- a/utils/TableGen/Record.cpp +++ b/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(LHS); - if (LHSs) { - std::string Name = LHSs->getValue(); + if (getType()->getAsString() == "string") { + StringInit *LHSs = dynamic_cast(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"; + DefInit *LHSd = dynamic_cast(LHS); + if (LHSd) { + return new StringInit(LHSd->getDef()->getName()); + } + +// VarInit *LHSv = dynamic_cast(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(LHS); +// if (!LHSo) { +// return new StringInit(LHS->getAsString()); +// } + } + else { + StringInit *LHSs = dynamic_cast(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()); + } + + std::string TemplateArgName = CurRec->getName()+":"+Name; + if (CurRec->isTemplateArg(TemplateArgName)) { + const RecordVal *RV = CurRec->getValue(TemplateArgName); + assert(RV && "Template arg doesn't exist??"); + + if (RV->getType() != getType()) { + throw "type mismatch in nameconcat"; + } + + return new VarInit(TemplateArgName, RV->getType()); + } + } + + 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()); } - 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??"); + if (Record *D = Records.getDef(Name)) + return new DefInit(D); - if (RV->getType() != getType()) { - throw "type mismatch in nameconcat"; - } - - return new VarInit(TemplateArgName, RV->getType()); - } + cerr << "Variable not defined: '" + Name + "'\n"; + assert(0 && "Variable not found"); + return 0; } - - 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; } 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(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/utils/TableGen/Record.h b/utils/TableGen/Record.h index 5f45ea09caf..2254dd84e08 100644 --- a/utils/TableGen/Record.h +++ b/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; };