//===- llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp ----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===--------------------------------------------------------------------===// #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/MCTargetAsmParser.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "gtest/gtest.h" using namespace llvm; namespace { // Come up with our hacked version of MCAsmInfo. // This hacked version derives from the main MCAsmInfo instance. // Here, we're free to override whatever we want, without polluting // the main MCAsmInfo interface. class MockedUpMCAsmInfo : public MCAsmInfo { public: void setRestrictCommentStringToStartOfStatement(bool Value) { RestrictCommentStringToStartOfStatement = Value; } void setCommentString(StringRef Value) { CommentString = Value; } }; // Setup a testing class that the GTest framework can call. class SystemZAsmLexerTest : public ::testing::Test { protected: static void SetUpTestCase() { LLVMInitializeSystemZTargetInfo(); LLVMInitializeSystemZTargetMC(); } std::unique_ptr MRI; std::unique_ptr MUPMAI; std::unique_ptr MII; std::unique_ptr Str; std::unique_ptr Parser; std::unique_ptr Ctx; SourceMgr SrcMgr; std::string TripleName; llvm::Triple Triple; const Target *TheTarget; const MCTargetOptions MCOptions; MCObjectFileInfo MOFI; SystemZAsmLexerTest() { // We will use the SystemZ triple, because of missing // Object File and Streamer support for the z/OS target. TripleName = "s390x-ibm-linux"; Triple = llvm::Triple(TripleName); std::string Error; TheTarget = TargetRegistry::lookupTarget(TripleName, Error); EXPECT_NE(TheTarget, nullptr); MRI.reset(TheTarget->createMCRegInfo(TripleName)); EXPECT_NE(MRI, nullptr); std::unique_ptr MAI; MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); EXPECT_NE(MAI, nullptr); // Now we cast to our mocked up version of MCAsmInfo. MUPMAI.reset(static_cast(MAI.release())); // MUPMAI should "hold" MAI. EXPECT_NE(MUPMAI, nullptr); // After releasing, MAI should now be null. EXPECT_EQ(MAI, nullptr); } void setupCallToAsmParser(StringRef AsmStr) { std::unique_ptr Buffer(MemoryBuffer::getMemBuffer(AsmStr)); SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); EXPECT_EQ(Buffer, nullptr); Ctx.reset( new MCContext(MUPMAI.get(), MRI.get(), &MOFI, &SrcMgr, &MCOptions)); MOFI.InitMCObjectFileInfo(Triple, false, *Ctx, false); Str.reset(TheTarget->createNullStreamer(*Ctx)); Parser.reset(createMCAsmParser(SrcMgr, *Ctx, *Str, *MUPMAI)); // Lex initially to get the string. Parser->getLexer().Lex(); } void lexAndCheckTokens(StringRef AsmStr, SmallVector ExpectedTokens) { // Get reference to AsmLexer. MCAsmLexer &Lexer = Parser->getLexer(); // Loop through all expected tokens checking one by one. for (size_t I = 0; I < ExpectedTokens.size(); ++I) { EXPECT_EQ(Lexer.getTok().getKind(), ExpectedTokens[I]); Lexer.Lex(); } } }; TEST_F(SystemZAsmLexerTest, CheckDontRestrictCommentStringToStartOfStatement) { StringRef AsmStr = "jne #-4"; // Setup. setupCallToAsmParser(AsmStr); SmallVector ExpectedTokens( {AsmToken::Identifier, AsmToken::EndOfStatement}); lexAndCheckTokens(AsmStr /* "jne #-4" */, ExpectedTokens); } // Testing MCAsmInfo's RestrictCommentStringToStartOfStatement attribute. TEST_F(SystemZAsmLexerTest, CheckRestrictCommentStringToStartOfStatement) { StringRef AsmStr = "jne #-4"; // Setup. MUPMAI->setRestrictCommentStringToStartOfStatement(true); setupCallToAsmParser(AsmStr); // When we are restricting the comment string to only the start of the // statement, The sequence of tokens we are expecting are: Identifier - "jne" // Hash - '#' // Minus - '-' // Integer - '4' SmallVector ExpectedTokens( {AsmToken::Identifier, AsmToken::Hash, AsmToken::Minus, AsmToken::Integer}); lexAndCheckTokens(AsmStr /* "jne #-4" */, ExpectedTokens); } // Test HLASM Comment Syntax ('*') TEST_F(SystemZAsmLexerTest, CheckHLASMComment) { StringRef AsmStr = "* lhi 1,10"; // Setup. MUPMAI->setCommentString("*"); setupCallToAsmParser(AsmStr); SmallVector ExpectedTokens( {AsmToken::EndOfStatement, AsmToken::Eof}); lexAndCheckTokens(AsmStr /* "* lhi 1,10" */, ExpectedTokens); } } // end anonymous namespace