diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index ae6a23dff99e..b068724a9584 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -361,7 +361,7 @@ class AsmParser : public MCAsmParser { DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE, DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM, DK_SLEB128, DK_ULEB128, - DK_ERR, + DK_ERR, DK_ERROR, DK_END }; @@ -475,8 +475,8 @@ class AsmParser : public MCAsmParser { // "end" bool parseDirectiveEnd(SMLoc DirectiveLoc); - // "err" - bool parseDirectiveErr(SMLoc DirectiveLoc); + // ".err" or ".error" + bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage); void initializeDirectiveKindMap(); }; @@ -1537,7 +1537,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { case DK_END: return parseDirectiveEnd(IDLoc); case DK_ERR: - return parseDirectiveErr(IDLoc); + return parseDirectiveError(IDLoc, false); + case DK_ERROR: + return parseDirectiveError(IDLoc, true); } return Error(IDLoc, "unknown directive"); @@ -3982,13 +3984,34 @@ bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) { return false; } -/// parseDirectiveErr -/// ::= .err -bool AsmParser::parseDirectiveErr(SMLoc Loc) { - if (!TheCondStack.empty()) - if (TheCondStack.back().Ignore) +/// parseDirectiveError +/// ::= .err +/// ::= .error [string] +bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) { + if (!TheCondStack.empty()) { + if (TheCondStack.back().Ignore) { + eatToEndOfStatement(); return false; - return Error(Loc, ".err encountered"); + } + } + + if (!WithMessage) + return Error(L, ".err encountered"); + + StringRef Message = ".error directive invoked in source file"; + if (Lexer.isNot(AsmToken::EndOfStatement)) { + if (Lexer.isNot(AsmToken::String)) { + TokError(".error argument must be a string"); + eatToEndOfStatement(); + return true; + } + + Message = getTok().getStringContents(); + Lex(); + } + + Error(L, Message); + return true; } /// parseDirectiveEndIf @@ -4117,6 +4140,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".endmacro"] = DK_ENDMACRO; DirectiveKindMap[".purgem"] = DK_PURGEM; DirectiveKindMap[".err"] = DK_ERR; + DirectiveKindMap[".error"] = DK_ERROR; } MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { diff --git a/test/MC/AsmParser/directive-err-diagnostics.s b/test/MC/AsmParser/directive-err-diagnostics.s new file mode 100644 index 000000000000..ccc5450d938b --- /dev/null +++ b/test/MC/AsmParser/directive-err-diagnostics.s @@ -0,0 +1,17 @@ +// RUN: not llvm-mc -triple i386 %s 2>&1 | FileCheck %s + + .error 0 +// CHECK: error: .error argument must be a string +// CHECK: .error 0 +// CHECK: ^ + + .ifeqs "0", "1" + .ifeqs "", "" + .error "message" + .endif + .endif +// CHECK-NOT: error: message +// CHECK-NOT: error: invalid instruction mnemonic 'message' +// CHECK-NOT: .error "message" +// CHECK-NOT: ^ + diff --git a/test/MC/AsmParser/directive-err.s b/test/MC/AsmParser/directive-err.s index 59c552a4a12b..63b89397f7ce 100644 --- a/test/MC/AsmParser/directive-err.s +++ b/test/MC/AsmParser/directive-err.s @@ -17,3 +17,14 @@ .endif // CHECK-NOT: error: .err encountered + .error "This is my error. There are many like it, but this one is mine." +// CHECK: error: This is my error. There are many like it, but this one is mine. + + .ifc one, two + .error "My error is my best friend." + .endif +// CHECK-NOT: error: My error is my best friend. + + .error +// CHECK: error: .error directive invoked in source file +