summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/MC/MCParser/AsmLexer.cpp')
-rw-r--r--contrib/llvm/lib/MC/MCParser/AsmLexer.cpp84
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.
OpenPOWER on IntegriCloud