[llvm] d612a75 - [TableGen] add !toupper and !tolower operators to change the casing of strings.

Zain Jaffal via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 7 04:42:14 PST 2023


Author: Zain Jaffal
Date: 2023-03-07T12:41:56Z
New Revision: d612a75279250b2816e06fcf9b9770575946ad69

URL: https://github.com/llvm/llvm-project/commit/d612a75279250b2816e06fcf9b9770575946ad69
DIFF: https://github.com/llvm/llvm-project/commit/d612a75279250b2816e06fcf9b9770575946ad69.diff

LOG: [TableGen] add !toupper and !tolower operators to change the casing of strings.

Reviewed By: fpetrogalli

Differential Revision: https://reviews.llvm.org/D145300

Added: 
    llvm/test/TableGen/string_ops.td

Modified: 
    llvm/docs/TableGen/ProgRef.rst
    llvm/include/llvm/TableGen/Record.h
    llvm/lib/TableGen/Record.cpp
    llvm/lib/TableGen/TGLexer.cpp
    llvm/lib/TableGen/TGLexer.h
    llvm/lib/TableGen/TGParser.cpp
    llvm/utils/kate/llvm-tablegen.xml

Removed: 
    


################################################################################
diff  --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index 16d24a92ab1d8..8c74831505633 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -1630,6 +1630,12 @@ and non-0 as true.
     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.
 
