Defer asm errors to post-statement failure

Recommitting after fixing AsmParser initialization and X86 inline asm
error cleanup.

Allow errors to be deferred and emitted as part of clean up to simplify
and shorten Assembly parser code. This will allow error messages to be
emitted in helper functions and be modified by the caller which has
better context.

As part of this many minor cleanups to the Parser:

* Unify parser cleanup on error
* Add Workaround for incorrect return values in ParseDirective instances
* Tighten checks on error-signifying return values for parser functions
  and fix in-tree TargetParsers to be more consistent with the changes.
* Fix AArch64 test cases checking for spurious error messages that are
  now fixed.

These changes should be backwards compatible with current Target Parsers
so long as the error status are correctly returned in appropriate
functions.

Reviewers: rnk, majnemer

Subscribers: aemerson, jyknight, llvm-commits

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

llvm-svn: 281762
This commit is contained in:
Nirav Dave 2016-09-16 18:30:20 +00:00
parent e0e0ed13f4
commit 2364748a49
16 changed files with 520 additions and 830 deletions

View File

@ -144,6 +144,7 @@ protected: // Can only create subclasses.
const char *TokStart;
bool SkipSpace;
bool AllowAtInIdentifier;
bool IsAtStartOfStatement;
MCAsmLexer();
@ -163,6 +164,8 @@ public:
/// the main input file has been reached.
const AsmToken &Lex() {
assert(!CurTok.empty());
// Mark if we parsing out a EndOfStatement.
IsAtStartOfStatement = CurTok.front().getKind() == AsmToken::EndOfStatement;
CurTok.erase(CurTok.begin());
// LexToken may generate multiple tokens via UnLex but will always return
// the first one. Place returned value at head of CurTok vector.
@ -174,9 +177,12 @@ public:
}
void UnLex(AsmToken const &Token) {
IsAtStartOfStatement = false;
CurTok.insert(CurTok.begin(), Token);
}
bool isAtStartOfStatement() { return IsAtStartOfStatement; }
virtual StringRef LexUntilEndOfStatement() = 0;
/// Get the current source location.

View File

@ -11,7 +11,9 @@
#define LLVM_MC_MCPARSER_MCASMPARSER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/Support/DataTypes.h"
@ -67,6 +69,12 @@ public:
typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
ExtensionDirectiveHandler;
struct MCPendingError {
SMLoc Loc;
SmallString<64> Msg;
SMRange Range;
};
private:
MCAsmParser(const MCAsmParser &) = delete;
void operator=(const MCAsmParser &) = delete;
@ -78,6 +86,11 @@ private:
protected: // Can only create subclasses.
MCAsmParser();
bool HadError;
SmallVector<MCPendingError, 1> PendingErrors;
/// Flag tracking whether any errors have been encountered.
public:
virtual ~MCAsmParser();
@ -122,21 +135,36 @@ public:
const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
/// \brief Emit a note at the location \p L, with the message \p Msg.
virtual void Note(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) = 0;
virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
/// \brief Emit a warning at the location \p L, with the message \p Msg.
///
/// \return The return value is true, if warnings are fatal.
virtual bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) = 0;
virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
/// \brief Return an error at the location \p L, with the message \p Msg. This
/// may be modified before being emitted.
///
/// \return The return value is always true, as an idiomatic convenience to
/// clients.
bool Error(SMLoc L, const Twine &Msg, SMRange Range = None);
/// \brief Emit an error at the location \p L, with the message \p Msg.
///
/// \return The return value is always true, as an idiomatic convenience to
/// clients.
virtual bool Error(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) = 0;
virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
bool hasPendingError() { return !PendingErrors.empty(); }
bool printPendingErrors() {
bool rv = !PendingErrors.empty();
for (auto Err : PendingErrors) {
printError(Err.Loc, Twine(Err.Msg), Err.Range);
}
PendingErrors.clear();
return rv;
}
/// \brief Get the next AsmToken in the stream, possibly handling file
/// inclusion first.
@ -146,7 +174,7 @@ public:
const AsmToken &getTok() const;
/// \brief Report an error at the current lexer location.
bool TokError(const Twine &Msg, ArrayRef<SMRange> Ranges = None);
bool TokError(const Twine &Msg, SMRange Range = None);
bool parseTokenLoc(SMLoc &Loc);
bool parseToken(AsmToken::TokenKind T, const Twine &Msg);

View File

