1 //===- llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp ----------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===--------------------------------------------------------------------===// 8 #include "llvm/MC/MCAsmInfo.h" 9 #include "llvm/MC/MCContext.h" 10 #include "llvm/MC/MCObjectFileInfo.h" 11 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 12 #include "llvm/MC/MCRegisterInfo.h" 13 #include "llvm/MC/MCStreamer.h" 14 #include "llvm/Support/MemoryBuffer.h" 15 #include "llvm/Support/SourceMgr.h" 16 #include "llvm/Support/TargetRegistry.h" 17 #include "llvm/Support/TargetSelect.h" 18 19 #include "gtest/gtest.h" 20 21 using namespace llvm; 22 23 namespace { 24 25 // Come up with our hacked version of MCAsmInfo. 26 // This hacked version derives from the main MCAsmInfo instance. 27 // Here, we're free to override whatever we want, without polluting 28 // the main MCAsmInfo interface. 29 class MockedUpMCAsmInfo : public MCAsmInfo { 30 public: 31 void setRestrictCommentStringToStartOfStatement(bool Value) { 32 RestrictCommentStringToStartOfStatement = Value; 33 } 34 void setCommentString(StringRef Value) { CommentString = Value; } 35 void setAllowAdditionalComments(bool Value) { 36 AllowAdditionalComments = Value; 37 } 38 void setAllowQuestionAtStartOfIdentifier(bool Value) { 39 AllowQuestionAtStartOfIdentifier = Value; 40 } 41 void setAllowAtAtStartOfIdentifier(bool Value) { 42 AllowAtAtStartOfIdentifier = Value; 43 } 44 void setAllowDollarAtStartOfIdentifier(bool Value) { 45 AllowDollarAtStartOfIdentifier = Value; 46 } 47 void setAllowHashAtStartOfIdentifier(bool Value) { 48 AllowHashAtStartOfIdentifier = Value; 49 } 50 void setAllowDotIsPC(bool Value) { DotIsPC = Value; } 51 void setAssemblerDialect(unsigned Value) { AssemblerDialect = Value; } 52 void setEmitLabelsInUpperCase(bool Value) { EmitLabelsInUpperCase = Value; } 53 }; 54 55 // Setup a testing class that the GTest framework can call. 56 class SystemZAsmLexerTest : public ::testing::Test { 57 protected: 58 static void SetUpTestCase() { 59 LLVMInitializeSystemZTargetInfo(); 60 LLVMInitializeSystemZTargetMC(); 61 LLVMInitializeSystemZAsmParser(); 62 } 63 64 std::unique_ptr<MCRegisterInfo> MRI; 65 std::unique_ptr<MockedUpMCAsmInfo> MUPMAI; 66 std::unique_ptr<const MCInstrInfo> MII; 67 std::unique_ptr<MCObjectFileInfo> MOFI; 68 std::unique_ptr<MCStreamer> Str; 69 std::unique_ptr<MCAsmParser> Parser; 70 std::unique_ptr<MCContext> Ctx; 71 std::unique_ptr<MCSubtargetInfo> STI; 72 std::unique_ptr<MCTargetAsmParser> TargetAsmParser; 73 74 SourceMgr SrcMgr; 75 std::string TripleName; 76 llvm::Triple Triple; 77 const Target *TheTarget; 78 79 const MCTargetOptions MCOptions; 80 81 SystemZAsmLexerTest() { 82 // We will use the SystemZ triple, because of missing 83 // Object File and Streamer support for the z/OS target. 84 TripleName = "s390x-ibm-linux"; 85 Triple = llvm::Triple(TripleName); 86 87 std::string Error; 88 TheTarget = TargetRegistry::lookupTarget(TripleName, Error); 89 EXPECT_NE(TheTarget, nullptr); 90 91 MRI.reset(TheTarget->createMCRegInfo(TripleName)); 92 EXPECT_NE(MRI, nullptr); 93 94 MII.reset(TheTarget->createMCInstrInfo()); 95 EXPECT_NE(MII, nullptr); 96 97 STI.reset(TheTarget->createMCSubtargetInfo(TripleName, "z10", "")); 98 EXPECT_NE(STI, nullptr); 99 100 std::unique_ptr<MCAsmInfo> MAI; 101 MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); 102 EXPECT_NE(MAI, nullptr); 103 104 // Now we cast to our mocked up version of MCAsmInfo. 105 MUPMAI.reset(static_cast<MockedUpMCAsmInfo *>(MAI.release())); 106 // MUPMAI should "hold" MAI. 107 EXPECT_NE(MUPMAI, nullptr); 108 // After releasing, MAI should now be null. 109 EXPECT_EQ(MAI, nullptr); 110 } 111 112 void setupCallToAsmParser(StringRef AsmStr) { 113 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(AsmStr)); 114 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 115 EXPECT_EQ(Buffer, nullptr); 116 117 Ctx.reset(new MCContext(Triple, MUPMAI.get(), MRI.get(), STI.get(), &SrcMgr, 118 &MCOptions)); 119 MOFI.reset(TheTarget->createMCObjectFileInfo(*Ctx, /*PIC=*/false, 120 /*LargeCodeModel=*/false)); 121 Ctx->setObjectFileInfo(MOFI.get()); 122 123 Str.reset(TheTarget->createNullStreamer(*Ctx)); 124 125 Parser.reset(createMCAsmParser(SrcMgr, *Ctx, *Str, *MUPMAI)); 126 127 TargetAsmParser.reset( 128 TheTarget->createMCAsmParser(*STI, *Parser, *MII, MCOptions)); 129 Parser->setTargetParser(*TargetAsmParser); 130 } 131 132 void lexAndCheckTokens(StringRef AsmStr, 133 SmallVector<AsmToken::TokenKind> ExpectedTokens) { 134 // Get reference to AsmLexer. 135 MCAsmLexer &Lexer = Parser->getLexer(); 136 // Loop through all expected tokens checking one by one. 137 for (size_t I = 0; I < ExpectedTokens.size(); ++I) { 138 EXPECT_EQ(Lexer.getTok().getKind(), ExpectedTokens[I]); 139 Lexer.Lex(); 140 } 141 } 142 143 void lexAndCheckIntegerTokensAndValues(StringRef AsmStr, 144 SmallVector<int64_t> ExpectedValues) { 145 // Get reference to AsmLexer. 146 MCAsmLexer &Lexer = Parser->getLexer(); 147 // Loop through all expected tokens and expected values. 148 for (size_t I = 0; I < ExpectedValues.size(); ++I) { 149 // Skip any EndOfStatement tokens, we're not concerned with them. 150 if (Lexer.getTok().getKind() == AsmToken::EndOfStatement) 151 continue; 152 EXPECT_EQ(Lexer.getTok().getKind(), AsmToken::Integer); 153 EXPECT_EQ(Lexer.getTok().getIntVal(), ExpectedValues[I]); 154 Lexer.Lex(); 155 } 156 } 157 }; 158 159 TEST_F(SystemZAsmLexerTest, CheckDontRestrictCommentStringToStartOfStatement) { 160 StringRef AsmStr = "jne #-4"; 161 162 // Setup. 163 setupCallToAsmParser(AsmStr); 164 165 // Lex initially to get the string. 166 Parser->getLexer().Lex(); 167 168 SmallVector<AsmToken::TokenKind> ExpectedTokens( 169 {AsmToken::Identifier, AsmToken::EndOfStatement}); 170 lexAndCheckTokens(AsmStr /* "jne #-4" */, ExpectedTokens); 171 } 172 173 // Testing MCAsmInfo's RestrictCommentStringToStartOfStatement attribute. 174 TEST_F(SystemZAsmLexerTest, CheckRestrictCommentStringToStartOfStatement) { 175 StringRef AsmStr = "jne #-4"; 176 177 // Setup. 178 MUPMAI->setRestrictCommentStringToStartOfStatement(true); 179 setupCallToAsmParser(AsmStr); 180 181 // Lex initially to get the string. 182 Parser->getLexer().Lex(); 183 184 // When we are restricting the comment string to only the start of the 185 // statement, The sequence of tokens we are expecting are: Identifier - "jne" 186 // Hash - '#' 187 // Minus - '-' 188 // Integer - '4' 189 SmallVector<AsmToken::TokenKind> ExpectedTokens( 190 {AsmToken::Identifier, AsmToken::Hash, AsmToken::Minus, 191 AsmToken::Integer}); 192 lexAndCheckTokens(AsmStr /* "jne #-4" */, ExpectedTokens); 193 } 194 195 // Test HLASM Comment Syntax ('*') 196 TEST_F(SystemZAsmLexerTest, CheckHLASMComment) { 197 StringRef AsmStr = "* lhi 1,10"; 198 199 // Setup. 200 MUPMAI->setCommentString("*"); 201 setupCallToAsmParser(AsmStr); 202 203 // Lex initially to get the string. 204 Parser->getLexer().Lex(); 205 206 SmallVector<AsmToken::TokenKind> ExpectedTokens( 207 {AsmToken::EndOfStatement, AsmToken::Eof}); 208 lexAndCheckTokens(AsmStr /* "* lhi 1,10" */, ExpectedTokens); 209 } 210 211 TEST_F(SystemZAsmLexerTest, CheckHashDefault) { 212 StringRef AsmStr = "lh#123"; 213 214 // Setup. 215 setupCallToAsmParser(AsmStr); 216 217 // Lex initially to get the string. 218 Parser->getLexer().Lex(); 219 220 // "lh" -> Identifier 221 // "#123" -> EndOfStatement (Lexed as a comment since CommentString is "#") 222 SmallVector<AsmToken::TokenKind> ExpectedTokens( 223 {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); 224 lexAndCheckTokens(AsmStr, ExpectedTokens); 225 } 226 227 // Test if "#" is accepted as an Identifier 228 TEST_F(SystemZAsmLexerTest, CheckAllowHashInIdentifier) { 229 StringRef AsmStr = "lh#123"; 230 231 // Setup. 232 setupCallToAsmParser(AsmStr); 233 Parser->getLexer().setAllowHashInIdentifier(true); 234 235 // Lex initially to get the string. 236 Parser->getLexer().Lex(); 237 238 // "lh123" -> Identifier 239 SmallVector<AsmToken::TokenKind> ExpectedTokens( 240 {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); 241 lexAndCheckTokens(AsmStr, ExpectedTokens); 242 } 243 244 TEST_F(SystemZAsmLexerTest, CheckAllowHashInIdentifier2) { 245 StringRef AsmStr = "lh#12*3"; 246 247 // Setup. 248 MUPMAI->setCommentString("*"); 249 MUPMAI->setRestrictCommentStringToStartOfStatement(true); 250 setupCallToAsmParser(AsmStr); 251 Parser->getLexer().setAllowHashInIdentifier(true); 252 253 // Lex initially to get the string. 254 Parser->getLexer().Lex(); 255 256 // "lh#12" -> Identifier 257 // "*" -> Star 258 // "3" -> Integer 259 SmallVector<AsmToken::TokenKind> ExpectedTokens( 260 {AsmToken::Identifier, AsmToken::Star, AsmToken::Integer, 261 AsmToken::EndOfStatement, AsmToken::Eof}); 262 lexAndCheckTokens(AsmStr, ExpectedTokens); 263 } 264 265 TEST_F(SystemZAsmLexerTest, DontCheckStrictCommentString) { 266 StringRef AsmStr = "# abc\n/* def */// xyz"; 267 268 // Setup. 269 setupCallToAsmParser(AsmStr); 270 271 // Lex initially to get the string. 272 Parser->getLexer().Lex(); 273 274 SmallVector<AsmToken::TokenKind> ExpectedTokens( 275 {AsmToken::EndOfStatement, AsmToken::Comment, AsmToken::EndOfStatement, 276 AsmToken::Eof}); 277 lexAndCheckTokens(AsmStr, ExpectedTokens); 278 } 279 280 TEST_F(SystemZAsmLexerTest, DontCheckStrictCommentString2) { 281 StringRef AsmStr = "# abc\n/* def */// xyz\n* rst"; 282 283 // Setup. 284 MUPMAI->setCommentString("*"); 285 setupCallToAsmParser(AsmStr); 286 287 // Lex initially to get the string. 288 Parser->getLexer().Lex(); 289 290 SmallVector<AsmToken::TokenKind> ExpectedTokens( 291 {AsmToken::EndOfStatement, AsmToken::Comment, AsmToken::EndOfStatement, 292 AsmToken::EndOfStatement, AsmToken::Eof}); 293 lexAndCheckTokens(AsmStr, ExpectedTokens); 294 } 295 296 TEST_F(SystemZAsmLexerTest, CheckStrictCommentString) { 297 StringRef AsmStr = "# abc\n/* def */// xyz"; 298 299 // Setup. 300 MUPMAI->setAllowAdditionalComments(false); 301 setupCallToAsmParser(AsmStr); 302 303 // Lex initially to get the string. 304 Parser->getLexer().Lex(); 305 306 // "# abc" -> still treated as a comment, since CommentString 307 // is set to "#" 308 SmallVector<AsmToken::TokenKind> ExpectedTokens; 309 ExpectedTokens.push_back(AsmToken::EndOfStatement); // "# abc\n" 310 ExpectedTokens.push_back(AsmToken::Slash); // "/" 311 ExpectedTokens.push_back(AsmToken::Star); // "*" 312 ExpectedTokens.push_back(AsmToken::Identifier); // "def" 313 ExpectedTokens.push_back(AsmToken::Star); // "*" 314 ExpectedTokens.push_back(AsmToken::Slash); // "/" 315 ExpectedTokens.push_back(AsmToken::Slash); // "/" 316 ExpectedTokens.push_back(AsmToken::Slash); // "/" 317 ExpectedTokens.push_back(AsmToken::Identifier); // "xyz" 318 ExpectedTokens.push_back(AsmToken::EndOfStatement); 319 ExpectedTokens.push_back(AsmToken::Eof); 320 321 lexAndCheckTokens(AsmStr, ExpectedTokens); 322 } 323 324 TEST_F(SystemZAsmLexerTest, CheckStrictCommentString2) { 325 StringRef AsmStr = "// abc"; 326 327 // Setup. 328 MUPMAI->setAllowAdditionalComments(false); 329 MUPMAI->setCommentString("//"); 330 setupCallToAsmParser(AsmStr); 331 332 // Lex initially to get the string. 333 Parser->getLexer().Lex(); 334 335 // "// abc" -> will still be treated as a comment because "//" is the 336 // CommentString 337 SmallVector<AsmToken::TokenKind> ExpectedTokens( 338 {AsmToken::EndOfStatement, AsmToken::Eof}); 339 lexAndCheckTokens(AsmStr /* "// abc" */, ExpectedTokens); 340 } 341 342 TEST_F(SystemZAsmLexerTest, CheckStrictCommentString3) { 343 StringRef AsmStr = "/* abc */"; 344 345 // Setup. 346 MUPMAI->setAllowAdditionalComments(false); 347 setupCallToAsmParser(AsmStr); 348 349 // Lex initially to get the string. 350 Parser->getLexer().Lex(); 351 352 SmallVector<AsmToken::TokenKind> ExpectedTokens; 353 ExpectedTokens.push_back(AsmToken::Slash); 354 ExpectedTokens.push_back(AsmToken::Star); 355 ExpectedTokens.push_back(AsmToken::Identifier); 356 ExpectedTokens.push_back(AsmToken::Star); 357 ExpectedTokens.push_back(AsmToken::Slash); 358 ExpectedTokens.push_back(AsmToken::EndOfStatement); 359 ExpectedTokens.push_back(AsmToken::Eof); 360 361 lexAndCheckTokens(AsmStr, ExpectedTokens); 362 } 363 364 TEST_F(SystemZAsmLexerTest, CheckStrictCommentString4) { 365 StringRef AsmStr = "# abc\n/* def */// xyz"; 366 367 // Setup. 368 MUPMAI->setCommentString("*"); 369 MUPMAI->setAllowAdditionalComments(false); 370 MUPMAI->setRestrictCommentStringToStartOfStatement(true); 371 setupCallToAsmParser(AsmStr); 372 373 // Lex initially to get the string. 374 Parser->getLexer().Lex(); 375 376 SmallVector<AsmToken::TokenKind> ExpectedTokens; 377 ExpectedTokens.push_back(AsmToken::Hash); // "#" 378 ExpectedTokens.push_back(AsmToken::Identifier); // "abc" 379 ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" 380 ExpectedTokens.push_back(AsmToken::Slash); // "/" 381 ExpectedTokens.push_back(AsmToken::Star); // "*" 382 ExpectedTokens.push_back(AsmToken::Identifier); // "def" 383 ExpectedTokens.push_back(AsmToken::Star); // "*" 384 ExpectedTokens.push_back(AsmToken::Slash); // "/" 385 ExpectedTokens.push_back(AsmToken::Slash); // "/" 386 ExpectedTokens.push_back(AsmToken::Slash); // "/" 387 ExpectedTokens.push_back(AsmToken::Identifier); // "xyz" 388 ExpectedTokens.push_back(AsmToken::EndOfStatement); 389 ExpectedTokens.push_back(AsmToken::Eof); 390 391 lexAndCheckTokens(AsmStr, ExpectedTokens); 392 } 393 394 TEST_F(SystemZAsmLexerTest, CheckStrictCommentString5) { 395 StringRef AsmStr = "#abc\n/* def */// xyz"; 396 397 // Setup. 398 MUPMAI->setCommentString("*"); 399 MUPMAI->setAllowAdditionalComments(false); 400 setupCallToAsmParser(AsmStr); 401 402 // Lex initially to get the string. 403 Parser->getLexer().Lex(); 404 405 SmallVector<AsmToken::TokenKind> ExpectedTokens; 406 ExpectedTokens.push_back(AsmToken::Hash); // "#" 407 ExpectedTokens.push_back(AsmToken::Identifier); // "abc" 408 ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" 409 ExpectedTokens.push_back(AsmToken::Slash); // "/" 410 ExpectedTokens.push_back(AsmToken::EndOfStatement); // "* def */// xyz" 411 ExpectedTokens.push_back(AsmToken::Eof); 412 413 lexAndCheckTokens(AsmStr, ExpectedTokens); 414 } 415 416 TEST_F(SystemZAsmLexerTest, CheckValidHLASMIntegers) { 417 StringRef AsmStr = "123\n000123\n1999\n007\n12300\n12021\n"; 418 // StringRef AsmStr = "123"; 419 // Setup. 420 setupCallToAsmParser(AsmStr); 421 Parser->getLexer().setLexHLASMIntegers(true); 422 423 // Lex initially to get the string. 424 Parser->getLexer().Lex(); 425 426 // SmallVector<int64_t> ExpectedValues({123}); 427 SmallVector<int64_t> ExpectedValues({123, 123, 1999, 7, 12300, 12021}); 428 lexAndCheckIntegerTokensAndValues(AsmStr, ExpectedValues); 429 } 430 431 TEST_F(SystemZAsmLexerTest, CheckInvalidHLASMIntegers) { 432 StringRef AsmStr = "0b0101\n0xDEADBEEF\nfffh\n.133\n"; 433 434 // Setup. 435 setupCallToAsmParser(AsmStr); 436 Parser->getLexer().setLexHLASMIntegers(true); 437 438 // Lex initially to get the string. 439 Parser->getLexer().Lex(); 440 441 SmallVector<AsmToken::TokenKind> ExpectedTokens; 442 ExpectedTokens.push_back(AsmToken::Integer); // "0" 443 ExpectedTokens.push_back(AsmToken::Identifier); // "b0101" 444 ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" 445 ExpectedTokens.push_back(AsmToken::Integer); // "0" 446 ExpectedTokens.push_back(AsmToken::Identifier); // "xDEADBEEF" 447 ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" 448 ExpectedTokens.push_back(AsmToken::Identifier); // "fffh" 449 ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" 450 ExpectedTokens.push_back(AsmToken::Real); // ".133" 451 ExpectedTokens.push_back(AsmToken::EndOfStatement); // "\n" 452 ExpectedTokens.push_back(AsmToken::Eof); 453 lexAndCheckTokens(AsmStr, ExpectedTokens); 454 } 455 456 TEST_F(SystemZAsmLexerTest, CheckDefaultIntegers) { 457 StringRef AsmStr = "0b0101\n0xDEADBEEF\nfffh\n"; 458 459 // Setup. 460 setupCallToAsmParser(AsmStr); 461 462 // Lex initially to get the string. 463 Parser->getLexer().Lex(); 464 465 SmallVector<int64_t> ExpectedValues({5, 0xDEADBEEF, 0xFFF}); 466 lexAndCheckIntegerTokensAndValues(AsmStr, ExpectedValues); 467 } 468 469 TEST_F(SystemZAsmLexerTest, CheckDefaultFloats) { 470 StringRef AsmStr = "0.333\n1.3\n2.5\n3.0\n"; 471 472 // Setup. 473 setupCallToAsmParser(AsmStr); 474 475 // Lex initially to get the string. 476 Parser->getLexer().Lex(); 477 478 SmallVector<AsmToken::TokenKind> ExpectedTokens; 479 480 for (int I = 0; I < 4; ++I) 481 ExpectedTokens.insert(ExpectedTokens.begin(), 482 {AsmToken::Real, AsmToken::EndOfStatement}); 483 484 ExpectedTokens.push_back(AsmToken::Eof); 485 lexAndCheckTokens(AsmStr, ExpectedTokens); 486 } 487 488 TEST_F(SystemZAsmLexerTest, CheckDefaultQuestionAtStartOfIdentifier) { 489 StringRef AsmStr = "?lh1?23"; 490 491 // Setup. 492 setupCallToAsmParser(AsmStr); 493 494 // Lex initially to get the string. 495 Parser->getLexer().Lex(); 496 497 SmallVector<AsmToken::TokenKind> ExpectedTokens( 498 {AsmToken::Error, AsmToken::Identifier, AsmToken::EndOfStatement, 499 AsmToken::Eof}); 500 lexAndCheckTokens(AsmStr, ExpectedTokens); 501 } 502 503 TEST_F(SystemZAsmLexerTest, CheckAcceptQuestionAtStartOfIdentifier) { 504 StringRef AsmStr = "?????lh1?23"; 505 506 // Setup. 507 MUPMAI->setAllowQuestionAtStartOfIdentifier(true); 508 setupCallToAsmParser(AsmStr); 509 510 // Lex initially to get the string. 511 Parser->getLexer().Lex(); 512 513 SmallVector<AsmToken::TokenKind> ExpectedTokens( 514 {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); 515 lexAndCheckTokens(AsmStr, ExpectedTokens); 516 } 517 518 TEST_F(SystemZAsmLexerTest, CheckDefaultAtAtStartOfIdentifier) { 519 StringRef AsmStr = "@@lh1?23"; 520 521 // Setup. 522 MUPMAI->setAllowQuestionAtStartOfIdentifier(true); 523 setupCallToAsmParser(AsmStr); 524 525 // Lex initially to get the string. 526 Parser->getLexer().Lex(); 527 528 SmallVector<AsmToken::TokenKind> ExpectedTokens( 529 {AsmToken::At, AsmToken::At, AsmToken::Identifier, 530 AsmToken::EndOfStatement, AsmToken::Eof}); 531 lexAndCheckTokens(AsmStr, ExpectedTokens); 532 } 533 534 TEST_F(SystemZAsmLexerTest, CheckAcceptAtAtStartOfIdentifier) { 535 StringRef AsmStr = "@@lh1?23"; 536 537 // Setup. 538 MUPMAI->setAllowAtAtStartOfIdentifier(true); 539 setupCallToAsmParser(AsmStr); 540 541 // Lex initially to get the string. 542 Parser->getLexer().Lex(); 543 544 SmallVector<AsmToken::TokenKind> ExpectedTokens( 545 {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); 546 lexAndCheckTokens(AsmStr, ExpectedTokens); 547 } 548 549 TEST_F(SystemZAsmLexerTest, CheckAccpetAtAtStartOfIdentifier2) { 550 StringRef AsmStr = "@@lj1?23"; 551 552 // Setup. 553 MUPMAI->setCommentString("@"); 554 MUPMAI->setAllowAtAtStartOfIdentifier(true); 555 setupCallToAsmParser(AsmStr); 556 557 // Lex initially to get the string. 558 Parser->getLexer().Lex(); 559 560 // "@@lj1?23" -> still lexed as a comment as that takes precedence. 561 SmallVector<AsmToken::TokenKind> ExpectedTokens( 562 {AsmToken::EndOfStatement, AsmToken::Eof}); 563 lexAndCheckTokens(AsmStr, ExpectedTokens); 564 } 565 566 TEST_F(SystemZAsmLexerTest, CheckDefaultDollarAtStartOfIdentifier) { 567 StringRef AsmStr = "$$ac$c"; 568 569 // Setup. 570 setupCallToAsmParser(AsmStr); 571 572 // Lex initially to get the string. 573 Parser->getLexer().Lex(); 574 575 SmallVector<AsmToken::TokenKind> ExpectedTokens( 576 {AsmToken::Dollar, AsmToken::Dollar, AsmToken::Identifier, 577 AsmToken::EndOfStatement, AsmToken::Eof}); 578 lexAndCheckTokens(AsmStr, ExpectedTokens); 579 } 580 581 TEST_F(SystemZAsmLexerTest, CheckAcceptDollarAtStartOfIdentifier) { 582 StringRef AsmStr = "$$ab$c"; 583 584 // Setup. 585 MUPMAI->setAllowDollarAtStartOfIdentifier(true); 586 setupCallToAsmParser(AsmStr); 587 588 // Lex initially to get the string. 589 Parser->getLexer().Lex(); 590 591 SmallVector<AsmToken::TokenKind> ExpectedTokens( 592 {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); 593 lexAndCheckTokens(AsmStr, ExpectedTokens); 594 } 595 596 TEST_F(SystemZAsmLexerTest, CheckAcceptHashAtStartOfIdentifier) { 597 StringRef AsmStr = "##a#b$c"; 598 599 // Setup. 600 MUPMAI->setAllowHashAtStartOfIdentifier(true); 601 MUPMAI->setCommentString("*"); 602 MUPMAI->setAllowAdditionalComments(false); 603 setupCallToAsmParser(AsmStr); 604 Parser->getLexer().setAllowHashInIdentifier(true); 605 606 // Lex initially to get the string. 607 Parser->getLexer().Lex(); 608 609 SmallVector<AsmToken::TokenKind> ExpectedTokens( 610 {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); 611 lexAndCheckTokens(AsmStr, ExpectedTokens); 612 } 613 614 TEST_F(SystemZAsmLexerTest, CheckAcceptHashAtStartOfIdentifier2) { 615 StringRef AsmStr = "##a#b$c"; 616 617 // Setup. 618 MUPMAI->setAllowHashAtStartOfIdentifier(true); 619 setupCallToAsmParser(AsmStr); 620 Parser->getLexer().setAllowHashInIdentifier(true); 621 622 // Lex initially to get the string. 623 Parser->getLexer().Lex(); 624 625 // By default, the CommentString attribute is set to "#". 626 // Hence, "##a#b$c" is lexed as a line comment irrespective 627 // of whether the AllowHashAtStartOfIdentifier attribute is set to true. 628 SmallVector<AsmToken::TokenKind> ExpectedTokens( 629 {AsmToken::EndOfStatement, AsmToken::Eof}); 630 lexAndCheckTokens(AsmStr, ExpectedTokens); 631 } 632 633 TEST_F(SystemZAsmLexerTest, CheckAcceptHashAtStartOfIdentifier3) { 634 StringRef AsmStr = "##a#b$c"; 635 636 // Setup. 637 MUPMAI->setAllowHashAtStartOfIdentifier(true); 638 MUPMAI->setCommentString("*"); 639 setupCallToAsmParser(AsmStr); 640 Parser->getLexer().setAllowHashInIdentifier(true); 641 642 // Lex initially to get the string. 643 Parser->getLexer().Lex(); 644 645 // By default, the AsmLexer treats strings that start with "#" 646 // as a line comment. 647 // Hence, "##a$b$c" is lexed as a line comment irrespective 648 // of whether the AllowHashAtStartOfIdentifier attribute is set to true. 649 SmallVector<AsmToken::TokenKind> ExpectedTokens( 650 {AsmToken::EndOfStatement, AsmToken::Eof}); 651 lexAndCheckTokens(AsmStr, ExpectedTokens); 652 } 653 654 TEST_F(SystemZAsmLexerTest, CheckAcceptHashAtStartOfIdentifier4) { 655 StringRef AsmStr = "##a#b$c"; 656 657 // Setup. 658 MUPMAI->setAllowHashAtStartOfIdentifier(true); 659 MUPMAI->setCommentString("*"); 660 MUPMAI->setAllowAdditionalComments(false); 661 setupCallToAsmParser(AsmStr); 662 Parser->getLexer().setAllowHashInIdentifier(true); 663 664 // Lex initially to get the string. 665 Parser->getLexer().Lex(); 666 667 // Since, the AllowAdditionalComments attribute is set to false, 668 // only strings starting with the CommentString attribute are 669 // lexed as possible comments. 670 // Hence, "##a$b$c" is lexed as an Identifier because the 671 // AllowHashAtStartOfIdentifier attribute is set to true. 672 SmallVector<AsmToken::TokenKind> ExpectedTokens( 673 {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); 674 lexAndCheckTokens(AsmStr, ExpectedTokens); 675 } 676 677 TEST_F(SystemZAsmLexerTest, CheckRejectDotAsCurrentPC) { 678 StringRef AsmStr = ".-4"; 679 680 // Setup. 681 MUPMAI->setAllowDotIsPC(false); 682 setupCallToAsmParser(AsmStr); 683 684 // Lex initially to get the string. 685 Parser->getLexer().Lex(); 686 687 const MCExpr *Expr; 688 bool ParsePrimaryExpr = Parser->parseExpression(Expr); 689 EXPECT_EQ(ParsePrimaryExpr, true); 690 EXPECT_EQ(Parser->hasPendingError(), true); 691 } 692 693 TEST_F(SystemZAsmLexerTest, CheckRejectStarAsCurrentPC) { 694 StringRef AsmStr = "*-4"; 695 696 // Setup. 697 setupCallToAsmParser(AsmStr); 698 699 // Lex initially to get the string. 700 Parser->getLexer().Lex(); 701 702 const MCExpr *Expr; 703 bool ParsePrimaryExpr = Parser->parseExpression(Expr); 704 EXPECT_EQ(ParsePrimaryExpr, true); 705 EXPECT_EQ(Parser->hasPendingError(), true); 706 } 707 708 TEST_F(SystemZAsmLexerTest, CheckRejectCharLiterals) { 709 StringRef AsmStr = "abc 'd'"; 710 711 // Setup. 712 setupCallToAsmParser(AsmStr); 713 Parser->getLexer().setLexHLASMStrings(true); 714 715 // Lex initially to get the string. 716 Parser->getLexer().Lex(); 717 718 SmallVector<AsmToken::TokenKind> ExpectedTokens( 719 {AsmToken::Identifier, AsmToken::Error, AsmToken::Error, 720 AsmToken::EndOfStatement, AsmToken::Eof}); 721 lexAndCheckTokens(AsmStr, ExpectedTokens); 722 } 723 724 TEST_F(SystemZAsmLexerTest, CheckRejectStringLiterals) { 725 StringRef AsmStr = "abc \"ef\""; 726 727 // Setup. 728 setupCallToAsmParser(AsmStr); 729 Parser->getLexer().setLexHLASMStrings(true); 730 731 // Lex initially to get the string. 732 Parser->getLexer().Lex(); 733 734 SmallVector<AsmToken::TokenKind> ExpectedTokens( 735 {AsmToken::Identifier, AsmToken::Error, AsmToken::Identifier, 736 AsmToken::Error, AsmToken::EndOfStatement, AsmToken::Eof}); 737 lexAndCheckTokens(AsmStr, ExpectedTokens); 738 } 739 740 TEST_F(SystemZAsmLexerTest, CheckPrintAcceptableSymbol) { 741 std::string AsmStr = "ab13_$.@"; 742 EXPECT_EQ(true, MUPMAI->isValidUnquotedName(AsmStr)); 743 AsmStr += "#"; 744 EXPECT_EQ(false, MUPMAI->isValidUnquotedName(AsmStr)); 745 } 746 747 TEST_F(SystemZAsmLexerTest, CheckPrintAcceptableSymbol2) { 748 MUPMAI->setAssemblerDialect(1); 749 std::string AsmStr = "ab13_$.@"; 750 EXPECT_EQ(true, MUPMAI->isValidUnquotedName(AsmStr)); 751 AsmStr += "#"; 752 EXPECT_EQ(true, MUPMAI->isValidUnquotedName(AsmStr)); 753 } 754 755 TEST_F(SystemZAsmLexerTest, CheckLabelCaseUpperCase2) { 756 StringRef AsmStr = "label\nlabel"; 757 758 // Setup. 759 setupCallToAsmParser(AsmStr); 760 761 // Lex initially to get the string. 762 Parser->getLexer().Lex(); 763 764 const MCExpr *Expr; 765 bool ParsePrimaryExpr = Parser->parseExpression(Expr); 766 EXPECT_EQ(ParsePrimaryExpr, false); 767 768 const MCSymbolRefExpr *SymbolExpr = dyn_cast<MCSymbolRefExpr>(Expr); 769 EXPECT_NE(SymbolExpr, nullptr); 770 EXPECT_NE(&SymbolExpr->getSymbol(), nullptr); 771 EXPECT_EQ((&SymbolExpr->getSymbol())->getName(), StringRef("label")); 772 773 // Lex the end of statement token. 774 Parser->getLexer().Lex(); 775 776 MUPMAI->setEmitLabelsInUpperCase(true); 777 778 ParsePrimaryExpr = Parser->parseExpression(Expr); 779 EXPECT_EQ(ParsePrimaryExpr, false); 780 781 SymbolExpr = dyn_cast<MCSymbolRefExpr>(Expr); 782 EXPECT_NE(SymbolExpr, nullptr); 783 EXPECT_NE(&SymbolExpr->getSymbol(), nullptr); 784 EXPECT_EQ((&SymbolExpr->getSymbol())->getName(), StringRef("LABEL")); 785 } 786 } // end anonymous namespace 787