summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/MC/MCParser/AsmLexer.h2
-rw-r--r--llvm/lib/MC/MCParser/AsmLexer.cpp44
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp5
3 files changed, 48 insertions, 3 deletions
diff --git a/llvm/include/llvm/MC/MCParser/AsmLexer.h b/llvm/include/llvm/MC/MCParser/AsmLexer.h
index c779121b6cf..06937e25f59 100644
--- a/llvm/include/llvm/MC/MCParser/AsmLexer.h
+++ b/llvm/include/llvm/MC/MCParser/AsmLexer.h
@@ -31,6 +31,7 @@ class AsmLexer : public MCAsmLexer {
StringRef CurBuf;
bool IsAtStartOfLine;
bool IsAtStartOfStatement;
+ bool IsParsingMSInlineAsm;
void operator=(const AsmLexer&) = delete;
AsmLexer(const AsmLexer&) = delete;
@@ -44,6 +45,7 @@ public:
~AsmLexer() override;
void setBuffer(StringRef Buf, const char *ptr = nullptr);
+ void setParsingMSInlineAsm(bool V) { IsParsingMSInlineAsm = V; }
StringRef LexUntilEndOfStatement() override;
diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp
index 71e35448919..c1f71bcc368 100644
--- a/llvm/lib/MC/MCParser/AsmLexer.cpp
+++ b/llvm/lib/MC/MCParser/AsmLexer.cpp
@@ -33,6 +33,7 @@ AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) {
CurPtr = nullptr;
IsAtStartOfLine = true;
IsAtStartOfStatement = true;
+ IsParsingMSInlineAsm = false;
AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@");
}
@@ -264,6 +265,45 @@ static AsmToken intToken(StringRef Ref, APInt &Value)
/// 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() {
+ // MASM-flavor binary integer: [01]+[bB]
+ // MASM-flavor hexadecimal integer: [0-9][0-9a-fA-F]*[hH]
+ if (IsParsingMSInlineAsm && isdigit(CurPtr[-1])) {
+ const char *FirstNonBinary = (CurPtr[-1] != '0' && CurPtr[-1] != '1') ?
+ CurPtr - 1 : nullptr;
+ const char *OldCurPtr = CurPtr;
+ while (isxdigit(*CurPtr)) {
+ if (*CurPtr != '0' && *CurPtr != '1' && !FirstNonBinary)
+ FirstNonBinary = CurPtr;
+ ++CurPtr;
+ }
+
+ unsigned Radix = 0;
+ if (*CurPtr == 'h' || *CurPtr == 'H') {
+ // hexadecimal number
+ ++CurPtr;
+ Radix = 16;
+ } else if (FirstNonBinary && FirstNonBinary + 1 == CurPtr &&
+ (*FirstNonBinary == 'b' || *FirstNonBinary == 'B'))
+ Radix = 2;
+
+ if (Radix == 2 || Radix == 16) {
+ StringRef Result(TokStart, CurPtr - TokStart);
+ APInt Value(128, 0, true);
+
+ if (Result.drop_back().getAsInteger(Radix, Value))
+ return ReturnError(TokStart, Radix == 2 ? "invalid binary number" :
+ "invalid hexdecimal number");
+
+ // MSVC accepts and ignores type suffices on integer literals.
+ SkipIgnoredIntegerSuffix(CurPtr);
+
+ return intToken(Result, Value);
+ }
+
+ // octal/decimal integers, or floating point numbers, fall through
+ CurPtr = OldCurPtr;
+ }
+
// Decimal integer: [1-9][0-9]*
if (CurPtr[-1] != '0' || CurPtr[0] == '.') {
unsigned Radix = doLookAhead(CurPtr, 10);
@@ -292,7 +332,7 @@ AsmToken AsmLexer::LexDigit() {
return intToken(Result, Value);
}
- if ((*CurPtr == 'b') || (*CurPtr == 'B')) {
+ if (!IsParsingMSInlineAsm && ((*CurPtr == 'b') || (*CurPtr == 'B'))) {
++CurPtr;
// See if we actually have "0b" as part of something like "jmp 0b\n"
if (!isdigit(CurPtr[0])) {
@@ -341,7 +381,7 @@ AsmToken AsmLexer::LexDigit() {
return ReturnError(TokStart, "invalid hexadecimal number");
// Consume the optional [hH].
- if (*CurPtr == 'h' || *CurPtr == 'H')
+ if (!IsParsingMSInlineAsm && (*CurPtr == 'h' || *CurPtr == 'H'))
++CurPtr;
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 03157671da1..43c88c96860 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -256,7 +256,10 @@ public:
const AsmToken &Lex() override;
- void setParsingInlineAsm(bool V) override { ParsingInlineAsm = V; }
+ void setParsingInlineAsm(bool V) override {
+ ParsingInlineAsm = V;
+ Lexer.setParsingMSInlineAsm(V);
+ }
bool isParsingInlineAsm() override { return ParsingInlineAsm; }
bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
OpenPOWER on IntegriCloud