summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2013-02-12 18:29:02 +0000
committerChad Rosier <mcrosier@apple.com>2013-02-12 18:29:02 +0000
commit8915e27704b2afd362a69c6be1111fb06bbcc727 (patch)
tree068e87c713405ef644808ce4b7e7bb49eea6c289 /lib/MC/MCParser
parent1cb058f77c7b15045c677ef30586fe45c2929010 (diff)
downloadllvm-8915e27704b2afd362a69c6be1111fb06bbcc727.tar.gz
llvm-8915e27704b2afd362a69c6be1111fb06bbcc727.tar.bz2
llvm-8915e27704b2afd362a69c6be1111fb06bbcc727.tar.xz
[ms-inline asm] Add support for lexing binary integers with a [bB] suffix.
This is complicated by backward labels (e.g., 0b can be both a backward label and a binary zero). The current implementation assumes [0-9]b is always a label and thus it's possible for 0b and 1b to not be interpreted correctly for ms-style inline assembly. However, this is relatively simple to fix in the inline assembly (i.e., drop the [bB]). This patch also limits backward labels to [0-9]b, so that only 0b and 1b are ambiguous. Part of rdar://12470373 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174983 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp59
1 files changed, 40 insertions, 19 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index 530e94e8d3..8fcc264d68 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -179,26 +179,48 @@ static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) {
}
}
bool isHex = *LookAhead == 'h' || *LookAhead == 'H';
- CurPtr = isHex || !FirstHex ? LookAhead : FirstHex;
+ bool isBinary = LookAhead[-1] == 'b' || LookAhead[-1] == 'B';
+ CurPtr = (isBinary || isHex || !FirstHex) ? LookAhead : FirstHex;
if (isHex)
return 16;
+ if (isBinary) {
+ --CurPtr;
+ return 2;
+ }
return DefaultRadix;
}
/// LexDigit: First character is [0-9].
/// Local Label: [0-9][:]
-/// Forward/Backward Label: [0-9][fb]
-/// Binary integer: 0b[01]+
+/// Forward/Backward Label: [0-9]+f or [0-9]b
+/// Binary integer: 0b[01]+ or [01][bB]
/// Octal integer: 0[0-7]+
/// 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() {
+
+ // Backward Label: [0-9]b
+ if (*CurPtr == 'b') {
+ // See if we actually have "0b" as part of something like "jmp 0b\n"
+ if (!isdigit(CurPtr[1])) {
+ long long Value;
+ StringRef Result(TokStart, CurPtr - TokStart);
+ if (Result.getAsInteger(10, Value))
+ return ReturnError(TokStart, "invalid backward label");
+
+ return AsmToken(AsmToken::Integer, Result, Value);
+ }
+ }
+
+ // Binary integer: 1[01]*[bB]
// Decimal integer: [1-9][0-9]*
+ // Hexidecimal integer: [1-9][0-9a-fA-F]*[hH]
if (CurPtr[-1] != '0' || CurPtr[0] == '.') {
unsigned Radix = doLookAhead(CurPtr, 10);
- bool isHex = Radix == 16;
+ bool isDecimal = Radix == 10;
+
// Check for floating point literals.
- if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) {
+ if (isDecimal && (*CurPtr == '.' || *CurPtr == 'e')) {
++CurPtr;
return LexFloatLiteral();
}
@@ -211,7 +233,7 @@ AsmToken AsmLexer::LexDigit() {
// integer, but that do fit in an unsigned one, we just convert them over.
unsigned long long UValue;
if (Result.getAsInteger(Radix, UValue))
- return ReturnError(TokStart, !isHex ? "invalid decimal number" :
+ return ReturnError(TokStart, isDecimal ? "invalid decimal number" :
"invalid hexdecimal number");
Value = (long long)UValue;
}
@@ -227,15 +249,9 @@ AsmToken AsmLexer::LexDigit() {
return AsmToken(AsmToken::Integer, Result, Value);
}
+ // Binary integer: 0b[01]+
if (*CurPtr == 'b') {
- ++CurPtr;
- // See if we actually have "0b" as part of something like "jmp 0b\n"
- if (!isdigit(CurPtr[0])) {
- --CurPtr;
- StringRef Result(TokStart, CurPtr - TokStart);
- return AsmToken(AsmToken::Integer, Result, 0);
- }
- const char *NumStart = CurPtr;
+ const char *NumStart = ++CurPtr;
while (CurPtr[0] == '0' || CurPtr[0] == '1')
++CurPtr;
@@ -256,6 +272,7 @@ AsmToken AsmLexer::LexDigit() {
return AsmToken(AsmToken::Integer, Result, Value);
}
+ // Hex integer: 0x[0-9a-fA-F]+
if (*CurPtr == 'x') {
++CurPtr;
const char *NumStart = CurPtr;
@@ -282,17 +299,21 @@ AsmToken AsmLexer::LexDigit() {
(int64_t)Result);
}
- // Either octal or hexidecimal.
+ // Binary: 0[01]*[Bb], but not 0b.
+ // Octal: 0[0-7]*
+ // Hexidecimal: [0][0-9a-fA-F]*[hH]
long long Value;
unsigned Radix = doLookAhead(CurPtr, 8);
- bool isHex = Radix == 16;
+ bool isBinary = Radix == 2;
+ bool isOctal = Radix == 8;
StringRef Result(TokStart, CurPtr - TokStart);
if (Result.getAsInteger(Radix, Value))
- return ReturnError(TokStart, !isHex ? "invalid octal number" :
+ return ReturnError(TokStart, isOctal ? "invalid octal number" :
+ isBinary ? "invalid binary number" :
"invalid hexdecimal number");
- // Consume the [hH].
- if (Radix == 16)
+ // Consume the [bB][hH].
+ if (Radix == 2 || Radix == 16)
++CurPtr;
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL