summaryrefslogtreecommitdiff
path: root/llvm/lib/TableGen
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2018-03-05 15:21:11 +0000
committerNicolai Haehnle <nhaehnle@gmail.com>2018-03-05 15:21:11 +0000
commitc95ddc5d70f1c1315f2a565ddbcaec339aa5bfc4 (patch)
tree3f6a3fd0371a7c9b2695003deb30b254393f7e0c /llvm/lib/TableGen
parent56c74ecffee23c4827842b8ed193b37863d30555 (diff)
TableGen: Resolve all template args simultaneously in AddSubClass
Summary: Use the new resolver interface more explicitly, and avoid traversing all the initializers multiple times. Add a test case for a pattern that was broken by an earlier version of this change. An additional change is that we now remove *all* template arguments after resolving them. Change-Id: I86c828c8cc84c18b052dfe0f64c0d5cbf3c4e13c Reviewers: arsenm, craig.topper, tra, MartinO Subscribers: wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D43652
Diffstat (limited to 'llvm/lib/TableGen')
-rw-r--r--llvm/lib/TableGen/Record.cpp39
-rw-r--r--llvm/lib/TableGen/TGParser.cpp15
2 files changed, 28 insertions, 26 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 990ef928f66..8b3ecebcf07 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1517,36 +1517,37 @@ void Record::setName(Init *NewName) {
// this. See TGParser::ParseDef and TGParser::ParseDefm.
}
-void Record::resolveReferencesTo(const RecordVal *RV) {
- RecordResolver RecResolver(*this);
- RecordValResolver RecValResolver(*this, RV);
- Resolver *R;
- if (RV)
- R = &RecValResolver;
- else
- R = &RecResolver;
-
+void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
for (RecordVal &Value : Values) {
- if (RV == &Value) // Skip resolve the same field as the given one
+ if (SkipVal == &Value) // Skip resolve the same field as the given one
continue;
- if (Init *V = Value.getValue())
- if (Value.setValue(V->resolveReferences(*R)))
+ if (Init *V = Value.getValue()) {
+ Init *VR = V->resolveReferences(R);
+ if (Value.setValue(VR))
PrintFatalError(getLoc(), "Invalid value is found when setting '" +
- Value.getNameInitAsString() +
- "' after resolving references" +
- (RV ? " against '" + RV->getNameInitAsString() +
- "' of (" + RV->getValue()->getAsUnquotedString() +
- ")"
- : "") + "\n");
+ Value.getNameInitAsString() +
+ "' after resolving references: " +
+ VR->getAsUnquotedString() + "\n");
+ }
}
Init *OldName = getNameInit();
- Init *NewName = Name->resolveReferences(*R);
+ Init *NewName = Name->resolveReferences(R);
if (NewName != OldName) {
// Re-register with RecordKeeper.
setName(NewName);
}
}
+void Record::resolveReferences() {
+ RecordResolver R(*this);
+ resolveReferences(R);
+}
+
+void Record::resolveReferencesTo(const RecordVal *RV) {
+ RecordValResolver R(*this, RV);
+ resolveReferences(R, RV);
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void Record::dump() const { errs() << *this; }
#endif
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index b42580c9cda..3c1f4f3ab6f 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -175,27 +175,28 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
// Loop over all of the template arguments, setting them to the specified
// value or leaving them as the default if necessary.
+ MapResolver R(CurRec);
+
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
if (i < SubClass.TemplateArgs.size()) {
// If a value is specified for this template arg, set it now.
if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i],
None, SubClass.TemplateArgs[i]))
return true;
-
- // Resolve it next.
- CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
-
- // Now remove it.
- CurRec->removeValue(TArgs[i]);
-
} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
return Error(SubClass.RefRange.Start,
"Value not specified for template argument #" +
Twine(i) + " (" + TArgs[i]->getAsUnquotedString() +
") of subclass '" + SC->getNameInitAsString() + "'!");
}
+
+ R.set(TArgs[i], CurRec->getValue(TArgs[i])->getValue());
+
+ CurRec->removeValue(TArgs[i]);
}
+ CurRec->resolveReferences(R);
+
// Since everything went well, we can now set the "superclass" list for the
// current record.
ArrayRef<std::pair<Record *, SMRange>> SCs = SC->getSuperClasses();