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