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