summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2014-02-09 16:22:00 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2014-02-09 16:22:00 +0000
commit275f65330731378c7cca967c19fb988038064235 (patch)
tree2f547007f3036aaef7fd51f1dcbb265d3f294394
parent965e3bc5ff578d9b5af706237c20c7bc2c66aacc (diff)
downloadllvm-275f65330731378c7cca967c19fb988038064235.tar.gz
llvm-275f65330731378c7cca967c19fb988038064235.tar.bz2
llvm-275f65330731378c7cca967c19fb988038064235.tar.xz
AsmParser: Parse (and ignore) nested .macro definitions.
This enables a slightly odd feature of gas. The macro is defined when the outermost macro is instantiated. PR18599 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201045 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/MC/MCParser/AsmParser.cpp29
-rw-r--r--test/MC/AsmParser/macro-def-in-instantiation.s20
2 files changed, 40 insertions, 9 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 459e126793..1736e7703c 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -3183,6 +3183,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
Lex();
AsmToken EndToken, StartToken = getTok();
+ unsigned MacroDepth = 0;
// Lex the macro definition.
for (;;) {
@@ -3191,15 +3192,25 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
return Error(DirectiveLoc, "no matching '.endmacro' in definition");
// Otherwise, check whether we have reach the .endmacro.
- if (getLexer().is(AsmToken::Identifier) &&
- (getTok().getIdentifier() == ".endm" ||
- getTok().getIdentifier() == ".endmacro")) {
- EndToken = getTok();
- Lex();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '" + EndToken.getIdentifier() +
- "' directive");
- break;
+ if (getLexer().is(AsmToken::Identifier)) {
+ if (getTok().getIdentifier() == ".endm" ||
+ getTok().getIdentifier() == ".endmacro") {
+ if (MacroDepth == 0) { // Outermost macro.
+ EndToken = getTok();
+ Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + EndToken.getIdentifier() +
+ "' directive");
+ break;
+ } else {
+ // Otherwise we just found the end of an inner macro.
+ --MacroDepth;
+ }
+ } else if (getTok().getIdentifier() == ".macro") {
+ // We allow nested macros. Those aren't instantiated until the outermost
+ // macro is expanded so just ignore them for now.
+ ++MacroDepth;
+ }
}
// Otherwise, scan til the end of the statement.
diff --git a/test/MC/AsmParser/macro-def-in-instantiation.s b/test/MC/AsmParser/macro-def-in-instantiation.s
index b6483b3b32..773df701aa 100644
--- a/test/MC/AsmParser/macro-def-in-instantiation.s
+++ b/test/MC/AsmParser/macro-def-in-instantiation.s
@@ -11,3 +11,23 @@ $4
.data
// CHECK: .byte 10
.mybyte 10
+
+// PR18599
+.macro macro_a
+
+.macro macro_b
+.byte 10
+.macro macro_c
+.endm
+
+macro_c
+.purgem macro_c
+.endm
+
+macro_b
+.endm
+
+macro_a
+macro_b
+// CHECK: .byte 10
+// CHECK: .byte 10