Skip to content

Commit 195ba45

Browse files
committed
[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 c6e787f (reverted by 1e5f29a)) Instead, skip the potential \n after jumpToLoc at handleMacroExit.
1 parent 219476d commit 195ba45

File tree

4 files changed

+34
-34
lines changed

4 files changed

+34
-34
lines changed

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2920,6 +2920,10 @@ void AsmParser::handleMacroExit() {
29202920
// Jump to the EndOfStatement we should return to, and consume it.
29212921
jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
29222922
Lex();
2923+
// If .endm/.endr is followed by \n instead of a comment, consume it so that
2924+
// we don't print an excess \n.
2925+
if (getTok().is(AsmToken::EndOfStatement))
2926+
Lex();
29232927

29242928
// Pop the instantiation entry.
29252929
delete ActiveMacros.back();
@@ -5624,27 +5628,22 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
56245628
return nullptr;
56255629
}
56265630

5627-
if (Lexer.is(AsmToken::Identifier) &&
5628-
(getTok().getIdentifier() == ".rep" ||
5629-
getTok().getIdentifier() == ".rept" ||
5630-
getTok().getIdentifier() == ".irp" ||
5631-
getTok().getIdentifier() == ".irpc")) {
5632-
++NestLevel;
5633-
}
5634-
5635-
// Otherwise, check whether we have reached the .endr.
5636-
if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
5637-
if (NestLevel == 0) {
5638-
EndToken = getTok();
5639-
Lex();
5640-
if (Lexer.isNot(AsmToken::EndOfStatement)) {
5641-
printError(getTok().getLoc(),
5642-
"unexpected token in '.endr' directive");
5631+
if (Lexer.is(AsmToken::Identifier)) {
5632+
StringRef Ident = getTok().getIdentifier();
5633+
if (Ident == ".rep" || Ident == ".rept" || Ident == ".irp" ||
5634+
Ident == ".irpc") {
5635+
++NestLevel;
5636+
} else if (Ident == ".endr") {
5637+
if (NestLevel == 0) {
5638+
EndToken = getTok();
5639+
Lex();
5640+
if (Lexer.is(AsmToken::EndOfStatement))
5641+
break;
5642+
printError(getTok().getLoc(), "expected newline");
56435643
return nullptr;
56445644
}
5645-
break;
5645+
--NestLevel;
56465646
}
5647-
--NestLevel;
56485647
}
56495648

56505649
// Otherwise, scan till the end of the statement.

llvm/test/MC/AsmParser/macro-arg.s

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@ escape 3
1717

1818
# CHECK: .long -1
1919
# CHECK-NEXT: .long -1
20-
# CHECK-EMPTY:
2120
double
22-
# CHECK: .long -1
2321
# CHECK-NEXT: .long -1
24-
# CHECK-EMPTY:
22+
# CHECK-NEXT: .long -1
2523
double ,
26-
# CHECK: .long 1
24+
# CHECK-NEXT: .long 1
2725
# CHECK-NEXT: .long -1
2826
double 1
2927
# CHECK: .long 2

llvm/test/MC/AsmParser/macro-irp.s

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
.irp reg,%eax,%ebx
44
pushl \reg
55
.endr
6+
pushl %ecx
67

78
// CHECK: pushl %eax
89
// CHECK: pushl %ebx
10+
// CHECK-NEXT: pushl %ecx
911

1012
.irp reg,%eax,%ebx
1113
.irp imm,4,3,5

llvm/test/MC/AsmParser/macro-rept.s

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
// RUN: llvm-mc -triple x86_64-unknown-unknown %s | FileCheck %s
1+
# RUN: llvm-mc -triple x86_64 %s | FileCheck %s
22

33
.rept 2
44
.long 1
55
.endr
66
# 3 "a.s"
7-
/// Test line marker after .endr \n.
7+
## Test line marker after .endr \n.
88

99
.rept 3
1010
.rept 2
1111
.long 0
1212
.endr
13-
.endr
14-
15-
// CHECK: .long 1
16-
// CHECK: .long 1
13+
.endr # comment after .endr
14+
.long 42
1715

18-
// CHECK: .long 0
19-
// CHECK: .long 0
20-
// CHECK: .long 0
16+
# CHECK: .long 1
17+
# CHECK-NEXT: .long 1
2118

22-
// CHECK: .long 0
23-
// CHECK: .long 0
24-
// CHECK: .long 0
19+
# CHECK: .long 0
20+
# CHECK-NEXT: .long 0
21+
# CHECK-NEXT: .long 0
22+
# CHECK-NEXT: .long 0
23+
# CHECK-NEXT: .long 0
24+
# CHECK-NEXT: .long 0
25+
# CHECK-NEXT: .long 42

0 commit comments

Comments
 (0)