Index: llvm/include/llvm/MC/MCParser/MCAsmLexer.h =================================================================== --- llvm/include/llvm/MC/MCParser/MCAsmLexer.h +++ llvm/include/llvm/MC/MCParser/MCAsmLexer.h @@ -55,6 +55,7 @@ bool LexMasmStrings = false; bool UseMasmDefaultRadix = false; unsigned DefaultRadix = 10; + bool LexHLASMIntegers = false; AsmCommentConsumer *CommentConsumer = nullptr; MCAsmLexer(); @@ -171,6 +172,9 @@ /// Set whether to lex masm-style string literals, such as 'Can''t find file' /// and "This ""value"" not found". void setLexMasmStrings(bool V) { LexMasmStrings = V; } + + /// Set whether to lex HLASM-style integers. For now this is only [0-9]* + void setLexHLASMIntegers(bool V) { LexHLASMIntegers = V; } }; } // end namespace llvm Index: llvm/lib/MC/MCParser/AsmLexer.cpp =================================================================== --- llvm/lib/MC/MCParser/AsmLexer.cpp +++ llvm/lib/MC/MCParser/AsmLexer.cpp @@ -320,6 +320,24 @@ /// 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() { + // HLASM-flavour decimal integer: [0-9]* + // FIXME: Later on, support for fb has to be added in + // as they probably would be needed for asm goto + if (LexHLASMIntegers) { + // You can have leading 0s in HLASM-flavour integers + // They don't mean octal integers + unsigned Radix = doHexLookAhead(CurPtr, 10, /*LexMasmIntegers*/ false); + StringRef Result(TokStart, CurPtr - TokStart); + + APInt Value(128, 0, true); + // The getAsInteger routine will remove leading zeros when + // when computing Value. + if (Result.getAsInteger(Radix, Value)) + return ReturnError(TokStart, "invalid " + radixName(Radix) + " number"); + + return intToken(Result, Value); + } + // MASM-flavor binary integer: [01]+[yY] (if DefaultRadix < 16, [bByY]) // MASM-flavor octal integer: [0-7]+[oOqQ] // MASM-flavor decimal integer: [0-9]+[tT] (if DefaultRadix < 16, [dDtT]) Index: llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp =================================================================== --- llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp +++ llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp @@ -109,6 +109,21 @@ Lexer.Lex(); } } + + void lexAndCheckIntegerTokensAndValues(StringRef AsmStr, + SmallVector ExpectedValues) { + // Get reference to AsmLexer. + MCAsmLexer &Lexer = Parser->getLexer(); + // Loop through all expected tokens and expected values. + for (size_t I = 0; I < ExpectedValues.size(); ++I) { + // Skip any EndOfStatement tokens, we're not concerned with them. + if (Lexer.getTok().getKind() == AsmToken::EndOfStatement) + continue; + EXPECT_EQ(Lexer.getTok().getKind(), AsmToken::Integer); + EXPECT_EQ(Lexer.getTok().getIntVal(), ExpectedValues[I]); + Lexer.Lex(); + } + } }; TEST_F(SystemZAsmLexerTest, CheckDontRestrictCommentStringToStartOfStatement) { @@ -367,4 +382,42 @@ lexAndCheckTokens(AsmStr, ExpectedTokens); } + +TEST_F(SystemZAsmLexerTest, CheckValidHLASMIntegers) { + StringRef AsmStr = "123\n000123\n1999\n007\n12300\n12021"; + // StringRef AsmStr = "123"; + // Setup. + setupCallToAsmParser(AsmStr); + Parser->getLexer().setLexHLASMIntegers(true); + + // Lex initially to get the string. + Parser->getLexer().Lex(); + + // SmallVector ExpectedValues({123}); + SmallVector ExpectedValues({123, 123, 1999, 7, 12300, 12021}); + lexAndCheckIntegerTokensAndValues(AsmStr, ExpectedValues); +} + +TEST_F(SystemZAsmLexerTest, CheckInvalidHLASMIntegers) { + StringRef AsmStr = "0b0101\n0xDEADBEEF\nfffh"; + + // Setup. + setupCallToAsmParser(AsmStr); + Parser->getLexer().setLexHLASMIntegers(true); + + // Lex initially to get the string. + Parser->getLexer().Lex(); + + SmallVector ExpectedTokens; + ExpectedTokens.push_back(AsmToken::Integer); // "0" + ExpectedTokens.push_back(AsmToken::Identifier); // "b0101" + ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" + ExpectedTokens.push_back(AsmToken::Integer); // "0" + ExpectedTokens.push_back(AsmToken::Identifier); // "xDEADBEEF" + ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" + ExpectedTokens.push_back(AsmToken::Identifier); // "fffh" + ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" + ExpectedTokens.push_back(AsmToken::Eof); + lexAndCheckTokens(AsmStr, ExpectedTokens); +} } // end anonymous namespace