diff options
Diffstat (limited to 'contrib/llvm/lib/MC/MCParser/AsmLexer.cpp')
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/AsmLexer.cpp | 84 |
1 files changed, 61 insertions, 23 deletions
diff --git a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp index f93f685..c1c594a 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -12,9 +12,9 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCParser/AsmLexer.h" -#include "llvm/Support/SMLoc.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SMLoc.h" #include <cctype> #include <cerrno> #include <cstdio> @@ -156,10 +156,36 @@ AsmToken AsmLexer::LexLineComment() { } static void SkipIgnoredIntegerSuffix(const char *&CurPtr) { - if (CurPtr[0] == 'L' && CurPtr[1] == 'L') - CurPtr += 2; - if (CurPtr[0] == 'U' && CurPtr[1] == 'L' && CurPtr[2] == 'L') - CurPtr += 3; + // Skip ULL, UL, U, L and LL suffices. + if (CurPtr[0] == 'U') + ++CurPtr; + if (CurPtr[0] == 'L') + ++CurPtr; + if (CurPtr[0] == 'L') + ++CurPtr; +} + +// Look ahead to search for first non-hex digit, if it's [hH], then we treat the +// integer as a hexadecimal, possibly with leading zeroes. +static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) { + const char *FirstHex = 0; + const char *LookAhead = CurPtr; + while (1) { + if (isdigit(*LookAhead)) { + ++LookAhead; + } else if (isxdigit(*LookAhead)) { + if (!FirstHex) + FirstHex = LookAhead; + ++LookAhead; + } else { + break; + } + } + bool isHex = *LookAhead == 'h' || *LookAhead == 'H'; + CurPtr = isHex || !FirstHex ? LookAhead : FirstHex; + if (isHex) + return 16; + return DefaultRadix; } /// LexDigit: First character is [0-9]. @@ -167,16 +193,15 @@ static void SkipIgnoredIntegerSuffix(const char *&CurPtr) { /// Forward/Backward Label: [0-9][fb] /// Binary integer: 0b[01]+ /// Octal integer: 0[0-7]+ -/// Hex integer: 0x[0-9a-fA-F]+ +/// Hex integer: 0x[0-9a-fA-F]+ or [0x]?[0-9][0-9a-fA-F]*[hH] /// Decimal integer: [1-9][0-9]* AsmToken AsmLexer::LexDigit() { // Decimal integer: [1-9][0-9]* if (CurPtr[-1] != '0' || CurPtr[0] == '.') { - while (isdigit(*CurPtr)) - ++CurPtr; - + unsigned Radix = doLookAhead(CurPtr, 10); + bool isHex = Radix == 16; // Check for floating point literals. - if (*CurPtr == '.' || *CurPtr == 'e') { + if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) { ++CurPtr; return LexFloatLiteral(); } @@ -184,17 +209,22 @@ AsmToken AsmLexer::LexDigit() { StringRef Result(TokStart, CurPtr - TokStart); long long Value; - if (Result.getAsInteger(10, Value)) { + if (Result.getAsInteger(Radix, Value)) { // Allow positive values that are too large to fit into a signed 64-bit // integer, but that do fit in an unsigned one, we just convert them over. unsigned long long UValue; - if (Result.getAsInteger(10, UValue)) - return ReturnError(TokStart, "invalid decimal number"); + if (Result.getAsInteger(Radix, UValue)) + return ReturnError(TokStart, !isHex ? "invalid decimal number" : + "invalid hexdecimal number"); Value = (long long)UValue; } - // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL - // suffixes on integer literals. + // Consume the [bB][hH]. + if (Radix == 2 || Radix == 16) + ++CurPtr; + + // The darwin/x86 (and x86-64) assembler accepts and ignores type + // suffices on integer literals. SkipIgnoredIntegerSuffix(CurPtr); return AsmToken(AsmToken::Integer, Result, Value); @@ -243,6 +273,10 @@ AsmToken AsmLexer::LexDigit() { if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result)) return ReturnError(TokStart, "invalid hexadecimal number"); + // Consume the optional [hH]. + if (*CurPtr == 'h' || *CurPtr == 'H') + ++CurPtr; + // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); @@ -251,14 +285,18 @@ AsmToken AsmLexer::LexDigit() { (int64_t)Result); } - // Must be an octal number, it starts with 0. - while (*CurPtr >= '0' && *CurPtr <= '9') - ++CurPtr; - - StringRef Result(TokStart, CurPtr - TokStart); + // Either octal or hexadecimal. long long Value; - if (Result.getAsInteger(8, Value)) - return ReturnError(TokStart, "invalid octal number"); + unsigned Radix = doLookAhead(CurPtr, 8); + bool isHex = Radix == 16; + StringRef Result(TokStart, CurPtr - TokStart); + if (Result.getAsInteger(Radix, Value)) + return ReturnError(TokStart, !isHex ? "invalid octal number" : + "invalid hexdecimal number"); + + // Consume the [hH]. + if (Radix == 16) + ++CurPtr; // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL // suffixes on integer literals. |