[llvm] 195ba45 - [MCAsmParser] .macro/.rept/.irp/.irpc: remove excess \n after expansion

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri May 17 23:02:58 PDT 2024


Author: Fangrui Song
Date: 2024-05-17T23:02:54-07:00
New Revision: 195ba4572129befa25ca56439515d7cb91587c56

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

LOG: [MCAsmParser] .macro/.rept/.irp/.irpc: remove excess \n after expansion

```
.irp foo,1
nop
.endr
nop
```

expands to an excess EOL between two nop lines. Other loop directives
and .macro have the same issue.

`Lex()` at "Jump to the macro instantiation and prime the lexer"
requires that there is one single \n token in CurTok. Therefore, we
cannot consume the trailing \n when parsing the macro(-like) body.
(commit c6e787f771d1f9d6a846b2d9b8db6adcd87e8dba (reverted by
1e5f29af81a5f6fda308074f6345b9fba4faa71c))

Instead, skip the potential \n after jumpToLoc at handleMacroExit.

Added: 
    

Modified: 
    llvm/lib/MC/MCParser/AsmParser.cpp
    llvm/test/MC/AsmParser/macro-arg.s
    llvm/test/MC/AsmParser/macro-irp.s
    llvm/test/MC/AsmParser/macro-rept.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index ce155be9c1c70..2cddaf330b3bc 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -2920,6 +2920,10 @@ void AsmParser::handleMacroExit() {
   // Jump to the EndOfStatement we should return to, and consume it.
   jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
   Lex();
+  // If .endm/.endr is followed by \n instead of a comment, consume it so that
+  // we don't print an excess \n.
+  if (getTok().is(AsmToken::EndOfStatement))
+    Lex();
 
   // Pop the instantiation entry.
   delete ActiveMacros.back();
@@ -5624,27 +5628,22 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
       return nullptr;
     }
 
-    if (Lexer.is(AsmToken::Identifier) &&
-        (getTok().getIdentifier() == ".rep" ||
-         getTok().getIdentifier() == ".rept" ||
-         getTok().getIdentifier() == ".irp" ||
-         getTok().getIdentifier() == ".irpc")) {
-      ++NestLevel;
-    }
-
-    // Otherwise, check whether we have reached the .endr.
-    if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
-      if (NestLevel == 0) {
-        EndToken = getTok();
-        Lex();
-        if (Lexer.isNot(AsmToken::EndOfStatement)) {
-          printError(getTok().getLoc(),
-                     "unexpected token in '.endr' directive");
+    if (Lexer.is(AsmToken::Identifier)) {
+      StringRef Ident = getTok().getIdentifier();
+      if (Ident == ".rep" || Ident == ".rept" || Ident == ".irp" ||
+          Ident == ".irpc") {
+        ++NestLevel;
+      } else if (Ident == ".endr") {
+        if (NestLevel == 0) {
+          EndToken = getTok();
+          Lex();
+          if (Lexer.is(AsmToken::EndOfStatement))
+            break;
+          printError(getTok().getLoc(), "expected newline");
           return nullptr;
         }
-        break;
+        --NestLevel;
       }
-      --NestLevel;
     }
 
     // Otherwise, scan till the end of the statement.

diff  --git a/llvm/test/MC/AsmParser/macro-arg.s b/llvm/test/MC/AsmParser/macro-arg.s
index a269873e9fa1c..19065402309ec 100644
--- a/llvm/test/MC/AsmParser/macro-arg.s
+++ b/llvm/test/MC/AsmParser/macro-arg.s
@@ -17,13 +17,11 @@ escape 3
 
 # CHECK:      .long -1
 # CHECK-NEXT: .long -1
-# CHECK-EMPTY:
 double
-# CHECK:      .long -1
 # CHECK-NEXT: .long -1
-# CHECK-EMPTY:
+# CHECK-NEXT: .long -1
 double ,
-# CHECK:      .long 1
+# CHECK-NEXT: .long 1
 # CHECK-NEXT: .long -1
 double 1
 # CHECK:      .long 2

diff  --git a/llvm/test/MC/AsmParser/macro-irp.s b/llvm/test/MC/AsmParser/macro-irp.s
index 42902bc94b5f8..7d4c7cc26942e 100644
--- a/llvm/test/MC/AsmParser/macro-irp.s
+++ b/llvm/test/MC/AsmParser/macro-irp.s
@@ -3,9 +3,11 @@
 .irp reg,%eax,%ebx
         pushl \reg
 .endr
+pushl %ecx
 
 // CHECK: pushl %eax
 // CHECK: pushl %ebx
+// CHECK-NEXT: pushl %ecx
 
 .irp reg,%eax,%ebx
 .irp imm,4,3,5

diff  --git a/llvm/test/MC/AsmParser/macro-rept.s b/llvm/test/MC/AsmParser/macro-rept.s
index 13599dd818415..c1a90b22c9f21 100644
--- a/llvm/test/MC/AsmParser/macro-rept.s
+++ b/llvm/test/MC/AsmParser/macro-rept.s
@@ -1,24 +1,25 @@
-// RUN: llvm-mc -triple x86_64-unknown-unknown %s | FileCheck %s
+# RUN: llvm-mc -triple x86_64 %s | FileCheck %s
 
 .rept 2
     .long 1
 .endr
 # 3 "a.s"
-/// Test line marker after .endr \n.
+## Test line marker after .endr \n.
 
 .rept 3
 .rept 2
     .long 0
 .endr
-.endr
-
-// CHECK: .long	1
-// CHECK: .long	1
+.endr # comment after .endr
+.long 42
 
-// CHECK: .long	0
-// CHECK: .long	0
-// CHECK: .long	0
+# CHECK:      .long 1
+# CHECK-NEXT: .long 1
 
-// CHECK: .long	0
-// CHECK: .long	0
-// CHECK: .long	0
+# CHECK:      .long 0
+# CHECK-NEXT: .long 0
+# CHECK-NEXT: .long 0
+# CHECK-NEXT: .long 0
+# CHECK-NEXT: .long 0
+# CHECK-NEXT: .long 0
+# CHECK-NEXT: .long 42


        


More information about the llvm-commits mailing list