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