diff --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst --- a/llvm/docs/TableGen/ProgRef.rst +++ b/llvm/docs/TableGen/ProgRef.rst @@ -1630,6 +1630,12 @@ This operator produces 1 if the string, list, or DAG *a* is empty; 0 otherwise. A dag is empty if it has no arguments; the operator does not count. +``!lower(``\ *a*\ ``)`` + This operator converts a to lower case. + +``!upper(``\ *a*\ ``)`` + This operator converts a to upper case. + ``!eq(`` *a*\ `,` *b*\ ``)`` This operator produces 1 if *a* is equal to *b*; 0 otherwise. The arguments must be ``bit``, ``bits``, ``int``, ``string``, or diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -785,7 +785,18 @@ /// class UnOpInit : public OpInit, public FoldingSetNode { public: - enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETDAGOP, LOG2 }; + enum UnaryOp : uint8_t { + LOWER, + UPPER, + CAST, + NOT, + HEAD, + TAIL, + SIZE, + EMPTY, + GETDAGOP, + LOG2 + }; private: Init *LHS; 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 @@ -778,6 +778,14 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const { RecordKeeper &RK = getRecordKeeper(); switch (getOpcode()) { + case LOWER: + if (StringInit *LHSs = dyn_cast(LHS)) + return StringInit::get(RK, LHSs->getValue().lower()); + break; + case UPPER: + if (StringInit *LHSs = dyn_cast(LHS)) + return StringInit::get(RK, LHSs->getValue().upper()); + break; case CAST: if (isa(getType())) { if (StringInit *LHSs = dyn_cast(LHS)) @@ -927,6 +935,12 @@ case EMPTY: Result = "!empty"; break; case GETDAGOP: Result = "!getdagop"; break; case LOG2 : Result = "!logtwo"; break; + case LOWER: + Result = "!lower"; + break; + case UPPER: + Result = "!upper"; + break; } return Result + "(" + LHS->getAsString() + ")"; } diff --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h --- a/llvm/lib/TableGen/TGLexer.h +++ b/llvm/lib/TableGen/TGLexer.h @@ -29,52 +29,129 @@ class Twine; namespace tgtok { - enum TokKind { - // Markers - Eof, Error, - - // Tokens with no info. - minus, plus, // - + - l_square, r_square, // [ ] - l_brace, r_brace, // { } - l_paren, r_paren, // ( ) - less, greater, // < > - colon, semi, // : ; - comma, dot, // , . - equal, question, // = ? - paste, // # - dotdotdot, // ... - - // Reserved keywords. ('ElseKW' is named to distinguish it from the - // existing 'Else' that means the preprocessor #else.) - Assert, Bit, Bits, Class, Code, Dag, Def, Defm, Defset, Defvar, ElseKW, - FalseKW, Field, Foreach, If, In, Include, Int, Let, List, MultiClass, - String, Then, TrueKW, - - // Bang operators. - XConcat, XADD, XSUB, XMUL, XDIV, XNOT, XLOG2, XAND, XOR, XXOR, XSRA, XSRL, - XSHL, XListConcat, XListSplat, XStrConcat, XInterleave, XSubstr, XFind, - XCast, XSubst, XForEach, XFilter, XFoldl, XHead, XTail, XSize, XEmpty, XIf, - XCond, XEq, XIsA, XDag, XNe, XLe, XLt, XGe, XGt, XSetDagOp, XGetDagOp, - XExists, XListRemove, - - // Boolean literals. - TrueVal, FalseVal, - - // Integer value. - IntVal, - - // Binary constant. Note that these are sized according to the number of - // bits given. - BinaryIntVal, - - // String valued tokens. - Id, StrVal, VarName, CodeFragment, - - // Preprocessing tokens for internal usage by the lexer. - // They are never returned as a result of Lex(). - Ifdef, Ifndef, Else, Endif, Define - }; +enum TokKind { + // Markers + Eof, + Error, + + // Tokens with no info. + minus, + plus, // - + + l_square, + r_square, // [ ] + l_brace, + r_brace, // { } + l_paren, + r_paren, // ( ) + less, + greater, // < > + colon, + semi, // : ; + comma, + dot, // , . + equal, + question, // = ? + paste, // # + dotdotdot, // ... + + // Reserved keywords. ('ElseKW' is named to distinguish it from the + // existing 'Else' that means the preprocessor #else.) + Assert, + Bit, + Bits, + Class, + Code, + Dag, + Def, + Defm, + Defset, + Defvar, + ElseKW, + FalseKW, + Field, + Foreach, + If, + In, + Include, + Int, + Let, + List, + MultiClass, + String, + Then, + TrueKW, + + // Bang operators. + XConcat, + XADD, + XSUB, + XMUL, + XDIV, + XNOT, + XLOG2, + XAND, + XOR, + XXOR, + XSRA, + XSRL, + XSHL, + XListConcat, + XListSplat, + XStrConcat, + XInterleave, + XSubstr, + XFind, + XCast, + XSubst, + XForEach, + XFilter, + XFoldl, + XHead, + XTail, + XSize, + XEmpty, + XIf, + XCond, + XEq, + XIsA, + XDag, + XNe, + XLe, + XLt, + XGe, + XGt, + XSetDagOp, + XGetDagOp, + XExists, + XListRemove, + XLower, + XUpper, + + // Boolean literals. + TrueVal, + FalseVal, + + // Integer value. + IntVal, + + // Binary constant. Note that these are sized according to the number of + // bits given. + BinaryIntVal, + + // String valued tokens. + Id, + StrVal, + VarName, + CodeFragment, + + // Preprocessing tokens for internal usage by the lexer. + // They are never returned as a result of Lex(). + Ifdef, + Ifndef, + Else, + Endif, + Define +}; } /// TGLexer - TableGen Lexer class. diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp --- a/llvm/lib/TableGen/TGLexer.cpp +++ b/llvm/lib/TableGen/TGLexer.cpp @@ -549,50 +549,52 @@ // Check to see which operator this is. tgtok::TokKind Kind = - StringSwitch(StringRef(Start, CurPtr - Start)) - .Case("eq", tgtok::XEq) - .Case("ne", tgtok::XNe) - .Case("le", tgtok::XLe) - .Case("lt", tgtok::XLt) - .Case("ge", tgtok::XGe) - .Case("gt", tgtok::XGt) - .Case("if", tgtok::XIf) - .Case("cond", tgtok::XCond) - .Case("isa", tgtok::XIsA) - .Case("head", tgtok::XHead) - .Case("tail", tgtok::XTail) - .Case("size", tgtok::XSize) - .Case("con", tgtok::XConcat) - .Case("dag", tgtok::XDag) - .Case("add", tgtok::XADD) - .Case("sub", tgtok::XSUB) - .Case("mul", tgtok::XMUL) - .Case("div", tgtok::XDIV) - .Case("not", tgtok::XNOT) - .Case("logtwo", tgtok::XLOG2) - .Case("and", tgtok::XAND) - .Case("or", tgtok::XOR) - .Case("xor", tgtok::XXOR) - .Case("shl", tgtok::XSHL) - .Case("sra", tgtok::XSRA) - .Case("srl", tgtok::XSRL) - .Case("cast", tgtok::XCast) - .Case("empty", tgtok::XEmpty) - .Case("subst", tgtok::XSubst) - .Case("foldl", tgtok::XFoldl) - .Case("foreach", tgtok::XForEach) - .Case("filter", tgtok::XFilter) - .Case("listconcat", tgtok::XListConcat) - .Case("listsplat", tgtok::XListSplat) - .Case("listremove", tgtok::XListRemove) - .Case("strconcat", tgtok::XStrConcat) - .Case("interleave", tgtok::XInterleave) - .Case("substr", tgtok::XSubstr) - .Case("find", tgtok::XFind) - .Cases("setdagop", "setop", tgtok::XSetDagOp) // !setop is deprecated. - .Cases("getdagop", "getop", tgtok::XGetDagOp) // !getop is deprecated. - .Case("exists", tgtok::XExists) - .Default(tgtok::Error); + StringSwitch(StringRef(Start, CurPtr - Start)) + .Case("eq", tgtok::XEq) + .Case("ne", tgtok::XNe) + .Case("le", tgtok::XLe) + .Case("lt", tgtok::XLt) + .Case("ge", tgtok::XGe) + .Case("gt", tgtok::XGt) + .Case("if", tgtok::XIf) + .Case("cond", tgtok::XCond) + .Case("isa", tgtok::XIsA) + .Case("head", tgtok::XHead) + .Case("tail", tgtok::XTail) + .Case("size", tgtok::XSize) + .Case("con", tgtok::XConcat) + .Case("dag", tgtok::XDag) + .Case("add", tgtok::XADD) + .Case("sub", tgtok::XSUB) + .Case("mul", tgtok::XMUL) + .Case("div", tgtok::XDIV) + .Case("not", tgtok::XNOT) + .Case("logtwo", tgtok::XLOG2) + .Case("and", tgtok::XAND) + .Case("or", tgtok::XOR) + .Case("xor", tgtok::XXOR) + .Case("shl", tgtok::XSHL) + .Case("sra", tgtok::XSRA) + .Case("srl", tgtok::XSRL) + .Case("cast", tgtok::XCast) + .Case("empty", tgtok::XEmpty) + .Case("subst", tgtok::XSubst) + .Case("foldl", tgtok::XFoldl) + .Case("foreach", tgtok::XForEach) + .Case("filter", tgtok::XFilter) + .Case("listconcat", tgtok::XListConcat) + .Case("listsplat", tgtok::XListSplat) + .Case("listremove", tgtok::XListRemove) + .Case("strconcat", tgtok::XStrConcat) + .Case("interleave", tgtok::XInterleave) + .Case("substr", tgtok::XSubstr) + .Case("find", tgtok::XFind) + .Cases("setdagop", "setop", tgtok::XSetDagOp) // !setop is deprecated. + .Cases("getdagop", "getop", tgtok::XGetDagOp) // !getop is deprecated. + .Case("exists", tgtok::XExists) + .Case("lower", tgtok::XLower) + .Case("upper", tgtok::XUpper) + .Default(tgtok::Error); return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator"); } 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 @@ -944,6 +944,8 @@ TokError("unknown bang operator"); return nullptr; case tgtok::XNOT: + case tgtok::XLower: + case tgtok::XUpper: case tgtok::XLOG2: case tgtok::XHead: case tgtok::XTail: @@ -967,6 +969,16 @@ return nullptr; } + break; + case tgtok::XLower: + Lex.Lex(); // eat the operation + Code = UnOpInit::LOWER; + Type = StringRecTy::get(Records); + break; + case tgtok::XUpper: + Lex.Lex(); // eat the operation + Code = UnOpInit::UPPER; + Type = StringRecTy::get(Records); break; case tgtok::XNOT: Lex.Lex(); // eat the operation @@ -2445,6 +2457,8 @@ case tgtok::XSize: case tgtok::XEmpty: case tgtok::XCast: + case tgtok::XLower: + case tgtok::XUpper: case tgtok::XGetDagOp: // Value ::= !unop '(' Value ')' case tgtok::XExists: case tgtok::XIsA: diff --git a/llvm/test/TableGen/string_ops.td b/llvm/test/TableGen/string_ops.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/string_ops.td @@ -0,0 +1,44 @@ +// RUN: llvm-tblgen %s | FileCheck %s + +// CHECK-LABEL: def LOWER1 { +// CHECK: int Value = 1; +// CHECK: } + +// CHECK-LABEL: def LOWER2 { +// CHECK: int Value = 1; +// CHECK: } + +// CHECK-LABEL: def LOWER3 { +// CHECK: int Value = 1; +// CHECK: } + +// CHECK-LABEL: def UPPER1 { +// CHECK: int Value = 1; +// CHECK: } + +// CHECK-LABEL: def UPPER2 { +// CHECK: int Value = 1; +// CHECK: } + +// CHECK-LABEL: def UPPER3 { +// CHECK: int Value = 1; +// CHECK: } + +class Base { + int Value = V; +} + +class Derived : + Base; + + +class Derived2 : + Base; + +def LOWER1 : Derived<"Str">; +def LOWER2 : Derived<"STr">; +def LOWER3 : Derived<"STR">; + +def UPPER1 : Derived2<"str">; +def UPPER2 : Derived2<"sTr">; +def UPPER3 : Derived2<"sTR">; diff --git a/llvm/utils/kate/llvm-tablegen.xml b/llvm/utils/kate/llvm-tablegen.xml --- a/llvm/utils/kate/llvm-tablegen.xml +++ b/llvm/utils/kate/llvm-tablegen.xml @@ -42,6 +42,8 @@ !ge !gt !ne + !lower + !upper class