mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
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:
parent
67acdf2977
commit
2c0266202d
@ -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>
|
||||
|
@ -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";
|
||||
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();
|
||||
|
||||
// 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<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");
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user