diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -887,13 +887,18 @@ if (LHSs && RHSs) { DefInit *LOp = dyn_cast(LHSs->getOperator()); DefInit *ROp = dyn_cast(RHSs->getOperator()); - if (!LOp || !ROp) + if ((!LOp && !isa(LHSs->getOperator())) || + (!ROp && !isa(RHSs->getOperator()))) break; - if (LOp->getDef() != ROp->getDef()) { + if (LOp && ROp && LOp->getDef() != ROp->getDef()) { PrintFatalError(Twine("Concatenated Dag operators do not match: '") + LHSs->getAsString() + "' vs. '" + RHSs->getAsString() + "'"); } + Init *Op = LOp ? LOp : ROp; + if (!Op) + Op = UnsetInit::get(); + SmallVector Args; SmallVector ArgNames; for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) { @@ -904,7 +909,7 @@ Args.push_back(RHSs->getArg(i)); ArgNames.push_back(RHSs->getArgName(i)); } - return DagInit::get(LHSs->getOperator(), nullptr, Args, ArgNames); + return DagInit::get(Op, nullptr, Args, ArgNames); } break; } diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -2024,7 +2024,8 @@ } case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' Lex.Lex(); // eat the '(' - if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast) { + if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast && + Lex.getCode() != tgtok::question) { TokError("expected identifier in dag init"); return nullptr; } diff --git a/llvm/test/TableGen/unsetop.td b/llvm/test/TableGen/unsetop.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/unsetop.td @@ -0,0 +1,24 @@ +// RUN: llvm-tblgen %s | FileCheck %s +// RUN: not llvm-tblgen -DERROR %s 2>&1 | FileCheck --check-prefix=ERROR %s + +def op; +def otherop; + +def test { + // CHECK: dag d = (? "hello":$world); + dag d = (? "hello":$world); + + // CHECK: dag undefNeither = (op 1, 2); + dag undefNeither = !con((op 1), (op 2)); + // CHECK: dag undefFirst = (op 1, 2); + dag undefFirst = !con((? 1), (op 2)); + // CHECK: dag undefSecond = (op 1, 2); + dag undefSecond = !con((op 1), (? 2)); + // CHECK: dag undefBoth = (? 1, 2); + dag undefBoth = !con((? 1), (? 2)); + +#ifdef ERROR + // ERROR: Concatenated Dag operators do not match: '(op 1)' vs. '(otherop 2)' + dag mismatch = !con((op 1), (otherop 2)); +#endif +}