@ -15,6 +15,7 @@
#ifndef LLVM_SUPPORT_SMLOC_H
#define LLVM_SUPPORT_SMLOC_H
#include "llvm/ADT/None.h"
#include <cassert>
namespace llvm {
@ -50,6 +51,7 @@ public:
SMLoc Start, End;
SMRange() {}
SMRange(NoneType) : Start(), End() {}
SMRange(SMLoc St, SMLoc En) : Start(St), End(En) {
assert(Start.isValid() == End.isValid() &&
"Start and end should either both be valid or both be invalid!");

View File

@ -178,9 +178,6 @@ private:
/// \brief Keeps track of how many .macro's have been instantiated.
unsigned NumOfMacroInstantiations;
/// Flag tracking whether any errors have been encountered.
unsigned HadError : 1;
/// The values from the last parsed cpp hash file line comment if any.
struct CppHashInfoTy {
StringRef Filename;
@ -247,12 +244,9 @@ public:
AssemblerDialect = i;
}
void Note(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) override;
bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) override;
bool Error(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) override;
void Note(SMLoc L, const Twine &Msg, SMRange Range = None) override;
bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) override;
bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) override;
const AsmToken &Lex() override;
@ -337,7 +331,8 @@ private:
void printMacroInstantiations();
void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) const {
SMRange Range = None) const {
ArrayRef<SMRange> Ranges(Range);
SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
}
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
@ -565,8 +560,9 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI)
: Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
PlatformParser(nullptr), CurBuffer(SM.getMainFileID()),
MacrosEnabledFlag(true), HadError(false), CppHashInfo(),
AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
MacrosEnabledFlag(true), CppHashInfo(), AssemblerDialect(~0U),
IsDarwin(false), ParsingInlineAsm(false) {
HadError = false;
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@ -609,24 +605,25 @@ void AsmParser::printMacroInstantiations() {
"while in macro instantiation");
}
void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
printMessage(L, SourceMgr::DK_Note, Msg, Ranges);
void AsmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
printPendingErrors();
printMessage(L, SourceMgr::DK_Note, Msg, Range);
printMacroInstantiations();
}
bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
bool AsmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
if(getTargetParser().getTargetOptions().MCNoWarn)
return false;
if (getTargetParser().getTargetOptions().MCFatalWarnings)
return Error(L, Msg, Ranges);
printMessage(L, SourceMgr::DK_Warning, Msg, Ranges);
return Error(L, Msg, Range);
printMessage(L, SourceMgr::DK_Warning, Msg, Range);
printMacroInstantiations();
return false;
}
bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
bool AsmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
HadError = true;
printMessage(L, SourceMgr::DK_Error, Msg, Ranges);
printMessage(L, SourceMgr::DK_Error, Msg, Range);
printMacroInstantiations();
return true;
}
@ -731,32 +728,38 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
if (!parseStatement(Info, nullptr))
continue;
// If we've failed, but on a Error Token, but did not consume it in
// favor of a better message, emit it now.
if (Lexer.getTok().is(AsmToken::Error)) {
// If we have a Lexer Error we are on an Error Token. Load in Lexer Error
// for printing ErrMsg via Lex() only if no (presumably better) parser error
// exists.
if (!hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
Lex();
}
// We had an error, validate that one was emitted and recover by skipping to
// the next line.
assert(HadError && "Parse statement returned an error, but none emitted!");
eatToEndOfStatement();
// parseStatement returned true so may need to emit an error.
printPendingErrors();
// Skipping to the next line if needed.
if (!getLexer().isAtStartOfStatement())
eatToEndOfStatement();
}
// All errors should have been emitted.
assert(!hasPendingError() && "unexpected error from parseStatement");
getTargetParser().flushPendingInstructions(getStreamer());
if (TheCondState.TheCond != StartingCondState.TheCond ||
TheCondState.Ignore != StartingCondState.Ignore)
return TokError("unmatched .ifs or .elses");
printError(getTok().getLoc(), "unmatched .ifs or .elses");
// Check to see there are no empty DwarfFile slots.
const auto &LineTables = getContext().getMCDwarfLineTables();
if (!LineTables.empty()) {
unsigned Index = 0;
for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
if (File.Name.empty() && Index != 0)
TokError("unassigned file number: " + Twine(Index) +
" for .file directives");
printError(getTok().getLoc(), "unassigned file number: " +
Twine(Index) +
" for .file directives");
++Index;
}
}
@ -776,9 +779,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// FIXME: We would really like to refer back to where the symbol was
// first referenced for a source location. We need to add something
// to track that. Currently, we just point to the end of the file.
HadError |=
Error(getTok().getLoc(), "assembler local symbol '" +
Sym->getName() + "' not defined");
printError(getTok().getLoc(), "assembler local symbol '" +
Sym->getName() + "' not defined");
}
}
@ -789,7 +791,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Reset the state of any "# line file" directives we've seen to the
// context as it was at the diagnostic site.
CppHashInfo = std::get<1>(LocSym);
HadError |= Error(std::get<0>(LocSym), "directional label undefined");
printError(std::get<0>(LocSym), "directional label undefined");
}
}
}
@ -804,7 +806,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
void AsmParser::checkForValidSection() {
if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) {
TokError("expected section directive before assembly directive");
printError(getTok().getLoc(),
"expected section directive before assembly directive");
Out.InitSections(false);
}
}
@ -1435,6 +1438,7 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
/// ::= Label* Identifier OperandList* EndOfStatement
bool AsmParser::parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI) {
assert(!hasPendingError() && "parseStatement started with pending error");
// Eat initial spaces and comments
while (Lexer.is(AsmToken::Space))
Lex();
@ -1467,15 +1471,19 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
if (Lexer.is(AsmToken::Integer)) {
LocalLabelVal = getTok().getIntVal();
if (LocalLabelVal < 0) {
if (!TheCondState.Ignore)
return TokError("unexpected token at start of statement");
if (!TheCondState.Ignore) {
Lex(); // always eat a token
return Error(IDLoc, "unexpected token at start of statement");
}
IDVal = "";
} else {
IDVal = getTok().getString();
Lex(); // Consume the integer token to be used as an identifier token.
if (Lexer.getKind() != AsmToken::Colon) {
if (!TheCondState.Ignore)
return TokError("unexpected token at start of statement");
if (!TheCondState.Ignore) {
Lex(); // always eat a token
return Error(IDLoc, "unexpected token at start of statement");
}
}
}
} else if (Lexer.is(AsmToken::Dot)) {
@ -1492,8 +1500,10 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
Lex();
IDVal = "}";
} else if (parseIdentifier(IDVal)) {
if (!TheCondState.Ignore)
return TokError("unexpected token at start of statement");
if (!TheCondState.Ignore) {
Lex(); // always eat a token
return Error(IDLoc, "unexpected token at start of statement");
}
IDVal = "";
}
@ -1655,9 +1665,20 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
getTargetParser().flushPendingInstructions(getStreamer());
// First query the target-specific parser. It will return 'true' if it
// isn't interested in this directive.
if (!getTargetParser().ParseDirective(ID))
SMLoc StartTokLoc = getTok().getLoc();
bool TPDirectiveReturn = getTargetParser().ParseDirective(ID);
if (hasPendingError())
return true;
// Currently the return value should be true if we are
// uninterested but as this is at odds with the standard parsing
// convention (return true = error) we have instances of a parsed
// directive that fails returning true as an error. Catch these
// cases as best as possible errors here.
if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
return true;
// Return if we did some parsing or believe we succeeded.
if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc())
return false;
// Next, check the extension directive map to see if any extension has
@ -1912,9 +1933,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
// Canonicalize the opcode to lower case.
std::string OpcodeStr = IDVal.lower();
ParseInstructionInfo IInfo(Info.AsmRewrites);
bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
Info.ParsedOperands);
Info.ParseError = HadError;
bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
Info.ParsedOperands);
Info.ParseError = ParseHadError;
// Dump the parsed representation, if requested.
if (getShowParsedOperands()) {
@ -1931,9 +1952,13 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
}
// Fail even if ParseInstruction erroneously returns false.
if (hasPendingError() || ParseHadError)
return true;
// If we are generating dwarf for the current section then generate a .loc
// directive for the instruction.
if (!HadError && getContext().getGenDwarfForAssembly() &&
if (!ParseHadError && getContext().getGenDwarfForAssembly() &&
getContext().getGenDwarfSectionSyms().count(
getStreamer().getCurrentSection().first)) {
unsigned Line;
@ -1975,15 +2000,13 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
}
// If parsing succeeded, match the instruction.
if (!HadError) {
if (!ParseHadError) {
uint64_t ErrorInfo;
getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
Info.ParsedOperands, Out,
ErrorInfo, ParsingInlineAsm);
if (getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
Info.ParsedOperands, Out,
ErrorInfo, ParsingInlineAsm))
return true;
}
// Don't skip the rest of the line, the instruction parser is responsible for
// that.
return false;
}
@ -2019,6 +2042,7 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L) {
"Lexing Cpp line comment: Expected String");
StringRef Filename = getTok().getString();
Lex();
// Get rid of the enclosing quotes.
Filename = Filename.substr(1, Filename.size() - 2);
@ -2353,27 +2377,19 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
MCAsmMacroParameter FA;
if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
if (parseIdentifier(FA.Name)) {
Error(IDLoc, "invalid argument identifier for formal argument");
eatToEndOfStatement();
return true;
}
if (parseIdentifier(FA.Name))
return Error(IDLoc, "invalid argument identifier for formal argument");
if (Lexer.isNot(AsmToken::Equal))
return TokError("expected '=' after formal parameter identifier");
if (Lexer.isNot(AsmToken::Equal)) {
TokError("expected '=' after formal parameter identifier");
eatToEndOfStatement();
return true;
}
Lex();
NamedParametersFound = true;
}
if (NamedParametersFound && FA.Name.empty()) {
Error(IDLoc, "cannot mix positional and keyword arguments");
eatToEndOfStatement();
return true;
}
if (NamedParametersFound && FA.Name.empty())
return Error(IDLoc, "cannot mix positional and keyword arguments");
bool Vararg = HasVararg && Parameter == (NParameters - 1);
if (parseMacroArgument(FA.Value, Vararg))
@ -2388,10 +2404,8 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
if (FAI >= NParameters) {
assert(M && "expected macro to be defined");
Error(IDLoc,
"parameter named '" + FA.Name + "' does not exist for macro '" +
M->Name + "'");
return true;
return Error(IDLoc, "parameter named '" + FA.Name +
"' does not exist for macro '" + M->Name + "'");
}
PI = FAI;
}
@ -2992,11 +3006,14 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
if (!HasFillExpr)
FillExpr = 0;
// Always emit an alignment here even if we thrown an error.
bool ReturnVal = false;
// Compute alignment in bytes.
if (IsPow2) {
// FIXME: Diagnose overflow.
if (Alignment >= 32) {
Error(AlignmentLoc, "invalid alignment value");
ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
Alignment = 31;
}
@ -3008,13 +3025,14 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
if (Alignment == 0)
Alignment = 1;
if (!isPowerOf2_64(Alignment))
Error(AlignmentLoc, "alignment must be a power of 2");
ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
}
// Diagnose non-sensical max bytes to align.
if (MaxBytesLoc.isValid()) {
if (MaxBytesToFill < 1) {
Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
ReturnVal |= Error(MaxBytesLoc,
"alignment directive can never be satisfied in this "
"many bytes, ignoring maximum bytes expression");
MaxBytesToFill = 0;
}
@ -3040,7 +3058,7 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
MaxBytesToFill);
}
return false;
return ReturnVal;
}
/// parseDirectiveFile
@ -3094,7 +3112,7 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
getContext().setGenDwarfForAssembly(false);
else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
0)
Error(FileNumberLoc, "file number already allocated");
return Error(FileNumberLoc, "file number already allocated");
}
return false;
@ -3346,7 +3364,7 @@ bool AsmParser::parseDirectiveCVInlineSiteId() {
if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
IALine, IACol, FunctionIdLoc))
Error(FunctionIdLoc, "function id already allocated");
return Error(FunctionIdLoc, "function id already allocated");
return false;
}
@ -4340,9 +4358,9 @@ bool AsmParser::parseDirectiveAbort() {
return true;
if (Str.empty())
Error(Loc, ".abort detected. Assembly stopping.");
return Error(Loc, ".abort detected. Assembly stopping.");
else
Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
return Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
// FIXME: Actually abort assembly here.
return false;
@ -4487,11 +4505,8 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
if (Lexer.isNot(AsmToken::String)) {
if (ExpectEqual)
TokError("expected string parameter for '.ifeqs' directive");
else
TokError("expected string parameter for '.ifnes' directive");
eatToEndOfStatement();
return true;
return TokError("expected string parameter for '.ifeqs' directive");
return TokError("expected string parameter for '.ifnes' directive");
}
StringRef String1 = getTok().getStringContents();
@ -4499,22 +4514,17 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
if (Lexer.isNot(AsmToken::Comma)) {
if (ExpectEqual)
TokError("expected comma after first string for '.ifeqs' directive");
else
TokError("expected comma after first string for '.ifnes' directive");
eatToEndOfStatement();
return true;
return TokError(
"expected comma after first string for '.ifeqs' directive");
return TokError("expected comma after first string for '.ifnes' directive");
}
Lex();
if (Lexer.isNot(AsmToken::String)) {
if (ExpectEqual)
TokError("expected string parameter for '.ifeqs' directive");
else
TokError("expected string parameter for '.ifnes' directive");
eatToEndOfStatement();
return true;
return TokError("expected string parameter for '.ifeqs' directive");
return TokError("expected string parameter for '.ifnes' directive");
}
StringRef String2 = getTok().getStringContents();
@ -4559,8 +4569,8 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
" an .elseif");
return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
" .if or an .elseif");
TheCondState.TheCond = AsmCond::ElseIfCond;
bool LastIgnoreState = false;
@ -4594,8 +4604,8 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
".elseif");
return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
" an .if or an .elseif");
TheCondState.TheCond = AsmCond::ElseCond;
bool LastIgnoreState = false;
if (!TheCondStack.empty())
@ -4637,18 +4647,14 @@ bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
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;
}
if (Lexer.isNot(AsmToken::String))
return TokError(".error argument must be a string");
Message = getTok().getStringContents();
Lex();
}
Error(L, Message);
return true;
return Error(L, Message);
}
/// parseDirectiveWarning
@ -4663,18 +4669,14 @@ bool AsmParser::parseDirectiveWarning(SMLoc L) {
StringRef Message = ".warning directive invoked in source file";
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (Lexer.isNot(AsmToken::String)) {
TokError(".warning argument must be a string");
eatToEndOfStatement();
return true;
}
if (Lexer.isNot(AsmToken::String))
return TokError(".warning argument must be a string");
Message = getTok().getStringContents();
Lex();
}
Warning(L, Message);
return false;
return Warning(L, Message);
}
/// parseDirectiveEndIf
@ -4685,8 +4687,8 @@ bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
return true;
if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
".else");
return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
"an .if or .else");
if (!TheCondStack.empty()) {
TheCondState = TheCondStack.back();
TheCondStack.pop_back();
@ -4838,7 +4840,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
while (true) {
// Check whether we have reached the end of the file.
if (getLexer().is(AsmToken::Eof)) {
Error(DirectiveLoc, "no matching '.endr' in definition");
printError(DirectiveLoc, "no matching '.endr' in definition");
return nullptr;
}
@ -4855,7 +4857,8 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
EndToken = getTok();
Lex();
if (Lexer.isNot(AsmToken::EndOfStatement)) {
TokError("unexpected token in '.endr' directive");
printError(getTok().getLoc(),
"unexpected token in '.endr' directive");
return nullptr;
}
break;
@ -4905,7 +4908,6 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
int64_t Count;
if (!CountExpr->evaluateAsAbsolute(Count)) {
eatToEndOfStatement();
return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
}
@ -5108,11 +5110,16 @@ bool AsmParser::parseMSInlineAsm(
continue;
ParseStatementInfo Info(&AsmStrRewrites);
if (parseStatement(Info, &SI))
return true;
bool StatementErr = parseStatement(Info, &SI);
if (Info.ParseError)
if (StatementErr || Info.ParseError) {
// Emit pending errors if any exist.
printPendingErrors();
return true;
}
// No pending error should exist here.
assert(!hasPendingError() && "unexpected error from parseStatement");
if (Info.Opcode == ~0U)
continue;
@ -5339,7 +5346,6 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
if (Parser.parseExpression(Value)) {
Parser.TokError("missing expression");
Parser.eatToEndOfStatement();
return true;
}

View File

@ -12,7 +12,8 @@
using namespace llvm;
MCAsmLexer::MCAsmLexer() : TokStart(nullptr), SkipSpace(true) {
MCAsmLexer::MCAsmLexer()
: TokStart(nullptr), SkipSpace(true), IsAtStartOfStatement(true) {
CurTok.emplace_back(AsmToken::Space, StringRef());
}

View File

@ -17,8 +17,9 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
MCAsmParser::MCAsmParser() : TargetParser(nullptr), ShowParsedOperands(0) {
}
MCAsmParser::MCAsmParser()
: TargetParser(nullptr), ShowParsedOperands(0), HadError(false),
PendingErrors() {}
MCAsmParser::~MCAsmParser() {
}
@ -84,8 +85,18 @@ bool MCAsmParser::check(bool P, SMLoc Loc, const Twine &Msg) {
return false;
}
bool MCAsmParser::TokError(const Twine &Msg, ArrayRef<SMRange> Ranges) {
Error(getLexer().getLoc(), Msg, Ranges);
bool MCAsmParser::TokError(const Twine &Msg, SMRange Range) {
return Error(getLexer().getLoc(), Msg, Range);
}
bool MCAsmParser::Error(SMLoc L, const Twine &Msg, SMRange Range) {
HadError = true;
MCPendingError PErr;
PErr.Loc = L;
Msg.toVector(PErr.Msg);
PErr.Range = Range;
PendingErrors.push_back(PErr);
return true;
}

View File

@ -2702,7 +2702,6 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
}
if (getLexer().isNot(AsmToken::EndOfStatement)) {
Parser.eatToEndOfStatement();
return TokError("unexpected token in argument list");
}
@ -3322,8 +3321,6 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
// IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi") {
bool IsError = parseSysAlias(Head, NameLoc, Operands);
if (IsError && getLexer().isNot(AsmToken::EndOfStatement))
Parser.eatToEndOfStatement();
return IsError;
}
@ -3380,7 +3377,6 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
if (parseOperand(Operands, false, false)) {
Parser.eatToEndOfStatement();
return true;
}
@ -3393,7 +3389,6 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
(N == 3 && condCodeThirdOperand) ||
(N == 2 && condCodeSecondOperand),
condCodeSecondOperand || condCodeThirdOperand)) {
Parser.eatToEndOfStatement();
return true;
}
@ -3425,7 +3420,6 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
if (getLexer().isNot(AsmToken::EndOfStatement)) {
SMLoc Loc = Parser.getTok().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
}
@ -4183,8 +4177,10 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
if (IDVal == ".inst")
return parseDirectiveInst(Loc);
}
if (IDVal == MCLOHDirectiveName())
return parseDirectiveLOH(IDVal, Loc);
return parseDirectiveLOH(IDVal, Loc);
return true;
}
static const struct {
@ -4345,7 +4341,6 @@ bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
MCAsmParser &Parser = getParser();
if (getLexer().is(AsmToken::EndOfStatement)) {
Parser.eatToEndOfStatement();
Error(Loc, "expected expression following directive");
return false;
}
@ -4403,8 +4398,6 @@ bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
/// ::= .loh <lohName | lohId> label1, ..., labelN
/// The number of arguments depends on the loh identifier.
bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
if (IDVal != MCLOHDirectiveName())
return true;
MCLOHType Kind;
if (getParser().getTok().isNot(AsmToken::Identifier)) {
if (getParser().getTok().isNot(AsmToken::Integer))
@ -4412,8 +4405,10 @@ bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
// We successfully get a numeric value for the identifier.
// Check if it is valid.
int64_t Id = getParser().getTok().getIntVal();
if (Id <= -1U && !isValidMCLOHType(Id))
return TokError("invalid numeric identifier in directive");
if (Id <= -1U && !isValidMCLOHType(Id)) {
TokError("invalid numeric identifier in directive");
return false;
}
Kind = (MCLOHType)Id;
} else {
StringRef Name = getTok().getIdentifier();
@ -4471,25 +4466,18 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
if (RegNum == static_cast<unsigned>(-1)) {
StringRef Kind;
RegNum = tryMatchVectorRegister(Kind, false);
if (!Kind.empty()) {
Error(SRegLoc, "vector register without type specifier expected");
return false;
}
if (!Kind.empty())
return Error(SRegLoc, "vector register without type specifier expected");
IsVector = true;
}
if (RegNum == static_cast<unsigned>(-1)) {
Parser.eatToEndOfStatement();
Error(SRegLoc, "register name or alias expected");
return false;
}
if (RegNum == static_cast<unsigned>(-1))
return Error(SRegLoc, "register name or alias expected");
// Shouldn't be anything else.
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
Error(Parser.getTok().getLoc(), "unexpected input in .req directive");
Parser.eatToEndOfStatement();
return false;
}
if (Parser.getTok().isNot(AsmToken::EndOfStatement))
return Error(Parser.getTok().getLoc(),
"unexpected input in .req directive");
Parser.Lex(); // Consume the EndOfStatement
@ -4497,7 +4485,7 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
Warning(L, "ignoring redefinition of register alias '" + Name + "'");
return true;
return false;
}
/// parseDirectiveUneq
@ -4506,7 +4494,6 @@ bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
MCAsmParser &Parser = getParser();
if (Parser.getTok().isNot(AsmToken::Identifier)) {
Error(Parser.getTok().getLoc(), "unexpected input in .unreq directive.");
Parser.eatToEndOfStatement();
return false;
}
RegisterReqs.erase(Parser.getTok().getIdentifier().lower());

