[ms] [llvm-ml] Support purging macro definitions
authorEric Astor <epastor@google.com>
Mon, 23 Nov 2020 19:20:17 +0000 (14:20 -0500)
committerEric Astor <epastor@google.com>
Mon, 23 Nov 2020 20:03:13 +0000 (15:03 -0500)
Support MASM's PURGE directive.

Reviewed By: thakis

Differential Revision: https://reviews.llvm.org/D89735

llvm/lib/MC/MCParser/COFFMasmParser.cpp
llvm/lib/MC/MCParser/MasmParser.cpp
llvm/test/tools/llvm-ml/macro.test

index 61d69ee4e7e8c3fec3e24dd183faccc60751c71b..aacce928c14198528fc811136d8571fe97a35917 100644 (file)
@@ -118,9 +118,7 @@ class COFFMasmParser : public MCAsmParserExtension {
     addDirectiveHandler<&COFFMasmParser::IgnoreDirective>("title");
 
     // Macro directives
-    // exitm
     // goto
-    // purge
 
     // Miscellaneous directives
     addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>("alias");
@@ -153,9 +151,6 @@ class COFFMasmParser : public MCAsmParserExtension {
     addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".mmx");
     addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".xmm");
 
-    // Repeat blocks directives
-    // goto
-
     // Scope directives
     // comm
     // externdef
index d717cadf4e4a76aad290aa5b6ca20a0a67076f00..9b63148c6860cb0a966aac783f0b3378aa11fbe9 100644 (file)
@@ -734,7 +734,7 @@ private:
     DK_MACRO,
     DK_EXITM,
     DK_ENDM,
-    DK_PURGEM,
+    DK_PURGE,
     DK_ERR,
     DK_ERRB,
     DK_ERRNB,
@@ -2311,7 +2311,7 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
     case DK_ENDM:
       Info.ExitValue = "";
       return parseDirectiveEndMacro(IDVal);
-    case DK_PURGEM:
+    case DK_PURGE:
       return parseDirectivePurgeMacro(IDLoc);
     case DK_END:
       return parseDirectiveEnd(IDLoc);
@@ -5544,23 +5544,27 @@ bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
 }
 
 /// parseDirectivePurgeMacro
-/// ::= .purgem
+/// ::= purge identifier ( , identifier )*
 bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
   StringRef Name;
-  SMLoc Loc;
-  if (parseTokenLoc(Loc) ||
-      check(parseIdentifier(Name), Loc,
-            "expected identifier in '.purgem' directive") ||
-      parseToken(AsmToken::EndOfStatement,
-                 "unexpected token in '.purgem' directive"))
-    return true;
+  while (true) {
+    SMLoc NameLoc;
+    if (parseTokenLoc(NameLoc) ||
+        check(parseIdentifier(Name), NameLoc,
+              "expected identifier in 'purge' directive"))
+      return true;
 
-  if (!getContext().lookupMacro(Name))
-    return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
+    DEBUG_WITH_TYPE("asm-macros", dbgs()
+                                      << "Un-defining macro: " << Name << "\n");
+    if (!getContext().lookupMacro(Name))
+      return Error(NameLoc, "macro '" + Name + "' is not defined");
+    getContext().undefineMacro(Name);
+
+    if (!parseOptionalToken(AsmToken::Comma))
+      break;
+    parseOptionalToken(AsmToken::EndOfStatement);
+  }
 
-  getContext().undefineMacro(Name);
-  DEBUG_WITH_TYPE("asm-macros", dbgs()
-                                    << "Un-defining macro: " << Name << "\n");
   return false;
 }
 
@@ -6322,7 +6326,7 @@ void MasmParser::initializeDirectiveKindMap() {
   DirectiveKindMap["macro"] = DK_MACRO;
   DirectiveKindMap["exitm"] = DK_EXITM;
   DirectiveKindMap["endm"] = DK_ENDM;
-  // DirectiveKindMap[".purgem"] = DK_PURGEM;
+  DirectiveKindMap["purge"] = DK_PURGE;
   DirectiveKindMap[".err"] = DK_ERR;
   DirectiveKindMap[".errb"] = DK_ERRB;
   DirectiveKindMap[".errnb"] = DK_ERRNB;
index 255cd485e36bafe2f6090200cd6965d03fea3e78..3a356c0abe3e4d93187ff11b004bfecdd1191464 100644 (file)
@@ -134,4 +134,23 @@ local_symbol_test PROC
 ; CHECK-NEXT: jmp "??0001"
 local_symbol_test ENDP
 
+PURGE ambiguous_substitution_macro, local_symbol_macro,
+      optional_parameter_macro
+
+; Redefinition
+local_symbol_macro MACRO
+  LOCAL b
+b: xor eax, eax
+   jmp b
+ENDM
+
+purge_test PROC
+; CHECK-LABEL: purge_test:
+
+  local_symbol_macro
+; CHECK: "??0002":
+; CHECK-NEXT: xor eax, eax
+; CHECK-NEXT: jmp "??0002"
+purge_test ENDP
+
 END