diff options
Diffstat (limited to 'llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 78 |
1 files changed, 50 insertions, 28 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index efad0e221e2..05fcd2a828d 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -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; - } - return Parser.Error(L, Msg, Range); + if (MatchingInlineAsm) return true; + return Parser.Error(L, Msg, Ranges); + } + + bool ErrorAndEatStatement(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = None, + bool MatchingInlineAsm = false) { + MCAsmParser &Parser = getParser(); + Parser.eatToEndOfStatement(); + return Error(L, Msg, Ranges, MatchingInlineAsm); } 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); } |