diff options
Diffstat (limited to 'llvm/lib/TableGen')
-rw-r--r-- | llvm/lib/TableGen/Record.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/TableGen/TGParser.cpp | 23 |
2 files changed, 37 insertions, 4 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 480a002b64a..4222a0b57fb 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -856,6 +856,24 @@ Init *BinOpInit::getStrConcat(Init *I0, Init *I1) { return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get()); } +static ListInit *ConcatListInits(const ListInit *LHS, + const ListInit *RHS) { + SmallVector<Init *, 8> Args; + Args.insert(Args.end(), LHS->begin(), LHS->end()); + Args.insert(Args.end(), RHS->begin(), RHS->end()); + return ListInit::get(Args, LHS->getElementType()); +} + +Init *BinOpInit::getListConcat(TypedInit *LHS, Init *RHS) { + assert(isa<ListRecTy>(LHS->getType()) && "First arg must be a list"); + + // Shortcut for the common case of concatenating two lists. + if (const ListInit *LHSList = dyn_cast<ListInit>(LHS)) + if (const ListInit *RHSList = dyn_cast<ListInit>(RHS)) + return ConcatListInits(LHSList, RHSList); + return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType()); +} + Init *BinOpInit::Fold(Record *CurRec) const { switch (getOpcode()) { case CONCAT: { diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp index 58343bda275..90c9b390e10 100644 --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -2119,16 +2119,31 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { case tgtok::paste: SMLoc PasteLoc = Lex.getLoc(); - - // Create a !strconcat() operation, first casting each operand to - // a string if necessary. - TypedInit *LHS = dyn_cast<TypedInit>(Result); if (!LHS) { Error(PasteLoc, "LHS of paste is not typed!"); return nullptr; } + // Check if it's a 'listA # listB' + if (isa<ListRecTy>(LHS->getType())) { + Lex.Lex(); // Eat the '#'. + + switch (Lex.getCode()) { + case tgtok::colon: + case tgtok::semi: + case tgtok::l_brace: + Result = LHS; // trailing paste, ignore. + break; + default: + Init *RHSResult = ParseValue(CurRec, ItemType, ParseNameMode); + Result = BinOpInit::getListConcat(LHS, RHSResult); + } + break; + } + + // Create a !strconcat() operation, first casting each operand to + // a string if necessary. if (LHS->getType() != StringRecTy::get()) { LHS = dyn_cast<TypedInit>( UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get()) |