/// Parse a register list.
bool ARMAsmParser::parseRegisterList(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
- assert(Parser.getTok().is(AsmToken::LCurly) &&
- "Token is not a Left Curly Brace");
+ if (Parser.getTok().isNot(AsmToken::LCurly))
+ return TokError("Token is not a Left Curly Brace");
SMLoc S = Parser.getTok().getLoc();
Parser.Lex(); // Eat '{' token.
SMLoc RegLoc = Parser.getTok().getLoc();
bool ARMAsmParser::parseMemory(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
SMLoc S, E;
- assert(Parser.getTok().is(AsmToken::LBrac) &&
- "Token is not a Left Bracket");
+ if (Parser.getTok().isNot(AsmToken::LBrac))
+ return TokError("Token is not a Left Bracket");
S = Parser.getTok().getLoc();
Parser.Lex(); // Eat left bracket token.
return true;
}
- while (getLexer().is(AsmToken::Comma)) {
- Parser.Lex(); // Eat the comma.
-
+ while (parseOptionalToken(AsmToken::Comma)) {
// Parse and remember the operand.
if (parseOperand(Operands, Mnemonic)) {
return true;
}
}
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- return TokError("unexpected token in argument list");
- }
-
- Parser.Lex(); // Consume the EndOfStatement
+ if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
+ return true;
if (RequireVFPRegisterListCheck) {
ARMOperand &Op = static_cast<ARMOperand &>(*Operands.back());
// Rt2 must be Rt + 1 and Rt must be even.
if (Rt + 1 != Rt2 || (Rt & 1)) {
- Error(Op2.getStartLoc(), isLoad
- ? "destination operands must be sequential"
- : "source operands must be sequential");
- return true;
+ return Error(Op2.getStartLoc(),
+ isLoad ? "destination operands must be sequential"
+ : "source operands must be sequential");
}
unsigned NewReg = MRI->getMatchingSuperReg(Reg1, ARM::gsub_0,
&(MRI->getRegClass(ARM::GPRPairRegClassID)));
StringRef IDVal = DirectiveID.getIdentifier();
if (IDVal == ".word")
- return parseLiteralValues(4, DirectiveID.getLoc());
+ parseLiteralValues(4, DirectiveID.getLoc());
else if (IDVal == ".short" || IDVal == ".hword")
- return parseLiteralValues(2, DirectiveID.getLoc());
+ parseLiteralValues(2, DirectiveID.getLoc());
else if (IDVal == ".thumb")
- return parseDirectiveThumb(DirectiveID.getLoc());
+ parseDirectiveThumb(DirectiveID.getLoc());
else if (IDVal == ".arm")
- return parseDirectiveARM(DirectiveID.getLoc());
+ parseDirectiveARM(DirectiveID.getLoc());
else if (IDVal == ".thumb_func")
- return parseDirectiveThumbFunc(DirectiveID.getLoc());
+ parseDirectiveThumbFunc(DirectiveID.getLoc());
else if (IDVal == ".code")
- return parseDirectiveCode(DirectiveID.getLoc());
+ parseDirectiveCode(DirectiveID.getLoc());
else if (IDVal == ".syntax")
- return parseDirectiveSyntax(DirectiveID.getLoc());
+ parseDirectiveSyntax(DirectiveID.getLoc());
else if (IDVal == ".unreq")
- return parseDirectiveUnreq(DirectiveID.getLoc());
+ parseDirectiveUnreq(DirectiveID.getLoc());
else if (IDVal == ".fnend")
- return parseDirectiveFnEnd(DirectiveID.getLoc());
+ parseDirectiveFnEnd(DirectiveID.getLoc());
else if (IDVal == ".cantunwind")
- return parseDirectiveCantUnwind(DirectiveID.getLoc());
+ parseDirectiveCantUnwind(DirectiveID.getLoc());
else if (IDVal == ".personality")
- return parseDirectivePersonality(DirectiveID.getLoc());
+ parseDirectivePersonality(DirectiveID.getLoc());
else if (IDVal == ".handlerdata")
- return parseDirectiveHandlerData(DirectiveID.getLoc());
+ parseDirectiveHandlerData(DirectiveID.getLoc());
else if (IDVal == ".setfp")
- return parseDirectiveSetFP(DirectiveID.getLoc());
+ parseDirectiveSetFP(DirectiveID.getLoc());
else if (IDVal == ".pad")
- return parseDirectivePad(DirectiveID.getLoc());
+ parseDirectivePad(DirectiveID.getLoc());
else if (IDVal == ".save")
- return parseDirectiveRegSave(DirectiveID.getLoc(), false);
+ parseDirectiveRegSave(DirectiveID.getLoc(), false);
else if (IDVal == ".vsave")
- return parseDirectiveRegSave(DirectiveID.getLoc(), true);
+ parseDirectiveRegSave(DirectiveID.getLoc(), true);
else if (IDVal == ".ltorg" || IDVal == ".pool")
- return parseDirectiveLtorg(DirectiveID.getLoc());
+ parseDirectiveLtorg(DirectiveID.getLoc());
else if (IDVal == ".even")
- return parseDirectiveEven(DirectiveID.getLoc());
+ parseDirectiveEven(DirectiveID.getLoc());
else if (IDVal == ".personalityindex")
- return parseDirectivePersonalityIndex(DirectiveID.getLoc());
+ parseDirectivePersonalityIndex(DirectiveID.getLoc());
else if (IDVal == ".unwind_raw")
- return parseDirectiveUnwindRaw(DirectiveID.getLoc());
+ parseDirectiveUnwindRaw(DirectiveID.getLoc());
else if (IDVal == ".movsp")
- return parseDirectiveMovSP(DirectiveID.getLoc());
+ parseDirectiveMovSP(DirectiveID.getLoc());
else if (IDVal == ".arch_extension")
- return parseDirectiveArchExtension(DirectiveID.getLoc());
+ parseDirectiveArchExtension(DirectiveID.getLoc());
else if (IDVal == ".align")
- return parseDirectiveAlign(DirectiveID.getLoc());
+ return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
else if (IDVal == ".thumb_set")
- return parseDirectiveThumbSet(DirectiveID.getLoc());
-
- if (!IsMachO && !IsCOFF) {
+ parseDirectiveThumbSet(DirectiveID.getLoc());
+ else if (!IsMachO && !IsCOFF) {
if (IDVal == ".arch")
- return parseDirectiveArch(DirectiveID.getLoc());
+ parseDirectiveArch(DirectiveID.getLoc());
else if (IDVal == ".cpu")
- return parseDirectiveCPU(DirectiveID.getLoc());
+ parseDirectiveCPU(DirectiveID.getLoc());
else if (IDVal == ".eabi_attribute")
- return parseDirectiveEabiAttr(DirectiveID.getLoc());
+ parseDirectiveEabiAttr(DirectiveID.getLoc());
else if (IDVal == ".fpu")
- return parseDirectiveFPU(DirectiveID.getLoc());
+ parseDirectiveFPU(DirectiveID.getLoc());
else if (IDVal == ".fnstart")
- return parseDirectiveFnStart(DirectiveID.getLoc());
+ parseDirectiveFnStart(DirectiveID.getLoc());
else if (IDVal == ".inst")
- return parseDirectiveInst(DirectiveID.getLoc());
+ parseDirectiveInst(DirectiveID.getLoc());
else if (IDVal == ".inst.n")
- return parseDirectiveInst(DirectiveID.getLoc(), 'n');
+ parseDirectiveInst(DirectiveID.getLoc(), 'n');
else if (IDVal == ".inst.w")
- return parseDirectiveInst(DirectiveID.getLoc(), 'w');
+ parseDirectiveInst(DirectiveID.getLoc(), 'w');
else if (IDVal == ".object_arch")
- return parseDirectiveObjectArch(DirectiveID.getLoc());
+ parseDirectiveObjectArch(DirectiveID.getLoc());
else if (IDVal == ".tlsdescseq")
- return parseDirectiveTLSDescSeq(DirectiveID.getLoc());
- }
-
- return true;
+ parseDirectiveTLSDescSeq(DirectiveID.getLoc());
+ else
+ return true;
+ } else
+ return true;
+ return false;
}
/// parseLiteralValues
/// ::= .short expression [, expression]*
/// ::= .word expression [, expression]*
bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
- MCAsmParser &Parser = getParser();
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- for (;;) {
- const MCExpr *Value;
- if (getParser().parseExpression(Value)) {
- return false;
- }
-
- getParser().getStreamer().EmitValue(Value, Size, L);
-
- if (getLexer().is(AsmToken::EndOfStatement))
- break;
-
- // FIXME: Improve diagnostic.
- if (getLexer().isNot(AsmToken::Comma)) {
- Error(L, "unexpected token in directive");
- return false;
- }
- Parser.Lex();
- }
- }
-
- Parser.Lex();
- return false;
+ auto parseOne = [&]() -> bool {
+ const MCExpr *Value;
+ if (getParser().parseExpression(Value))
+ return true;
+ getParser().getStreamer().EmitValue(Value, Size, L);
+ return false;
+ };
+ return (parseMany(parseOne));
}
/// parseDirectiveThumb
/// ::= .thumb
bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
- MCAsmParser &Parser = getParser();
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- Error(L, "unexpected token in directive");
- return false;
- }
- Parser.Lex();
-
- if (!hasThumb()) {
- Error(L, "target does not support Thumb mode");
- return false;
- }
+ if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive") ||
+ check(!hasThumb(), L, "target does not support Thumb mode"))
+ return true;
if (!isThumb())
SwitchMode();
/// parseDirectiveARM
/// ::= .arm
bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
- MCAsmParser &Parser = getParser();
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- Error(L, "unexpected token in directive");
- return false;
- }
- Parser.Lex();
-
- if (!hasARM()) {
- Error(L, "target does not support ARM mode");
- return false;
- }
+ if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive") ||
+ check(!hasARM(), L, "target does not support ARM mode"))
+ return true;
if (isThumb())
SwitchMode();
-
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
return false;
}
// Darwin asm has (optionally) function name after .thumb_func direction
// ELF doesn't
- if (IsMachO) {
- const AsmToken &Tok = Parser.getTok();
- if (Tok.isNot(AsmToken::EndOfStatement)) {
- if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) {
- Error(L, "unexpected token in .thumb_func directive");
- return false;
- }
- MCSymbol *Func =
- getParser().getContext().getOrCreateSymbol(Tok.getIdentifier());
+ if (IsMachO) {
+ if (Parser.getTok().is(AsmToken::Identifier) ||
+ Parser.getTok().is(AsmToken::String)) {
+ MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
+ Parser.getTok().getIdentifier());
getParser().getStreamer().EmitThumbFunc(Func);
- Parser.Lex(); // Consume the identifier token.
+ Parser.Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.thumb_func' directive"))
+ return true;
return false;
}
}
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- Error(Parser.getTok().getLoc(), "unexpected token in directive");
- return false;
- }
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.thumb_func' directive"))
+ return true;
NextSymbolIsThumb = true;
return false;
}
StringRef Mode = Tok.getString();
- if (Mode == "unified" || Mode == "UNIFIED") {
- Parser.Lex();
- } else if (Mode == "divided" || Mode == "DIVIDED") {
- Error(L, "'.syntax divided' arm asssembly not supported");
- return false;
- } else {
- Error(L, "unrecognized syntax mode in .syntax directive");
- return false;
- }
-
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- Error(Parser.getTok().getLoc(), "unexpected token in directive");
- return false;
- }
Parser.Lex();
+ if (check(Mode == "divided" || Mode == "DIVIDED", L,
+ "'.syntax divided' arm assembly not supported") ||
+ check(Mode != "unified" && Mode != "UNIFIED", L,
+ "unrecognized syntax mode in .syntax directive") ||
+ parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
+ return true;
// TODO tell the MC streamer the mode
// getParser().getStreamer().Emit???();
bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
- if (Tok.isNot(AsmToken::Integer)) {
- Error(L, "unexpected token in .code directive");
- return false;
- }
+ if (Tok.isNot(AsmToken::Integer))
+ return Error(L, "unexpected token in .code directive");
int64_t Val = Parser.getTok().getIntVal();
if (Val != 16 && Val != 32) {
Error(L, "invalid operand to .code directive");
}
Parser.Lex();
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- Error(Parser.getTok().getLoc(), "unexpected token in directive");
- return false;
- }
- Parser.Lex();
+ if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
+ return true;
if (Val == 16) {
- if (!hasThumb()) {
- Error(L, "target does not support Thumb mode");
- return false;
- }
+ if (!hasThumb())
+ return Error(L, "target does not support Thumb mode");
if (!isThumb())
SwitchMode();
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
} else {
- if (!hasARM()) {
- Error(L, "target does not support ARM mode");
- return false;
- }
+ if (!hasARM())
+ return Error(L, "target does not support ARM mode");
if (isThumb())
SwitchMode();
Parser.Lex(); // Eat the '.req' token.
unsigned Reg;
SMLoc SRegLoc, ERegLoc;
- if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
- Error(SRegLoc, "register name expected");
- return false;
- }
-
- // Shouldn't be anything else.
- if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
- Error(Parser.getTok().getLoc(), "unexpected input in .req directive.");
- return false;
- }
-
- Parser.Lex(); // Consume the EndOfStatement
+ if (check(ParseRegister(Reg, SRegLoc, ERegLoc), SRegLoc,
+ "register name expected") ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected input in .req directive."))
+ return true;
- if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg) {
- Error(SRegLoc, "redefinition of '" + Name + "' does not match original.");
- return false;
- }
+ if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg)
+ return Error(SRegLoc,
+ "redefinition of '" + Name + "' does not match original.");
return false;
}
/// ::= .unreq registername
bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
MCAsmParser &Parser = getParser();
- if (Parser.getTok().isNot(AsmToken::Identifier)) {
- Error(L, "unexpected input in .unreq directive.");
- return false;
- }
+ if (Parser.getTok().isNot(AsmToken::Identifier))
+ return Error(L, "unexpected input in .unreq directive.");
RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
Parser.Lex(); // Eat the identifier.
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected input in '.unreq' directive"))
+ return true;
return false;
}
/// ::= .arch token
bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
StringRef Arch = getParser().parseStringToEndOfStatement().trim();
-
unsigned ID = ARM::parseArch(Arch);
- if (ID == ARM::AK_INVALID) {
- Error(L, "Unknown arch name");
- return false;
- }
+ if (ID == ARM::AK_INVALID)
+ return Error(L, "Unknown arch name");
bool WasThumb = isThumb();
Triple T;
const MCExpr *AttrExpr;
TagLoc = Parser.getTok().getLoc();
- if (Parser.parseExpression(AttrExpr)) {
- return false;
- }
+ if (Parser.parseExpression(AttrExpr))
+ return true;
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
- if (!CE) {
- Error(TagLoc, "expected numeric constant");
- return false;
- }
+ if (check(!CE, TagLoc, "expected numeric constant"))
+ return true;
Tag = CE->getValue();
}
- if (Parser.getTok().isNot(AsmToken::Comma)) {
- Error(Parser.getTok().getLoc(), "comma expected");
- return false;
- }
- Parser.Lex(); // skip comma
+ if (Parser.parseToken(AsmToken::Comma, "comma expected"))
+ return true;
StringRef StringValue = "";
bool IsStringValue = false;
if (IsIntegerValue) {
const MCExpr *ValueExpr;
SMLoc ValueExprLoc = Parser.getTok().getLoc();
- if (Parser.parseExpression(ValueExpr)) {
- return false;
- }
+ if (Parser.parseExpression(ValueExpr))
+ return true;
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
- if (!CE) {
- Error(ValueExprLoc, "expected numeric constant");
- return false;
- }
-
+ if (!CE)
+ return Error(ValueExprLoc, "expected numeric constant");
IntegerValue = CE->getValue();
}
if (Tag == ARMBuildAttrs::compatibility) {
- if (Parser.getTok().isNot(AsmToken::Comma))
- IsStringValue = false;
- if (Parser.getTok().isNot(AsmToken::Comma)) {
- Error(Parser.getTok().getLoc(), "comma expected");
- return false;
- } else {
- Parser.Lex();
- }
+ if (Parser.parseToken(AsmToken::Comma, "comma expected"))
+ return true;
}
if (IsStringValue) {
- if (Parser.getTok().isNot(AsmToken::String)) {
- Error(Parser.getTok().getLoc(), "bad string constant");
- return false;
- }
+ if (Parser.getTok().isNot(AsmToken::String))
+ return Error(Parser.getTok().getLoc(), "bad string constant");
StringValue = Parser.getTok().getStringContents();
Parser.Lex();
}
+ if (Parser.parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.eabi_attribute' directive"))
+ return true;
+
if (IsIntegerValue && IsStringValue) {
assert(Tag == ARMBuildAttrs::compatibility);
getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
// FIXME: This is using table-gen data, but should be moved to
// ARMTargetParser once that is table-gen'd.
- if (!getSTI().isCPUStringValid(CPU)) {
- Error(L, "Unknown CPU name");
- return false;
- }
+ if (!getSTI().isCPUStringValid(CPU))
+ return Error(L, "Unknown CPU name");
bool WasThumb = isThumb();
MCSubtargetInfo &STI = copySTI();
unsigned ID = ARM::parseFPU(FPU);
std::vector<StringRef> Features;
- if (!ARM::getFPUFeatures(ID, Features)) {
- Error(FPUNameLoc, "Unknown FPU name");
- return false;
- }
+ if (!ARM::getFPUFeatures(ID, Features))
+ return Error(FPUNameLoc, "Unknown FPU name");
MCSubtargetInfo &STI = copySTI();
for (auto Feature : Features)
/// parseDirectiveFnStart
/// ::= .fnstart
bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.fnstart' directive"))
+ return true;
+
if (UC.hasFnStart()) {
Error(L, ".fnstart starts before the end of previous one");
UC.emitFnStartLocNotes();
- return false;
+ return true;
}
// Reset the unwind directives parser state
/// parseDirectiveFnEnd
/// ::= .fnend
bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.fnend' directive"))
+ return true;
// Check the ordering of unwind directives
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .fnend directive");
- return false;
- }
+ if (!UC.hasFnStart())
+ return Error(L, ".fnstart must precede .fnend directive");
// Reset the unwind directives parser state
getTargetStreamer().emitFnEnd();
/// parseDirectiveCantUnwind
/// ::= .cantunwind
bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
- UC.recordCantUnwind(L);
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.cantunwind' directive"))
+ return true;
+ UC.recordCantUnwind(L);
// Check the ordering of unwind directives
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .cantunwind directive");
- return false;
- }
+ if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive"))
+ return true;
+
if (UC.hasHandlerData()) {
Error(L, ".cantunwind can't be used with .handlerdata directive");
UC.emitHandlerDataLocNotes();
- return false;
+ return true;
}
if (UC.hasPersonality()) {
Error(L, ".cantunwind can't be used with .personality directive");
UC.emitPersonalityLocNotes();
- return false;
+ return true;
}
getTargetStreamer().emitCantUnwind();
MCAsmParser &Parser = getParser();
bool HasExistingPersonality = UC.hasPersonality();
+ // Parse the name of the personality routine
+ if (Parser.getTok().isNot(AsmToken::Identifier))
+ return Error(L, "unexpected input in .personality directive.");
+ StringRef Name(Parser.getTok().getIdentifier());
+ Parser.Lex();
+
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.personality' directive"))
+ return true;
+
UC.recordPersonality(L);
// Check the ordering of unwind directives
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .personality directive");
- return false;
- }
+ if (!UC.hasFnStart())
+ return Error(L, ".fnstart must precede .personality directive");
if (UC.cantUnwind()) {
Error(L, ".personality can't be used with .cantunwind directive");
UC.emitCantUnwindLocNotes();
- return false;
+ return true;
}
if (UC.hasHandlerData()) {
Error(L, ".personality must precede .handlerdata directive");
UC.emitHandlerDataLocNotes();
- return false;
+ return true;
}
if (HasExistingPersonality) {
Error(L, "multiple personality directives");
UC.emitPersonalityLocNotes();
- return false;
- }
-
- // Parse the name of the personality routine
- if (Parser.getTok().isNot(AsmToken::Identifier)) {
- Error(L, "unexpected input in .personality directive.");
- return false;
+ return true;
}
- StringRef Name(Parser.getTok().getIdentifier());
- Parser.Lex();
MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
getTargetStreamer().emitPersonality(PR);
/// parseDirectiveHandlerData
/// ::= .handlerdata
bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
- UC.recordHandlerData(L);
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.handlerdata' directive"))
+ return true;
+ UC.recordHandlerData(L);
// Check the ordering of unwind directives
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .personality directive");
- return false;
- }
+ if (!UC.hasFnStart())
+ return Error(L, ".fnstart must precede .personality directive");
if (UC.cantUnwind()) {
Error(L, ".handlerdata can't be used with .cantunwind directive");
UC.emitCantUnwindLocNotes();
- return false;
+ return true;
}
getTargetStreamer().emitHandlerData();
bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
MCAsmParser &Parser = getParser();
// Check the ordering of unwind directives
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .setfp directive");
- return false;
- }
- if (UC.hasHandlerData()) {
- Error(L, ".setfp must precede .handlerdata directive");
- return false;
- }
+ if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") ||
+ check(UC.hasHandlerData(), L,
+ ".setfp must precede .handlerdata directive"))
+ return true;
// Parse fpreg
SMLoc FPRegLoc = Parser.getTok().getLoc();
int FPReg = tryParseRegister();
- if (FPReg == -1) {
- Error(FPRegLoc, "frame pointer register expected");
- return false;
- }
- // Consume comma
- if (Parser.getTok().isNot(AsmToken::Comma)) {
- Error(Parser.getTok().getLoc(), "comma expected");
- return false;
- }
- Parser.Lex(); // skip comma
+ if (check(FPReg == -1, FPRegLoc, "frame pointer register expected") ||
+ Parser.parseToken(AsmToken::Comma, "comma expected"))
+ return true;
// Parse spreg
SMLoc SPRegLoc = Parser.getTok().getLoc();
int SPReg = tryParseRegister();
- if (SPReg == -1) {
- Error(SPRegLoc, "stack pointer register expected");
- return false;
- }
-
- if (SPReg != ARM::SP && SPReg != UC.getFPReg()) {
- Error(SPRegLoc, "register should be either $sp or the latest fp register");
- return false;
- }
+ if (check(SPReg == -1, SPRegLoc, "stack pointer register expected") ||
+ check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
+ "register should be either $sp or the latest fp register"))
+ return true;
// Update the frame pointer register
UC.saveFPReg(FPReg);
// Parse offset
int64_t Offset = 0;
- if (Parser.getTok().is(AsmToken::Comma)) {
- Parser.Lex(); // skip comma
-
+ if (Parser.parseOptionalToken(AsmToken::Comma)) {
if (Parser.getTok().isNot(AsmToken::Hash) &&
- Parser.getTok().isNot(AsmToken::Dollar)) {
- Error(Parser.getTok().getLoc(), "'#' expected");
- return false;
- }
+ Parser.getTok().isNot(AsmToken::Dollar))
+ return Error(Parser.getTok().getLoc(), "'#' expected");
Parser.Lex(); // skip hash token.
const MCExpr *OffsetExpr;
SMLoc ExLoc = Parser.getTok().getLoc();
SMLoc EndLoc;
- if (getParser().parseExpression(OffsetExpr, EndLoc)) {
- Error(ExLoc, "malformed setfp offset");
- return false;
- }
+ if (getParser().parseExpression(OffsetExpr, EndLoc))
+ return Error(ExLoc, "malformed setfp offset");
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
- if (!CE) {
- Error(ExLoc, "setfp offset must be an immediate");
- return false;
- }
-
+ if (check(!CE, ExLoc, "setfp offset must be an immediate"))
+ return true;
Offset = CE->getValue();
}
+ if (Parser.parseToken(AsmToken::EndOfStatement))
+ return true;
+
getTargetStreamer().emitSetFP(static_cast<unsigned>(FPReg),
static_cast<unsigned>(SPReg), Offset);
return false;
bool ARMAsmParser::parseDirectivePad(SMLoc L) {
MCAsmParser &Parser = getParser();
// Check the ordering of unwind directives
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .pad directive");
- return false;
- }
- if (UC.hasHandlerData()) {
- Error(L, ".pad must precede .handlerdata directive");
- return false;
- }
+ if (!UC.hasFnStart())
+ return Error(L, ".fnstart must precede .pad directive");
+ if (UC.hasHandlerData())
+ return Error(L, ".pad must precede .handlerdata directive");
// Parse the offset
if (Parser.getTok().isNot(AsmToken::Hash) &&
- Parser.getTok().isNot(AsmToken::Dollar)) {
- Error(Parser.getTok().getLoc(), "'#' expected");
- return false;
- }
+ Parser.getTok().isNot(AsmToken::Dollar))
+ return Error(Parser.getTok().getLoc(), "'#' expected");
Parser.Lex(); // skip hash token.
const MCExpr *OffsetExpr;
SMLoc ExLoc = Parser.getTok().getLoc();
SMLoc EndLoc;
- if (getParser().parseExpression(OffsetExpr, EndLoc)) {
- Error(ExLoc, "malformed pad offset");
- return false;
- }
+ if (getParser().parseExpression(OffsetExpr, EndLoc))
+ return Error(ExLoc, "malformed pad offset");
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
- if (!CE) {
- Error(ExLoc, "pad offset must be an immediate");
- return false;
- }
+ if (!CE)
+ return Error(ExLoc, "pad offset must be an immediate");
+
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.pad' directive"))
+ return true;
getTargetStreamer().emitPad(CE->getValue());
return false;
/// ::= .vsave { registers }
bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
// Check the ordering of unwind directives
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .save or .vsave directives");
- return false;
- }
- if (UC.hasHandlerData()) {
- Error(L, ".save or .vsave must precede .handlerdata directive");
- return false;
- }
+ if (!UC.hasFnStart())
+ return Error(L, ".fnstart must precede .save or .vsave directives");
+ if (UC.hasHandlerData())
+ return Error(L, ".save or .vsave must precede .handlerdata directive");
// RAII object to make sure parsed operands are deleted.
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
// Parse the register list
- if (parseRegisterList(Operands))
- return false;
+ if (parseRegisterList(Operands) ||
+ parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
+ return true;
ARMOperand &Op = (ARMOperand &)*Operands[0];
- if (!IsVector && !Op.isRegList()) {
- Error(L, ".save expects GPR registers");
- return false;
- }
- if (IsVector && !Op.isDPRRegList()) {
- Error(L, ".vsave expects DPR registers");
- return false;
- }
+ if (!IsVector && !Op.isRegList())
+ return Error(L, ".save expects GPR registers");
+ if (IsVector && !Op.isDPRRegList())
+ return Error(L, ".vsave expects DPR registers");
getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
return false;
/// ::= .inst.n opcode [, ...]
/// ::= .inst.w opcode [, ...]
bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
- MCAsmParser &Parser = getParser();
- int Width;
+ int Width = 4;
if (isThumb()) {
switch (Suffix) {
Width = 2;
break;
case 'w':
- Width = 4;
break;
default:
- Error(Loc, "cannot determine Thumb instruction size, "
- "use inst.n/inst.w instead");
- return false;
+ return Error(Loc, "cannot determine Thumb instruction size, "
+ "use inst.n/inst.w instead");
}
} else {
- if (Suffix) {
- Error(Loc, "width suffixes are invalid in ARM mode");
- return false;
- }
- Width = 4;
- }
-
- if (getLexer().is(AsmToken::EndOfStatement)) {
- Error(Loc, "expected expression following directive");
- return false;
+ if (Suffix)
+ return Error(Loc, "width suffixes are invalid in ARM mode");
}
- for (;;) {
+ auto parseOne = [&]() -> bool {
const MCExpr *Expr;
-
- if (getParser().parseExpression(Expr)) {
- Error(Loc, "expected expression");
- return false;
- }
-
+ if (getParser().parseExpression(Expr))
+ return true;
const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
if (!Value) {
- Error(Loc, "expected constant expression");
- return false;
+ return Error(Loc, "expected constant expression");
}
switch (Width) {
case 2:
- if (Value->getValue() > 0xffff) {
- Error(Loc, "inst.n operand is too big, use inst.w instead");
- return false;
- }
+ if (Value->getValue() > 0xffff)
+ return Error(Loc, "inst.n operand is too big, use inst.w instead");
break;
case 4:
- if (Value->getValue() > 0xffffffff) {
- Error(Loc,
- StringRef(Suffix ? "inst.w" : "inst") + " operand is too big");
- return false;
- }
+ if (Value->getValue() > 0xffffffff)
+ return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +
+ " operand is too big");
break;
default:
llvm_unreachable("only supported widths are 2 and 4");
}
getTargetStreamer().emitInst(Value->getValue(), Suffix);
+ return false;
+ };
- if (getLexer().is(AsmToken::EndOfStatement))
- break;
-
- if (getLexer().isNot(AsmToken::Comma)) {
- Error(Loc, "unexpected token in directive");
- return false;
- }
-
- Parser.Lex();
- }
-
- Parser.Lex();
+ if (parseOptionalToken(AsmToken::EndOfStatement))
+ return Error(Loc, "expected expression following directive");
+ if (parseMany(parseOne))
+ return true;
return false;
}
/// parseDirectiveLtorg
/// ::= .ltorg | .pool
bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
+ if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
+ return true;
getTargetStreamer().emitCurrentConstantPool();
return false;
}
bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
const MCSection *Section = getStreamer().getCurrentSectionOnly();
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- TokError("unexpected token in directive");
- return false;
- }
+ if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
+ return true;
if (!Section) {
getStreamer().InitSections(false);
MCAsmParser &Parser = getParser();
bool HasExistingPersonality = UC.hasPersonality();
+ const MCExpr *IndexExpression;
+ SMLoc IndexLoc = Parser.getTok().getLoc();
+ if (Parser.parseExpression(IndexExpression) ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.personalityindex' directive")) {
+ return true;
+ }
+
UC.recordPersonalityIndex(L);
if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .personalityindex directive");
- return false;
+ return Error(L, ".fnstart must precede .personalityindex directive");
}
if (UC.cantUnwind()) {
Error(L, ".personalityindex cannot be used with .cantunwind");
UC.emitCantUnwindLocNotes();
- return false;
+ return true;
}
if (UC.hasHandlerData()) {
Error(L, ".personalityindex must precede .handlerdata directive");
UC.emitHandlerDataLocNotes();
- return false;
+ return true;
}
if (HasExistingPersonality) {
Error(L, "multiple personality directives");
UC.emitPersonalityLocNotes();
- return false;
- }
-
- const MCExpr *IndexExpression;
- SMLoc IndexLoc = Parser.getTok().getLoc();
- if (Parser.parseExpression(IndexExpression)) {
- return false;
+ return true;
}
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression);
- if (!CE) {
- Error(IndexLoc, "index must be a constant number");
- return false;
- }
- if (CE->getValue() < 0 ||
- CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX) {
- Error(IndexLoc, "personality routine index should be in range [0-3]");
- return false;
- }
+ if (!CE)
+ return Error(IndexLoc, "index must be a constant number");
+ if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX)
+ return Error(IndexLoc,
+ "personality routine index should be in range [0-3]");
getTargetStreamer().emitPersonalityIndex(CE->getValue());
return false;
/// ::= .unwind_raw offset, opcode [, opcode...]
bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
MCAsmParser &Parser = getParser();
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .unwind_raw directives");
- return false;
- }
-
int64_t StackOffset;
-
const MCExpr *OffsetExpr;
SMLoc OffsetLoc = getLexer().getLoc();
- if (getLexer().is(AsmToken::EndOfStatement) ||
- getParser().parseExpression(OffsetExpr)) {
- Error(OffsetLoc, "expected expression");
- return false;
- }
+
+ if (!UC.hasFnStart())
+ return Error(L, ".fnstart must precede .unwind_raw directives");
+ if (getParser().parseExpression(OffsetExpr))
+ return Error(OffsetLoc, "expected expression");
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
- if (!CE) {
- Error(OffsetLoc, "offset must be a constant");
- return false;
- }
+ if (!CE)
+ return Error(OffsetLoc, "offset must be a constant");
StackOffset = CE->getValue();
- if (getLexer().isNot(AsmToken::Comma)) {
- Error(getLexer().getLoc(), "expected comma");
- return false;
- }
- Parser.Lex();
+ if (Parser.parseToken(AsmToken::Comma, "expected comma"))
+ return true;
SmallVector<uint8_t, 16> Opcodes;
- for (;;) {
- const MCExpr *OE;
+ auto parseOne = [&]() -> bool {
+ const MCExpr *OE;
SMLoc OpcodeLoc = getLexer().getLoc();
- if (getLexer().is(AsmToken::EndOfStatement) || Parser.parseExpression(OE)) {
- Error(OpcodeLoc, "expected opcode expression");
- return false;
- }
-
+ if (check(getLexer().is(AsmToken::EndOfStatement) ||
+ Parser.parseExpression(OE),
+ OpcodeLoc, "expected opcode expression"))
+ return true;
const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE);
- if (!OC) {
- Error(OpcodeLoc, "opcode value must be a constant");
- return false;
- }
-
+ if (!OC)
+ return Error(OpcodeLoc, "opcode value must be a constant");
const int64_t Opcode = OC->getValue();
- if (Opcode & ~0xff) {
- Error(OpcodeLoc, "invalid opcode");
- return false;
- }
-
+ if (Opcode & ~0xff)
+ return Error(OpcodeLoc, "invalid opcode");
Opcodes.push_back(uint8_t(Opcode));
+ return false;
+ };
- if (getLexer().is(AsmToken::EndOfStatement))
- break;
-
- if (getLexer().isNot(AsmToken::Comma)) {
- Error(getLexer().getLoc(), "unexpected token in directive");
- return false;
- }
-
- Parser.Lex();
- }
+ // Must have at least 1 element
+ SMLoc OpcodeLoc = getLexer().getLoc();
+ if (parseOptionalToken(AsmToken::EndOfStatement))
+ return Error(OpcodeLoc, "expected opcode expression");
+ if (parseMany(parseOne))
+ return true;
getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
-
- Parser.Lex();
return false;
}
bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
MCAsmParser &Parser = getParser();
- if (getLexer().isNot(AsmToken::Identifier)) {
- TokError("expected variable after '.tlsdescseq' directive");
- return false;
- }
+ if (getLexer().isNot(AsmToken::Identifier))
+ return TokError("expected variable after '.tlsdescseq' directive");
const MCSymbolRefExpr *SRE =
MCSymbolRefExpr::create(Parser.getTok().getIdentifier(),
MCSymbolRefExpr::VK_ARM_TLSDESCSEQ, getContext());
Lex();
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- Error(Parser.getTok().getLoc(), "unexpected token");
- return false;
- }
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.tlsdescseq' directive"))
+ return true;
getTargetStreamer().AnnotateTLSDescriptorSequence(SRE);
return false;
/// ::= .movsp reg [, #offset]
bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
MCAsmParser &Parser = getParser();
- if (!UC.hasFnStart()) {
- Error(L, ".fnstart must precede .movsp directives");
- return false;
- }
- if (UC.getFPReg() != ARM::SP) {
- Error(L, "unexpected .movsp directive");
- return false;
- }
+ if (!UC.hasFnStart())
+ return Error(L, ".fnstart must precede .movsp directives");
+ if (UC.getFPReg() != ARM::SP)
+ return Error(L, "unexpected .movsp directive");
SMLoc SPRegLoc = Parser.getTok().getLoc();
int SPReg = tryParseRegister();
- if (SPReg == -1) {
- Error(SPRegLoc, "register expected");
- return false;
- }
-
- if (SPReg == ARM::SP || SPReg == ARM::PC) {
- Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
- return false;
- }
+ if (SPReg == -1)
+ return Error(SPRegLoc, "register expected");
+ if (SPReg == ARM::SP || SPReg == ARM::PC)
+ return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
int64_t Offset = 0;
- if (Parser.getTok().is(AsmToken::Comma)) {
- Parser.Lex();
-
- if (Parser.getTok().isNot(AsmToken::Hash)) {
- Error(Parser.getTok().getLoc(), "expected #constant");
- return false;
- }
- Parser.Lex();
+ if (Parser.parseOptionalToken(AsmToken::Comma)) {
+ if (Parser.parseToken(AsmToken::Hash, "expected #constant"))
+ return true;
const MCExpr *OffsetExpr;
SMLoc OffsetLoc = Parser.getTok().getLoc();
- if (Parser.parseExpression(OffsetExpr)) {
- Error(OffsetLoc, "malformed offset expression");
- return false;
- }
+
+ if (Parser.parseExpression(OffsetExpr))
+ return Error(OffsetLoc, "malformed offset expression");
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
- if (!CE) {
- Error(OffsetLoc, "offset must be an immediate constant");
- return false;
- }
+ if (!CE)
+ return Error(OffsetLoc, "offset must be an immediate constant");
Offset = CE->getValue();
}
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.movsp' directive"))
+ return true;
+
getTargetStreamer().emitMovSP(SPReg, Offset);
UC.saveFPReg(SPReg);
/// ::= .object_arch name
bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
MCAsmParser &Parser = getParser();
- if (getLexer().isNot(AsmToken::Identifier)) {
- Error(getLexer().getLoc(), "unexpected token");
- return false;
- }
+ if (getLexer().isNot(AsmToken::Identifier))
+ return Error(getLexer().getLoc(), "unexpected token");
StringRef Arch = Parser.getTok().getString();
SMLoc ArchLoc = Parser.getTok().getLoc();
unsigned ID = ARM::parseArch(Arch);
- if (ID == ARM::AK_INVALID) {
- Error(ArchLoc, "unknown architecture '" + Arch + "'");
- return false;
- }
+ if (ID == ARM::AK_INVALID)
+ return Error(ArchLoc, "unknown architecture '" + Arch + "'");
+ if (parseToken(AsmToken::EndOfStatement))
+ return true;
getTargetStreamer().emitObjectArch(ID);
-
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- Error(getLexer().getLoc(), "unexpected token");
- }
-
return false;
}
bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
// NOTE: if this is not the end of the statement, fall back to the target
// agnostic handling for this directive which will correctly handle this.
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return true;
-
- // '.align' is target specifically handled to mean 2**2 byte alignment.
- const MCSection *Section = getStreamer().getCurrentSectionOnly();
- assert(Section && "must have section to emit alignment");
- if (Section->UseCodeAlign())
- getStreamer().EmitCodeAlignment(4, 0);
- else
- getStreamer().EmitValueToAlignment(4, 0, 1, 0);
-
- return false;
+ if (parseOptionalToken(AsmToken::EndOfStatement)) {
+ // '.align' is target specifically handled to mean 2**2 byte alignment.
+ const MCSection *Section = getStreamer().getCurrentSectionOnly();
+ assert(Section && "must have section to emit alignment");
+ if (Section->UseCodeAlign())
+ getStreamer().EmitCodeAlignment(4, 0);
+ else
+ getStreamer().EmitValueToAlignment(4, 0, 1, 0);
+ return false;
+ }
+ return true;
}
/// parseDirectiveThumbSet
MCAsmParser &Parser = getParser();
StringRef Name;
- if (Parser.parseIdentifier(Name)) {
- TokError("expected identifier after '.thumb_set'");
- return false;
- }
-
- if (getLexer().isNot(AsmToken::Comma)) {
- TokError("expected comma after name '" + Name + "'");
- return false;
- }
- Lex();
+ if (check(Parser.parseIdentifier(Name),
+ "expected identifier after '.thumb_set'") ||
+ parseToken(AsmToken::Comma, "expected comma after name '" + Name + "'"))
+ return true;
MCSymbol *Sym;
const MCExpr *Value;
bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
MCAsmParser &Parser = getParser();
- if (getLexer().isNot(AsmToken::Identifier)) {
- Error(getLexer().getLoc(), "expected architecture extension name");
- return false;
- }
+ if (getLexer().isNot(AsmToken::Identifier))
+ return Error(getLexer().getLoc(), "expected architecture extension name");
StringRef Name = Parser.getTok().getString();
SMLoc ExtLoc = Parser.getTok().getLoc();
Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.arch_extension' directive"))
+ return true;
+
bool EnableFeature = true;
if (Name.startswith_lower("no")) {
EnableFeature = false;
Name = Name.substr(2);
}
unsigned FeatureKind = ARM::parseArchExt(Name);
- if (FeatureKind == ARM::AEK_INVALID) {
- Error(ExtLoc, "unknown architectural extension: " + Name);
- return false;
- }
+ if (FeatureKind == ARM::AEK_INVALID)
+ return Error(ExtLoc, "unknown architectural extension: " + Name);
for (const auto &Extension : Extensions) {
if (Extension.Kind != FeatureKind)
continue;
- if (Extension.Features.none()) {
- Error(ExtLoc, "unsupported architectural extension: " + Name);
- return false;
- }
+ if (Extension.Features.none())
+ return Error(ExtLoc, "unsupported architectural extension: " + Name);
- if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck) {
- Error(ExtLoc, "architectural extension '" + Name + "' is not "
- "allowed for the current base architecture");
- return false;
- }
+ if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck)
+ return Error(ExtLoc, "architectural extension '" + Name +
+ "' is not "
+ "allowed for the current base architecture");
MCSubtargetInfo &STI = copySTI();
FeatureBitset ToggleFeatures = EnableFeature
return false;
}
- Error(ExtLoc, "unknown architectural extension: " + Name);
- return false;
+ return Error(ExtLoc, "unknown architectural extension: " + Name);
}
// Define this matcher function after the auto-generated include so we