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