View File

@ -339,16 +339,14 @@ class ARMAsmParser : public MCTargetAsmParser {
return;
}
void Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = None) {
return getParser().Note(L, Msg, Ranges);
void Note(SMLoc L, const Twine &Msg, SMRange Range = None) {
return getParser().Note(L, Msg, Range);
}
bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) {
return getParser().Warning(L, Msg, Ranges);
bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) {
return getParser().Warning(L, Msg, Range);
}
bool Error(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) {
return getParser().Error(L, Msg, Ranges);
bool Error(SMLoc L, const Twine &Msg, SMRange Range = None) {
return getParser().Error(L, Msg, Range);
}
bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
@ -6008,7 +6006,6 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// In Thumb1, only the branch (B) instruction can be predicated.
if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
Parser.eatToEndOfStatement();
return Error(NameLoc, "conditional execution not supported in Thumb1");
}
@ -6022,14 +6019,12 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
if (Mnemonic == "it") {
SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
if (ITMask.size() > 3) {
Parser.eatToEndOfStatement();
return Error(Loc, "too many conditions on IT instruction");
}
unsigned Mask = 8;
for (unsigned i = ITMask.size(); i != 0; --i) {
char pos = ITMask[i - 1];
if (pos != 't' && pos != 'e') {
Parser.eatToEndOfStatement();
return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
}
Mask >>= 1;
@ -6055,14 +6050,12 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// If we had a carry-set on an instruction that can't do that, issue an
// error.
if (!CanAcceptCarrySet && CarrySetting) {
Parser.eatToEndOfStatement();
return Error(NameLoc, "instruction '" + Mnemonic +
"' can not set flags, but 's' suffix specified");
}
// If we had a predication code on an instruction that can't do that, issue an
// error.
if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
Parser.eatToEndOfStatement();
return Error(NameLoc, "instruction '" + Mnemonic +
"' is not predicable, but condition code specified");
}
@ -6106,7 +6099,6 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// For for ARM mode generate an error if the .n qualifier is used.
if (ExtraToken == ".n" && !isThumb()) {
SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
Parser.eatToEndOfStatement();
return Error(Loc, "instruction with .n (narrow) qualifier not allowed in "
"arm mode");
}
@ -6124,7 +6116,6 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
if (parseOperand(Operands, Mnemonic)) {
Parser.eatToEndOfStatement();
return true;
}
@ -6133,16 +6124,13 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// Parse and remember the operand.
if (parseOperand(Operands, Mnemonic)) {
Parser.eatToEndOfStatement();
return true;
}
}
}
if (getLexer().isNot(AsmToken::EndOfStatement)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
return TokError("unexpected token in argument list");
}
Parser.Lex(); // Consume the EndOfStatement
@ -9334,7 +9322,6 @@ bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
for (;;) {
const MCExpr *Value;
if (getParser().parseExpression(Value)) {
Parser.eatToEndOfStatement();
return false;
}
@ -9437,7 +9424,6 @@ bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
Error(Parser.getTok().getLoc(), "unexpected token in directive");
Parser.eatToEndOfStatement();
return false;
}
@ -9530,14 +9516,12 @@ bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
unsigned Reg;
SMLoc SRegLoc, ERegLoc;
if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
Parser.eatToEndOfStatement();
Error(SRegLoc, "register name expected");
return false;
}
// Shouldn't be anything else.
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
Parser.eatToEndOfStatement();
Error(Parser.getTok().getLoc(), "unexpected input in .req directive.");
return false;
}
@ -9557,7 +9541,6 @@ bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
MCAsmParser &Parser = getParser();
if (Parser.getTok().isNot(AsmToken::Identifier)) {
Parser.eatToEndOfStatement();
Error(L, "unexpected input in .unreq directive.");
return false;
}
@ -9627,7 +9610,6 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
Tag = ARMBuildAttrs::AttrTypeFromString(Name);
if (Tag == -1) {
Error(TagLoc, "attribute name not recognised: " + Name);
Parser.eatToEndOfStatement();
return false;
}
Parser.Lex();
@ -9636,14 +9618,12 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
TagLoc = Parser.getTok().getLoc();
if (Parser.parseExpression(AttrExpr)) {
Parser.eatToEndOfStatement();
return false;
}
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
if (!CE) {
Error(TagLoc, "expected numeric constant");
Parser.eatToEndOfStatement();
return false;
}
@ -9652,7 +9632,6 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
if (Parser.getTok().isNot(AsmToken::Comma)) {
Error(Parser.getTok().getLoc(), "comma expected");
Parser.eatToEndOfStatement();
return false;
}
Parser.Lex(); // skip comma
@ -9679,14 +9658,12 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
const MCExpr *ValueExpr;
SMLoc ValueExprLoc = Parser.getTok().getLoc();
if (Parser.parseExpression(ValueExpr)) {
Parser.eatToEndOfStatement();
return false;
}
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
if (!CE) {
Error(ValueExprLoc, "expected numeric constant");
Parser.eatToEndOfStatement();
return false;
}
@ -9698,7 +9675,6 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
IsStringValue = false;
if (Parser.getTok().isNot(AsmToken::Comma)) {
Error(Parser.getTok().getLoc(), "comma expected");
Parser.eatToEndOfStatement();
return false;
} else {
Parser.Lex();
@ -9708,7 +9684,6 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
if (IsStringValue) {
if (Parser.getTok().isNot(AsmToken::String)) {
Error(Parser.getTok().getLoc(), "bad string constant");
Parser.eatToEndOfStatement();
return false;
}
@ -9852,7 +9827,6 @@ bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
return false;
}
if (HasExistingPersonality) {
Parser.eatToEndOfStatement();
Error(L, "multiple personality directives");
UC.emitPersonalityLocNotes();
return false;
@ -9860,7 +9834,6 @@ bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
// Parse the name of the personality routine
if (Parser.getTok().isNot(AsmToken::Identifier)) {
Parser.eatToEndOfStatement();
Error(L, "unexpected input in .personality directive.");
return false;
}
@ -10060,14 +10033,12 @@ bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
Width = 4;
break;
default:
Parser.eatToEndOfStatement();
Error(Loc, "cannot determine Thumb instruction size, "
"use inst.n/inst.w instead");
return false;
}
} else {
if (Suffix) {
Parser.eatToEndOfStatement();
Error(Loc, "width suffixes are invalid in ARM mode");
return false;
}
@ -10075,7 +10046,6 @@ bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
}
if (getLexer().is(AsmToken::EndOfStatement)) {
Parser.eatToEndOfStatement();
Error(Loc, "expected expression following directive");
return false;
}
@ -10167,24 +10137,20 @@ bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
UC.recordPersonalityIndex(L);
if (!UC.hasFnStart()) {
Parser.eatToEndOfStatement();
Error(L, ".fnstart must precede .personalityindex directive");
return false;
}
if (UC.cantUnwind()) {
Parser.eatToEndOfStatement();
Error(L, ".personalityindex cannot be used with .cantunwind");
UC.emitCantUnwindLocNotes();
return false;
}
if (UC.hasHandlerData()) {
Parser.eatToEndOfStatement();
Error(L, ".personalityindex must precede .handlerdata directive");
UC.emitHandlerDataLocNotes();
return false;
}
if (HasExistingPersonality) {
Parser.eatToEndOfStatement();
Error(L, "multiple personality directives");
UC.emitPersonalityLocNotes();
return false;
@ -10193,19 +10159,16 @@ bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
const MCExpr *IndexExpression;
SMLoc IndexLoc = Parser.getTok().getLoc();
if (Parser.parseExpression(IndexExpression)) {
Parser.eatToEndOfStatement();
return false;
}
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression);
if (!CE) {
Parser.eatToEndOfStatement();
Error(IndexLoc, "index must be a constant number");
return false;
}
if (CE->getValue() < 0 ||
CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX) {
Parser.eatToEndOfStatement();
Error(IndexLoc, "personality routine index should be in range [0-3]");
return false;
}
@ -10219,7 +10182,6 @@ bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
MCAsmParser &Parser = getParser();
if (!UC.hasFnStart()) {
Parser.eatToEndOfStatement();
Error(L, ".fnstart must precede .unwind_raw directives");
return false;
}
@ -10231,14 +10193,12 @@ bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
if (getLexer().is(AsmToken::EndOfStatement) ||
getParser().parseExpression(OffsetExpr)) {
Error(OffsetLoc, "expected expression");
Parser.eatToEndOfStatement();
return false;
}
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
if (!CE) {
Error(OffsetLoc, "offset must be a constant");
Parser.eatToEndOfStatement();
return false;
}
@ -10246,7 +10206,6 @@ bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
if (getLexer().isNot(AsmToken::Comma)) {
Error(getLexer().getLoc(), "expected comma");
Parser.eatToEndOfStatement();
return false;
}
Parser.Lex();
@ -10258,21 +10217,18 @@ bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
SMLoc OpcodeLoc = getLexer().getLoc();
if (getLexer().is(AsmToken::EndOfStatement) || Parser.parseExpression(OE)) {
Error(OpcodeLoc, "expected opcode expression");
Parser.eatToEndOfStatement();
return false;
}
const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE);
if (!OC) {
Error(OpcodeLoc, "opcode value must be a constant");
Parser.eatToEndOfStatement();
return false;
}
const int64_t Opcode = OC->getValue();
if (Opcode & ~0xff) {
Error(OpcodeLoc, "invalid opcode");
Parser.eatToEndOfStatement();
return false;
}
@ -10283,7 +10239,6 @@ bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
if (getLexer().isNot(AsmToken::Comma)) {
Error(getLexer().getLoc(), "unexpected token in directive");
Parser.eatToEndOfStatement();
return false;
}
@ -10303,7 +10258,6 @@ bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
if (getLexer().isNot(AsmToken::Identifier)) {
TokError("expected variable after '.tlsdescseq' directive");
Parser.eatToEndOfStatement();
return false;
}
@ -10314,7 +10268,6 @@ bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
Error(Parser.getTok().getLoc(), "unexpected token");
Parser.eatToEndOfStatement();
return false;
}
@ -10327,12 +10280,10 @@ bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
MCAsmParser &Parser = getParser();
if (!UC.hasFnStart()) {
Parser.eatToEndOfStatement();
Error(L, ".fnstart must precede .movsp directives");
return false;
}
if (UC.getFPReg() != ARM::SP) {
Parser.eatToEndOfStatement();
Error(L, "unexpected .movsp directive");
return false;
}
@ -10340,13 +10291,11 @@ bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
SMLoc SPRegLoc = Parser.getTok().getLoc();
int SPReg = tryParseRegister();
if (SPReg == -1) {
Parser.eatToEndOfStatement();
Error(SPRegLoc, "register expected");
return false;
}
if (SPReg == ARM::SP || SPReg == ARM::PC) {
Parser.eatToEndOfStatement();
Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
return false;
}
@ -10357,7 +10306,6 @@ bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
if (Parser.getTok().isNot(AsmToken::Hash)) {
Error(Parser.getTok().getLoc(), "expected #constant");
Parser.eatToEndOfStatement();
return false;
}
Parser.Lex();
@ -10365,14 +10313,12 @@ bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
const MCExpr *OffsetExpr;
SMLoc OffsetLoc = Parser.getTok().getLoc();
if (Parser.parseExpression(OffsetExpr)) {
Parser.eatToEndOfStatement();
Error(OffsetLoc, "malformed offset expression");
return false;
}
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
if (!CE) {
Parser.eatToEndOfStatement();
Error(OffsetLoc, "offset must be an immediate constant");
return false;
}
@ -10392,7 +10338,6 @@ bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::Identifier)) {
Error(getLexer().getLoc(), "unexpected token");
Parser.eatToEndOfStatement();
return false;
}
@ -10404,7 +10349,6 @@ bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
if (ID == ARM::AK_INVALID) {
Error(ArchLoc, "unknown architecture '" + Arch + "'");
Parser.eatToEndOfStatement();
return false;
}
@ -10412,7 +10356,6 @@ bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
Error(getLexer().getLoc(), "unexpected token");
Parser.eatToEndOfStatement();
}
return false;
@ -10445,13 +10388,11 @@ bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
StringRef Name;
if (Parser.parseIdentifier(Name)) {
TokError("expected identifier after '.thumb_set'");
Parser.eatToEndOfStatement();
return false;
}
if (getLexer().isNot(AsmToken::Comma)) {
TokError("expected comma after name '" + Name + "'");
Parser.eatToEndOfStatement();
return false;
}
Lex();
@ -10515,7 +10456,6 @@ bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
if (getLexer().isNot(AsmToken::Identifier)) {
Error(getLexer().getLoc(), "expected architecture extension name");
Parser.eatToEndOfStatement();
return false;
}
@ -10561,7 +10501,6 @@ bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
}
Error(ExtLoc, "unknown architectural extension: " + Name);
Parser.eatToEndOfStatement();
return false;
}

