mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Temporarily Revert "[MC] Defer asm errors to post-statement failure" as it's causing errors on the sanitizer bots.
This reverts commit r281249. llvm-svn: 281280
This commit is contained in:
parent
7881c692f8
commit
cefa1ba100
@ -144,7 +144,6 @@ protected: // Can only create subclasses.
|
||||
const char *TokStart;
|
||||
bool SkipSpace;
|
||||
bool AllowAtInIdentifier;
|
||||
bool IsAtStartOfStatement;
|
||||
|
||||
MCAsmLexer();
|
||||
|
||||
@ -164,8 +163,6 @@ 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.
|
||||
@ -177,12 +174,9 @@ 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.
|
||||
|
@ -11,9 +11,7 @@
|
||||
#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"
|
||||
|
||||
@ -69,12 +67,6 @@ 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;
|
||||
@ -86,11 +78,6 @@ private:
|
||||
protected: // Can only create subclasses.
|
||||
MCAsmParser();
|
||||
|
||||
bool HadError;
|
||||
|
||||
SmallVector<MCPendingError, 1> PendingErrors;
|
||||
/// Flag tracking whether any errors have been encountered.
|
||||
|
||||
public:
|
||||
virtual ~MCAsmParser();
|
||||
|
||||
@ -135,36 +122,21 @@ 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, SMRange Range = None) = 0;
|
||||
virtual void Note(SMLoc L, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = 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, 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);
|
||||
virtual bool Warning(SMLoc L, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = None) = 0;
|
||||
|
||||
/// \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 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;
|
||||
}
|
||||
virtual bool Error(SMLoc L, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = None) = 0;
|
||||
|
||||
/// \brief Get the next AsmToken in the stream, possibly handling file
|
||||
/// inclusion first.
|
||||
@ -174,7 +146,7 @@ public:
|
||||
const AsmToken &getTok() const;
|
||||
|
||||
/// \brief Report an error at the current lexer location.
|
||||
bool TokError(const Twine &Msg, SMRange Range = None);
|
||||
bool TokError(const Twine &Msg, ArrayRef<SMRange> Ranges = None);
|
||||
|
||||
bool parseTokenLoc(SMLoc &Loc);
|
||||
bool parseToken(AsmToken::TokenKind T, const Twine &Msg);
|
||||
|
@ -15,7 +15,6 @@
|
||||
#ifndef LLVM_SUPPORT_SMLOC_H
|
||||
#define LLVM_SUPPORT_SMLOC_H
|
||||
|
||||
#include "llvm/ADT/None.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
@ -51,7 +50,6 @@ 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!");
|
||||
|
@ -178,6 +178,9 @@ 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;
|
||||
@ -244,9 +247,12 @@ public:
|
||||
AssemblerDialect = i;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
const AsmToken &Lex() override;
|
||||
|
||||
@ -331,8 +337,7 @@ private:
|
||||
|
||||
void printMacroInstantiations();
|
||||
void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
|
||||
SMRange Range = None) const {
|
||||
ArrayRef<SMRange> Ranges(Range);
|
||||
ArrayRef<SMRange> Ranges = None) const {
|
||||
SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
|
||||
}
|
||||
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
|
||||
@ -560,8 +565,8 @@ 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), CppHashInfo(), AssemblerDialect(~0U),
|
||||
IsDarwin(false), ParsingInlineAsm(false) {
|
||||
MacrosEnabledFlag(true), HadError(false), CppHashInfo(),
|
||||
AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
|
||||
// Save the old handler.
|
||||
SavedDiagHandler = SrcMgr.getDiagHandler();
|
||||
SavedDiagContext = SrcMgr.getDiagContext();
|
||||
@ -604,25 +609,24 @@ void AsmParser::printMacroInstantiations() {
|
||||
"while in macro instantiation");
|
||||
}
|
||||
|
||||
void AsmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
|
||||
printPendingErrors();
|
||||
printMessage(L, SourceMgr::DK_Note, Msg, Range);
|
||||
void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
|
||||
printMessage(L, SourceMgr::DK_Note, Msg, Ranges);
|
||||
printMacroInstantiations();
|
||||
}
|
||||
|
||||
bool AsmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
|
||||
bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
|
||||
if(getTargetParser().getTargetOptions().MCNoWarn)
|
||||
return false;
|
||||
if (getTargetParser().getTargetOptions().MCFatalWarnings)
|
||||
return Error(L, Msg, Range);
|
||||
printMessage(L, SourceMgr::DK_Warning, Msg, Range);
|
||||
return Error(L, Msg, Ranges);
|
||||
printMessage(L, SourceMgr::DK_Warning, Msg, Ranges);
|
||||
printMacroInstantiations();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AsmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
|
||||
bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
|
||||
HadError = true;
|
||||
printMessage(L, SourceMgr::DK_Error, Msg, Range);
|
||||
printMessage(L, SourceMgr::DK_Error, Msg, Ranges);
|
||||
printMacroInstantiations();
|
||||
return true;
|
||||
}
|
||||
@ -727,37 +731,31 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
|
||||
if (!parseStatement(Info, nullptr))
|
||||
continue;
|
||||
|
||||
// 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)) {
|
||||
// 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)) {
|
||||
Lex();
|
||||
}
|
||||
|
||||
// parseStatement returned true so may need to emit an error.
|
||||
printPendingErrors();
|
||||
|
||||
// Skipping to the next line if needed.
|
||||
if (!getLexer().isAtStartOfStatement())
|
||||
// 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();
|
||||
}
|
||||
|
||||
// All errors should have been emitted.
|
||||
assert(!hasPendingError() && "unexpected error from parseStatement");
|
||||
|
||||
getTargetParser().flushPendingInstructions(getStreamer());
|
||||
|
||||
if (TheCondState.TheCond != StartingCondState.TheCond ||
|
||||
TheCondState.Ignore != StartingCondState.Ignore)
|
||||
printError(getTok().getLoc(), "unmatched .ifs or .elses");
|
||||
return TokError("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)
|
||||
printError(getTok().getLoc(), "unassigned file number: " +
|
||||
Twine(Index) +
|
||||
TokError("unassigned file number: " + Twine(Index) +
|
||||
" for .file directives");
|
||||
++Index;
|
||||
}
|
||||
@ -778,7 +776,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.
|
||||
printError(getTok().getLoc(), "assembler local symbol '" +
|
||||
HadError |=
|
||||
Error(getTok().getLoc(), "assembler local symbol '" +
|
||||
Sym->getName() + "' not defined");
|
||||
}
|
||||
}
|
||||
@ -790,7 +789,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);
|
||||
printError(std::get<0>(LocSym), "directional label undefined");
|
||||
HadError |= Error(std::get<0>(LocSym), "directional label undefined");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -805,8 +804,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
|
||||
|
||||
void AsmParser::checkForValidSection() {
|
||||
if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) {
|
||||
printError(getTok().getLoc(),
|
||||
"expected section directive before assembly directive");
|
||||
TokError("expected section directive before assembly directive");
|
||||
Out.InitSections(false);
|
||||
}
|
||||
}
|
||||
@ -1437,7 +1435,6 @@ 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();
|
||||
@ -1470,19 +1467,15 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
||||
if (Lexer.is(AsmToken::Integer)) {
|
||||
LocalLabelVal = getTok().getIntVal();
|
||||
if (LocalLabelVal < 0) {
|
||||
if (!TheCondState.Ignore) {
|
||||
Lex(); // always eat a token
|
||||
return Error(IDLoc, "unexpected token at start of statement");
|
||||
}
|
||||
if (!TheCondState.Ignore)
|
||||
return TokError("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) {
|
||||
Lex(); // always eat a token
|
||||
return Error(IDLoc, "unexpected token at start of statement");
|
||||
}
|
||||
if (!TheCondState.Ignore)
|
||||
return TokError("unexpected token at start of statement");
|
||||
}
|
||||
}
|
||||
} else if (Lexer.is(AsmToken::Dot)) {
|
||||
@ -1499,10 +1492,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
||||
Lex();
|
||||
IDVal = "}";
|
||||
} else if (parseIdentifier(IDVal)) {
|
||||
if (!TheCondState.Ignore) {
|
||||
Lex(); // always eat a token
|
||||
return Error(IDLoc, "unexpected token at start of statement");
|
||||
}
|
||||
if (!TheCondState.Ignore)
|
||||
return TokError("unexpected token at start of statement");
|
||||
IDVal = "";
|
||||
}
|
||||
|
||||
@ -1664,20 +1655,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
||||
|
||||
getTargetParser().flushPendingInstructions(getStreamer());
|
||||
|
||||
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())
|
||||
// First query the target-specific parser. It will return 'true' if it
|
||||
// isn't interested in this directive.
|
||||
if (!getTargetParser().ParseDirective(ID))
|
||||
return false;
|
||||
|
||||
// Next, check the extension directive map to see if any extension has
|
||||
@ -1932,9 +1912,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
||||
// Canonicalize the opcode to lower case.
|
||||
std::string OpcodeStr = IDVal.lower();
|
||||
ParseInstructionInfo IInfo(Info.AsmRewrites);
|
||||
bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
|
||||
bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
|
||||
Info.ParsedOperands);
|
||||
Info.ParseError = ParseHadError;
|
||||
Info.ParseError = HadError;
|
||||
|
||||
// Dump the parsed representation, if requested.
|
||||
if (getShowParsedOperands()) {
|
||||
@ -1951,13 +1931,9 @@ 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 (!ParseHadError && getContext().getGenDwarfForAssembly() &&
|
||||
if (!HadError && getContext().getGenDwarfForAssembly() &&
|
||||
getContext().getGenDwarfSectionSyms().count(
|
||||
getStreamer().getCurrentSection().first)) {
|
||||
unsigned Line;
|
||||
@ -1999,13 +1975,15 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
||||
}
|
||||
|
||||
// If parsing succeeded, match the instruction.
|
||||
if (!ParseHadError) {
|
||||
if (!HadError) {
|
||||
uint64_t ErrorInfo;
|
||||
if (getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
|
||||
getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
|
||||
Info.ParsedOperands, Out,
|
||||
ErrorInfo, ParsingInlineAsm))
|
||||
return true;
|
||||
ErrorInfo, ParsingInlineAsm);
|
||||
}
|
||||
|
||||
// Don't skip the rest of the line, the instruction parser is responsible for
|
||||
// that.
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2041,7 +2019,6 @@ 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);
|
||||
|
||||
@ -2376,19 +2353,27 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
|
||||
MCAsmMacroParameter FA;
|
||||
|
||||
if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
|
||||
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 (parseIdentifier(FA.Name)) {
|
||||
Error(IDLoc, "invalid argument identifier for formal argument");
|
||||
eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Lexer.isNot(AsmToken::Equal)) {
|
||||
TokError("expected '=' after formal parameter identifier");
|
||||
eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
Lex();
|
||||
|
||||
NamedParametersFound = true;
|
||||
}
|
||||
|
||||
if (NamedParametersFound && FA.Name.empty())
|
||||
return Error(IDLoc, "cannot mix positional and keyword arguments");
|
||||
if (NamedParametersFound && FA.Name.empty()) {
|
||||
Error(IDLoc, "cannot mix positional and keyword arguments");
|
||||
eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vararg = HasVararg && Parameter == (NParameters - 1);
|
||||
if (parseMacroArgument(FA.Value, Vararg))
|
||||
@ -2403,8 +2388,10 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
|
||||
|
||||
if (FAI >= NParameters) {
|
||||
assert(M && "expected macro to be defined");
|
||||
return Error(IDLoc, "parameter named '" + FA.Name +
|
||||
"' does not exist for macro '" + M->Name + "'");
|
||||
Error(IDLoc,
|
||||
"parameter named '" + FA.Name + "' does not exist for macro '" +
|
||||
M->Name + "'");
|
||||
return true;
|
||||
}
|
||||
PI = FAI;
|
||||
}
|
||||
@ -3005,14 +2992,11 @@ 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) {
|
||||
ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
|
||||
Error(AlignmentLoc, "invalid alignment value");
|
||||
Alignment = 31;
|
||||
}
|
||||
|
||||
@ -3024,14 +3008,13 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
|
||||
if (Alignment == 0)
|
||||
Alignment = 1;
|
||||
if (!isPowerOf2_64(Alignment))
|
||||
ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
|
||||
Error(AlignmentLoc, "alignment must be a power of 2");
|
||||
}
|
||||
|
||||
// Diagnose non-sensical max bytes to align.
|
||||
if (MaxBytesLoc.isValid()) {
|
||||
if (MaxBytesToFill < 1) {
|
||||
ReturnVal |= Error(MaxBytesLoc,
|
||||
"alignment directive can never be satisfied in this "
|
||||
Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
|
||||
"many bytes, ignoring maximum bytes expression");
|
||||
MaxBytesToFill = 0;
|
||||
}
|
||||
@ -3057,7 +3040,7 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
|
||||
MaxBytesToFill);
|
||||
}
|
||||
|
||||
return ReturnVal;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveFile
|
||||
@ -3111,7 +3094,7 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
|
||||
getContext().setGenDwarfForAssembly(false);
|
||||
else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
|
||||
0)
|
||||
return Error(FileNumberLoc, "file number already allocated");
|
||||
Error(FileNumberLoc, "file number already allocated");
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -3363,7 +3346,7 @@ bool AsmParser::parseDirectiveCVInlineSiteId() {
|
||||
|
||||
if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
|
||||
IALine, IACol, FunctionIdLoc))
|
||||
return Error(FunctionIdLoc, "function id already allocated");
|
||||
Error(FunctionIdLoc, "function id already allocated");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -4357,9 +4340,9 @@ bool AsmParser::parseDirectiveAbort() {
|
||||
return true;
|
||||
|
||||
if (Str.empty())
|
||||
return Error(Loc, ".abort detected. Assembly stopping.");
|
||||
Error(Loc, ".abort detected. Assembly stopping.");
|
||||
else
|
||||
return Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
|
||||
Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
|
||||
// FIXME: Actually abort assembly here.
|
||||
|
||||
return false;
|
||||
@ -4504,8 +4487,11 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
|
||||
bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
|
||||
if (Lexer.isNot(AsmToken::String)) {
|
||||
if (ExpectEqual)
|
||||
return TokError("expected string parameter for '.ifeqs' directive");
|
||||
return TokError("expected string parameter for '.ifnes' directive");
|
||||
TokError("expected string parameter for '.ifeqs' directive");
|
||||
else
|
||||
TokError("expected string parameter for '.ifnes' directive");
|
||||
eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
StringRef String1 = getTok().getStringContents();
|
||||
@ -4513,17 +4499,22 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
|
||||
|
||||
if (Lexer.isNot(AsmToken::Comma)) {
|
||||
if (ExpectEqual)
|
||||
return TokError(
|
||||
"expected comma after first string for '.ifeqs' directive");
|
||||
return TokError("expected comma after first string for '.ifnes' directive");
|
||||
TokError("expected comma after first string for '.ifeqs' directive");
|
||||
else
|
||||
TokError("expected comma after first string for '.ifnes' directive");
|
||||
eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
Lex();
|
||||
|
||||
if (Lexer.isNot(AsmToken::String)) {
|
||||
if (ExpectEqual)
|
||||
return TokError("expected string parameter for '.ifeqs' directive");
|
||||
return TokError("expected string parameter for '.ifnes' directive");
|
||||
TokError("expected string parameter for '.ifeqs' directive");
|
||||
else
|
||||
TokError("expected string parameter for '.ifnes' directive");
|
||||
eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
StringRef String2 = getTok().getStringContents();
|
||||
@ -4568,8 +4559,8 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
|
||||
bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
|
||||
if (TheCondState.TheCond != AsmCond::IfCond &&
|
||||
TheCondState.TheCond != AsmCond::ElseIfCond)
|
||||
return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
|
||||
" .if or an .elseif");
|
||||
Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
|
||||
" an .elseif");
|
||||
TheCondState.TheCond = AsmCond::ElseIfCond;
|
||||
|
||||
bool LastIgnoreState = false;
|
||||
@ -4603,8 +4594,8 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
|
||||
|
||||
if (TheCondState.TheCond != AsmCond::IfCond &&
|
||||
TheCondState.TheCond != AsmCond::ElseIfCond)
|
||||
return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
|
||||
" an .if or an .elseif");
|
||||
Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
|
||||
".elseif");
|
||||
TheCondState.TheCond = AsmCond::ElseCond;
|
||||
bool LastIgnoreState = false;
|
||||
if (!TheCondStack.empty())
|
||||
@ -4646,14 +4637,18 @@ 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))
|
||||
return TokError(".error argument must be a string");
|
||||
if (Lexer.isNot(AsmToken::String)) {
|
||||
TokError(".error argument must be a string");
|
||||
eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
Message = getTok().getStringContents();
|
||||
Lex();
|
||||
}
|
||||
|
||||
return Error(L, Message);
|
||||
Error(L, Message);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// parseDirectiveWarning
|
||||
@ -4668,14 +4663,18 @@ bool AsmParser::parseDirectiveWarning(SMLoc L) {
|
||||
|
||||
StringRef Message = ".warning directive invoked in source file";
|
||||
if (Lexer.isNot(AsmToken::EndOfStatement)) {
|
||||
if (Lexer.isNot(AsmToken::String))
|
||||
return TokError(".warning argument must be a string");
|
||||
if (Lexer.isNot(AsmToken::String)) {
|
||||
TokError(".warning argument must be a string");
|
||||
eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
Message = getTok().getStringContents();
|
||||
Lex();
|
||||
}
|
||||
|
||||
return Warning(L, Message);
|
||||
Warning(L, Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveEndIf
|
||||
@ -4686,8 +4685,8 @@ bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
|
||||
return true;
|
||||
|
||||
if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
|
||||
return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
|
||||
"an .if or .else");
|
||||
Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
|
||||
".else");
|
||||
if (!TheCondStack.empty()) {
|
||||
TheCondState = TheCondStack.back();
|
||||
TheCondStack.pop_back();
|
||||
@ -4839,7 +4838,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
|
||||
while (true) {
|
||||
// Check whether we have reached the end of the file.
|
||||
if (getLexer().is(AsmToken::Eof)) {
|
||||
printError(DirectiveLoc, "no matching '.endr' in definition");
|
||||
Error(DirectiveLoc, "no matching '.endr' in definition");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -4856,8 +4855,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
|
||||
EndToken = getTok();
|
||||
Lex();
|
||||
if (Lexer.isNot(AsmToken::EndOfStatement)) {
|
||||
printError(getTok().getLoc(),
|
||||
"unexpected token in '.endr' directive");
|
||||
TokError("unexpected token in '.endr' directive");
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
@ -4907,6 +4905,7 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
|
||||
|
||||
int64_t Count;
|
||||
if (!CountExpr->evaluateAsAbsolute(Count)) {
|
||||
eatToEndOfStatement();
|
||||
return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
|
||||
}
|
||||
|
||||
@ -5109,16 +5108,11 @@ bool AsmParser::parseMSInlineAsm(
|
||||
continue;
|
||||
|
||||
ParseStatementInfo Info(&AsmStrRewrites);
|
||||
bool StatementErr = parseStatement(Info, &SI);
|
||||
|
||||
if (StatementErr || Info.ParseError) {
|
||||
// Emit pending errors if any exist.
|
||||
printPendingErrors();
|
||||
if (parseStatement(Info, &SI))
|
||||
return true;
|
||||
}
|
||||
|
||||
// No pending error should exist here.
|
||||
assert(!hasPendingError() && "unexpected error from parseStatement");
|
||||
if (Info.ParseError)
|
||||
return true;
|
||||
|
||||
if (Info.Opcode == ~0U)
|
||||
continue;
|
||||
@ -5345,6 +5339,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
|
||||
|
||||
if (Parser.parseExpression(Value)) {
|
||||
Parser.TokError("missing expression");
|
||||
Parser.eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,7 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
MCAsmLexer::MCAsmLexer()
|
||||
: TokStart(nullptr), SkipSpace(true), IsAtStartOfStatement(true) {
|
||||
MCAsmLexer::MCAsmLexer() : TokStart(nullptr), SkipSpace(true) {
|
||||
CurTok.emplace_back(AsmToken::Space, StringRef());
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,8 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
MCAsmParser::MCAsmParser()
|
||||
: TargetParser(nullptr), ShowParsedOperands(0), PendingErrors() {}
|
||||
MCAsmParser::MCAsmParser() : TargetParser(nullptr), ShowParsedOperands(0) {
|
||||
}
|
||||
|
||||
MCAsmParser::~MCAsmParser() {
|
||||
}
|
||||
@ -84,18 +84,8 @@ bool MCAsmParser::check(bool P, SMLoc Loc, const Twine &Msg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
bool MCAsmParser::TokError(const Twine &Msg, ArrayRef<SMRange> Ranges) {
|
||||
Error(getLexer().getLoc(), Msg, Ranges);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2702,6 +2702,7 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
|
||||
}
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
Parser.eatToEndOfStatement();
|
||||
return TokError("unexpected token in argument list");
|
||||
}
|
||||
|
||||
@ -3321,6 +3322,8 @@ 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;
|
||||
}
|
||||
|
||||
@ -3377,6 +3380,7 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
// Read the first operand.
|
||||
if (parseOperand(Operands, false, false)) {
|
||||
Parser.eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3389,6 +3393,7 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
|
||||
(N == 3 && condCodeThirdOperand) ||
|
||||
(N == 2 && condCodeSecondOperand),
|
||||
condCodeSecondOperand || condCodeThirdOperand)) {
|
||||
Parser.eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3420,6 +3425,7 @@ 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");
|
||||
}
|
||||
|
||||
@ -4177,10 +4183,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||
if (IDVal == ".inst")
|
||||
return parseDirectiveInst(Loc);
|
||||
}
|
||||
if (IDVal == MCLOHDirectiveName())
|
||||
return parseDirectiveLOH(IDVal, Loc);
|
||||
|
||||
return true;
|
||||
return parseDirectiveLOH(IDVal, Loc);
|
||||
}
|
||||
|
||||
static const struct {
|
||||
@ -4341,6 +4345,7 @@ 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;
|
||||
}
|
||||
@ -4398,6 +4403,8 @@ 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))
|
||||
@ -4405,10 +4412,8 @@ 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)) {
|
||||
TokError("invalid numeric identifier in directive");
|
||||
return false;
|
||||
}
|
||||
if (Id <= -1U && !isValidMCLOHType(Id))
|
||||
return TokError("invalid numeric identifier in directive");
|
||||
Kind = (MCLOHType)Id;
|
||||
} else {
|
||||
StringRef Name = getTok().getIdentifier();
|
||||
@ -4466,18 +4471,25 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
|
||||
if (RegNum == static_cast<unsigned>(-1)) {
|
||||
StringRef Kind;
|
||||
RegNum = tryMatchVectorRegister(Kind, false);
|
||||
if (!Kind.empty())
|
||||
return Error(SRegLoc, "vector register without type specifier expected");
|
||||
if (!Kind.empty()) {
|
||||
Error(SRegLoc, "vector register without type specifier expected");
|
||||
return false;
|
||||
}
|
||||
IsVector = true;
|
||||
}
|
||||
|
||||
if (RegNum == static_cast<unsigned>(-1))
|
||||
return Error(SRegLoc, "register name or alias expected");
|
||||
if (RegNum == static_cast<unsigned>(-1)) {
|
||||
Parser.eatToEndOfStatement();
|
||||
Error(SRegLoc, "register name or alias expected");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Shouldn't be anything else.
|
||||
if (Parser.getTok().isNot(AsmToken::EndOfStatement))
|
||||
return Error(Parser.getTok().getLoc(),
|
||||
"unexpected input in .req directive");
|
||||
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
|
||||
Error(Parser.getTok().getLoc(), "unexpected input in .req directive");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
Parser.Lex(); // Consume the EndOfStatement
|
||||
|
||||
@ -4485,7 +4497,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 false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// parseDirectiveUneq
|
||||
@ -4494,6 +4506,7 @@ 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());
|
||||
|
@ -339,14 +339,16 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
return;
|
||||
}
|
||||
|
||||
void Note(SMLoc L, const Twine &Msg, SMRange Range = None) {
|
||||
return getParser().Note(L, Msg, Range);
|
||||
void Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = None) {
|
||||
return getParser().Note(L, Msg, Ranges);
|
||||
}
|
||||
bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) {
|
||||
return getParser().Warning(L, Msg, Range);
|
||||
bool Warning(SMLoc L, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = None) {
|
||||
return getParser().Warning(L, Msg, Ranges);
|
||||
}
|
||||
bool Error(SMLoc L, const Twine &Msg, SMRange Range = None) {
|
||||
return getParser().Error(L, Msg, Range);
|
||||
bool Error(SMLoc L, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = None) {
|
||||
return getParser().Error(L, Msg, Ranges);
|
||||
}
|
||||
|
||||
bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
|
||||
@ -6006,6 +6008,7 @@ 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");
|
||||
}
|
||||
|
||||
@ -6019,12 +6022,14 @@ 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;
|
||||
@ -6050,12 +6055,14 @@ 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");
|
||||
}
|
||||
@ -6099,6 +6106,7 @@ 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");
|
||||
}
|
||||
@ -6116,6 +6124,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
// Read the first operand.
|
||||
if (parseOperand(Operands, Mnemonic)) {
|
||||
Parser.eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -6124,13 +6133,16 @@ 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)) {
|
||||
return TokError("unexpected token in argument list");
|
||||
SMLoc Loc = getLexer().getLoc();
|
||||
Parser.eatToEndOfStatement();
|
||||
return Error(Loc, "unexpected token in argument list");
|
||||
}
|
||||
|
||||
Parser.Lex(); // Consume the EndOfStatement
|
||||
@ -9319,6 +9331,7 @@ bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
|
||||
for (;;) {
|
||||
const MCExpr *Value;
|
||||
if (getParser().parseExpression(Value)) {
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -9421,6 +9434,7 @@ bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
Error(Parser.getTok().getLoc(), "unexpected token in directive");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -9513,12 +9527,14 @@ 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;
|
||||
}
|
||||
@ -9538,6 +9554,7 @@ 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;
|
||||
}
|
||||
@ -9607,6 +9624,7 @@ 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();
|
||||
@ -9615,12 +9633,14 @@ 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;
|
||||
}
|
||||
|
||||
@ -9629,6 +9649,7 @@ 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
|
||||
@ -9655,12 +9676,14 @@ 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;
|
||||
}
|
||||
|
||||
@ -9672,6 +9695,7 @@ 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();
|
||||
@ -9681,6 +9705,7 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
|
||||
if (IsStringValue) {
|
||||
if (Parser.getTok().isNot(AsmToken::String)) {
|
||||
Error(Parser.getTok().getLoc(), "bad string constant");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -9824,6 +9849,7 @@ bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
|
||||
return false;
|
||||
}
|
||||
if (HasExistingPersonality) {
|
||||
Parser.eatToEndOfStatement();
|
||||
Error(L, "multiple personality directives");
|
||||
UC.emitPersonalityLocNotes();
|
||||
return false;
|
||||
@ -9831,6 +9857,7 @@ 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;
|
||||
}
|
||||
@ -10030,12 +10057,14 @@ 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;
|
||||
}
|
||||
@ -10043,6 +10072,7 @@ bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
|
||||
}
|
||||
|
||||
if (getLexer().is(AsmToken::EndOfStatement)) {
|
||||
Parser.eatToEndOfStatement();
|
||||
Error(Loc, "expected expression following directive");
|
||||
return false;
|
||||
}
|
||||
@ -10134,20 +10164,24 @@ 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;
|
||||
@ -10156,16 +10190,19 @@ 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;
|
||||
}
|
||||
@ -10179,6 +10216,7 @@ 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;
|
||||
}
|
||||
@ -10190,12 +10228,14 @@ 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;
|
||||
}
|
||||
|
||||
@ -10203,6 +10243,7 @@ bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
|
||||
|
||||
if (getLexer().isNot(AsmToken::Comma)) {
|
||||
Error(getLexer().getLoc(), "expected comma");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
Parser.Lex();
|
||||
@ -10214,18 +10255,21 @@ 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;
|
||||
}
|
||||
|
||||
@ -10236,6 +10280,7 @@ bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
|
||||
|
||||
if (getLexer().isNot(AsmToken::Comma)) {
|
||||
Error(getLexer().getLoc(), "unexpected token in directive");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -10255,6 +10300,7 @@ bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
|
||||
|
||||
if (getLexer().isNot(AsmToken::Identifier)) {
|
||||
TokError("expected variable after '.tlsdescseq' directive");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -10265,6 +10311,7 @@ bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
Error(Parser.getTok().getLoc(), "unexpected token");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -10277,10 +10324,12 @@ 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;
|
||||
}
|
||||
@ -10288,11 +10337,13 @@ 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;
|
||||
}
|
||||
@ -10303,6 +10354,7 @@ bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
|
||||
|
||||
if (Parser.getTok().isNot(AsmToken::Hash)) {
|
||||
Error(Parser.getTok().getLoc(), "expected #constant");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
Parser.Lex();
|
||||
@ -10310,12 +10362,14 @@ 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;
|
||||
}
|
||||
@ -10335,6 +10389,7 @@ bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
if (getLexer().isNot(AsmToken::Identifier)) {
|
||||
Error(getLexer().getLoc(), "unexpected token");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -10346,6 +10401,7 @@ bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
|
||||
|
||||
if (ID == ARM::AK_INVALID) {
|
||||
Error(ArchLoc, "unknown architecture '" + Arch + "'");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -10353,6 +10409,7 @@ bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
Error(getLexer().getLoc(), "unexpected token");
|
||||
Parser.eatToEndOfStatement();
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -10385,11 +10442,13 @@ 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();
|
||||
@ -10453,6 +10512,7 @@ bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
|
||||
|
||||
if (getLexer().isNot(AsmToken::Identifier)) {
|
||||
Error(getLexer().getLoc(), "expected architecture extension name");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -10498,6 +10558,7 @@ bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
|
||||
}
|
||||
|
||||
Error(ExtLoc, "unknown architectural extension: " + Name);
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ class HexagonAsmParser : public MCTargetAsmParser {
|
||||
uint64_t &ErrorInfo, bool MatchingInlineAsm) override;
|
||||
|
||||
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind) override;
|
||||
bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
|
||||
void OutOfRange(SMLoc IDLoc, long long Val, long long Max);
|
||||
int processInstruction(MCInst &Inst, OperandVector const &Operands,
|
||||
SMLoc IDLoc);
|
||||
|
||||
@ -637,63 +637,60 @@ bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
|
||||
uint64_t Err = Check.getError();
|
||||
if (Err != HexagonMCErrInfo::CHECK_SUCCESS) {
|
||||
if (HexagonMCErrInfo::CHECK_ERROR_BRANCHES & Err)
|
||||
return Error(
|
||||
IDLoc,
|
||||
Error(IDLoc,
|
||||
"unconditional branch cannot precede another branch in packet");
|
||||
|
||||
if (HexagonMCErrInfo::CHECK_ERROR_NEWP & Err ||
|
||||
HexagonMCErrInfo::CHECK_ERROR_NEWV & Err)
|
||||
return Error(IDLoc, "register `" + R +
|
||||
Error(IDLoc, "register `" + R +
|
||||
"' used with `.new' "
|
||||
"but not validly modified in the same packet");
|
||||
|
||||
if (HexagonMCErrInfo::CHECK_ERROR_REGISTERS & Err)
|
||||
return Error(IDLoc, "register `" + R + "' modified more than once");
|
||||
Error(IDLoc, "register `" + R + "' modified more than once");
|
||||
|
||||
if (HexagonMCErrInfo::CHECK_ERROR_READONLY & Err)
|
||||
return Error(IDLoc, "cannot write to read-only register `" + R + "'");
|
||||
Error(IDLoc, "cannot write to read-only register `" + R + "'");
|
||||
|
||||
if (HexagonMCErrInfo::CHECK_ERROR_LOOP & Err)
|
||||
return Error(IDLoc, "loop-setup and some branch instructions "
|
||||
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');
|
||||
return Error(IDLoc,
|
||||
"packet marked with `:endloop" + N + "' " +
|
||||
Error(IDLoc, "packet marked with `:endloop" + N + "' " +
|
||||
"cannot contain instructions that modify register " +
|
||||
"`" + R + "'");
|
||||
}
|
||||
|
||||
if (HexagonMCErrInfo::CHECK_ERROR_SOLO & Err)
|
||||
return Error(
|
||||
IDLoc,
|
||||
Error(IDLoc,
|
||||
"instruction cannot appear in packet with other instructions");
|
||||
|
||||
if (HexagonMCErrInfo::CHECK_ERROR_NOSLOTS & Err)
|
||||
return Error(IDLoc, "too many slots used in packet");
|
||||
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)
|
||||
return Error(IDLoc, "invalid instruction packet");
|
||||
Error(IDLoc, "invalid instruction packet");
|
||||
else if (HexagonShuffler::SHUFFLE_ERROR_STORES == Erm)
|
||||
return Error(IDLoc, "invalid instruction packet: too many stores");
|
||||
Error(IDLoc, "invalid instruction packet: too many stores");
|
||||
else if (HexagonShuffler::SHUFFLE_ERROR_LOADS == Erm)
|
||||
return Error(IDLoc, "invalid instruction packet: too many loads");
|
||||
Error(IDLoc, "invalid instruction packet: too many loads");
|
||||
else if (HexagonShuffler::SHUFFLE_ERROR_BRANCHES == Erm)
|
||||
return Error(IDLoc, "too many branches in packet");
|
||||
Error(IDLoc, "too many branches in packet");
|
||||
else if (HexagonShuffler::SHUFFLE_ERROR_NOSLOTS == Erm)
|
||||
return Error(IDLoc, "invalid instruction packet: out of slots");
|
||||
Error(IDLoc, "invalid instruction packet: out of slots");
|
||||
else if (HexagonShuffler::SHUFFLE_ERROR_SLOTS == Erm)
|
||||
return Error(IDLoc, "invalid instruction packet: slot error");
|
||||
Error(IDLoc, "invalid instruction packet: slot error");
|
||||
else if (HexagonShuffler::SHUFFLE_ERROR_ERRATA2 == Erm)
|
||||
return Error(IDLoc, "v60 packet violation");
|
||||
Error(IDLoc, "v60 packet violation");
|
||||
else if (HexagonShuffler::SHUFFLE_ERROR_STORE_LOAD_CONFLICT == Erm)
|
||||
return Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
|
||||
Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
|
||||
else
|
||||
return Error(IDLoc, "unknown error in instruction packet");
|
||||
Error(IDLoc, "unknown error in instruction packet");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1511,8 +1508,7 @@ unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
|
||||
return Match_InvalidOperand;
|
||||
}
|
||||
|
||||
// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
|
||||
bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
|
||||
void 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: ";
|
||||
@ -1520,7 +1516,7 @@ bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
|
||||
ES << "0-" << Max;
|
||||
else
|
||||
ES << Max << "-" << (-Max - 1);
|
||||
return Parser.printError(IDLoc, ES.str().c_str());
|
||||
Error(IDLoc, ES.str().c_str());
|
||||
}
|
||||
|
||||
int HexagonAsmParser::processInstruction(MCInst &Inst,
|
||||
|
@ -924,10 +924,8 @@ 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.getParser().printError(
|
||||
StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
|
||||
AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
|
||||
"registers");
|
||||
}
|
||||
|
||||
@ -1862,7 +1860,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 getParser().hasPendingError();
|
||||
return false;
|
||||
}
|
||||
} else if (Op.isExpr()) {
|
||||
const MCExpr *Expr = Op.getExpr();
|
||||
@ -1872,11 +1870,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 getParser().hasPendingError();
|
||||
return false;
|
||||
}
|
||||
} else if (!isEvaluated(Expr)) {
|
||||
expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
|
||||
return getParser().hasPendingError();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2468,7 +2466,6 @@ 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.
|
||||
@ -2695,9 +2692,9 @@ bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
|
||||
Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
|
||||
} else {
|
||||
if (!isInt<17>(Offset.getImm()))
|
||||
return Error(IDLoc, "branch target out of range");
|
||||
Error(IDLoc, "branch target out of range");
|
||||
if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
|
||||
return Error(IDLoc, "branch to misaligned address");
|
||||
Error(IDLoc, "branch to misaligned address");
|
||||
Inst.clear();
|
||||
Inst.setOpcode(Mips::BEQ_MM);
|
||||
Inst.addOperand(MCOperand::createReg(Mips::ZERO));
|
||||
@ -3305,7 +3302,8 @@ bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
if (hasMips32r6() || hasMips64r6()) {
|
||||
return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
|
||||
Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
|
||||
return false;
|
||||
}
|
||||
|
||||
warnIfNoMacro(IDLoc);
|
||||
@ -3382,8 +3380,10 @@ bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
if (hasMips32r6() || hasMips64r6())
|
||||
return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
|
||||
if (hasMips32r6() || hasMips64r6()) {
|
||||
Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
|
||||
return false;
|
||||
}
|
||||
|
||||
const MCOperand &DstRegOp = Inst.getOperand(0);
|
||||
assert(DstRegOp.isReg() && "expected register operand kind");
|
||||
@ -4817,10 +4817,12 @@ 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(
|
||||
@ -4845,10 +4847,12 @@ 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(
|
||||
@ -4868,6 +4872,7 @@ 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.
|
||||
@ -4878,6 +4883,7 @@ 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))
|
||||
@ -4889,6 +4895,7 @@ 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
|
||||
@ -4902,6 +4909,7 @@ 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.
|
||||
@ -4911,7 +4919,9 @@ 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);
|
||||
}
|
||||
|
||||
@ -5412,6 +5422,7 @@ bool MipsAsmParser::eatComma(StringRef ErrorStr) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
if (getLexer().isNot(AsmToken::Comma)) {
|
||||
SMLoc Loc = getLexer().getLoc();
|
||||
Parser.eatToEndOfStatement();
|
||||
return Error(Loc, ErrorStr);
|
||||
}
|
||||
|
||||
@ -5520,6 +5531,7 @@ bool MipsAsmParser::parseDirectiveCPSetup() {
|
||||
MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
|
||||
if (!FuncRegOpnd.isGPRAsmReg()) {
|
||||
reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5538,6 +5550,7 @@ bool MipsAsmParser::parseDirectiveCPSetup() {
|
||||
if (Parser.parseExpression(OffsetExpr) ||
|
||||
!OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
|
||||
reportParseError(ExprLoc, "expected save register or stack offset");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5547,6 +5560,7 @@ 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();
|
||||
@ -5834,8 +5848,9 @@ bool MipsAsmParser::parseDirectiveOption() {
|
||||
AsmToken Tok = Parser.getTok();
|
||||
// At the moment only identifiers are supported.
|
||||
if (Tok.isNot(AsmToken::Identifier)) {
|
||||
return Error(Parser.getTok().getLoc(),
|
||||
"unexpected token, expected identifier");
|
||||
Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
StringRef Option = Tok.getIdentifier();
|
||||
@ -5847,8 +5862,9 @@ bool MipsAsmParser::parseDirectiveOption() {
|
||||
getTargetStreamer().emitDirectiveOptionPic0();
|
||||
Parser.Lex();
|
||||
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
|
||||
return Error(Parser.getTok().getLoc(),
|
||||
Error(Parser.getTok().getLoc(),
|
||||
"unexpected token, expected end of statement");
|
||||
Parser.eatToEndOfStatement();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -5860,8 +5876,9 @@ bool MipsAsmParser::parseDirectiveOption() {
|
||||
getTargetStreamer().emitDirectiveOptionPic2();
|
||||
Parser.Lex();
|
||||
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
|
||||
return Error(Parser.getTok().getLoc(),
|
||||
Error(Parser.getTok().getLoc(),
|
||||
"unexpected token, expected end of statement");
|
||||
Parser.eatToEndOfStatement();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -5952,7 +5969,8 @@ bool MipsAsmParser::parseDirectiveModule() {
|
||||
return false; // parseDirectiveModule has finished successfully.
|
||||
} else if (Option == "nooddspreg") {
|
||||
if (!isABI_O32()) {
|
||||
return Error(L, "'.module nooddspreg' requires the O32 ABI");
|
||||
Error(L, "'.module nooddspreg' requires the O32 ABI");
|
||||
return false;
|
||||
}
|
||||
|
||||
setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
|
||||
@ -6413,6 +6431,8 @@ 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;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ class SparcAsmParser : public MCTargetAsmParser {
|
||||
return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
|
||||
}
|
||||
|
||||
bool expandSET(MCInst &Inst, SMLoc IDLoc,
|
||||
void expandSET(MCInst &Inst, SMLoc IDLoc,
|
||||
SmallVectorImpl<MCInst> &Instructions);
|
||||
|
||||
public:
|
||||
@ -466,7 +466,7 @@ public:
|
||||
|
||||
} // end namespace
|
||||
|
||||
bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
|
||||
void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
|
||||
SmallVectorImpl<MCInst> &Instructions) {
|
||||
MCOperand MCRegOp = Inst.getOperand(0);
|
||||
MCOperand MCValOp = Inst.getOperand(1);
|
||||
@ -479,8 +479,8 @@ bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
|
||||
|
||||
// Allow either a signed or unsigned 32-bit immediate.
|
||||
if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
|
||||
return Error(IDLoc,
|
||||
"set: argument must be between -2147483648 and 4294967295");
|
||||
Error(IDLoc, "set: argument must be between -2147483648 and 4294967295");
|
||||
return;
|
||||
}
|
||||
|
||||
// If the value was expressed as a large unsigned number, that's ok.
|
||||
@ -537,7 +537,6 @@ bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
|
||||
TmpInst.addOperand(MCOperand::createExpr(Expr));
|
||||
Instructions.push_back(TmpInst);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
@ -557,8 +556,7 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
Instructions.push_back(Inst);
|
||||
break;
|
||||
case SP::SET:
|
||||
if (expandSET(Inst, IDLoc, Instructions))
|
||||
return true;
|
||||
expandSET(Inst, IDLoc, Instructions);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -628,11 +626,13 @@ 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,12 +645,14 @@ 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.
|
||||
|
@ -959,6 +959,7 @@ bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
// Read the first operand.
|
||||
if (parseOperand(Operands, Name)) {
|
||||
Parser.eatToEndOfStatement();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -966,11 +967,13 @@ 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");
|
||||
}
|
||||
}
|
||||
|
@ -659,14 +659,20 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
bool Error(SMLoc L, const Twine &Msg, SMRange Range = None,
|
||||
bool Error(SMLoc L, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = None,
|
||||
bool MatchingInlineAsm = false) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
if (MatchingInlineAsm) {
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
if (MatchingInlineAsm) return true;
|
||||
return Parser.Error(L, Msg, Ranges);
|
||||
}
|
||||
return Parser.Error(L, Msg, Range);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
|
||||
@ -1889,11 +1895,13 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
|
||||
if(getLexer().is(AsmToken::Integer)) {
|
||||
// Parse memory broadcasting ({1to<NUM>}).
|
||||
if (getLexer().getTok().getIntVal() != 1)
|
||||
return !TokError("Expected 1to<NUM> at this point");
|
||||
return !ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"Expected 1to<NUM> at this point");
|
||||
Parser.Lex(); // Eat "1" of 1to8
|
||||
if (!getLexer().is(AsmToken::Identifier) ||
|
||||
!getLexer().getTok().getIdentifier().startswith("to"))
|
||||
return !TokError("Expected 1to<NUM> at this point");
|
||||
return !ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"Expected 1to<NUM> at this point");
|
||||
// Recognize only reasonable suffixes.
|
||||
const char *BroadcastPrimitive =
|
||||
StringSwitch<const char*>(getLexer().getTok().getIdentifier())
|
||||
@ -1903,10 +1911,12 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
|
||||
.Case("to16", "{1to16}")
|
||||
.Default(nullptr);
|
||||
if (!BroadcastPrimitive)
|
||||
return !TokError("Invalid memory broadcast primitive.");
|
||||
return !ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"Invalid memory broadcast primitive.");
|
||||
Parser.Lex(); // Eat "toN" of 1toN
|
||||
if (!getLexer().is(AsmToken::RCurly))
|
||||
return !TokError("Expected } at this point");
|
||||
return !ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"Expected } at this point");
|
||||
Parser.Lex(); // Eat "}"
|
||||
Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
|
||||
consumedToken));
|
||||
@ -1919,7 +1929,8 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
|
||||
if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
|
||||
Operands.push_back(std::move(Op));
|
||||
if (!getLexer().is(AsmToken::RCurly))
|
||||
return !TokError("Expected } at this point");
|
||||
return !ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"Expected } at this point");
|
||||
Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
|
||||
|
||||
// Parse "zeroing non-masked" semantic {z}
|
||||
@ -1927,10 +1938,12 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
|
||||
Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
|
||||
if (!getLexer().is(AsmToken::Identifier) ||
|
||||
getLexer().getTok().getIdentifier() != "z")
|
||||
return !TokError("Expected z at this point");
|
||||
return !ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"Expected z at this point");
|
||||
Parser.Lex(); // Eat the z
|
||||
if (!getLexer().is(AsmToken::RCurly))
|
||||
return !TokError("Expected } at this point");
|
||||
return !ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"Expected } at this point");
|
||||
Parser.Lex(); // Eat the }
|
||||
}
|
||||
}
|
||||
@ -2274,6 +2287,7 @@ 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
|
||||
@ -2289,7 +2303,8 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
isParsingIntelSyntax() && isParsingInlineAsm() &&
|
||||
(getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
|
||||
return TokError("unexpected token in argument list");
|
||||
return ErrorAndEatStatement(getLexer().getLoc(),
|
||||
"unexpected token in argument list");
|
||||
}
|
||||
|
||||
// Consume the EndOfStatement or the prefix separator Slash
|
||||
@ -2555,6 +2570,7 @@ 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:";
|
||||
@ -2564,7 +2580,7 @@ bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
|
||||
OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
|
||||
Mask <<= 1;
|
||||
}
|
||||
return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
|
||||
return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
|
||||
}
|
||||
|
||||
bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
@ -2575,7 +2591,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!");
|
||||
SMRange EmptyRange = None;
|
||||
ArrayRef<SMRange> EmptyRanges = None;
|
||||
|
||||
// First, handle aliases that expand to multiple instructions.
|
||||
MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
|
||||
@ -2682,7 +2698,7 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OS << "'" << Base << MatchChars[i] << "'";
|
||||
}
|
||||
OS << ")";
|
||||
Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
|
||||
Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2692,15 +2708,17 @@ 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 + "'",
|
||||
Op.getLocRange(), MatchingInlineAsm);
|
||||
Ranges, 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", EmptyRange,
|
||||
MatchingInlineAsm);
|
||||
return Error(IDLoc, "too few operands for instruction",
|
||||
EmptyRanges, MatchingInlineAsm);
|
||||
|
||||
X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
|
||||
if (Operand.getStartLoc().isValid()) {
|
||||
@ -2710,7 +2728,7 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
}
|
||||
}
|
||||
|
||||
return Error(IDLoc, "invalid operand for instruction", EmptyRange,
|
||||
return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
|
||||
MatchingInlineAsm);
|
||||
}
|
||||
|
||||
@ -2727,13 +2745,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", EmptyRange,
|
||||
return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
|
||||
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",
|
||||
EmptyRange, MatchingInlineAsm);
|
||||
EmptyRanges, MatchingInlineAsm);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2746,7 +2764,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();
|
||||
SMRange EmptyRange = None;
|
||||
ArrayRef<SMRange> EmptyRanges = None;
|
||||
|
||||
// First, handle aliases that expand to multiple instructions.
|
||||
MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
|
||||
@ -2818,8 +2836,10 @@ 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 + "'",
|
||||
Op.getLocRange(), MatchingInlineAsm);
|
||||
Ranges, MatchingInlineAsm);
|
||||
}
|
||||
|
||||
// If exactly one matched, then we treat that as a successful match (and the
|
||||
@ -2842,9 +2862,11 @@ 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 + "\'",
|
||||
UnsizedMemOp->getLocRange(), MatchingInlineAsm);
|
||||
Ranges, MatchingInlineAsm);
|
||||
}
|
||||
|
||||
// If one instruction matched with a missing feature, report this as a
|
||||
@ -2860,12 +2882,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", EmptyRange,
|
||||
return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
|
||||
MatchingInlineAsm);
|
||||
}
|
||||
|
||||
// If all of these were an outright failure, report it in a useless way.
|
||||
return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
|
||||
return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
|
||||
MatchingInlineAsm);
|
||||
}
|
||||
|
||||
|
@ -21,21 +21,47 @@
|
||||
// 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: [[@LINE-1]]:19: error: invalid operand for instruction
|
||||
// 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: ^
|
||||
|
||||
//AdvSIMD RDMA scalar
|
||||
sqrdmlah h0, h1, h2
|
||||
|
@ -17,5 +17,3 @@ 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
Loading…
x
Reference in New Issue
Block a user