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