diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/TableGen/TGParser.cpp | 46 | ||||
| -rw-r--r-- | llvm/lib/TableGen/TGParser.h | 4 |
2 files changed, 44 insertions, 6 deletions
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp index 23ef5354fca..0e654f98241 100644 --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -2322,7 +2322,9 @@ Record *TGParser:: InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, Init *&DefmPrefix, - SMRange DefmPrefixRange) { + SMRange DefmPrefixRange, + const std::vector<Init *> &TArgs, + std::vector<Init *> &TemplateVals) { // We need to preserve DefProto so it can be reused for later // instantiations, so create a new Record to inherit from it. @@ -2338,7 +2340,6 @@ InstantiateMulticlassDef(MultiClass &MC, } Init *DefName = DefProto->getNameInit(); - StringInit *DefNameString = dyn_cast<StringInit>(DefName); if (DefNameString) { @@ -2386,12 +2387,40 @@ InstantiateMulticlassDef(MultiClass &MC, RecordVal *DefNameRV = CurRec->getValue("NAME"); CurRec->resolveReferencesTo(DefNameRV); + // Check if the name is a complex pattern. + // If so, resolve it. + DefName = CurRec->getNameInit(); + DefNameString = dyn_cast<StringInit>(DefName); + + // OK the pattern is more complex than simply using NAME. + // Let's use the heavy weaponery. + if (!DefNameString) { + ResolveMulticlassDefArgs(MC, CurRec.get(), DefmPrefixRange.Start, + Lex.getLoc(), TArgs, TemplateVals, + false/*Delete args*/); + DefName = CurRec->getNameInit(); + DefNameString = dyn_cast<StringInit>(DefName); + + if (!DefNameString) + DefName = DefName->convertInitializerTo(StringRecTy::get()); + + // We ran out of options here... + DefNameString = dyn_cast<StringInit>(DefName); + if (!DefNameString) { + PrintFatalError(CurRec->getLoc()[CurRec->getLoc().size() - 1], + DefName->getAsUnquotedString() + " is not a string."); + return nullptr; + } + + CurRec->setName(DefName); + } + // Now that NAME references are resolved and we're at the top level of // any multiclass expansions, add the record to the RecordKeeper. If we are // currently in a multiclass, it means this defm appears inside a // multiclass and its name won't be fully resolvable until we see - // the top-level defm. Therefore, we don't add this to the - // RecordKeeper at this point. If we did we could get duplicate + // the top-level defm. Therefore, we don't add this to the + // RecordKeeper at this point. If we did we could get duplicate // defs as more than one probably refers to NAME or some other // common internal placeholder. @@ -2523,12 +2552,19 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { // Loop over all the def's in the multiclass, instantiating each one. for (const std::unique_ptr<Record> &DefProto : MC->DefPrototypes) { + // The record name construction goes as follow: + // - If the def name is a string, prepend the prefix. + // - If the def name is a more complex pattern, use that pattern. + // As a result, the record is instanciated before resolving + // arguments, as it would make its name a string. Record *CurRec = InstantiateMulticlassDef(*MC, DefProto.get(), DefmPrefix, SMRange(DefmLoc, - DefmPrefixEndLoc)); + DefmPrefixEndLoc), + TArgs, TemplateVals); if (!CurRec) return true; + // Now that the record is instanciated, we can resolve arguments. if (ResolveMulticlassDefArgs(*MC, CurRec, DefmLoc, SubClassLoc, TArgs, TemplateVals, true/*Delete args*/)) return Error(SubClassLoc, "could not instantiate def"); diff --git a/llvm/lib/TableGen/TGParser.h b/llvm/lib/TableGen/TGParser.h index 22a00e59195..d69d1f4572f 100644 --- a/llvm/lib/TableGen/TGParser.h +++ b/llvm/lib/TableGen/TGParser.h @@ -138,7 +138,9 @@ private: // Parser methods. Record *InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, Init *&DefmPrefix, - SMRange DefmPrefixRange); + SMRange DefmPrefixRange, + const std::vector<Init *> &TArgs, + std::vector<Init *> &TemplateVals); bool ResolveMulticlassDefArgs(MultiClass &MC, Record *DefProto, SMLoc DefmPrefixLoc, |

