diff options
author | Javed Absar <javed.absar@arm.com> | 2019-01-25 10:25:25 +0000 |
---|---|---|
committer | Javed Absar <javed.absar@arm.com> | 2019-01-25 10:25:25 +0000 |
commit | a3e3d8528644b3e432538853804553c62fea7722 (patch) | |
tree | 797687c37a0bb0af848b5346f88d14cce00164c9 /llvm/lib/TableGen/TGParser.cpp | |
parent | 7a35bdb7ec6958429bebd42f3ce40f19cdc9fbd8 (diff) | |
download | llvm-a3e3d8528644b3e432538853804553c62fea7722.zip llvm-a3e3d8528644b3e432538853804553c62fea7722.tar.gz llvm-a3e3d8528644b3e432538853804553c62fea7722.tar.bz2 |
[TblGen] Extend !if semantics through new feature !cond
This patch extends TableGen language with !cond operator.
Instead of embedding !if inside !if which can get cumbersome,
one can now use !cond.
Below is an example to convert an integer 'x' into a string:
!cond(!lt(x,0) : "Negative",
!eq(x,0) : "Zero",
!eq(x,1) : "One,
1 : "MoreThanOne")
Reviewed By: hfinkel, simon_tatham, greened
Differential Revision: https://reviews.llvm.org/D55758
llvm-svn: 352185
Diffstat (limited to 'llvm/lib/TableGen/TGParser.cpp')
-rw-r--r-- | llvm/lib/TableGen/TGParser.cpp | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp index cfbab2c..22b4b16b 100644 --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -1444,6 +1444,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec); } + case tgtok::XCond: + return ParseOperationCond(CurRec, ItemType); + case tgtok::XFoldl: { // Value ::= !foldl '(' Id ',' Id ',' Value ',' Value ',' Value ')' Lex.Lex(); // eat the operation @@ -1602,6 +1605,91 @@ RecTy *TGParser::ParseOperatorType() { return Type; } +Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) { + Lex.Lex(); // eat the operation 'cond' + + if (Lex.getCode() != tgtok::l_paren) { + TokError("expected '(' after !cond operator"); + return nullptr; + } + Lex.Lex(); // eat the '(' + + // Parse through '[Case: Val,]+' + SmallVector<Init *, 4> Case; + SmallVector<Init *, 4> Val; + while (true) { + if (Lex.getCode() == tgtok::r_paren) { + Lex.Lex(); // eat the ')' + break; + } + + Init *V = ParseValue(CurRec); + if (!V) + return nullptr; + Case.push_back(V); + + if (Lex.getCode() != tgtok::colon) { + TokError("expected ':' following a condition in !cond operator"); + return nullptr; + } + Lex.Lex(); // eat the ':' + + V = ParseValue(CurRec, ItemType); + if (!V) + return nullptr; + Val.push_back(V); + + if (Lex.getCode() == tgtok::r_paren) { + Lex.Lex(); // eat the ')' + break; + } + + if (Lex.getCode() != tgtok::comma) { + TokError("expected ',' or ')' following a value in !cond operator"); + return nullptr; + } + Lex.Lex(); // eat the ',' + } + + if (Case.size() < 1) { + TokError("there should be at least 1 'condition : value' in the !cond operator"); + return nullptr; + } + + // resolve type + RecTy *Type = nullptr; + for (Init *V : Val) { + RecTy *VTy = nullptr; + if (TypedInit *Vt = dyn_cast<TypedInit>(V)) + VTy = Vt->getType(); + if (BitsInit *Vbits = dyn_cast<BitsInit>(V)) + VTy = BitsRecTy::get(Vbits->getNumBits()); + if (isa<BitInit>(V)) + VTy = BitRecTy::get(); + + if (Type == nullptr) { + if (!isa<UnsetInit>(V)) + Type = VTy; + } else { + if (!isa<UnsetInit>(V)) { + RecTy *RType = resolveTypes(Type, VTy); + if (!RType) { + TokError(Twine("inconsistent types '") + Type->getAsString() + + "' and '" + VTy->getAsString() + "' for !cond"); + return nullptr; + } + Type = RType; + } + } + } + + if (!Type) { + TokError("could not determine type for !cond from its arguments"); + return nullptr; + } + return CondOpInit::get(Case, Val, Type)->Fold(CurRec); +} + /// ParseSimpleValue - Parse a tblgen value. This returns null on error. /// /// SimpleValue ::= IDValue @@ -1620,6 +1708,7 @@ RecTy *TGParser::ParseOperatorType() { /// SimpleValue ::= SRLTOK '(' Value ',' Value ')' /// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')' /// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')' +/// SimpleValue ::= COND '(' [Value ':' Value,]+ ')' /// Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { @@ -1932,6 +2021,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, case tgtok::XListConcat: case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')' case tgtok::XIf: + case tgtok::XCond: case tgtok::XFoldl: case tgtok::XForEach: case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' |