[llvm] e533a17 - [TableGen] Fix non-standard escape warnings for braces in InstAlias

Cullen Rhodes via llvm-commits llvm-commits at lists.llvm.org
Thu May 28 02:37:06 PDT 2020


Author: Cullen Rhodes
Date: 2020-05-28T09:36:24Z
New Revision: e533a176b3d4d936a4870cd1a3273941ba699882

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

LOG: [TableGen] Fix non-standard escape warnings for braces in InstAlias

Summary:
TableGen interprets braces ('{}') in the asm string of instruction aliases as
variants but when defining aliases with literal braces they have to be escaped
to prevent them being removed.

Braces are escaped with '\\', for example:

  def FooBraces : InstAlias<"foo \\{$imm\\}", (foo IntOperand:$imm)>;

Although when TableGen is emitting the assembly writer (-gen-asm-writer)
the AsmString that gets emitted is:

  AsmString = "foo \{$\x01\}";

In c/c++ braces don't need to be escaped which causes compilation
warnings:

  warning: use of non-standard escape character '\{' [-Wpedantic]

This patch fixes the issue by unescaping the flattened alias asm string
in the asm writer, by replacing '\{\}' with '{}'.

Reviewed By: hfinkel

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

Added: 
    llvm/test/TableGen/AliasAsmString.td

Modified: 
    llvm/utils/TableGen/AsmWriterEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/TableGen/AliasAsmString.td b/llvm/test/TableGen/AliasAsmString.td
new file mode 100644
index 000000000000..dedcc4b2af89
--- /dev/null
+++ b/llvm/test/TableGen/AliasAsmString.td
@@ -0,0 +1,28 @@
+// RUN: llvm-tblgen -gen-asm-writer -I %p/../../include %s | FileCheck %s
+
+include "llvm/Target/Target.td"
+
+def ArchInstrInfo : InstrInfo { }
+
+def Arch : Target {
+  let InstructionSet = ArchInstrInfo;
+}
+
+def Reg : Register<"reg">;
+
+def RegClass : RegisterClass<"foo", [i32], 0, (add Reg)>;
+
+def IntOperand: Operand<i32>;
+
+def foo : Instruction {
+  let Size = 2;
+  let OutOperandList = (outs);
+  let InOperandList = (ins IntOperand:$imm);
+  let AsmString = "foo $imm";
+  let Namespace = "Arch";
+}
+
+def FooBraces : InstAlias<"foo \\{$imm\\}", (foo IntOperand:$imm)>;
+
+// CHECK: static const char AsmStrings[] =
+// CHECK-NEXT: /* 0 */ "foo {$\x01}\0"

diff  --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 72c7baa139a9..d10ea71e97e3 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -267,6 +267,27 @@ static void UnescapeString(std::string &Str) {
   }
 }
 
+/// UnescapeAliasString - Supports literal braces in InstAlias asm string which
+/// are escaped with '\\' to avoid being interpreted as variants. Braces must
+/// be unescaped before c++ code is generated as (e.g.):
+///
+///   AsmString = "foo \{$\x01\}";
+///
+/// causes non-standard escape character warnings.
+static void UnescapeAliasString(std::string &Str) {
+  for (unsigned i = 0; i != Str.size(); ++i) {
+    if (Str[i] == '\\' && i != Str.size()-1) {
+      switch (Str[i+1]) {
+      default: continue;  // Don't execute the code after the switch.
+      case '{': Str[i] = '{'; break;
+      case '}': Str[i] = '}'; break;
+      }
+      // Nuke the second character.
+      Str.erase(Str.begin()+i+1);
+    }
+  }
+}
+
 /// EmitPrintInstruction - Generate the code for the "printInstruction" method
 /// implementation. Destroys all instances of AsmWriterInst information, by
 /// clearing the Instructions vector.
@@ -803,6 +824,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
 
       std::string FlatAliasAsmString =
           CodeGenInstruction::FlattenAsmStringVariants(CGA.AsmString, Variant);
+      UnescapeAliasString(FlatAliasAsmString);
 
       // Don't emit the alias if it has more operands than what it's aliasing.
       if (NumResultOps < CountNumOperands(FlatAliasAsmString, Variant))


        


More information about the llvm-commits mailing list