Index: llvm/trunk/include/llvm/TableGen/Record.h =================================================================== --- llvm/trunk/include/llvm/TableGen/Record.h +++ llvm/trunk/include/llvm/TableGen/Record.h @@ -1349,7 +1349,14 @@ /// If there are any field references that refer to fields /// that have been filled in, we can propagate the values now. - void resolveReferences() { resolveReferencesTo(nullptr); } + void resolveReferences(); + + /// Apply the resolver to the name of the record as well as to the + /// initializers of all fields of the record except SkipVal. + /// + /// The resolver should not resolve any of the fields itself, to avoid + /// recursion / infinite loops. + void resolveReferences(Resolver &R, const RecordVal *SkipVal = nullptr); /// If anything in this record refers to RV, replace the /// reference to RV with the RHS of RV. If RV is null, we resolve all Index: llvm/trunk/lib/TableGen/Record.cpp =================================================================== --- llvm/trunk/lib/TableGen/Record.cpp +++ llvm/trunk/lib/TableGen/Record.cpp @@ -1517,36 +1517,37 @@ // 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 Index: llvm/trunk/lib/TableGen/TGParser.cpp =================================================================== --- llvm/trunk/lib/TableGen/TGParser.cpp +++ llvm/trunk/lib/TableGen/TGParser.cpp @@ -175,27 +175,28 @@ // 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> SCs = SC->getSuperClasses(); Index: llvm/trunk/test/TableGen/template-arg-dependency.td =================================================================== --- llvm/trunk/test/TableGen/template-arg-dependency.td +++ llvm/trunk/test/TableGen/template-arg-dependency.td @@ -0,0 +1,16 @@ +// RUN: llvm-tblgen %s | FileCheck %s +// XFAIL: vg_leak + +// CHECK: --- Defs --- + +// CHECK: def A0 { +// CHECK: int ret = 3; +// CHECK: } + +class A { + int ret = sum; +} + +def A0 : A<1>;