AsmParser: Parse (and ignore) nested .macro definitions.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sun, 9 Feb 2014 16:22:00 +0000 (16:22 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sun, 9 Feb 2014 16:22:00 +0000 (16:22 +0000)
This enables a slightly odd feature of gas. The macro is defined when
the outermost macro is instantiated.

PR18599

llvm-svn: 201045

llvm/lib/MC/MCParser/AsmParser.cpp
llvm/test/MC/AsmParser/macro-def-in-instantiation.s

index 459e126..1736e77 100644 (file)
@@ -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.
index b6483b3..773df70 100644 (file)
@@ -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