[llvm] da368f2 - [MCParser] .altmacro: Support argument expansion not preceded by \

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 11 22:11:50 PDT 2024


Author: Fangrui Song
Date: 2024-07-11T22:11:46-07:00
New Revision: da368f24050f34de0327d04068a608ba971fa47c

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

LOG: [MCParser] .altmacro: Support argument expansion not preceded by \

In the .altmacro mode, an argument can be expanded even if not preceded
by \. This behavior is not enabled for Darwin, which uses $
(`isIdentifierChar('$')` is true) for macro expansion.

This is f8b1ca4992a22b4b65282c09dd6f07a1a2839070 with a fix.

Added: 
    

Modified: 
    llvm/lib/MC/MCParser/AsmParser.cpp
    llvm/test/MC/AsmParser/altmacro-arg.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index b3d16d555deb7..a08a4e626ef16 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -2504,7 +2504,34 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
                             ArrayRef<MCAsmMacroArgument> A,
                             bool EnableAtPseudoVariable) {
   unsigned NParameters = Parameters.size();
-  bool HasVararg = NParameters ? Parameters.back().Vararg : false;
+  auto expandArg = [&](unsigned Index) {
+    bool HasVararg = NParameters ? Parameters.back().Vararg : false;
+    bool VarargParameter = HasVararg && Index == (NParameters - 1);
+    for (const AsmToken &Token : A[Index])
+      // For altmacro mode, you can write '%expr'.
+      // The prefix '%' evaluates the expression 'expr'
+      // and uses the result as a string (e.g. replace %(1+2) with the
+      // string "3").
+      // Here, we identify the integer token which is the result of the
+      // absolute expression evaluation and replace it with its string
+      // representation.
+      if (AltMacroMode && Token.getString().front() == '%' &&
+          Token.is(AsmToken::Integer))
+        // Emit an integer value to the buffer.
+        OS << Token.getIntVal();
+      // Only Token that was validated as a string and begins with '<'
+      // is considered altMacroString!!!
+      else if (AltMacroMode && Token.getString().front() == '<' &&
+               Token.is(AsmToken::String)) {
+        OS << angleBracketString(Token.getStringContents());
+      }
+      // We expect no quotes around the string's contents when
+      // parsing for varargs.
+      else if (Token.isNot(AsmToken::String) || VarargParameter)
+        OS << Token.getString();
+      else
+        OS << Token.getStringContents();
+  };
 
   // A macro without parameters is handled 
diff erently on Darwin:
   // gas accepts no arguments and does no substitutions
@@ -2538,39 +2565,15 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
       for (; Index < NParameters; ++Index)
         if (Parameters[Index].Name == Argument)
           break;
-      if (Index == NParameters) {
+      if (Index == NParameters)
         OS << '\\' << Argument;
-      } else {
-        bool VarargParameter = HasVararg && Index == (NParameters - 1);
-        for (const AsmToken &Token : A[Index]) {
-          // For altmacro mode, you can write '%expr'.
-          // The prefix '%' evaluates the expression 'expr'
-          // and uses the result as a string (e.g. replace %(1+2) with the
-          // string "3").
-          // Here, we identify the integer token which is the result of the
-          // absolute expression evaluation and replace it with its string
-          // representation.
-          if (AltMacroMode && Token.getString().front() == '%' &&
-              Token.is(AsmToken::Integer))
-            // Emit an integer value to the buffer.
-            OS << Token.getIntVal();
-          // Only Token that was validated as a string and begins with '<'
-          // is considered altMacroString!!!
-          else if (AltMacroMode && Token.getString().front() == '<' &&
-                   Token.is(AsmToken::String)) {
-            OS << angleBracketString(Token.getStringContents());
-          }
-          // We expect no quotes around the string's contents when
-          // parsing for varargs.
-          else if (Token.isNot(AsmToken::String) || VarargParameter)
-            OS << Token.getString();
-          else
-            OS << Token.getStringContents();
-        }
-      }
+      else
+        expandArg(Index);
       continue;
     }
 
+    // In Darwin mode, $ is used for macro expansion, not considered an
+    // identifier char.
     if (Body[I] == '$' && I + 1 != End && IsDarwin && !NParameters) {
       // This macro has no parameters, look for $0, $1, etc.
       switch (Body[I + 1]) {
@@ -2599,8 +2602,28 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
       }
     }
 
-    OS << Body[I];
-    ++I;
+    if (!isIdentifierChar(Body[I]) || IsDarwin) {
+      OS << Body[I++];
+      continue;
+    }
+
+    const size_t Start = I;
+    while (++I && isIdentifierChar(Body[I])) {
+    }
+    StringRef Token(Body.data() + Start, I - Start);
+    if (AltMacroMode) {
+      unsigned Index = 0;
+      for (; Index != NParameters; ++Index)
+        if (Parameters[Index].Name == Token)
+          break;
+      if (Index != NParameters) {
+        expandArg(Index);
+        if (I != End && Body[I] == '&')
+          ++I;
+        continue;
+      }
+    }
+    OS << Token;
   }
 
   ++Macro.Count;

diff  --git a/llvm/test/MC/AsmParser/altmacro-arg.s b/llvm/test/MC/AsmParser/altmacro-arg.s
index 9c91a15b4d155..713f5ad4aeab7 100644
--- a/llvm/test/MC/AsmParser/altmacro-arg.s
+++ b/llvm/test/MC/AsmParser/altmacro-arg.s
@@ -1,3 +1,4 @@
+## Arguments can be expanded even if they are not preceded by \
 # RUN: rm -rf %t && split-file %s %t && cd %t
 # RUN: llvm-mc -triple=x86_64 a.s | FileCheck %s
 # RUN: llvm-mc -triple=x86_64 b.s | FileCheck %s --check-prefix=CHECK1
@@ -5,10 +6,10 @@
 #--- a.s
 .altmacro
 # CHECK:      ja .Ltmp0
-# CHECK-NEXT: xorq %rax, %rax
+# CHECK-NEXT: xorq %rbx, %rbx
 # CHECK:      .data
 # CHECK-NEXT: .ascii "b cc rbx"
-# CHECK-NEXT: .ascii "ara rax rax raxx"
+# CHECK-NEXT: .ascii "bcc ccx rbx raxx"
 .macro gen a, ra, rax
   ja 1f
   xorq %rax, %rax
@@ -21,8 +22,8 @@ gen b, cc, rbx
 
 #--- b.s
 .altmacro
-# CHECK1:      1 1 ._a&a
-# CHECK1-NEXT: 1 2 ._a&a $b&b
+# CHECK1:      1 1 1a
+# CHECK1-NEXT: 1 2 1a 2b
 # CHECK1-NEXT: \$b \$b
 .irp ._a,1
   .print "\._a \._a& ._a&a"


        


More information about the llvm-commits mailing list