diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-07-13 18:49:30 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-07-13 18:49:30 +0000 |
commit | 19906729a490744ce3071d20e3d514cadc12e6c5 (patch) | |
tree | ad57a65f42a16d11ba8d64a1a0e66a4b2ddccd5d /lib/Target/ARM/AsmParser/ARMAsmParser.cpp | |
parent | da9f278c741e8ced7c1652720270918eb04ed348 (diff) |
Improve ARM assembly parsing diagnostics a bit.
Catch potential cascading errors on a malformed so_reg operand and bail after
the first error.
Add some tests for the diagnostics we do want.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135055 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 035907dd0a..c72b206db9 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -53,7 +53,7 @@ class ARMAsmParser : public TargetAsmParser { int TryParseRegister(); virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); - bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); + int TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &, ARMII::AddrMode AddrMode); @@ -1017,11 +1017,12 @@ int ARMAsmParser::TryParseRegister() { return RegNum; } -/// Try to parse a register name. The token must be an Identifier when called, -/// and if it is a register name the token is eaten and the register number is -/// returned. Otherwise return -1. -/// -bool ARMAsmParser::TryParseShiftRegister( +// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. +// If a recoverable error occurs, return 1. If an irrecoverable error +// occurs, return -1. An irrecoverable error is one where tokens have been +// consumed in the process of trying to parse the shifter (i.e., when it is +// indeed a shifter operand, but malformed). +int ARMAsmParser::TryParseShiftRegister( SmallVectorImpl<MCParsedAsmOperand*> &Operands) { SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); @@ -1038,7 +1039,7 @@ bool ARMAsmParser::TryParseShiftRegister( .Default(ARM_AM::no_shift); if (ShiftTy == ARM_AM::no_shift) - return true; + return 1; Parser.Lex(); // Eat the operator. @@ -1062,12 +1063,16 @@ bool ARMAsmParser::TryParseShiftRegister( Parser.Lex(); // Eat hash. SMLoc ImmLoc = Parser.getTok().getLoc(); const MCExpr *ShiftExpr = 0; - if (getParser().ParseExpression(ShiftExpr)) - return Error(ImmLoc, "invalid immediate shift value"); + if (getParser().ParseExpression(ShiftExpr)) { + Error(ImmLoc, "invalid immediate shift value"); + return -1; + } // The expression must be evaluatable as an immediate. const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); - if (!CE) - return Error(ImmLoc, "invalid immediate shift value"); + if (!CE) { + Error(ImmLoc, "invalid immediate shift value"); + return -1; + } // Range check the immediate. // lsl, ror: 0 <= imm <= 31 // lsr, asr: 0 <= imm <= 32 @@ -1075,24 +1080,28 @@ bool ARMAsmParser::TryParseShiftRegister( if (Imm < 0 || ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { - return Error(ImmLoc, "immediate shift value out of range"); + Error(ImmLoc, "immediate shift value out of range"); + return -1; } } else if (Parser.getTok().is(AsmToken::Identifier)) { ShiftReg = TryParseRegister(); SMLoc L = Parser.getTok().getLoc(); - if (ShiftReg == -1) - return Error (L, "expected immediate or register in shift operand"); - } else - return Error (Parser.getTok().getLoc(), + if (ShiftReg == -1) { + Error (L, "expected immediate or register in shift operand"); + return -1; + } + } else { + Error (Parser.getTok().getLoc(), "expected immediate or register in shift operand"); + return -1; + } } - Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, ShiftReg, Imm, S, Parser.getTok().getLoc())); - return false; + return 0; } @@ -1737,15 +1746,18 @@ bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, default: Error(Parser.getTok().getLoc(), "unexpected token in operand"); return true; - case AsmToken::Identifier: + case AsmToken::Identifier: { if (!TryParseRegisterWithWriteBack(Operands)) return false; - if (!TryParseShiftRegister(Operands)) + int Res = TryParseShiftRegister(Operands); + if (Res == 0) // success return false; - + else if (Res == -1) // irrecoverable error + return true; // Fall though for the Identifier case that is not a register or a // special name. + } case AsmToken::Integer: // things like 1f and 2b as a branch targets case AsmToken::Dot: { // . as a branch target // This was not a register so parse other operands that start with an |