diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/TableGen/Record.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/TableGen/TGLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/TableGen/TGLexer.h | 2 | ||||
-rw-r--r-- | llvm/lib/TableGen/TGParser.cpp | 39 |
4 files changed, 66 insertions, 1 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 2fbe4cc493f..48197f04d11 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -1114,6 +1114,30 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { } break; } + + case DAG: { + ListInit *MHSl = dyn_cast<ListInit>(MHS); + ListInit *RHSl = dyn_cast<ListInit>(RHS); + bool MHSok = MHSl || isa<UnsetInit>(MHS); + bool RHSok = RHSl || isa<UnsetInit>(RHS); + + if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS)) + break; // Typically prevented by the parser, but might happen with template args + + if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) { + SmallVector<std::pair<Init *, StringInit *>, 8> Children; + unsigned Size = MHSl ? MHSl->size() : RHSl->size(); + for (unsigned i = 0; i != Size; ++i) { + Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(); + Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(); + if (!isa<StringInit>(Name) && !isa<UnsetInit>(Name)) + return const_cast<TernOpInit *>(this); + Children.emplace_back(Node, dyn_cast<StringInit>(Name)); + } + return DagInit::get(LHS, nullptr, Children); + } + break; + } } return const_cast<TernOpInit *>(this); @@ -1155,6 +1179,7 @@ std::string TernOpInit::getAsString() const { case SUBST: Result = "!subst"; break; case FOREACH: Result = "!foreach"; break; case IF: Result = "!if"; break; + case DAG: Result = "!dag"; break; } return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", " + RHS->getAsString() + ")"; diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp index f833782e203..d4762a42191 100644 --- a/llvm/lib/TableGen/TGLexer.cpp +++ b/llvm/lib/TableGen/TGLexer.cpp @@ -473,6 +473,7 @@ tgtok::TokKind TGLexer::LexExclaim() { .Case("tail", tgtok::XTail) .Case("size", tgtok::XSize) .Case("con", tgtok::XConcat) + .Case("dag", tgtok::XDag) .Case("add", tgtok::XADD) .Case("and", tgtok::XAND) .Case("or", tgtok::XOR) diff --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h index 2ffc2efdc30..18559773d74 100644 --- a/llvm/lib/TableGen/TGLexer.h +++ b/llvm/lib/TableGen/TGLexer.h @@ -48,7 +48,7 @@ namespace tgtok { // !keywords. XConcat, XADD, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast, - XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty, XIf, XEq, XIsA, + XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty, XIf, XEq, XIsA, XDag, // Integer value. IntVal, diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp index 5d87bfdf19d..629320975a6 100644 --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -1159,6 +1159,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { ->Fold(CurRec, CurMultiClass); } + case tgtok::XDag: case tgtok::XIf: case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' TernOpInit::TernaryOp Code; @@ -1168,6 +1169,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { Lex.Lex(); // eat the operation switch (LexCode) { default: llvm_unreachable("Unhandled code!"); + case tgtok::XDag: + Code = TernOpInit::DAG; + Type = DagRecTy::get(); + ItemType = nullptr; + break; case tgtok::XIf: Code = TernOpInit::IF; break; @@ -1190,6 +1196,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { } Lex.Lex(); // eat the ',' + SMLoc MHSLoc = Lex.getLoc(); Init *MHS = ParseValue(CurRec, ItemType); if (!MHS) return nullptr; @@ -1200,6 +1207,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { } Lex.Lex(); // eat the ',' + SMLoc RHSLoc = Lex.getLoc(); Init *RHS = ParseValue(CurRec, ItemType); if (!RHS) return nullptr; @@ -1212,6 +1220,36 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { switch (LexCode) { default: llvm_unreachable("Unhandled code!"); + case tgtok::XDag: { + TypedInit *MHSt = dyn_cast<TypedInit>(MHS); + if (!MHSt && !isa<UnsetInit>(MHS)) { + Error(MHSLoc, "could not determine type of the child list in !dag"); + return nullptr; + } + if (MHSt && !isa<ListRecTy>(MHSt->getType())) { + Error(MHSLoc, Twine("expected list of children, got type '") + + MHSt->getType()->getAsString() + "'"); + return nullptr; + } + + TypedInit *RHSt = dyn_cast<TypedInit>(RHS); + if (!RHSt && !isa<UnsetInit>(RHS)) { + Error(RHSLoc, "could not determine type of the name list in !dag"); + return nullptr; + } + if (RHSt && StringRecTy::get()->getListTy() != RHSt->getType()) { + Error(RHSLoc, Twine("expected list<string>, got type '") + + RHSt->getType()->getAsString() + "'"); + return nullptr; + } + + if (!MHSt && !RHSt) { + Error(MHSLoc, + "cannot have both unset children and unset names in !dag"); + return nullptr; + } + break; + } case tgtok::XIf: { RecTy *MHSTy = nullptr; RecTy *RHSTy = nullptr; @@ -1728,6 +1766,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, case tgtok::XCast: // Value ::= !unop '(' Value ')' case tgtok::XIsA: case tgtok::XConcat: + case tgtok::XDag: case tgtok::XADD: case tgtok::XAND: case tgtok::XOR: |