View File

@ -114,7 +114,7 @@ class HexagonAsmParser : public MCTargetAsmParser {
uint64_t &ErrorInfo, bool MatchingInlineAsm) override;
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind) override;
void OutOfRange(SMLoc IDLoc, long long Val, long long Max);
bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
int processInstruction(MCInst &Inst, OperandVector const &Operands,
SMLoc IDLoc);
@ -637,60 +637,63 @@ bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
uint64_t Err = Check.getError();
if (Err != HexagonMCErrInfo::CHECK_SUCCESS) {
if (HexagonMCErrInfo::CHECK_ERROR_BRANCHES & Err)
Error(IDLoc,
"unconditional branch cannot precede another branch in packet");
return Error(
IDLoc,
"unconditional branch cannot precede another branch in packet");
if (HexagonMCErrInfo::CHECK_ERROR_NEWP & Err ||
HexagonMCErrInfo::CHECK_ERROR_NEWV & Err)
Error(IDLoc, "register `" + R +
"' used with `.new' "
"but not validly modified in the same packet");
return Error(IDLoc, "register `" + R +
"' used with `.new' "
"but not validly modified in the same packet");
if (HexagonMCErrInfo::CHECK_ERROR_REGISTERS & Err)
Error(IDLoc, "register `" + R + "' modified more than once");
return Error(IDLoc, "register `" + R + "' modified more than once");
if (HexagonMCErrInfo::CHECK_ERROR_READONLY & Err)
Error(IDLoc, "cannot write to read-only register `" + R + "'");
return Error(IDLoc, "cannot write to read-only register `" + R + "'");
if (HexagonMCErrInfo::CHECK_ERROR_LOOP & Err)
Error(IDLoc, "loop-setup and some branch instructions "
"cannot be in the same packet");
return Error(IDLoc, "loop-setup and some branch instructions "
"cannot be in the same packet");
if (HexagonMCErrInfo::CHECK_ERROR_ENDLOOP & Err) {
Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
Error(IDLoc, "packet marked with `:endloop" + N + "' " +
return Error(IDLoc,
"packet marked with `:endloop" + N + "' " +
"cannot contain instructions that modify register " +
"`" + R + "'");
}
if (HexagonMCErrInfo::CHECK_ERROR_SOLO & Err)
Error(IDLoc,
"instruction cannot appear in packet with other instructions");
return Error(
IDLoc,
"instruction cannot appear in packet with other instructions");
if (HexagonMCErrInfo::CHECK_ERROR_NOSLOTS & Err)
Error(IDLoc, "too many slots used in packet");
return Error(IDLoc, "too many slots used in packet");
if (Err & HexagonMCErrInfo::CHECK_ERROR_SHUFFLE) {
uint64_t Erm = Check.getShuffleError();
if (HexagonShuffler::SHUFFLE_ERROR_INVALID == Erm)
Error(IDLoc, "invalid instruction packet");
return Error(IDLoc, "invalid instruction packet");
else if (HexagonShuffler::SHUFFLE_ERROR_STORES == Erm)
Error(IDLoc, "invalid instruction packet: too many stores");
return Error(IDLoc, "invalid instruction packet: too many stores");
else if (HexagonShuffler::SHUFFLE_ERROR_LOADS == Erm)
Error(IDLoc, "invalid instruction packet: too many loads");
return Error(IDLoc, "invalid instruction packet: too many loads");
else if (HexagonShuffler::SHUFFLE_ERROR_BRANCHES == Erm)
Error(IDLoc, "too many branches in packet");
return Error(IDLoc, "too many branches in packet");
else if (HexagonShuffler::SHUFFLE_ERROR_NOSLOTS == Erm)
Error(IDLoc, "invalid instruction packet: out of slots");
return Error(IDLoc, "invalid instruction packet: out of slots");
else if (HexagonShuffler::SHUFFLE_ERROR_SLOTS == Erm)
Error(IDLoc, "invalid instruction packet: slot error");
return Error(IDLoc, "invalid instruction packet: slot error");
else if (HexagonShuffler::SHUFFLE_ERROR_ERRATA2 == Erm)
Error(IDLoc, "v60 packet violation");
return Error(IDLoc, "v60 packet violation");
else if (HexagonShuffler::SHUFFLE_ERROR_STORE_LOAD_CONFLICT == Erm)
Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
return Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
else
Error(IDLoc, "unknown error in instruction packet");
return Error(IDLoc, "unknown error in instruction packet");
}
}
@ -1508,7 +1511,8 @@ unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
return Match_InvalidOperand;
}
void HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
std::string errStr;
raw_string_ostream ES(errStr);
ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
@ -1516,7 +1520,7 @@ void HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
ES << "0-" << Max;
else
ES << Max << "-" << (-Max - 1);
Error(IDLoc, ES.str().c_str());
return Parser.printError(IDLoc, ES.str().c_str());
}
int HexagonAsmParser::processInstruction(MCInst &Inst,

View File

@ -924,9 +924,11 @@ public:
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
// FIXME: We ought to do this for -integrated-as without -via-file-asm too.
// FIXME: This should propagate failure up to parseStatement.
if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
"registers");
AsmParser.getParser().printError(
StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
"registers");
}
void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
@ -1860,7 +1862,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
if (MemOffset < -32768 || MemOffset > 32767) {
// Offset can't exceed 16bit value.
expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
return false;
return getParser().hasPendingError();
}
} else if (Op.isExpr()) {
const MCExpr *Expr = Op.getExpr();
@ -1870,11 +1872,11 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
if (SR->getKind() == MCSymbolRefExpr::VK_None) {
// Expand symbol.
expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
return false;
return getParser().hasPendingError();
}
} else if (!isEvaluated(Expr)) {
expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
return false;
return getParser().hasPendingError();
}
}
}
@ -2466,6 +2468,7 @@ bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
Error(IDLoc, "la used to load 64-bit address");
// Continue as if we had 'dla' instead.
Is32BitAddress = false;
return true;
}
// dla requires 64-bit addresses.
@ -2692,9 +2695,9 @@ bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
} else {
if (!isInt<17>(Offset.getImm()))
Error(IDLoc, "branch target out of range");
return Error(IDLoc, "branch target out of range");
if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
Error(IDLoc, "branch to misaligned address");
return Error(IDLoc, "branch to misaligned address");
Inst.clear();
Inst.setOpcode(Mips::BEQ_MM);
Inst.addOperand(MCOperand::createReg(Mips::ZERO));
@ -3302,8 +3305,7 @@ bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
MipsTargetStreamer &TOut = getTargetStreamer();
if (hasMips32r6() || hasMips64r6()) {
Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
return false;
return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
}
warnIfNoMacro(IDLoc);
@ -3380,10 +3382,8 @@ bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer();
if (hasMips32r6() || hasMips64r6()) {
Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
return false;
}
if (hasMips32r6() || hasMips64r6())
return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
const MCOperand &DstRegOp = Inst.getOperand(0);
assert(DstRegOp.isReg() && "expected register operand kind");
@ -4817,12 +4817,10 @@ bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
Parser.Lex();
if (parseOperand(Operands, Name)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
}
if (Parser.getTok().isNot(AsmToken::RParen)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token, expected ')'");
}
Operands.push_back(
@ -4847,12 +4845,10 @@ bool MipsAsmParser::parseBracketSuffix(StringRef Name,
Parser.Lex();
if (parseOperand(Operands, Name)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
}
if (Parser.getTok().isNot(AsmToken::RBrac)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token, expected ']'");
}
Operands.push_back(
@ -4872,7 +4868,6 @@ bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// Check if we have valid mnemonic
if (!mnemonicIsValid(Name, 0)) {
Parser.eatToEndOfStatement();
return Error(NameLoc, "unknown instruction");
}
// First operand in MCInst is instruction mnemonic.
@ -4883,7 +4878,6 @@ bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// Read the first operand.
if (parseOperand(Operands, Name)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
}
if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
@ -4895,7 +4889,6 @@ bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// Parse and remember the operand.
if (parseOperand(Operands, Name)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
}
// Parse bracket and parenthesis suffixes before we iterate
@ -4909,7 +4902,6 @@ bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
}
if (getLexer().isNot(AsmToken::EndOfStatement)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
}
Parser.Lex(); // Consume the EndOfStatement.
@ -4919,9 +4911,7 @@ bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// FIXME: Given that these have the same name, these should both be
// consistent on affecting the Parser.
bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
MCAsmParser &Parser = getParser();
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, ErrorMsg);
}
@ -5422,7 +5412,6 @@ bool MipsAsmParser::eatComma(StringRef ErrorStr) {
MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::Comma)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, ErrorStr);
}
@ -5531,7 +5520,6 @@ bool MipsAsmParser::parseDirectiveCPSetup() {
MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
if (!FuncRegOpnd.isGPRAsmReg()) {
reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
Parser.eatToEndOfStatement();
return false;
}
@ -5550,7 +5538,6 @@ bool MipsAsmParser::parseDirectiveCPSetup() {
if (Parser.parseExpression(OffsetExpr) ||
!OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
reportParseError(ExprLoc, "expected save register or stack offset");
Parser.eatToEndOfStatement();
return false;
}
@ -5560,7 +5547,6 @@ bool MipsAsmParser::parseDirectiveCPSetup() {
MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
if (!SaveOpnd.isGPRAsmReg()) {
reportParseError(SaveOpnd.getStartLoc(), "invalid register");
Parser.eatToEndOfStatement();
return false;
}
Save = SaveOpnd.getGPR32Reg();
@ -5848,9 +5834,8 @@ bool MipsAsmParser::parseDirectiveOption() {
AsmToken Tok = Parser.getTok();
// At the moment only identifiers are supported.
if (Tok.isNot(AsmToken::Identifier)) {
Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
Parser.eatToEndOfStatement();
return false;
return Error(Parser.getTok().getLoc(),
"unexpected token, expected identifier");
}
StringRef Option = Tok.getIdentifier();
@ -5862,9 +5847,8 @@ bool MipsAsmParser::parseDirectiveOption() {
getTargetStreamer().emitDirectiveOptionPic0();
Parser.Lex();
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
Error(Parser.getTok().getLoc(),
"unexpected token, expected end of statement");
Parser.eatToEndOfStatement();
return Error(Parser.getTok().getLoc(),
"unexpected token, expected end of statement");
}
return false;
}
@ -5876,9 +5860,8 @@ bool MipsAsmParser::parseDirectiveOption() {
getTargetStreamer().emitDirectiveOptionPic2();
Parser.Lex();
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
Error(Parser.getTok().getLoc(),
"unexpected token, expected end of statement");
Parser.eatToEndOfStatement();
return Error(Parser.getTok().getLoc(),
"unexpected token, expected end of statement");
}
return false;
}
@ -5969,8 +5952,7 @@ bool MipsAsmParser::parseDirectiveModule() {
return false; // parseDirectiveModule has finished successfully.
} else if (Option == "nooddspreg") {
if (!isABI_O32()) {
Error(L, "'.module nooddspreg' requires the O32 ABI");
return false;
return Error(L, "'.module nooddspreg' requires the O32 ABI");
}
setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
@ -6431,8 +6413,6 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
Error(Parser.getTok().getLoc(),
"unexpected token, expected end of statement");
// Clear line
Parser.eatToEndOfStatement();
}
return false;
}

View File

@ -84,7 +84,7 @@ class SparcAsmParser : public MCTargetAsmParser {
return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
}
void expandSET(MCInst &Inst, SMLoc IDLoc,
bool expandSET(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
public:
@ -466,7 +466,7 @@ public:
} // end namespace
void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
MCOperand MCRegOp = Inst.getOperand(0);
MCOperand MCValOp = Inst.getOperand(1);
@ -479,8 +479,8 @@ void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
// Allow either a signed or unsigned 32-bit immediate.
if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
Error(IDLoc, "set: argument must be between -2147483648 and 4294967295");
return;
return Error(IDLoc,
"set: argument must be between -2147483648 and 4294967295");
}
// If the value was expressed as a large unsigned number, that's ok.
@ -537,6 +537,7 @@ void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
TmpInst.addOperand(MCOperand::createExpr(Expr));
Instructions.push_back(TmpInst);
}
return false;
}
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
@ -556,7 +557,8 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Instructions.push_back(Inst);
break;
case SP::SET:
expandSET(Inst, IDLoc, Instructions);
if (expandSET(Inst, IDLoc, Instructions))
return true;
break;
}
@ -626,13 +628,11 @@ bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
if (getLexer().is(AsmToken::Comma)) {
if (parseBranchModifiers(Operands) != MatchOperand_Success) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token");
}
}
if (parseOperand(Operands, Name) != MatchOperand_Success) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token");
}
@ -645,14 +645,12 @@ bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
// Parse and remember the operand.
if (parseOperand(Operands, Name) != MatchOperand_Success) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token");
}
}
}
if (getLexer().isNot(AsmToken::EndOfStatement)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token");
}
Parser.Lex(); // Consume the EndOfStatement.

