xref: /llvm-project/clang/unittests/Lex/LexerTest.cpp (revision cebac48bf7e52e352b8cda806a64dab66df4c64f)
1 //===- unittests/Lex/LexerTest.cpp ------ Lexer tests ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "clang/Lex/Lexer.h"
11 #include "clang/Basic/Diagnostic.h"
12 #include "clang/Basic/DiagnosticOptions.h"
13 #include "clang/Basic/FileManager.h"
14 #include "clang/Basic/LangOptions.h"
15 #include "clang/Basic/MemoryBufferCache.h"
16 #include "clang/Basic/SourceManager.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Basic/TargetOptions.h"
19 #include "clang/Lex/HeaderSearch.h"
20 #include "clang/Lex/HeaderSearchOptions.h"
21 #include "clang/Lex/MacroArgs.h"
22 #include "clang/Lex/MacroInfo.h"
23 #include "clang/Lex/ModuleLoader.h"
24 #include "clang/Lex/Preprocessor.h"
25 #include "clang/Lex/PreprocessorOptions.h"
26 #include "gtest/gtest.h"
27 
28 using namespace clang;
29 
30 namespace {
31 
32 // The test fixture.
33 class LexerTest : public ::testing::Test {
34 protected:
35   LexerTest()
36     : FileMgr(FileMgrOpts),
37       DiagID(new DiagnosticIDs()),
38       Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
39       SourceMgr(Diags, FileMgr),
40       TargetOpts(new TargetOptions)
41   {
42     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
43     Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
44   }
45 
46   std::unique_ptr<Preprocessor> CreatePP(StringRef Source,
47                                          TrivialModuleLoader &ModLoader) {
48     std::unique_ptr<llvm::MemoryBuffer> Buf =
49         llvm::MemoryBuffer::getMemBuffer(Source);
50     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
51 
52     MemoryBufferCache PCMCache;
53     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
54                             Diags, LangOpts, Target.get());
55     std::unique_ptr<Preprocessor> PP = llvm::make_unique<Preprocessor>(
56         std::make_shared<PreprocessorOptions>(), Diags, LangOpts, SourceMgr,
57         PCMCache, HeaderInfo, ModLoader,
58         /*IILookup =*/nullptr,
59         /*OwnsHeaderSearch =*/false);
60     PP->Initialize(*Target);
61     PP->EnterMainSourceFile();
62     return PP;
63   }
64 
65   std::vector<Token> Lex(StringRef Source) {
66     TrivialModuleLoader ModLoader;
67     auto PP = CreatePP(Source, ModLoader);
68 
69     std::vector<Token> toks;
70     while (1) {
71       Token tok;
72       PP->Lex(tok);
73       if (tok.is(tok::eof))
74         break;
75       toks.push_back(tok);
76     }
77 
78     return toks;
79   }
80 
81   std::vector<Token> CheckLex(StringRef Source,
82                               ArrayRef<tok::TokenKind> ExpectedTokens) {
83     auto toks = Lex(Source);
84     EXPECT_EQ(ExpectedTokens.size(), toks.size());
85     for (unsigned i = 0, e = ExpectedTokens.size(); i != e; ++i) {
86       EXPECT_EQ(ExpectedTokens[i], toks[i].getKind());
87     }
88 
89     return toks;
90   }
91 
92   std::string getSourceText(Token Begin, Token End) {
93     bool Invalid;
94     StringRef Str =
95         Lexer::getSourceText(CharSourceRange::getTokenRange(SourceRange(
96                                     Begin.getLocation(), End.getLocation())),
97                              SourceMgr, LangOpts, &Invalid);
98     if (Invalid)
99       return "<INVALID>";
100     return Str;
101   }
102 
103   FileSystemOptions FileMgrOpts;
104   FileManager FileMgr;
105   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
106   DiagnosticsEngine Diags;
107   SourceManager SourceMgr;
108   LangOptions LangOpts;
109   std::shared_ptr<TargetOptions> TargetOpts;
110   IntrusiveRefCntPtr<TargetInfo> Target;
111 };
112 
113 TEST_F(LexerTest, GetSourceTextExpandsToMaximumInMacroArgument) {
114   std::vector<tok::TokenKind> ExpectedTokens;
115   ExpectedTokens.push_back(tok::identifier);
116   ExpectedTokens.push_back(tok::l_paren);
117   ExpectedTokens.push_back(tok::identifier);
118   ExpectedTokens.push_back(tok::r_paren);
119 
120   std::vector<Token> toks = CheckLex("#define M(x) x\n"
121                                      "M(f(M(i)))",
122                                      ExpectedTokens);
123 
124   EXPECT_EQ("M(i)", getSourceText(toks[2], toks[2]));
125 }
126 
127 TEST_F(LexerTest, GetSourceTextExpandsToMaximumInMacroArgumentForEndOfMacro) {
128   std::vector<tok::TokenKind> ExpectedTokens;
129   ExpectedTokens.push_back(tok::identifier);
130   ExpectedTokens.push_back(tok::identifier);
131 
132   std::vector<Token> toks = CheckLex("#define M(x) x\n"
133                                      "M(M(i) c)",
134                                      ExpectedTokens);
135 
136   EXPECT_EQ("M(i)", getSourceText(toks[0], toks[0]));
137 }
138 
139 TEST_F(LexerTest, GetSourceTextExpandsInMacroArgumentForBeginOfMacro) {
140   std::vector<tok::TokenKind> ExpectedTokens;
141   ExpectedTokens.push_back(tok::identifier);
142   ExpectedTokens.push_back(tok::identifier);
143   ExpectedTokens.push_back(tok::identifier);
144 
145   std::vector<Token> toks = CheckLex("#define M(x) x\n"
146                                      "M(c c M(i))",
147                                      ExpectedTokens);
148 
149   EXPECT_EQ("c M(i)", getSourceText(toks[1], toks[2]));
150 }
151 
152 TEST_F(LexerTest, GetSourceTextExpandsInMacroArgumentForEndOfMacro) {
153   std::vector<tok::TokenKind> ExpectedTokens;
154   ExpectedTokens.push_back(tok::identifier);
155   ExpectedTokens.push_back(tok::identifier);
156   ExpectedTokens.push_back(tok::identifier);
157 
158   std::vector<Token> toks = CheckLex("#define M(x) x\n"
159                                      "M(M(i) c c)",
160                                      ExpectedTokens);
161 
162   EXPECT_EQ("M(i) c", getSourceText(toks[0], toks[1]));
163 }
164 
165 TEST_F(LexerTest, GetSourceTextInSeparateFnMacros) {
166   std::vector<tok::TokenKind> ExpectedTokens;
167   ExpectedTokens.push_back(tok::identifier);
168   ExpectedTokens.push_back(tok::identifier);
169   ExpectedTokens.push_back(tok::identifier);
170   ExpectedTokens.push_back(tok::identifier);
171 
172   std::vector<Token> toks = CheckLex("#define M(x) x\n"
173                                      "M(c M(i)) M(M(i) c)",
174                                      ExpectedTokens);
175 
176   EXPECT_EQ("<INVALID>", getSourceText(toks[1], toks[2]));
177 }
178 
179 TEST_F(LexerTest, GetSourceTextWorksAcrossTokenPastes) {
180   std::vector<tok::TokenKind> ExpectedTokens;
181   ExpectedTokens.push_back(tok::identifier);
182   ExpectedTokens.push_back(tok::l_paren);
183   ExpectedTokens.push_back(tok::identifier);
184   ExpectedTokens.push_back(tok::r_paren);
185 
186   std::vector<Token> toks = CheckLex("#define M(x) x\n"
187                                      "#define C(x) M(x##c)\n"
188                                      "M(f(C(i)))",
189                                      ExpectedTokens);
190 
191   EXPECT_EQ("C(i)", getSourceText(toks[2], toks[2]));
192 }
193 
194 TEST_F(LexerTest, GetSourceTextExpandsAcrossMultipleMacroCalls) {
195   std::vector<tok::TokenKind> ExpectedTokens;
196   ExpectedTokens.push_back(tok::identifier);
197   ExpectedTokens.push_back(tok::l_paren);
198   ExpectedTokens.push_back(tok::identifier);
199   ExpectedTokens.push_back(tok::r_paren);
200 
201   std::vector<Token> toks = CheckLex("#define M(x) x\n"
202                                      "f(M(M(i)))",
203                                      ExpectedTokens);
204   EXPECT_EQ("M(M(i))", getSourceText(toks[2], toks[2]));
205 }
206 
207 TEST_F(LexerTest, GetSourceTextInMiddleOfMacroArgument) {
208   std::vector<tok::TokenKind> ExpectedTokens;
209   ExpectedTokens.push_back(tok::identifier);
210   ExpectedTokens.push_back(tok::l_paren);
211   ExpectedTokens.push_back(tok::identifier);
212   ExpectedTokens.push_back(tok::r_paren);
213 
214   std::vector<Token> toks = CheckLex("#define M(x) x\n"
215                                      "M(f(i))",
216                                      ExpectedTokens);
217   EXPECT_EQ("i", getSourceText(toks[2], toks[2]));
218 }
219 
220 TEST_F(LexerTest, GetSourceTextExpandsAroundDifferentMacroCalls) {
221   std::vector<tok::TokenKind> ExpectedTokens;
222   ExpectedTokens.push_back(tok::identifier);
223   ExpectedTokens.push_back(tok::l_paren);
224   ExpectedTokens.push_back(tok::identifier);
225   ExpectedTokens.push_back(tok::r_paren);
226 
227   std::vector<Token> toks = CheckLex("#define M(x) x\n"
228                                      "#define C(x) x\n"
229                                      "f(C(M(i)))",
230                                      ExpectedTokens);
231   EXPECT_EQ("C(M(i))", getSourceText(toks[2], toks[2]));
232 }
233 
234 TEST_F(LexerTest, GetSourceTextOnlyExpandsIfFirstTokenInMacro) {
235   std::vector<tok::TokenKind> ExpectedTokens;
236   ExpectedTokens.push_back(tok::identifier);
237   ExpectedTokens.push_back(tok::l_paren);
238   ExpectedTokens.push_back(tok::identifier);
239   ExpectedTokens.push_back(tok::identifier);
240   ExpectedTokens.push_back(tok::r_paren);
241 
242   std::vector<Token> toks = CheckLex("#define M(x) x\n"
243                                      "#define C(x) c x\n"
244                                      "f(C(M(i)))",
245                                      ExpectedTokens);
246   EXPECT_EQ("M(i)", getSourceText(toks[3], toks[3]));
247 }
248 
249 TEST_F(LexerTest, GetSourceTextExpandsRecursively) {
250   std::vector<tok::TokenKind> ExpectedTokens;
251   ExpectedTokens.push_back(tok::identifier);
252   ExpectedTokens.push_back(tok::identifier);
253   ExpectedTokens.push_back(tok::l_paren);
254   ExpectedTokens.push_back(tok::identifier);
255   ExpectedTokens.push_back(tok::r_paren);
256 
257   std::vector<Token> toks = CheckLex("#define M(x) x\n"
258                                      "#define C(x) c M(x)\n"
259                                      "C(f(M(i)))",
260                                      ExpectedTokens);
261   EXPECT_EQ("M(i)", getSourceText(toks[3], toks[3]));
262 }
263 
264 TEST_F(LexerTest, LexAPI) {
265   std::vector<tok::TokenKind> ExpectedTokens;
266   ExpectedTokens.push_back(tok::l_square);
267   ExpectedTokens.push_back(tok::identifier);
268   ExpectedTokens.push_back(tok::r_square);
269   ExpectedTokens.push_back(tok::l_square);
270   ExpectedTokens.push_back(tok::identifier);
271   ExpectedTokens.push_back(tok::r_square);
272   ExpectedTokens.push_back(tok::identifier);
273   ExpectedTokens.push_back(tok::identifier);
274   ExpectedTokens.push_back(tok::identifier);
275   ExpectedTokens.push_back(tok::identifier);
276 
277   std::vector<Token> toks = CheckLex("#define M(x) [x]\n"
278                                      "#define N(x) x\n"
279                                      "#define INN(x) x\n"
280                                      "#define NOF1 INN(val)\n"
281                                      "#define NOF2 val\n"
282                                      "M(foo) N([bar])\n"
283                                      "N(INN(val)) N(NOF1) N(NOF2) N(val)",
284                                      ExpectedTokens);
285 
286   SourceLocation lsqrLoc = toks[0].getLocation();
287   SourceLocation idLoc = toks[1].getLocation();
288   SourceLocation rsqrLoc = toks[2].getLocation();
289   std::pair<SourceLocation,SourceLocation>
290     macroPair = SourceMgr.getExpansionRange(lsqrLoc);
291   SourceRange macroRange = SourceRange(macroPair.first, macroPair.second);
292 
293   SourceLocation Loc;
294   EXPECT_TRUE(Lexer::isAtStartOfMacroExpansion(lsqrLoc, SourceMgr, LangOpts, &Loc));
295   EXPECT_EQ(Loc, macroRange.getBegin());
296   EXPECT_FALSE(Lexer::isAtStartOfMacroExpansion(idLoc, SourceMgr, LangOpts));
297   EXPECT_FALSE(Lexer::isAtEndOfMacroExpansion(idLoc, SourceMgr, LangOpts));
298   EXPECT_TRUE(Lexer::isAtEndOfMacroExpansion(rsqrLoc, SourceMgr, LangOpts, &Loc));
299   EXPECT_EQ(Loc, macroRange.getEnd());
300 
301   CharSourceRange range = Lexer::makeFileCharRange(
302            CharSourceRange::getTokenRange(lsqrLoc, idLoc), SourceMgr, LangOpts);
303   EXPECT_TRUE(range.isInvalid());
304   range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(idLoc, rsqrLoc),
305                                    SourceMgr, LangOpts);
306   EXPECT_TRUE(range.isInvalid());
307   range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(lsqrLoc, rsqrLoc),
308                                    SourceMgr, LangOpts);
309   EXPECT_TRUE(!range.isTokenRange());
310   EXPECT_EQ(range.getAsRange(),
311             SourceRange(macroRange.getBegin(),
312                         macroRange.getEnd().getLocWithOffset(1)));
313 
314   StringRef text = Lexer::getSourceText(
315                                CharSourceRange::getTokenRange(lsqrLoc, rsqrLoc),
316                                SourceMgr, LangOpts);
317   EXPECT_EQ(text, "M(foo)");
318 
319   SourceLocation macroLsqrLoc = toks[3].getLocation();
320   SourceLocation macroIdLoc = toks[4].getLocation();
321   SourceLocation macroRsqrLoc = toks[5].getLocation();
322   SourceLocation fileLsqrLoc = SourceMgr.getSpellingLoc(macroLsqrLoc);
323   SourceLocation fileIdLoc = SourceMgr.getSpellingLoc(macroIdLoc);
324   SourceLocation fileRsqrLoc = SourceMgr.getSpellingLoc(macroRsqrLoc);
325 
326   range = Lexer::makeFileCharRange(
327       CharSourceRange::getTokenRange(macroLsqrLoc, macroIdLoc),
328       SourceMgr, LangOpts);
329   EXPECT_EQ(SourceRange(fileLsqrLoc, fileIdLoc.getLocWithOffset(3)),
330             range.getAsRange());
331 
332   range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(macroIdLoc, macroRsqrLoc),
333                                    SourceMgr, LangOpts);
334   EXPECT_EQ(SourceRange(fileIdLoc, fileRsqrLoc.getLocWithOffset(1)),
335             range.getAsRange());
336 
337   macroPair = SourceMgr.getExpansionRange(macroLsqrLoc);
338   range = Lexer::makeFileCharRange(
339                      CharSourceRange::getTokenRange(macroLsqrLoc, macroRsqrLoc),
340                      SourceMgr, LangOpts);
341   EXPECT_EQ(SourceRange(macroPair.first, macroPair.second.getLocWithOffset(1)),
342             range.getAsRange());
343 
344   text = Lexer::getSourceText(
345           CharSourceRange::getTokenRange(SourceRange(macroLsqrLoc, macroIdLoc)),
346           SourceMgr, LangOpts);
347   EXPECT_EQ(text, "[bar");
348 
349 
350   SourceLocation idLoc1 = toks[6].getLocation();
351   SourceLocation idLoc2 = toks[7].getLocation();
352   SourceLocation idLoc3 = toks[8].getLocation();
353   SourceLocation idLoc4 = toks[9].getLocation();
354   EXPECT_EQ("INN", Lexer::getImmediateMacroName(idLoc1, SourceMgr, LangOpts));
355   EXPECT_EQ("INN", Lexer::getImmediateMacroName(idLoc2, SourceMgr, LangOpts));
356   EXPECT_EQ("NOF2", Lexer::getImmediateMacroName(idLoc3, SourceMgr, LangOpts));
357   EXPECT_EQ("N", Lexer::getImmediateMacroName(idLoc4, SourceMgr, LangOpts));
358 }
359 
360 TEST_F(LexerTest, DontMergeMacroArgsFromDifferentMacroFiles) {
361   std::vector<Token> toks =
362       Lex("#define helper1 0\n"
363           "void helper2(const char *, ...);\n"
364           "#define M1(a, ...) helper2(a, ##__VA_ARGS__)\n"
365           "#define M2(a, ...) M1(a, helper1, ##__VA_ARGS__)\n"
366           "void f1() { M2(\"a\", \"b\"); }");
367 
368   // Check the file corresponding to the "helper1" macro arg in M2.
369   //
370   // The lexer used to report its size as 31, meaning that the end of the
371   // expansion would be on the *next line* (just past `M2("a", "b")`). Make
372   // sure that we get the correct end location (the comma after "helper1").
373   SourceLocation helper1ArgLoc = toks[20].getLocation();
374   EXPECT_EQ(SourceMgr.getFileIDSize(SourceMgr.getFileID(helper1ArgLoc)), 8U);
375 }
376 
377 TEST_F(LexerTest, DontOverallocateStringifyArgs) {
378   TrivialModuleLoader ModLoader;
379   auto PP = CreatePP("\"StrArg\", 5, 'C'", ModLoader);
380 
381   llvm::BumpPtrAllocator Allocator;
382   std::array<IdentifierInfo *, 3> ParamList;
383   MacroInfo *MI = PP->AllocateMacroInfo({});
384   MI->setIsFunctionLike();
385   MI->setParameterList(ParamList, Allocator);
386   EXPECT_EQ(3u, MI->getNumParams());
387   EXPECT_TRUE(MI->isFunctionLike());
388 
389   Token Eof;
390   Eof.setKind(tok::eof);
391   std::vector<Token> ArgTokens;
392   while (1) {
393     Token tok;
394     PP->Lex(tok);
395     if (tok.is(tok::eof)) {
396       ArgTokens.push_back(Eof);
397       break;
398     }
399     if (tok.is(tok::comma))
400       ArgTokens.push_back(Eof);
401     else
402       ArgTokens.push_back(tok);
403   }
404 
405   auto MacroArgsDeleter = [&PP](MacroArgs *M) { M->destroy(*PP); };
406   std::unique_ptr<MacroArgs, decltype(MacroArgsDeleter)> MA(
407       MacroArgs::create(MI, ArgTokens, false, *PP), MacroArgsDeleter);
408   Token Result = MA->getStringifiedArgument(0, *PP, {}, {});
409   EXPECT_EQ(tok::string_literal, Result.getKind());
410   EXPECT_STREQ("\"\\\"StrArg\\\"\"", Result.getLiteralData());
411   Result = MA->getStringifiedArgument(1, *PP, {}, {});
412   EXPECT_EQ(tok::string_literal, Result.getKind());
413   EXPECT_STREQ("\"5\"", Result.getLiteralData());
414   Result = MA->getStringifiedArgument(2, *PP, {}, {});
415   EXPECT_EQ(tok::string_literal, Result.getKind());
416   EXPECT_STREQ("\"'C'\"", Result.getLiteralData());
417 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
418   EXPECT_DEATH(MA->getStringifiedArgument(3, *PP, {}, {}),
419                "Invalid argument number!");
420 #endif
421 }
422 
423 TEST_F(LexerTest, IsNewLineEscapedValid) {
424   auto hasNewLineEscaped = [](const char *S) {
425     return Lexer::isNewLineEscaped(S, S + strlen(S) - 1);
426   };
427 
428   EXPECT_TRUE(hasNewLineEscaped("\\\r"));
429   EXPECT_TRUE(hasNewLineEscaped("\\\n"));
430   EXPECT_TRUE(hasNewLineEscaped("\\\r\n"));
431   EXPECT_TRUE(hasNewLineEscaped("\\\n\r"));
432   EXPECT_TRUE(hasNewLineEscaped("\\ \t\v\f\r"));
433   EXPECT_TRUE(hasNewLineEscaped("\\ \t\v\f\r\n"));
434 
435   EXPECT_FALSE(hasNewLineEscaped("\\\r\r"));
436   EXPECT_FALSE(hasNewLineEscaped("\\\r\r\n"));
437   EXPECT_FALSE(hasNewLineEscaped("\\\n\n"));
438   EXPECT_FALSE(hasNewLineEscaped("\r"));
439   EXPECT_FALSE(hasNewLineEscaped("\n"));
440   EXPECT_FALSE(hasNewLineEscaped("\r\n"));
441   EXPECT_FALSE(hasNewLineEscaped("\n\r"));
442   EXPECT_FALSE(hasNewLineEscaped("\r\r"));
443   EXPECT_FALSE(hasNewLineEscaped("\n\n"));
444 }
445 
446 TEST_F(LexerTest, GetBeginningOfTokenWithEscapedNewLine) {
447   // Each line should have the same length for
448   // further offset calculation to be more straightforward.
449   const unsigned IdentifierLength = 8;
450   std::string TextToLex = "rabarbar\n"
451                           "foo\\\nbar\n"
452                           "foo\\\rbar\n"
453                           "fo\\\r\nbar\n"
454                           "foo\\\n\rba\n";
455   std::vector<tok::TokenKind> ExpectedTokens{5, tok::identifier};
456   std::vector<Token> LexedTokens = CheckLex(TextToLex, ExpectedTokens);
457 
458   for (const Token &Tok : LexedTokens) {
459     std::pair<FileID, unsigned> OriginalLocation =
460         SourceMgr.getDecomposedLoc(Tok.getLocation());
461     for (unsigned Offset = 0; Offset < IdentifierLength; ++Offset) {
462       SourceLocation LookupLocation =
463           Tok.getLocation().getLocWithOffset(Offset);
464 
465       std::pair<FileID, unsigned> FoundLocation =
466           SourceMgr.getDecomposedExpansionLoc(
467               Lexer::GetBeginningOfToken(LookupLocation, SourceMgr, LangOpts));
468 
469       // Check that location returned by the GetBeginningOfToken
470       // is the same as original token location reported by Lexer.
471       EXPECT_EQ(FoundLocation.second, OriginalLocation.second);
472     }
473   }
474 }
475 
476 TEST_F(LexerTest, AvoidPastEndOfStringDereference) {
477   std::vector<Token> LexedTokens = Lex("  //  \\\n");
478   EXPECT_TRUE(LexedTokens.empty());
479 }
480 
481 TEST_F(LexerTest, StringizingRasString) {
482   // For "std::string Lexer::Stringify(StringRef Str, bool Charify)".
483   std::string String1 = R"(foo
484     {"bar":[]}
485     baz)";
486   // For "void Lexer::Stringify(SmallVectorImpl<char> &Str)".
487   SmallString<128> String2;
488   String2 += String1.c_str();
489 
490   // Corner cases.
491   std::string String3 = R"(\
492     \n
493     \\n
494     \\)";
495   SmallString<128> String4;
496   String4 += String3.c_str();
497   std::string String5 = R"(a\
498 
499 
500     \\b)";
501   SmallString<128> String6;
502   String6 += String5.c_str();
503 
504   String1 = Lexer::Stringify(StringRef(String1));
505   Lexer::Stringify(String2);
506   String3 = Lexer::Stringify(StringRef(String3));
507   Lexer::Stringify(String4);
508   String5 = Lexer::Stringify(StringRef(String5));
509   Lexer::Stringify(String6);
510 
511   EXPECT_EQ(String1, R"(foo\n    {\"bar\":[]}\n    baz)");
512   EXPECT_EQ(String2, R"(foo\n    {\"bar\":[]}\n    baz)");
513   EXPECT_EQ(String3, R"(\\\n    \\n\n    \\\\n\n    \\\\)");
514   EXPECT_EQ(String4, R"(\\\n    \\n\n    \\\\n\n    \\\\)");
515   EXPECT_EQ(String5, R"(a\\\n\n\n    \\\\b)");
516   EXPECT_EQ(String6, R"(a\\\n\n\n    \\\\b)");
517 }
518 
519 } // anonymous namespace
520