+``!tolower(``\ *a*\ ``)``
+  This operator converts a string input *a* to lower case.
+
+``!toupper(``\ *a*\ ``)``
+  This operator converts a string input *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
index ba89da3cbe925..6326d62d34865 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -785,7 +785,18 @@ class OpInit : public TypedInit {
 ///
 class UnOpInit : public OpInit, public FoldingSetNode {
 public:
-  enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETDAGOP, LOG2 };
+  enum UnaryOp : uint8_t {
+    TOLOWER,
+    TOUPPER,
+    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
index 363bf7b446d53..a61fd3cea10e8 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -778,6 +778,14 @@ void UnOpInit::Profile(FoldingSetNodeID &ID) const {
 Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
   RecordKeeper &RK = getRecordKeeper();
   switch (getOpcode()) {
+  case TOLOWER:
+    if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
+      return StringInit::get(RK, LHSs->getValue().lower());
+    break;
+  case TOUPPER:
+    if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
+      return StringInit::get(RK, LHSs->getValue().upper());
+    break;
   case CAST:
     if (isa<StringRecTy>(getType())) {
       if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
@@ -927,6 +935,12 @@ std::string UnOpInit::getAsString() const {
   case EMPTY: Result = "!empty"; break;
   case GETDAGOP: Result = "!getdagop"; break;
   case LOG2 : Result = "!logtwo"; break;
+  case TOLOWER:
+    Result = "!tolower";
+    break;
+  case TOUPPER:
+    Result = "!toupper";
+    break;
   }
   return Result + "(" + LHS->getAsString() + ")";
 }

diff  --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index f2148b40a1b57..ba63d0b671ce6 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -549,50 +549,52 @@ tgtok::TokKind TGLexer::LexExclaim() {
 
   // Check to see which operator this is.
   tgtok::TokKind Kind =
-    StringSwitch<tgtok::TokKind>(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<tgtok::TokKind>(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("tolower", tgtok::XToLower)
+          .Case("toupper", tgtok::XToUpper)
+          .Default(tgtok::Error);
 
   return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator");
 }

diff  --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index 284f1bade9de1..93e28a4417a47 100644
--- a/llvm/lib/TableGen/TGLexer.h
+++ b/llvm/lib/TableGen/TGLexer.h
@@ -29,11 +29,11 @@ class SourceMgr;
 class Twine;
 
 namespace tgtok {
-  enum TokKind {
-    // Markers
+enum TokKind {
+  // Markers
     Eof, Error,
 
-    // Tokens with no info.
+  // Tokens with no info.
     minus, plus,        // - +
     l_square, r_square, // [ ]
     l_brace, r_brace,   // { }
@@ -45,36 +45,36 @@ namespace tgtok {
     paste,              // #
     dotdotdot,          // ...
 
-    // Reserved keywords. ('ElseKW' is named to distinguish it from the
-    // existing 'Else' that means the preprocessor #else.)
+  // 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.
+  // 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,
+    XExists, XListRemove,  XToLower, XToUpper,
 
-    // Boolean literals.
+  // Boolean literals.
     TrueVal, FalseVal,
 
-    // Integer value.
-    IntVal,
+  // Integer value.
+  IntVal,
 
-    // Binary constant.  Note that these are sized according to the number of
-    // bits given.
-    BinaryIntVal,
+  // Binary constant.  Note that these are sized according to the number of
+  // bits given.
+  BinaryIntVal,
 
-    // String valued tokens.
+  // String valued tokens.
     Id, StrVal, VarName, CodeFragment,
 
-    // Preprocessing tokens for internal usage by the lexer.
-    // They are never returned as a result of Lex().
+  // 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/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 735e565fc4174..6c52edc5dd413 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -969,6 +969,8 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
     TokError("unknown bang operator");
     return nullptr;
   case tgtok::XNOT:
+  case tgtok::XToLower:
+  case tgtok::XToUpper:
   case tgtok::XLOG2:
   case tgtok::XHead:
   case tgtok::XTail:
@@ -992,6 +994,16 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
         return nullptr;
       }
 
+      break;
+    case tgtok::XToLower:
+      Lex.Lex(); // eat the operation
+      Code = UnOpInit::TOLOWER;
+      Type = StringRecTy::get(Records);
+      break;
+    case tgtok::XToUpper:
+      Lex.Lex(); // eat the operation
+      Code = UnOpInit::TOUPPER;
+      Type = StringRecTy::get(Records);
       break;
     case tgtok::XNOT:
       Lex.Lex();  // eat the operation
@@ -2470,6 +2482,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
   case tgtok::XSize:
   case tgtok::XEmpty:
   case tgtok::XCast:
+  case tgtok::XToLower:
+  case tgtok::XToUpper:
   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
index 0000000000000..68581dd9cd655
--- /dev/null
+++ b/llvm/test/TableGen/string_ops.td
@@ -0,0 +1,39 @@
+// RUN: llvm-tblgen %s | FileCheck %s
+
+class ToLower<string str> {
+  string s = !tolower(str);
+}
+
+class ToUpper<string str> {
+  string s = !toupper(str);
+}
+
+// CHECK-LABEL: def LOWER1 {
+// CHECK: string s = "str";
+// CHECK: }
+def LOWER1: ToLower<"STR">;
+
+// CHECK-LABEL: def LOWER2 {
+// CHECK: string s = "str";
+// CHECK: }
+def LOWER2 : ToLower<"Str">;
+
+// CHECK-LABEL: def LOWER3 {
+// CHECK: string s = "str";
+// CHECK: }
+def LOWER3 : ToLower<"STr">;
+
+// CHECK-LABEL: def UPPER1 {
+// CHECK: string s = "STR";
+// CHECK: }
+def UPPER1 : ToUpper<"str">;
+
+// CHECK-LABEL: def UPPER2 {
+// CHECK: string s = "STR";
+// CHECK: }
+def UPPER2 : ToUpper<"sTr">;
+
+// CHECK-LABEL: def UPPER3 {
+// CHECK: string s = "STR";
+// CHECK: }
+def UPPER3 : ToUpper<"sTR">;
\ No newline at end of file

diff  --git a/llvm/utils/kate/llvm-tablegen.xml b/llvm/utils/kate/llvm-tablegen.xml
index 38bb3083a0daf..486d373a1186d 100644
--- a/llvm/utils/kate/llvm-tablegen.xml
+++ b/llvm/utils/kate/llvm-tablegen.xml
@@ -42,6 +42,8 @@
       <item> !ge </item>
       <item> !gt </item>
       <item> !ne </item>
+      <item> !tolower </item>
+      <item> !toupper </item>
     </list>
     <list name="objects">
       <item> class </item>


        


More information about the llvm-commits mailing list