View File

@ -959,7 +959,6 @@ bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
if (parseOperand(Operands, Name)) {
Parser.eatToEndOfStatement();
return true;
}
@ -967,13 +966,11 @@ bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
while (getLexer().is(AsmToken::Comma)) {
Parser.Lex();
if (parseOperand(Operands, Name)) {
Parser.eatToEndOfStatement();
return true;
}
}
if (getLexer().isNot(AsmToken::EndOfStatement)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
}
}

View File

@ -659,20 +659,15 @@ private:
}
};
bool Error(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None,
bool Error(SMLoc L, const Twine &Msg, SMRange Range = None,
bool MatchingInlineAsm = false) {
MCAsmParser &Parser = getParser();
if (MatchingInlineAsm) return true;
return Parser.Error(L, Msg, Ranges);
}
bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None,
bool MatchingInlineAsm = false) {
MCAsmParser &Parser = getParser();
Parser.eatToEndOfStatement();
return Error(L, Msg, Ranges, MatchingInlineAsm);
if (MatchingInlineAsm) {
if (!getLexer().isAtStartOfStatement())
Parser.eatToEndOfStatement();
return false;
}
return Parser.Error(L, Msg, Range);
}
std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
@ -1895,13 +1890,11 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
if(getLexer().is(AsmToken::Integer)) {
// Parse memory broadcasting ({1to<NUM>}).
if (getLexer().getTok().getIntVal() != 1)
return !ErrorAndEatStatement(getLexer().getLoc(),
"Expected 1to<NUM> at this point");
return !TokError("Expected 1to<NUM> at this point");
Parser.Lex(); // Eat "1" of 1to8
if (!getLexer().is(AsmToken::Identifier) ||
!getLexer().getTok().getIdentifier().startswith("to"))
return !ErrorAndEatStatement(getLexer().getLoc(),
"Expected 1to<NUM> at this point");
return !TokError("Expected 1to<NUM> at this point");
// Recognize only reasonable suffixes.
const char *BroadcastPrimitive =
StringSwitch<const char*>(getLexer().getTok().getIdentifier())
@ -1911,12 +1904,10 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
.Case("to16", "{1to16}")
.Default(nullptr);
if (!BroadcastPrimitive)
return !ErrorAndEatStatement(getLexer().getLoc(),
"Invalid memory broadcast primitive.");
return !TokError("Invalid memory broadcast primitive.");
Parser.Lex(); // Eat "toN" of 1toN
if (!getLexer().is(AsmToken::RCurly))
return !ErrorAndEatStatement(getLexer().getLoc(),
"Expected } at this point");
return !TokError("Expected } at this point");
Parser.Lex(); // Eat "}"
Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
consumedToken));
@ -1929,8 +1920,7 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
Operands.push_back(std::move(Op));
if (!getLexer().is(AsmToken::RCurly))
return !ErrorAndEatStatement(getLexer().getLoc(),
"Expected } at this point");
return !TokError("Expected } at this point");
Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
// Parse "zeroing non-masked" semantic {z}
@ -1938,12 +1928,10 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
if (!getLexer().is(AsmToken::Identifier) ||
getLexer().getTok().getIdentifier() != "z")
return !ErrorAndEatStatement(getLexer().getLoc(),
"Expected z at this point");
return !TokError("Expected z at this point");
Parser.Lex(); // Eat the z
if (!getLexer().is(AsmToken::RCurly))
return !ErrorAndEatStatement(getLexer().getLoc(),
"Expected } at this point");
return !TokError("Expected } at this point");
Parser.Lex(); // Eat the }
}
}
@ -2287,7 +2275,6 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
if (!HandleAVX512Operand(Operands, *Operands.back()))
return true;
} else {
Parser.eatToEndOfStatement();
return true;
}
// check for comma and eat it
@ -2303,8 +2290,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
isParsingIntelSyntax() && isParsingInlineAsm() &&
(getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
return ErrorAndEatStatement(getLexer().getLoc(),
"unexpected token in argument list");
return TokError("unexpected token in argument list");
}
// Consume the EndOfStatement or the prefix separator Slash
@ -2570,7 +2556,6 @@ void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
bool MatchingInlineAsm) {
assert(ErrorInfo && "Unknown missing feature!");
ArrayRef<SMRange> EmptyRanges = None;
SmallString<126> Msg;
raw_svector_ostream OS(Msg);
OS << "instruction requires:";
@ -2580,7 +2565,7 @@ bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
Mask <<= 1;
}
return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
}
bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
@ -2591,7 +2576,7 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
assert(!Operands.empty() && "Unexpect empty operand list!");
X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
assert(Op.isToken() && "Leading operand should always be a mnemonic!");
ArrayRef<SMRange> EmptyRanges = None;
SMRange EmptyRange = None;
// First, handle aliases that expand to multiple instructions.
MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
@ -2698,7 +2683,7 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
OS << "'" << Base << MatchChars[i] << "'";
}
OS << ")";
Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
return true;
}
@ -2708,17 +2693,15 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
// mnemonic was invalid.
if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
if (!WasOriginallyInvalidOperand) {
SMRange OpRange = Op.getLocRange();
ArrayRef<SMRange> Ranges = MatchingInlineAsm ? EmptyRanges : OpRange;
return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
Ranges, MatchingInlineAsm);
Op.getLocRange(), MatchingInlineAsm);
}
// Recover location info for the operand if we know which was the problem.
if (ErrorInfo != ~0ULL) {
if (ErrorInfo >= Operands.size())
return Error(IDLoc, "too few operands for instruction",
EmptyRanges, MatchingInlineAsm);
return Error(IDLoc, "too few operands for instruction", EmptyRange,
MatchingInlineAsm);
X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
if (Operand.getStartLoc().isValid()) {
@ -2728,7 +2711,7 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
}
}
return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
return Error(IDLoc, "invalid operand for instruction", EmptyRange,
MatchingInlineAsm);
}
@ -2745,13 +2728,13 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
// operand failure.
if (std::count(std::begin(Match), std::end(Match),
Match_InvalidOperand) == 1) {
return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
return Error(IDLoc, "invalid operand for instruction", EmptyRange,
MatchingInlineAsm);
}
// If all of these were an outright failure, report it in a useless way.
Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
EmptyRanges, MatchingInlineAsm);
EmptyRange, MatchingInlineAsm);
return true;
}
@ -2764,7 +2747,7 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
assert(Op.isToken() && "Leading operand should always be a mnemonic!");
StringRef Mnemonic = Op.getToken();
ArrayRef<SMRange> EmptyRanges = None;
SMRange EmptyRange = None;
// First, handle aliases that expand to multiple instructions.
MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
@ -2836,10 +2819,8 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
// If it's a bad mnemonic, all results will be the same.
if (Match.back() == Match_MnemonicFail) {
ArrayRef<SMRange> Ranges =
MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
Ranges, MatchingInlineAsm);
Op.getLocRange(), MatchingInlineAsm);
}
// If exactly one matched, then we treat that as a successful match (and the
@ -2862,11 +2843,9 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
} else if (NumSuccessfulMatches > 1) {
assert(UnsizedMemOp &&
"multiple matches only possible with unsized memory operands");
SMRange OpRange = UnsizedMemOp->getLocRange();
ArrayRef<SMRange> Ranges = MatchingInlineAsm ? EmptyRanges : OpRange;
return Error(UnsizedMemOp->getStartLoc(),
"ambiguous operand size for instruction '" + Mnemonic + "\'",
Ranges, MatchingInlineAsm);
UnsizedMemOp->getLocRange(), MatchingInlineAsm);
}
// If one instruction matched with a missing feature, report this as a
@ -2882,12 +2861,12 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
// operand failure.
if (std::count(std::begin(Match), std::end(Match),
Match_InvalidOperand) == 1) {
return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
return Error(IDLoc, "invalid operand for instruction", EmptyRange,
MatchingInlineAsm);
}
// If all of these were an outright failure, report it in a useless way.
return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
MatchingInlineAsm);
}

