Skip to content

Commit

Permalink
Asm Parser: support .error directive
Browse files Browse the repository at this point in the history
The .error directive is similar to .err in that it will halt assembly if it is
evaluated for assembly.  However, it permits a user supplied message to be
rendered.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201999 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
compnerd committed Feb 23, 2014
1 parent e3d661f commit 6631253
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 10 deletions.
44 changes: 34 additions & 10 deletions lib/MC/MCParser/AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down Expand Up @@ -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();
};
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
17 changes: 17 additions & 0 deletions test/MC/AsmParser/directive-err-diagnostics.s
Original file line number Diff line number Diff line change
@@ -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: ^

11 changes: 11 additions & 0 deletions test/MC/AsmParser/directive-err.s
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 6631253

Please sign in to comment.