From 7be867e48300861b7b1bf614eb204463533d6724 Mon Sep 17 00:00:00 2001 From: David Greene Date: Wed, 19 Oct 2011 13:04:31 +0000 Subject: [PATCH] Process Defm Prefix as Init Parse and process a defm prefix as an Init expression. This allows paste operations to create defm prefixes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142523 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/TableGen/TGParser.cpp | 58 ++++++++++++++++++++++++++------------- lib/TableGen/TGParser.h | 2 +- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp index 35a0adf58d6..e88a23256ce 100644 --- a/lib/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -1970,25 +1970,51 @@ bool TGParser::ParseMultiClass() { Record *TGParser:: InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, - const std::string &DefmPrefix, + Init *DefmPrefix, SMLoc DefmPrefixLoc) { + // We need to preserve DefProto so it can be reused for later + // instantiations, so create a new Record to inherit from it. + // Add in the defm name. If the defm prefix is empty, give each // instantiated def a unique name. Otherwise, if "#NAME#" exists in the // name, substitute the prefix for #NAME#. Otherwise, use the defm name // as a prefix. - std::string DefName = DefProto->getName(); - if (DefmPrefix.empty()) { - DefName = GetNewAnonymousName(); - } else { - std::string::size_type idx = DefName.find("#NAME#"); - if (idx != std::string::npos) { - DefName.replace(idx, 6, DefmPrefix); - } else { - // Add the suffix to the defm name to get the new name. - DefName = DefmPrefix + DefName; - } + StringInit *DefNameString = + dynamic_cast(DefProto->getNameInit()); + + if (DefNameString == 0) { + Error(DefmPrefixLoc, "Def name is not a string"); + return 0; } + if (DefmPrefix == 0) + DefmPrefix = StringInit::get(GetNewAnonymousName()); + + Init *DefName = DefProto->getNameInit(); + + // See if we can substitute #NAME#. + Init *NewDefName = + TernOpInit::get(TernOpInit::SUBST, + StringInit::get("#NAME#"), + DefmPrefix, + DefName, + StringRecTy::get())->Fold(DefProto, &MC); + + if (NewDefName == DefName) { + // We did't do any substitution. We should concatenate the given + // prefix and name. + if (DefmPrefix == 0) + DefmPrefix = StringInit::get(GetNewAnonymousName()); + + DefName = + BinOpInit::get(BinOpInit::STRCONCAT, + UnOpInit::get(UnOpInit::CAST, DefmPrefix, + StringRecTy::get())->Fold(DefProto, &MC), + DefName, StringRecTy::get())->Fold(DefProto, &MC); + } + else + DefName = NewDefName; + Record *CurRec = new Record(DefName, DefmPrefixLoc, Records); SubClassReference Ref; @@ -2086,14 +2112,9 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { assert(Lex.getCode() == tgtok::Defm && "Unexpected token!"); Init *DefmPrefix = 0; - std::string DefmPrefixString; if (Lex.Lex() == tgtok::Id) { // eat the defm. DefmPrefix = ParseObjectName(CurMultiClass); - StringInit *DefmPrefixStringInit = dynamic_cast(DefmPrefix); - if (DefmPrefixStringInit == 0) - return TokError("defm prefix is not a string"); - DefmPrefixString = DefmPrefixStringInit->getValue(); } SMLoc DefmPrefixLoc = Lex.getLoc(); @@ -2132,8 +2153,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) { Record *DefProto = MC->DefPrototypes[i]; - Record *CurRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefixString, - DefmPrefixLoc); + Record *CurRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix, DefmPrefixLoc); if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc, SubClassLoc, TArgs, TemplateVals, true/*Delete args*/)) diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h index 7295febb9fd..54cd99a8a4a 100644 --- a/lib/TableGen/TGParser.h +++ b/lib/TableGen/TGParser.h @@ -101,7 +101,7 @@ private: // Parser methods. bool ParseMultiClass(); Record *InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, - const std::string &DefmPrefix, + Init *DefmPrefix, SMLoc DefmPrefixLoc); bool ResolveMulticlassDefArgs(MultiClass &MC, Record *DefProto,