Index: llvm/trunk/include/llvm/MC/MCParser/AsmLexer.h =================================================================== --- llvm/trunk/include/llvm/MC/MCParser/AsmLexer.h +++ llvm/trunk/include/llvm/MC/MCParser/AsmLexer.h @@ -31,6 +31,7 @@ StringRef CurBuf; bool IsAtStartOfLine; bool IsAtStartOfStatement; + bool IsParsingMSInlineAsm; void operator=(const AsmLexer&) = delete; AsmLexer(const AsmLexer&) = delete; @@ -44,6 +45,7 @@ ~AsmLexer() override; void setBuffer(StringRef Buf, const char *ptr = nullptr); + void setParsingMSInlineAsm(bool V) { IsParsingMSInlineAsm = V; } StringRef LexUntilEndOfStatement() override; Index: llvm/trunk/lib/MC/MCParser/AsmLexer.cpp =================================================================== --- llvm/trunk/lib/MC/MCParser/AsmLexer.cpp +++ llvm/trunk/lib/MC/MCParser/AsmLexer.cpp @@ -33,6 +33,7 @@ CurPtr = nullptr; IsAtStartOfLine = true; IsAtStartOfStatement = true; + IsParsingMSInlineAsm = false; AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); } @@ -264,6 +265,45 @@ /// 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 @@ 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 @@ 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 Index: llvm/trunk/lib/MC/MCParser/AsmParser.cpp =================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp @@ -256,7 +256,10 @@ 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,