View File

@ -21,47 +21,21 @@
// CHECK: sqrdmlsh v0.8h, v1.8h, v2.8h // encoding: [0x20,0x8c,0x42,0x6e]
sqrdmlah v0.2h, v1.2h, v2.2h
// CHECK-ERROR: [[@LINE-1]]:12: error: invalid operand for instruction
sqrdmlsh v0.2h, v1.2h, v2.2h
// CHECK-ERROR: [[@LINE-1]]:12: error: invalid operand for instruction
sqrdmlah v0.8s, v1.8s, v2.8s
// CHECK-ERROR: [[@LINE-1]]:12: error: invalid vector kind qualifier
// CHECK-ERROR: [[@LINE-2]]:19: error: invalid vector kind qualifier
// CHECK-ERROR: [[@LINE-3]]:26: error: invalid vector kind qualifier
sqrdmlsh v0.8s, v1.8s, v2.8s
// CHECK-ERROR: [[@LINE-1]]:12: error: invalid vector kind qualifier
// CHECK-ERROR: [[@LINE-2]]:19: error: invalid vector kind qualifier
// CHECK-ERROR: [[@LINE-3]]:26: error: invalid vector kind qualifier
sqrdmlah v0.2s, v1.4h, v2.8h
// CHECK-ERROR: [[@LINE-1]]:19: error: invalid operand for instruction
sqrdmlsh v0.4s, v1.8h, v2.2s
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: sqrdmlah v0.2h, v1.2h, v2.2h
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: sqrdmlsh v0.2h, v1.2h, v2.2h
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid vector kind qualifier
// CHECK-ERROR: sqrdmlah v0.8s, v1.8s, v2.8s
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid vector kind qualifier
// CHECK-ERROR: sqrdmlah v0.8s, v1.8s, v2.8s
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid vector kind qualifier
// CHECK-ERROR: sqrdmlah v0.8s, v1.8s, v2.8s
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: sqrdmlah v0.8s, v1.8s, v2.8s
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid vector kind qualifier
// CHECK-ERROR: sqrdmlsh v0.8s, v1.8s, v2.8s
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid vector kind qualifier
// CHECK-ERROR: sqrdmlsh v0.8s, v1.8s, v2.8s
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid vector kind qualifier
// CHECK-ERROR: sqrdmlsh v0.8s, v1.8s, v2.8s
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: sqrdmlsh v0.8s, v1.8s, v2.8s
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: sqrdmlah v0.2s, v1.4h, v2.8h
// CHECK-ERROR: ^
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: sqrdmlsh v0.4s, v1.8h, v2.2s
// CHECK-ERROR: ^
// CHECK-ERROR: [[@LINE-1]]:19: error: invalid operand for instruction
//AdvSIMD RDMA scalar
sqrdmlah h0, h1, h2

View File

@ -17,3 +17,5 @@ diagnostics:
.inst 0x5e104020 0x5e104020
// CHECK-ERROR: unexpected token in directive
// CHECK-ERROR-NOT: unexpected token at start of statement

File diff suppressed because it is too large Load Diff