[llvm] e70f376 - [MCParser] Simplify macro-like body expansion

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 5 13:19:21 PDT 2024


Author: Fangrui Song
Date: 2024-07-05T13:19:16-07:00
New Revision: e70f376b25ea96f3b0db75ff77ae1a58d53f2119

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

LOG: [MCParser] Simplify macro-like body expansion

Make it easy to support argument expansion in the altmacro mode.

Added: 
    

Modified: 
    llvm/lib/MC/MCParser/AsmParser.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 13879220a25e75..4b7c7f07fed990 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -2505,129 +2505,96 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
   // A macro without parameters is handled 
diff erently on Darwin:
   // gas accepts no arguments and does no substitutions
   StringRef Body = Macro.Body;
-  while (!Body.empty()) {
-    // Scan for the next substitution.
-    std::size_t End = Body.size(), Pos = 0;
-    for (; Pos != End; ++Pos) {
-      // Check for a substitution or escape.
-      if (IsDarwin && !NParameters) {
-        // This macro has no parameters, look for $0, $1, etc.
-        if (Body[Pos] != '$' || Pos + 1 == End)
-          continue;
+  size_t I = 0, End = Body.size();
+  while (I != End) {
+    if (Body[I] == '\\' && I + 1 != End) {
+      // Check for \@ and \+ pseudo variables.
+      if (EnableAtPseudoVariable && Body[I + 1] == '@') {
+        OS << NumOfMacroInstantiations;
+        I += 2;
+        continue;
+      }
+      if (Body[I + 1] == '+') {
+        OS << Macro.Count;
+        I += 2;
+        continue;
+      }
+      if (Body[I + 1] == '(' && Body[I + 2] == ')') {
+        I += 3;
+        continue;
+      }
 
-        char Next = Body[Pos + 1];
-        if (Next == '$' || Next == 'n' ||
-            isdigit(static_cast<unsigned char>(Next)))
+      size_t Pos = ++I;
+      while (I != End && isIdentifierChar(Body[I]))
+        ++I;
+      StringRef Argument(Body.data() + Pos, I - Pos);
+      unsigned Index = 0;
+      for (; Index < NParameters; ++Index)
+        if (Parameters[Index].Name == Argument)
           break;
+      if (Index == NParameters) {
+        OS << '\\' << Argument;
       } else {
-        // This macro has parameters, look for \foo, \bar, etc.
-        if (Body[Pos] == '\\' && Pos + 1 != End)
-          break;
+        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();
+        }
       }
+      continue;
     }
 
-    // Add the prefix.
-    OS << Body.slice(0, Pos);
-
-    // Check if we reached the end.
-    if (Pos == End)
-      break;
-
-    if (IsDarwin && !NParameters) {
-      switch (Body[Pos + 1]) {
+    if (Body[I] == '$' && I + 1 != End && IsDarwin && !NParameters) {
+      // This macro has no parameters, look for $0, $1, etc.
+      switch (Body[I + 1]) {
       // $$ => $
       case '$':
         OS << '$';
-        break;
-
+        I += 2;
+        continue;
       // $n => number of arguments
       case 'n':
         OS << A.size();
-        break;
-
-      // $[0-9] => argument
+        I += 2;
+        continue;
       default: {
-        // Missing arguments are ignored.
-        unsigned Index = Body[Pos + 1] - '0';
-        if (Index >= A.size())
+        if (!isDigit(Body[I + 1]))
           break;
-
-        // Otherwise substitute with the token values, with spaces eliminated.
-        for (const AsmToken &Token : A[Index])
-          OS << Token.getString();
-        break;
-      }
-      }
-      Pos += 2;
-    } else {
-      // Check for \@ and \+ pseudo variables.
-      unsigned I = Pos + 1;
-      if (I + 1 != End) {
-        if (EnableAtPseudoVariable && Body[I] == '@') {
-          ++I;
-        } else if (Body[I] == '+') {
-          ++I;
-        } else {
-          while (isIdentifierChar(Body[I]) && I + 1 != End)
-            ++I;
-        }
-      }
-
-      const char *Begin = Body.data() + Pos + 1;
-      StringRef Argument(Begin, I - (Pos + 1));
-      unsigned Index = 0;
-
-      if (Argument == "@") {
-        OS << NumOfMacroInstantiations;
-        Pos += 2;
-      } else if (Argument == "+") {
-        OS << Macro.Count;
-        Pos += 2;
-      } else {
-        for (; Index < NParameters; ++Index)
-          if (Parameters[Index].Name == Argument)
-            break;
-
-        if (Index == NParameters) {
-          if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
-            Pos += 3;
-          else {
-            OS << '\\' << Argument;
-            Pos = I;
-          }
-        } else {
-          bool VarargParameter = HasVararg && Index == (NParameters - 1);
+        // $[0-9] => argument
+        // Missing arguments are ignored.
+        unsigned Index = Body[I + 1] - '0';
+        if (Index < A.size())
           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();
-
-          Pos += 1 + Argument.size();
-        }
+            OS << Token.getString();
+        I += 2;
+        continue;
+      }
       }
     }
-    // Update the scan point.
-    Body = Body.substr(Pos);
+
+    OS << Body[I];
+    ++I;
   }
 
   ++Macro.Count;


        


More information about the llvm-commits mailing list