Index: llvm/trunk/include/llvm/MC/MCParser/MCAsmParserExtension.h =================================================================== --- llvm/trunk/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ llvm/trunk/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -68,8 +68,8 @@ 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); Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -68,8 +68,6 @@ 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 @@ 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 @@ 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 @@ /// 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 @@ 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 @@ // 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 @@ 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 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ // 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 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(LowerCase) @@ -2952,19 +2917,13 @@ .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 @@ 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 @@ 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 @@ } } - 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ // // 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 @@ 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 @@ 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 @@ 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 @@ getParser().parseStringToEndOfStatement().trim().split('+'); unsigned ID = AArch64::parseArch(Arch); - if (ID == static_cast(AArch64::ArchKind::AK_INVALID)) { - Error(ArchLoc, "unknown arch name"); - return false; - } + if (ID == static_cast(AArch64::ArchKind::AK_INVALID)) + return Error(ArchLoc, "unknown arch name"); + + if (parseToken(AsmToken::EndOfStatement)) + return true; // Get the architecture and extension features. std::vector AArch64Features; @@ -4276,6 +4213,9 @@ std::tie(CPU, ExtensionString) = getParser().parseStringToEndOfStatement().trim().split('+'); + if (parseToken(AsmToken::EndOfStatement)) + return true; + SmallVector RequestedExtensions; if (!ExtensionString.empty()) ExtensionString.split(RequestedExtensions, '+'); @@ -4322,66 +4262,39 @@ /// 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; - - 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(); - } - } + auto parseOp = [&]() -> bool { + const MCExpr *Value; + if (getParser().parseExpression(Value)) + return true; + getParser().getStreamer().EmitValue(Value, Size, L); + return false; + }; - 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(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 @@ // ::= .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 @@ // 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 @@ 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 @@ /// 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 @@ 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 @@ /// ::= .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; } Index: llvm/trunk/test/MC/AArch64/basic-a64-diagnostics.s =================================================================== --- llvm/trunk/test/MC/AArch64/basic-a64-diagnostics.s +++ llvm/trunk/test/MC/AArch64/basic-a64-diagnostics.s @@ -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 Index: llvm/trunk/test/MC/AArch64/inst-directive-diagnostic.s =================================================================== --- llvm/trunk/test/MC/AArch64/inst-directive-diagnostic.s +++ llvm/trunk/test/MC/AArch64/inst-directive-diagnostic.s @@ -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