Index: include/llvm/TableGen/Record.h =================================================================== --- include/llvm/TableGen/Record.h +++ include/llvm/TableGen/Record.h @@ -802,7 +802,7 @@ class BinOpInit : public OpInit, public FoldingSetNode { public: enum BinaryOp : uint8_t { ADD, AND, OR, SHL, SRA, SRL, LISTCONCAT, - STRCONCAT, CONCAT, EQ }; + STRCONCAT, CODECONCAT, CONCAT, EQ }; private: Init *LHS, *RHS; Index: lib/TableGen/Record.cpp =================================================================== --- lib/TableGen/Record.cpp +++ lib/TableGen/Record.cpp @@ -763,11 +763,10 @@ ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType()); } -static StringInit *ConcatStringInits(const StringInit *I0, - const StringInit *I1) { +template static T *ConcatStringInits(const T *I0, const T *I1) { SmallString<80> Concat(I0->getValue()); Concat.append(I1->getValue()); - return StringInit::get(Concat); + return T::get(Concat); } Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { @@ -813,6 +812,13 @@ return ConcatStringInits(LHSs, RHSs); break; } + case CODECONCAT: { + CodeInit *LHSs = dyn_cast(LHS); + CodeInit *RHSs = dyn_cast(RHS); + if (LHSs && RHSs) + return ConcatStringInits(LHSs, RHSs); + break; + } case EQ: { // try to fold eq comparison for 'bit' and 'int', otherwise fallback // to string objects. @@ -885,6 +891,7 @@ case EQ: Result = "!eq"; break; case LISTCONCAT: Result = "!listconcat"; break; case STRCONCAT: Result = "!strconcat"; break; + case CODECONCAT: Result = "!codeconcat"; break; } return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; } Index: lib/TableGen/TGLexer.h =================================================================== --- lib/TableGen/TGLexer.h +++ lib/TableGen/TGLexer.h @@ -47,8 +47,8 @@ MultiClass, String, // !keywords. - XConcat, XADD, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast, - XSubst, XForEach, XHead, XTail, XEmpty, XIf, XEq, + XConcat, XADD, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat, + XCodeConcat, XCast, XSubst, XForEach, XHead, XTail, XEmpty, XIf, XEq, // Integer value. IntVal, Index: lib/TableGen/TGLexer.cpp =================================================================== --- lib/TableGen/TGLexer.cpp +++ lib/TableGen/TGLexer.cpp @@ -482,6 +482,7 @@ .Case("foreach", tgtok::XForEach) .Case("listconcat", tgtok::XListConcat) .Case("strconcat", tgtok::XStrConcat) + .Case("codeconcat", tgtok::XCodeConcat) .Default(tgtok::Error); return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator"); Index: lib/TableGen/TGParser.cpp =================================================================== --- lib/TableGen/TGParser.cpp +++ lib/TableGen/TGParser.cpp @@ -888,7 +888,8 @@ case tgtok::XSHL: case tgtok::XEq: case tgtok::XListConcat: - case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')' + case tgtok::XStrConcat: + case tgtok::XCodeConcat: { // Value ::= !binop '(' Value ',' Value ')' tgtok::TokKind OpTok = Lex.getCode(); SMLoc OpLoc = Lex.getLoc(); Lex.Lex(); // eat the operation @@ -914,6 +915,10 @@ Code = BinOpInit::STRCONCAT; Type = StringRecTy::get(); break; + case tgtok::XCodeConcat: + Code = BinOpInit::CODECONCAT; + Type = CodeRecTy::get(); + break; } if (Lex.getCode() != tgtok::l_paren) { @@ -955,7 +960,8 @@ // We allow multiple operands to associative operators like !strconcat as // shorthand for nesting them. - if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT) { + if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::CODECONCAT || + Code == BinOpInit::LISTCONCAT) { while (InitList.size() > 2) { Init *RHS = InitList.pop_back_val(); RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type)) @@ -1455,6 +1461,7 @@ case tgtok::XEq: case tgtok::XListConcat: case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')' + case tgtok::XCodeConcat: case tgtok::XIf: case tgtok::XForEach: case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'