diff --git a/llvm/lib/MC/MCParser/COFFMasmParser.cpp b/llvm/lib/MC/MCParser/COFFMasmParser.cpp --- a/llvm/lib/MC/MCParser/COFFMasmParser.cpp +++ b/llvm/lib/MC/MCParser/COFFMasmParser.cpp @@ -45,6 +45,7 @@ bool ParseDirectiveSegment(StringRef, SMLoc); bool ParseDirectiveSegmentEnd(StringRef, SMLoc); bool ParseDirectiveIncludelib(StringRef, SMLoc); + bool ParseDirectiveOption(StringRef, SMLoc); bool ParseDirectiveAlias(StringRef, SMLoc); @@ -118,7 +119,7 @@ // .fpo addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>( "includelib"); - // option + addDirectiveHandler<&COFFMasmParser::ParseDirectiveOption>("option"); // popcontext // pushcontext // .safeseh @@ -303,6 +304,45 @@ return false; } +/// ParseDirectiveOption +/// ::= "option" option-list +bool COFFMasmParser::ParseDirectiveOption(StringRef Directive, SMLoc Loc) { + auto parseOption = [&]() -> bool { + StringRef Option; + if (getParser().parseIdentifier(Option)) + return TokError("expected identifier for option name"); + if (Option.equals_insensitive("prologue")) { + StringRef MacroId; + if (parseToken(AsmToken::Colon) || getParser().parseIdentifier(MacroId)) + return TokError("expected :macroId after OPTION PROLOGUE"); + if (MacroId.equals_insensitive("none")) { + // Since we currently don't implement prologues/epilogues, NONE is our + // default. + return false; + } else { + return TokError("OPTION PROLOGUE is currently unsupported"); + } + } else if (Option.equals_insensitive("epilogue")) { + StringRef MacroId; + if (parseToken(AsmToken::Colon) || getParser().parseIdentifier(MacroId)) + return TokError("expected :macroId after OPTION EPILOGUE"); + if (MacroId.equals_insensitive("none")) { + // Since we currently don't implement prologues/epilogues, NONE is our + // default. + return false; + } else { + return TokError("OPTION EPILOGUE is currently unsupported"); + } + } else { + return TokError("OPTION '" + Option + "' is currently unsupported"); + } + }; + + if (parseMany(parseOption)) + return addErrorSuffix(" in OPTION directive"); + return false; +} + /// ParseDirectiveProc /// TODO(epastor): Implement parameters and other attributes. /// ::= label "proc" [[distance]] diff --git a/llvm/test/tools/llvm-ml/option_prologue_epilogue_none.asm b/llvm/test/tools/llvm-ml/option_prologue_epilogue_none.asm new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-ml/option_prologue_epilogue_none.asm @@ -0,0 +1,17 @@ +; RUN: llvm-ml -filetype=s %s /Fo - | FileCheck %s + +OPTION PROLOGUE:NONE, EPILOGUE:NONE + +.code + +t1 PROC + ret +t1 ENDP + +; CHECK-LABEL: t1: +; CHECK-NOT: pop +; CHECK-NOT: push +; CHECK: {{^ *}}ret{{ *$}} + +end +