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-flavour 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 @@ -429,26 +429,32 @@ } // Decimal integer: [1-9][0-9]* - if (CurPtr[-1] != '0' || CurPtr[0] == '.') { + // HLASM-flavour decimal integer: [0-9][0-9]* + // FIXME: Later on, support for fb for HLASM has to be added in + // as they probably would be needed for asm goto + if (LexHLASMIntegers || CurPtr[-1] != '0' || CurPtr[0] == '.') { unsigned Radix = doHexLookAhead(CurPtr, 10, LexMasmIntegers); - bool isHex = Radix == 16; - // Check for floating point literals. - if (!isHex && (*CurPtr == '.' || *CurPtr == 'e' || *CurPtr == 'E')) { - if (*CurPtr == '.') - ++CurPtr; - return LexFloatLiteral(); + + if (!LexHLASMIntegers) { + bool isHex = Radix == 16; + // Check for floating point literals. + if (!isHex && (*CurPtr == '.' || *CurPtr == 'e' || *CurPtr == 'E')) { + if (*CurPtr == '.') + ++CurPtr; + return LexFloatLiteral(); + } } StringRef Result(TokStart, CurPtr - TokStart); APInt Value(128, 0, true); - if (Result.getAsInteger(Radix, Value)) { + if (Result.getAsInteger(Radix, Value)) return ReturnError(TokStart, "invalid " + radixName(Radix) + " number"); - } - // The darwin/x86 (and x86-64) assembler accepts and ignores type - // suffices on integer literals. - SkipIgnoredIntegerSuffix(CurPtr); + if (!LexHLASMIntegers) + // The darwin/x86 (and x86-64) assembler accepts and ignores type + // suffices on integer literals. + SkipIgnoredIntegerSuffix(CurPtr); return intToken(Result, Value); } 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,76 @@ lexAndCheckTokens(AsmStr, ExpectedTokens); } + +TEST_F(SystemZAsmLexerTest, CheckValidHLASMIntegers) { + StringRef AsmStr = "123\n000123\n1999\n007\n12300\n12021\n"; + // 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\n.133\n"; + + // 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::Real); // ".133" + ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" + ExpectedTokens.push_back(AsmToken::Eof); + lexAndCheckTokens(AsmStr, ExpectedTokens); +} + +TEST_F(SystemZAsmLexerTest, CheckDefaultIntegers) { + StringRef AsmStr = "0b0101\n0xDEADBEEF\nfffh\n"; + + // Setup. + setupCallToAsmParser(AsmStr); + + // Lex initially to get the string. + Parser->getLexer().Lex(); + + SmallVector ExpectedValues({5, 0xDEADBEEF, 0xFFF}); + lexAndCheckIntegerTokensAndValues(AsmStr, ExpectedValues); +} + +TEST_F(SystemZAsmLexerTest, CheckDefaultFloats) { + StringRef AsmStr = "0.333\n1.3\n2.5\n3.0\n"; + + // Setup. + setupCallToAsmParser(AsmStr); + + // Lex initially to get the string. + Parser->getLexer().Lex(); + + SmallVector ExpectedTokens; + + for (int I = 0; I < 4; ++I) + ExpectedTokens.insert(ExpectedTokens.begin(), + {AsmToken::Real, AsmToken::EndOfStatement}); + + ExpectedTokens.push_back(AsmToken::Eof); + lexAndCheckTokens(AsmStr, ExpectedTokens); +} } // end anonymous namespace