[MC][AArch64] Cleanup end-of-line parsing in AArch64 AsmParser.

Reviewers: t.p.northover, rengolin

Subscribers: llvm-commits, aemerson

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

llvm-svn: 286265
This commit is contained in:
Nirav Dave 2016-11-08 18:31:04 +00:00
parent 1619805099
commit e833c6c61a
4 changed files with 147 additions and 241 deletions

View File

@ -68,8 +68,8 @@ public:
bool Warning(SMLoc L, const Twine &Msg) {
return getParser().Warning(L, Msg);
}
bool Error(SMLoc L, const Twine &Msg) {
return getParser().Error(L, Msg);
bool Error(SMLoc L, const Twine &Msg, SMRange Range = SMRange()) {
return getParser().Error(L, Msg, Range);
}
void Note(SMLoc L, const Twine &Msg) {
getParser().Note(L, Msg);

View File

@ -68,8 +68,6 @@ private:
bool parseOperand(OperandVector &Operands, bool isCondCode,
bool invertCondCode);
void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
bool Error(SMLoc L, const Twine &Msg) { return getParser().Error(L, Msg); }
bool showMatchError(SMLoc Loc, unsigned ErrCode);
bool parseDirectiveArch(SMLoc L);
@ -1972,7 +1970,8 @@ unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
int AArch64AsmParser::tryParseRegister() {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
if (Tok.isNot(AsmToken::Identifier))
return -1;
std::string lowerCase = Tok.getString().lower();
unsigned RegNum = matchRegisterNameAlias(lowerCase, false);
@ -2062,10 +2061,9 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
SMLoc S = getLoc();
const AsmToken &Tok = Parser.getTok();
// Either an identifier for named values or a 5-bit immediate.
bool Hash = Tok.is(AsmToken::Hash);
if (Hash || Tok.is(AsmToken::Integer)) {
if (Hash)
Parser.Lex(); // Eat hash token.
// Eat optional hash.
if (parseOptionalToken(AsmToken::Hash) ||
Tok.is(AsmToken::Integer)) {
const MCExpr *ImmVal;
if (getParser().parseExpression(ImmVal))
return MatchOperand_ParseFail;
@ -2182,14 +2180,10 @@ AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
/// instruction.
OperandMatchResultTy
AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
SMLoc S = getLoc();
const MCExpr *Expr;
if (Parser.getTok().is(AsmToken::Hash)) {
Parser.Lex(); // Eat hash token.
}
parseOptionalToken(AsmToken::Hash);
if (getParser().parseExpression(Expr))
return MatchOperand_ParseFail;
@ -2205,18 +2199,11 @@ AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
SMLoc S = getLoc();
bool Hash = false;
if (Parser.getTok().is(AsmToken::Hash)) {
Parser.Lex(); // Eat '#'
Hash = true;
}
bool Hash = parseOptionalToken(AsmToken::Hash);
// Handle negation, as that still comes through as a separate token.
bool isNegative = false;
if (Parser.getTok().is(AsmToken::Minus)) {
isNegative = true;
Parser.Lex();
}
bool isNegative = parseOptionalToken(AsmToken::Minus);
const AsmToken &Tok = Parser.getTok();
if (Tok.is(AsmToken::Real)) {
APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
@ -2307,9 +2294,7 @@ AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
// Eat 'lsl'
Parser.Lex();
if (Parser.getTok().is(AsmToken::Hash)) {
Parser.Lex();
}
parseOptionalToken(AsmToken::Hash);
if (Parser.getTok().isNot(AsmToken::Integer)) {
Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
@ -2410,7 +2395,8 @@ AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
SMLoc S = Tok.getLoc();
Parser.Lex();
bool Hash = getLexer().is(AsmToken::Hash);
bool Hash = parseOptionalToken(AsmToken::Hash);
if (!Hash && getLexer().isNot(AsmToken::Integer)) {
if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
@ -2427,9 +2413,6 @@ AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
return MatchOperand_Success;
}
if (Hash)
Parser.Lex(); // Eat the '#'.
// Make sure we do actually have a number or a parenthesized expression.
SMLoc E = Parser.getTok().getLoc();
if (!Parser.getTok().is(AsmToken::Integer) &&
@ -2698,19 +2681,12 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
bool HasRegister = false;
// Check for the optional register operand.
if (getLexer().is(AsmToken::Comma)) {
Parser.Lex(); // Eat comma.
if (parseOptionalToken(AsmToken::Comma)) {
if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
return TokError("expected register operand");
HasRegister = true;
}
if (getLexer().isNot(AsmToken::EndOfStatement)) {
return TokError("unexpected token in argument list");
}
if (ExpectRegister && !HasRegister) {
return TokError("specified " + Mnemonic + " op requires a register");
}
@ -2718,7 +2694,9 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
return TokError("specified " + Mnemonic + " op does not use a register");
}
Parser.Lex(); // Consume the EndOfStatement
if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
return true;
return false;
}
@ -2728,11 +2706,9 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
const AsmToken &Tok = Parser.getTok();
// Can be either a #imm style literal or an option name
bool Hash = Tok.is(AsmToken::Hash);
if (Hash || Tok.is(AsmToken::Integer)) {
if (parseOptionalToken(AsmToken::Hash) ||
Tok.is(AsmToken::Integer)) {
// Immediate operand.
if (Hash)
Parser.Lex(); // Eat the '#'
const MCExpr *ImmVal;
SMLoc ExprLoc = getLoc();
if (getParser().parseExpression(ImmVal))
@ -2826,10 +2802,8 @@ bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
AArch64Operand::CreateToken(Kind, false, S, getContext()));
// If there is an index specifier following the register, parse that too.
if (Parser.getTok().is(AsmToken::LBrac)) {
SMLoc SIdx = getLoc();
Parser.Lex(); // Eat left bracket token.
SMLoc SIdx = getLoc();
if (parseOptionalToken(AsmToken::LBrac)) {
const MCExpr *ImmVal;
if (getParser().parseExpression(ImmVal))
return false;
@ -2840,12 +2814,9 @@ bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
}
SMLoc E = getLoc();
if (Parser.getTok().isNot(AsmToken::RBrac)) {
Error(E, "']' expected");
return false;
}
Parser.Lex(); // Eat right bracket token.
if (parseToken(AsmToken::RBrac, "']' expected"))
return false;
Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
E, getContext()));
@ -2871,18 +2842,16 @@ bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
// A small number of instructions (FMOVXDhighr, for example) have "[1]"
// as a string token in the instruction itself.
if (getLexer().getKind() == AsmToken::LBrac) {
SMLoc LBracS = getLoc();
Parser.Lex();
const AsmToken &Tok = Parser.getTok();
SMLoc LBracS = getLoc();
const AsmToken &Tok = Parser.getTok();
if (parseOptionalToken(AsmToken::LBrac)) {
if (Tok.is(AsmToken::Integer)) {
SMLoc IntS = getLoc();
int64_t Val = Tok.getIntVal();
if (Val == 1) {
Parser.Lex();
if (getLexer().getKind() == AsmToken::RBrac) {
SMLoc RBracS = getLoc();
Parser.Lex();
SMLoc RBracS = getLoc();
if (parseOptionalToken(AsmToken::RBrac)) {
Operands.push_back(
AArch64Operand::CreateToken("[", false, LBracS, getContext()));
Operands.push_back(
@ -2903,15 +2872,11 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
bool HasELFModifier = false;
AArch64MCExpr::VariantKind RefKind;
if (Parser.getTok().is(AsmToken::Colon)) {
Parser.Lex(); // Eat ':"
if (parseOptionalToken(AsmToken::Colon)) {
HasELFModifier = true;
if (Parser.getTok().isNot(AsmToken::Identifier)) {
Error(Parser.getTok().getLoc(),
"expect relocation specifier in operand after ':'");
return true;
}
if (Parser.getTok().isNot(AsmToken::Identifier))
return TokError("expect relocation specifier in operand after ':'");
std::string LowerCase = Parser.getTok().getIdentifier().lower();
RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
@ -2952,19 +2917,13 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
.Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
.Default(AArch64MCExpr::VK_INVALID);
if (RefKind == AArch64MCExpr::VK_INVALID) {
Error(Parser.getTok().getLoc(),
"expect relocation specifier in operand after ':'");
return true;
}
if (RefKind == AArch64MCExpr::VK_INVALID)
return TokError("expect relocation specifier in operand after ':'");
Parser.Lex(); // Eat identifier
if (Parser.getTok().isNot(AsmToken::Colon)) {
Error(Parser.getTok().getLoc(), "expect ':' after relocation specifier");
if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier"))
return true;
}
Parser.Lex(); // Eat ':'
}
if (getParser().parseExpression(ImmVal))
@ -2989,9 +2948,7 @@ bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
int64_t PrevReg = FirstReg;
unsigned Count = 1;
if (Parser.getTok().is(AsmToken::Minus)) {
Parser.Lex(); // Eat the minus.
if (parseOptionalToken(AsmToken::Minus)) {
SMLoc Loc = getLoc();
StringRef NextKind;
int64_t Reg = tryMatchVectorRegister(NextKind, true);
@ -3010,9 +2967,7 @@ bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
Count += Space;
}
else {
while (Parser.getTok().is(AsmToken::Comma)) {
Parser.Lex(); // Eat the comma token.
while (parseOptionalToken(AsmToken::Comma)) {
SMLoc Loc = getLoc();
StringRef NextKind;
int64_t Reg = tryMatchVectorRegister(NextKind, true);
@ -3032,9 +2987,8 @@ bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
}
}
if (Parser.getTok().isNot(AsmToken::RCurly))
return Error(getLoc(), "'}' expected");
Parser.Lex(); // Eat the '}' token.
if (parseToken(AsmToken::RCurly, "'}' expected"))
return true;
if (Count > 4)
return Error(S, "invalid number of vectors");
@ -3048,10 +3002,8 @@ bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
// If there is an index specifier following the list, parse that too.
if (Parser.getTok().is(AsmToken::LBrac)) {
SMLoc SIdx = getLoc();
Parser.Lex(); // Eat left bracket token.
SMLoc SIdx = getLoc();
if (parseOptionalToken(AsmToken::LBrac)) { // Eat left bracket token.
const MCExpr *ImmVal;
if (getParser().parseExpression(ImmVal))
return false;
@ -3062,12 +3014,8 @@ bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
}
SMLoc E = getLoc();
if (Parser.getTok().isNot(AsmToken::RBrac)) {
Error(E, "']' expected");
if (parseToken(AsmToken::RBrac, "']' expected"))
return false;
}
Parser.Lex(); // Eat right bracket token.
Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
E, getContext()));
@ -3092,15 +3040,13 @@ AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
SMLoc S = getLoc();
Parser.Lex(); // Eat register
if (Parser.getTok().isNot(AsmToken::Comma)) {
if (!parseOptionalToken(AsmToken::Comma)) {
Operands.push_back(
AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
return MatchOperand_Success;
}
Parser.Lex(); // Eat comma.
if (Parser.getTok().is(AsmToken::Hash))
Parser.Lex(); // Eat hash
parseOptionalToken(AsmToken::Hash);
if (Parser.getTok().isNot(AsmToken::Integer)) {
Error(getLoc(), "index must be absent or #0");
@ -3181,7 +3127,6 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
S = getLoc();
if (getParser().parseExpression(IdVal))
return true;
E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
return false;
@ -3191,8 +3136,8 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
case AsmToken::Hash: {
// #42 -> immediate.
S = getLoc();
if (getLexer().is(AsmToken::Hash))
Parser.Lex();
parseOptionalToken(AsmToken::Hash);
// Parse a negative sign
bool isNegative = false;
@ -3235,9 +3180,9 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
return false;
}
case AsmToken::Equal: {
SMLoc Loc = Parser.getTok().getLoc();
SMLoc Loc = getLoc();
if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
return Error(Loc, "unexpected token in operand");
return TokError("unexpected token in operand");
Parser.Lex(); // Eat '='
const MCExpr *SubExprVal;
if (getParser().parseExpression(SubExprVal))
@ -3325,10 +3270,8 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
StringRef Head = Name.slice(Start, Next);
// 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);
return IsError;
}
if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi")
return parseSysAlias(Head, NameLoc, Operands);
Operands.push_back(
AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
@ -3387,9 +3330,7 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
}
unsigned N = 2;
while (getLexer().is(AsmToken::Comma)) {
Parser.Lex(); // Eat the comma.
while (parseOptionalToken(AsmToken::Comma)) {
// Parse and remember the operand.
if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
(N == 3 && condCodeThirdOperand) ||
@ -3406,30 +3347,23 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
//
// It's someone else's responsibility to make sure these tokens are sane
// in the given context!
if (Parser.getTok().is(AsmToken::RBrac)) {
SMLoc Loc = Parser.getTok().getLoc();
Operands.push_back(AArch64Operand::CreateToken("]", false, Loc,
getContext()));
Parser.Lex();
}
if (Parser.getTok().is(AsmToken::Exclaim)) {
SMLoc Loc = Parser.getTok().getLoc();
Operands.push_back(AArch64Operand::CreateToken("!", false, Loc,
getContext()));
Parser.Lex();
}
SMLoc RLoc = Parser.getTok().getLoc();
if (parseOptionalToken(AsmToken::RBrac))
Operands.push_back(
AArch64Operand::CreateToken("]", false, RLoc, getContext()));
SMLoc ELoc = Parser.getTok().getLoc();
if (parseOptionalToken(AsmToken::Exclaim))
Operands.push_back(
AArch64Operand::CreateToken("!", false, ELoc, getContext()));
++N;
}
}
if (getLexer().isNot(AsmToken::EndOfStatement)) {
SMLoc Loc = Parser.getTok().getLoc();
return Error(Loc, "unexpected token in argument list");
}
if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
return true;
Parser.Lex(); // Consume the EndOfStatement
return false;
}
@ -4080,7 +4014,8 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
if (ErrorInfo != ~0ULL) {
if (ErrorInfo >= Operands.size())
return Error(IDLoc, "too few operands for instruction");
return Error(IDLoc, "too few operands for instruction",
SMRange(IDLoc, getTok().getLoc()));
ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
if (ErrorLoc == SMLoc())
@ -4143,7 +4078,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_MSR:
case Match_MRS: {
if (ErrorInfo >= Operands.size())
return Error(IDLoc, "too few operands for instruction");
return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc()));
// Any time we get here, there's nothing fancy to do. Just get the
// operand SMLoc and display the diagnostic.
SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
@ -4166,30 +4101,31 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
StringRef IDVal = DirectiveID.getIdentifier();
SMLoc Loc = DirectiveID.getLoc();
if (IDVal == ".arch")
return parseDirectiveArch(Loc);
if (IDVal == ".cpu")
return parseDirectiveCPU(Loc);
if (IDVal == ".hword")
return parseDirectiveWord(2, Loc);
if (IDVal == ".word")
return parseDirectiveWord(4, Loc);
if (IDVal == ".xword")
return parseDirectiveWord(8, Loc);
if (IDVal == ".tlsdesccall")
return parseDirectiveTLSDescCall(Loc);
if (IDVal == ".ltorg" || IDVal == ".pool")
return parseDirectiveLtorg(Loc);
if (IDVal == ".unreq")
return parseDirectiveUnreq(Loc);
if (!IsMachO && !IsCOFF) {
parseDirectiveArch(Loc);
else if (IDVal == ".cpu")
parseDirectiveCPU(Loc);
else if (IDVal == ".hword")
parseDirectiveWord(2, Loc);
else if (IDVal == ".word")
parseDirectiveWord(4, Loc);
else if (IDVal == ".xword")
parseDirectiveWord(8, Loc);
else if (IDVal == ".tlsdesccall")
parseDirectiveTLSDescCall(Loc);
else if (IDVal == ".ltorg" || IDVal == ".pool")
parseDirectiveLtorg(Loc);
else if (IDVal == ".unreq")
parseDirectiveUnreq(Loc);
else if (!IsMachO && !IsCOFF) {
if (IDVal == ".inst")
return parseDirectiveInst(Loc);
}
if (IDVal == MCLOHDirectiveName())
return parseDirectiveLOH(IDVal, Loc);
return true;
parseDirectiveInst(Loc);
else
return true;
} else if (IDVal == MCLOHDirectiveName())
parseDirectiveLOH(IDVal, Loc);
else
return true;
return false;
}
static const struct {
@ -4220,10 +4156,11 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
getParser().parseStringToEndOfStatement().trim().split('+');
unsigned ID = AArch64::parseArch(Arch);
if (ID == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID)) {
Error(ArchLoc, "unknown arch name");
return false;
}
if (ID == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
return Error(ArchLoc, "unknown arch name");
if (parseToken(AsmToken::EndOfStatement))
return true;
// Get the architecture and extension features.
std::vector<StringRef> AArch64Features;
@ -4276,6 +4213,9 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
std::tie(CPU, ExtensionString) =
getParser().parseStringToEndOfStatement().trim().split('+');
if (parseToken(AsmToken::EndOfStatement))
return true;
SmallVector<StringRef, 4> RequestedExtensions;
if (!ExtensionString.empty())
ExtensionString.split(RequestedExtensions, '+');
@ -4322,66 +4262,39 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
/// parseDirectiveWord
/// ::= .word [ expression (, expression)* ]
bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
const MCExpr *Value;
if (getParser().parseExpression(Value))
return true;
auto parseOp = [&]() -> bool {
const MCExpr *Value;
if (getParser().parseExpression(Value))
return true;
getParser().getStreamer().EmitValue(Value, Size, L);
return false;
};
getParser().getStreamer().EmitValue(Value, Size, L);
if (getLexer().is(AsmToken::EndOfStatement))
break;
// FIXME: Improve diagnostic.
if (getLexer().isNot(AsmToken::Comma))
return Error(L, "unexpected token in directive");
Parser.Lex();
}
}
Parser.Lex();
if (parseMany(parseOp))
return true;
return false;
}
/// parseDirectiveInst
/// ::= .inst opcode [, ...]
bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
MCAsmParser &Parser = getParser();
if (getLexer().is(AsmToken::EndOfStatement)) {
Error(Loc, "expected expression following directive");
return false;
}
if (getLexer().is(AsmToken::EndOfStatement))
return Error(Loc, "expected expression following '.inst' directive");
for (;;) {
auto parseOp = [&]() -> bool {
SMLoc L = getLoc();
const MCExpr *Expr;
if (getParser().parseExpression(Expr)) {
Error(Loc, "expected expression");
return false;
}
if (check(getParser().parseExpression(Expr), L, "expected expression"))
return true;
const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
if (!Value) {
Error(Loc, "expected constant expression");
return false;
}
if (check(!Value, L, "expected constant expression"))
return true;
getTargetStreamer().emitInst(Value->getValue());
return false;
};
if (getLexer().is(AsmToken::EndOfStatement))
break;
if (getLexer().isNot(AsmToken::Comma)) {
Error(Loc, "unexpected token in directive");
return false;
}
Parser.Lex(); // Eat comma.
}
Parser.Lex();
if (parseMany(parseOp))
return addErrorSuffix(" in '.inst' directive");
return false;
}
@ -4389,8 +4302,10 @@ bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
// ::= .tlsdesccall symbol
bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
StringRef Name;
if (getParser().parseIdentifier(Name))
return Error(L, "expected symbol after directive");
if (check(getParser().parseIdentifier(Name), L,
"expected symbol after directive") ||
parseToken(AsmToken::EndOfStatement))
return true;
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
@ -4414,10 +4329,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();
@ -4445,12 +4358,13 @@ bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
if (Idx + 1 == NbArgs)
break;
if (getLexer().isNot(AsmToken::Comma))
return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
Lex();
if (parseToken(AsmToken::Comma,
"unexpected token in '" + Twine(IDVal) + "' directive"))
return true;
}
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
if (parseToken(AsmToken::EndOfStatement,
"unexpected token in '" + Twine(IDVal) + "' directive"))
return true;
getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
return false;
@ -4459,6 +4373,8 @@ bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
/// parseDirectiveLtorg
/// ::= .ltorg | .pool
bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
return true;
getTargetStreamer().emitCurrentConstantPool();
return false;
}
@ -4484,11 +4400,9 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
return Error(SRegLoc, "register name or alias expected");
// Shouldn't be anything else.
if (Parser.getTok().isNot(AsmToken::EndOfStatement))
return Error(Parser.getTok().getLoc(),
"unexpected input in .req directive");
Parser.Lex(); // Consume the EndOfStatement
if (parseToken(AsmToken::EndOfStatement,
"unexpected input in .req directive"))
return true;
auto pair = std::make_pair(IsVector, RegNum);
if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
@ -4501,12 +4415,12 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
/// ::= .unreq registername
bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
MCAsmParser &Parser = getParser();
if (Parser.getTok().isNot(AsmToken::Identifier)) {
Error(Parser.getTok().getLoc(), "unexpected input in .unreq directive.");
return false;
}
if (getTok().isNot(AsmToken::Identifier))
return TokError("unexpected input in .unreq directive.");
RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
Parser.Lex(); // Eat the identifier.
if (parseToken(AsmToken::EndOfStatement))
return addErrorSuffix("in '.unreq' directive");
return false;
}

View File

@ -3287,18 +3287,10 @@
msr spsel, #-1
msr spsel #-1
msr daifclr, #16
// CHECK-ERROR-NEXT: error: {{expected|immediate must be an}} integer in range [0, 15]
// CHECK-ERROR-NEXT: msr daifset, x4
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: {{expected|immediate must be an}} integer in range [0, 15]
// CHECK-ERROR-NEXT: msr spsel, #-1
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: {{expected comma before next operand|unexpected token in argument list}}
// CHECK-ERROR-NEXT: msr spsel #-1
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: {{expected|immediate must be an}} integer in range [0, 15]
// CHECK-ERROR-NEXT: msr daifclr, #16
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR: [[@LINE-4]]:22: error: {{expected|immediate must be an}} integer in range [0, 15]
// CHECK-ERROR: [[@LINE-4]]:20: error: {{expected|immediate must be an}} integer in range [0, 15]
// CHECK-ERROR: [[@LINE-4]]:{{9|19}}: error: {{too few operands for instruction|expected comma before next operand|unexpected token in argument list}}
// CHECK-ERROR: [[@LINE-4]]:22: error: {{expected|immediate must be an}} integer in range [0, 15]
sys #8, c1, c2, #7, x9
sys #3, c16, c2, #3, x10
@ -3308,7 +3300,7 @@
sysl x13, #3, c16, c2, #3
sysl x9, #2, c11, c16, #5
sysl x4, #4, c9, c8, #8
// CHECK-ERROR-NEXT: error: {{expected|immediate must be an}} integer in range [0, 7]
// CHECK-ERROR: error: {{expected|immediate must be an}} integer in range [0, 7]
// CHECK-ERROR-NEXT: sys #8, c1, c2, #7, x9
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: Expected cN operand where 0 <= N <= 15

View File

@ -7,15 +7,15 @@
diagnostics:
.Label:
.inst
// CHECK-ERROR: expected expression following directive
// CHECK: [[@LINE-1]]:5: error: expected expression following '.inst' directive
.inst 0x5e104020,
// CHECK-ERROR: expected expression
// CHECK: [[@LINE-1]]:22: error: unknown token in expression in '.inst' directive
.inst .Label
// CHECK-ERROR: expected constant expression
// CHECK: [[@LINE-1]]:11: error: expected constant expression in '.inst' directive
.inst 0x5e104020 0x5e104020
// CHECK-ERROR: unexpected token in directive
// CHECK: [[@LINE-1]]:22: error: unexpected token in '.inst' directive
// CHECK-ERROR-NOT: unexpected token at start of statement