Implement !cast<string>.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74444 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Greene 2009-06-29 20:05:29 +00:00
parent 67acdf2977
commit 2c0266202d
3 changed files with 93 additions and 41 deletions

View File

@ -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&lt;type&gt;(a, b)</tt></dt>
<dd>Shorthand for !cast<type>(!strconcat(a, b))</dd>
<dt><tt>!subst(a, b, c)</tt></dt>

View File

@ -537,6 +537,33 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
switch (getOpcode()) {
default: assert(0 && "Unknown unop");
case CAST: {
if (getType()->getAsString() == "string") {
StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
if (LHSs) {
return LHSs;
}
DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
if (LHSd) {
return new StringInit(LHSd->getDef()->getName());
}
// 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();
@ -584,6 +611,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
assert(0 && "Variable not found");
return 0;
}
}
break;
}
case CAR: {
@ -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");

View File

@ -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;
};