1 #include "../../lib/Format/Macros.h" 2 #include "../../lib/Format/UnwrappedLineParser.h" 3 #include "TestLexer.h" 4 #include "llvm/ADT/ArrayRef.h" 5 #include "llvm/ADT/SmallVector.h" 6 #include "llvm/ADT/StringRef.h" 7 8 #include "gmock/gmock.h" 9 #include "gtest/gtest.h" 10 #include <map> 11 #include <memory> 12 #include <vector> 13 14 namespace clang { 15 namespace format { 16 namespace { 17 18 using UnexpandedMap = 19 llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>; 20 21 // Keeps track of a sequence of macro expansions. 22 // 23 // The expanded tokens are accessible via getTokens(), while a map of macro call 24 // identifier token to unexpanded token stream is accessible via 25 // getUnexpanded(). 26 class Expansion { 27 public: 28 Expansion(TestLexer &Lex, MacroExpander &Macros) : Lex(Lex), Macros(Macros) {} 29 30 // Appends the token stream obtained from expanding the macro Name given 31 // the provided arguments, to be later retrieved with getTokens(). 32 // Returns the list of tokens making up the unexpanded macro call. 33 TokenList 34 expand(llvm::StringRef Name, 35 const SmallVector<llvm::SmallVector<FormatToken *, 8>, 1> &Args) { 36 auto *ID = Lex.id(Name); 37 auto UnexpandedLine = std::make_unique<UnwrappedLine>(); 38 UnexpandedLine->Tokens.push_back(ID); 39 if (!Args.empty()) { 40 UnexpandedLine->Tokens.push_back(Lex.id("(")); 41 for (auto I = Args.begin(), E = Args.end(); I != E; ++I) { 42 if (I != Args.begin()) 43 UnexpandedLine->Tokens.push_back(Lex.id(",")); 44 UnexpandedLine->Tokens.insert(UnexpandedLine->Tokens.end(), I->begin(), 45 I->end()); 46 } 47 UnexpandedLine->Tokens.push_back(Lex.id(")")); 48 } 49 Unexpanded[ID] = std::move(UnexpandedLine); 50 51 auto Expanded = uneof(Macros.expand(ID, Args)); 52 Tokens.append(Expanded.begin(), Expanded.end()); 53 54 TokenList UnexpandedTokens; 55 for (const UnwrappedLineNode &Node : Unexpanded[ID]->Tokens) { 56 UnexpandedTokens.push_back(Node.Tok); 57 } 58 return UnexpandedTokens; 59 } 60 61 TokenList expand(llvm::StringRef Name, 62 const std::vector<std::string> &Args = {}) { 63 return expand(Name, lexArgs(Args)); 64 } 65 66 const UnexpandedMap &getUnexpanded() const { return Unexpanded; } 67 68 const TokenList &getTokens() const { return Tokens; } 69 70 private: 71 llvm::SmallVector<TokenList, 1> 72 lexArgs(const std::vector<std::string> &Args) { 73 llvm::SmallVector<TokenList, 1> Result; 74 for (const auto &Arg : Args) { 75 Result.push_back(uneof(Lex.lex(Arg))); 76 } 77 return Result; 78 } 79 llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>> Unexpanded; 80 llvm::SmallVector<FormatToken *, 8> Tokens; 81 TestLexer &Lex; 82 MacroExpander &Macros; 83 }; 84 85 struct Chunk { 86 Chunk(llvm::ArrayRef<FormatToken *> Tokens) 87 : Tokens(Tokens.begin(), Tokens.end()) {} 88 Chunk(llvm::ArrayRef<UnwrappedLine> Children) 89 : Children(Children.begin(), Children.end()) {} 90 llvm::SmallVector<UnwrappedLineNode, 1> Tokens; 91 llvm::SmallVector<UnwrappedLine, 0> Children; 92 }; 93 94 bool tokenMatches(const FormatToken *Left, const FormatToken *Right) { 95 if (Left->getType() == Right->getType() && 96 Left->TokenText == Right->TokenText) 97 return true; 98 llvm::dbgs() << Left->TokenText << " != " << Right->TokenText << "\n"; 99 return false; 100 } 101 102 // Allows to produce chunks of a token list by typing the code of equal tokens. 103 // 104 // Created from a list of tokens, users call "consume" to get the next chunk 105 // of tokens, checking that they match the written code. 106 struct Matcher { 107 Matcher(const TokenList &Tokens, TestLexer &Lex) 108 : Tokens(Tokens), It(this->Tokens.begin()), Lex(Lex) {} 109 110 Chunk consume(StringRef Tokens) { 111 TokenList Result; 112 for (const FormatToken *Token : uneof(Lex.lex(Tokens))) { 113 assert(tokenMatches(*It, Token)); 114 Result.push_back(*It); 115 ++It; 116 } 117 return Chunk(Result); 118 } 119 120 TokenList Tokens; 121 TokenList::iterator It; 122 TestLexer &Lex; 123 }; 124 125 UnexpandedMap mergeUnexpanded(const UnexpandedMap &M1, 126 const UnexpandedMap &M2) { 127 UnexpandedMap Result; 128 for (const auto &KV : M1) { 129 Result[KV.first] = std::make_unique<UnwrappedLine>(*KV.second); 130 } 131 for (const auto &KV : M2) { 132 Result[KV.first] = std::make_unique<UnwrappedLine>(*KV.second); 133 } 134 return Result; 135 } 136 137 class MacroCallReconstructorTest : public ::testing::Test { 138 public: 139 MacroCallReconstructorTest() : Lex(Allocator, Buffers) {} 140 141 std::unique_ptr<MacroExpander> 142 createExpander(const std::vector<std::string> &MacroDefinitions) { 143 return std::make_unique<MacroExpander>(MacroDefinitions, 144 Lex.SourceMgr.get(), Lex.Style, 145 Lex.Allocator, Lex.IdentTable); 146 } 147 148 UnwrappedLine line(llvm::ArrayRef<FormatToken *> Tokens) { 149 UnwrappedLine Result; 150 for (FormatToken *Tok : Tokens) { 151 Result.Tokens.push_back(UnwrappedLineNode(Tok)); 152 } 153 return Result; 154 } 155 156 UnwrappedLine line(llvm::StringRef Text) { return line({lex(Text)}); } 157 158 UnwrappedLine line(llvm::ArrayRef<Chunk> Chunks) { 159 UnwrappedLine Result; 160 for (const Chunk &Chunk : Chunks) { 161 Result.Tokens.insert(Result.Tokens.end(), Chunk.Tokens.begin(), 162 Chunk.Tokens.end()); 163 assert(!Result.Tokens.empty()); 164 Result.Tokens.back().Children.append(Chunk.Children.begin(), 165 Chunk.Children.end()); 166 } 167 return Result; 168 } 169 170 TokenList lex(llvm::StringRef Text) { return uneof(Lex.lex(Text)); } 171 172 Chunk tokens(llvm::StringRef Text) { return Chunk(lex(Text)); } 173 174 Chunk children(llvm::ArrayRef<UnwrappedLine> Children) { 175 return Chunk(Children); 176 } 177 178 llvm::SpecificBumpPtrAllocator<FormatToken> Allocator; 179 std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers; 180 TestLexer Lex; 181 }; 182 183 bool matchesTokens(const UnwrappedLine &L1, const UnwrappedLine &L2) { 184 if (L1.Tokens.size() != L2.Tokens.size()) 185 return false; 186 for (auto L1It = L1.Tokens.begin(), L2It = L2.Tokens.begin(); 187 L1It != L1.Tokens.end(); ++L1It, ++L2It) { 188 if (L1It->Tok != L2It->Tok) 189 return false; 190 if (L1It->Children.size() != L2It->Children.size()) 191 return false; 192 for (auto L1ChildIt = L1It->Children.begin(), 193 L2ChildIt = L2It->Children.begin(); 194 L1ChildIt != L1It->Children.end(); ++L1ChildIt, ++L2ChildIt) { 195 if (!matchesTokens(*L1ChildIt, *L2ChildIt)) 196 return false; 197 } 198 } 199 return true; 200 } 201 MATCHER_P(matchesLine, line, "") { return matchesTokens(arg, line); } 202 203 TEST_F(MacroCallReconstructorTest, Identifier) { 204 auto Macros = createExpander({"X=x"}); 205 Expansion Exp(Lex, *Macros); 206 TokenList Call = Exp.expand("X"); 207 208 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 209 Unexp.addLine(line(Exp.getTokens())); 210 EXPECT_TRUE(Unexp.finished()); 211 Matcher U(Call, Lex); 212 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(line(U.consume("X")))); 213 } 214 215 TEST_F(MacroCallReconstructorTest, NestedLineWithinCall) { 216 auto Macros = createExpander({"C(a)=class X { a; };"}); 217 Expansion Exp(Lex, *Macros); 218 TokenList Call = Exp.expand("C", {"void f()"}); 219 220 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 221 Matcher E(Exp.getTokens(), Lex); 222 Unexp.addLine(line(E.consume("class X {"))); 223 EXPECT_FALSE(Unexp.finished()); 224 Unexp.addLine(line(E.consume("void f();"))); 225 EXPECT_FALSE(Unexp.finished()); 226 Unexp.addLine(line(E.consume("};"))); 227 EXPECT_TRUE(Unexp.finished()); 228 Matcher U(Call, Lex); 229 EXPECT_THAT(std::move(Unexp).takeResult(), 230 matchesLine(line(U.consume("C(void f())")))); 231 } 232 233 TEST_F(MacroCallReconstructorTest, MultipleLinesInNestedMultiParamsExpansion) { 234 auto Macros = createExpander({"C(a, b)=a b", "B(a)={a}"}); 235 Expansion Exp1(Lex, *Macros); 236 TokenList Call1 = Exp1.expand("B", {"b"}); 237 Expansion Exp2(Lex, *Macros); 238 TokenList Call2 = Exp2.expand("C", {uneof(Lex.lex("a")), Exp1.getTokens()}); 239 240 UnexpandedMap Unexpanded = 241 mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded()); 242 MacroCallReconstructor Unexp(0, Unexpanded); 243 Matcher E(Exp2.getTokens(), Lex); 244 Unexp.addLine(line(E.consume("a"))); 245 EXPECT_FALSE(Unexp.finished()); 246 Unexp.addLine(line(E.consume("{"))); 247 EXPECT_FALSE(Unexp.finished()); 248 Unexp.addLine(line(E.consume("b"))); 249 EXPECT_FALSE(Unexp.finished()); 250 Unexp.addLine(line(E.consume("}"))); 251 EXPECT_TRUE(Unexp.finished()); 252 253 Matcher U1(Call1, Lex); 254 auto Middle = U1.consume("B(b)"); 255 Matcher U2(Call2, Lex); 256 auto Chunk1 = U2.consume("C(a, "); 257 auto Chunk2 = U2.consume("{ b }"); 258 auto Chunk3 = U2.consume(")"); 259 260 EXPECT_THAT(std::move(Unexp).takeResult(), 261 matchesLine(line({Chunk1, Middle, Chunk3}))); 262 } 263 264 TEST_F(MacroCallReconstructorTest, StatementSequence) { 265 auto Macros = createExpander({"SEMI=;"}); 266 Expansion Exp(Lex, *Macros); 267 TokenList Call1 = Exp.expand("SEMI"); 268 TokenList Call2 = Exp.expand("SEMI"); 269 TokenList Call3 = Exp.expand("SEMI"); 270 271 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 272 Matcher E(Exp.getTokens(), Lex); 273 Unexp.addLine(line(E.consume(";"))); 274 EXPECT_TRUE(Unexp.finished()); 275 Unexp.addLine(line(E.consume(";"))); 276 EXPECT_TRUE(Unexp.finished()); 277 Unexp.addLine(line(E.consume(";"))); 278 EXPECT_TRUE(Unexp.finished()); 279 Matcher U1(Call1, Lex); 280 Matcher U2(Call2, Lex); 281 Matcher U3(Call3, Lex); 282 EXPECT_THAT(std::move(Unexp).takeResult(), 283 matchesLine(line( 284 {U1.consume("SEMI"), 285 children({line({U2.consume("SEMI"), 286 children({line(U3.consume("SEMI"))})})})}))); 287 } 288 289 TEST_F(MacroCallReconstructorTest, NestedBlock) { 290 auto Macros = createExpander({"ID(x)=x"}); 291 // Test: ID({ ID(a *b); }) 292 // 1. expand ID(a *b) -> a *b 293 Expansion Exp1(Lex, *Macros); 294 TokenList Call1 = Exp1.expand("ID", {"a *b"}); 295 // 2. expand ID({ a *b; }) 296 TokenList Arg; 297 Arg.push_back(Lex.id("{")); 298 Arg.append(Exp1.getTokens().begin(), Exp1.getTokens().end()); 299 Arg.push_back(Lex.id(";")); 300 Arg.push_back(Lex.id("}")); 301 Expansion Exp2(Lex, *Macros); 302 TokenList Call2 = Exp2.expand("ID", {Arg}); 303 304 // Consume as-if formatted: 305 // { 306 // a *b; 307 // } 308 UnexpandedMap Unexpanded = 309 mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded()); 310 MacroCallReconstructor Unexp(0, Unexpanded); 311 Matcher E(Exp2.getTokens(), Lex); 312 Unexp.addLine(line(E.consume("{"))); 313 EXPECT_FALSE(Unexp.finished()); 314 Unexp.addLine(line(E.consume("a *b;"))); 315 EXPECT_FALSE(Unexp.finished()); 316 Unexp.addLine(line(E.consume("}"))); 317 EXPECT_TRUE(Unexp.finished()); 318 319 // Expect lines: 320 // ID({ 321 // ID(a *b); 322 // }) 323 Matcher U1(Call1, Lex); 324 Matcher U2(Call2, Lex); 325 auto Chunk2Start = U2.consume("ID("); 326 auto Chunk2LBrace = U2.consume("{"); 327 U2.consume("a *b"); 328 auto Chunk2Mid = U2.consume(";"); 329 auto Chunk2RBrace = U2.consume("}"); 330 auto Chunk2End = U2.consume(")"); 331 auto Chunk1 = U1.consume("ID(a *b)"); 332 333 auto Expected = line({Chunk2Start, 334 children({ 335 line(Chunk2LBrace), 336 line({Chunk1, Chunk2Mid}), 337 line(Chunk2RBrace), 338 }), 339 Chunk2End}); 340 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 341 } 342 343 TEST_F(MacroCallReconstructorTest, NestedChildBlocks) { 344 auto Macros = createExpander({"ID(x)=x", "CALL(x)=f([] { x })"}); 345 // Test: ID(CALL(CALL(return a * b;))) 346 // 1. expand CALL(return a * b;) 347 Expansion Exp1(Lex, *Macros); 348 TokenList Call1 = Exp1.expand("CALL", {"return a * b;"}); 349 // 2. expand CALL(f([] { return a * b; })) 350 Expansion Exp2(Lex, *Macros); 351 TokenList Call2 = Exp2.expand("CALL", {Exp1.getTokens()}); 352 // 3. expand ID({ f([] { f([] { return a * b; }) }) }) 353 TokenList Arg3; 354 Arg3.push_back(Lex.id("{")); 355 Arg3.append(Exp2.getTokens().begin(), Exp2.getTokens().end()); 356 Arg3.push_back(Lex.id("}")); 357 Expansion Exp3(Lex, *Macros); 358 TokenList Call3 = Exp3.expand("ID", {Arg3}); 359 360 // Consume as-if formatted in three unwrapped lines: 361 // 0: { 362 // 1: f([] { 363 // f([] { 364 // return a * b; 365 // }) 366 // }) 367 // 2: } 368 UnexpandedMap Unexpanded = mergeUnexpanded( 369 Exp1.getUnexpanded(), 370 mergeUnexpanded(Exp2.getUnexpanded(), Exp3.getUnexpanded())); 371 MacroCallReconstructor Unexp(0, Unexpanded); 372 Matcher E(Exp3.getTokens(), Lex); 373 Unexp.addLine(line(E.consume("{"))); 374 Unexp.addLine( 375 line({E.consume("f([] {"), 376 children({line({E.consume("f([] {"), 377 children({line(E.consume("return a * b;"))}), 378 E.consume("})")})}), 379 E.consume("})")})); 380 Unexp.addLine(line(E.consume("}"))); 381 EXPECT_TRUE(Unexp.finished()); 382 383 // Expect lines: 384 // ID( 385 // { 386 // CALL(CALL(return a * b;)) 387 // } 388 // ) 389 Matcher U1(Call1, Lex); 390 Matcher U2(Call2, Lex); 391 Matcher U3(Call3, Lex); 392 auto Chunk3Start = U3.consume("ID("); 393 auto Chunk3LBrace = U3.consume("{"); 394 U3.consume("f([] { f([] { return a * b; }) })"); 395 auto Chunk3RBrace = U3.consume("}"); 396 auto Chunk3End = U3.consume(")"); 397 auto Chunk2Start = U2.consume("CALL("); 398 U2.consume("f([] { return a * b; })"); 399 auto Chunk2End = U2.consume(")"); 400 auto Chunk1 = U1.consume("CALL(return a * b;)"); 401 402 auto Expected = line({ 403 Chunk3Start, 404 children({ 405 line(Chunk3LBrace), 406 line({ 407 Chunk2Start, 408 Chunk1, 409 Chunk2End, 410 }), 411 line(Chunk3RBrace), 412 }), 413 Chunk3End, 414 }); 415 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 416 } 417 418 TEST_F(MacroCallReconstructorTest, NestedChildrenMultipleArguments) { 419 auto Macros = createExpander({"CALL(a, b)=f([] { a; b; })"}); 420 Expansion Exp(Lex, *Macros); 421 TokenList Call = Exp.expand("CALL", {std::string("int a"), "int b"}); 422 423 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 424 Matcher E(Exp.getTokens(), Lex); 425 Unexp.addLine(line({ 426 E.consume("f([] {"), 427 children({ 428 line(E.consume("int a;")), 429 line(E.consume("int b;")), 430 }), 431 E.consume("})"), 432 })); 433 EXPECT_TRUE(Unexp.finished()); 434 Matcher U(Call, Lex); 435 auto Expected = line(U.consume("CALL(int a, int b)")); 436 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 437 } 438 439 TEST_F(MacroCallReconstructorTest, ReverseOrderArgumentsInExpansion) { 440 auto Macros = createExpander({"CALL(a, b)=b + a"}); 441 Expansion Exp(Lex, *Macros); 442 TokenList Call = Exp.expand("CALL", {std::string("x"), "y"}); 443 444 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 445 Matcher E(Exp.getTokens(), Lex); 446 Unexp.addLine(line(E.consume("y + x"))); 447 EXPECT_TRUE(Unexp.finished()); 448 Matcher U(Call, Lex); 449 auto Expected = line(U.consume("CALL(x, y)")); 450 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 451 } 452 453 TEST_F(MacroCallReconstructorTest, MultipleToplevelUnwrappedLines) { 454 auto Macros = createExpander({"ID(a, b)=a b"}); 455 Expansion Exp(Lex, *Macros); 456 TokenList Call = Exp.expand("ID", {std::string("x; x"), "y"}); 457 458 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 459 Matcher E(Exp.getTokens(), Lex); 460 Unexp.addLine(line(E.consume("x;"))); 461 Unexp.addLine(line(E.consume("x y"))); 462 EXPECT_TRUE(Unexp.finished()); 463 Matcher U(Call, Lex); 464 auto Expected = line({ 465 U.consume("ID("), 466 children({ 467 line(U.consume("x;")), 468 line(U.consume("x")), 469 }), 470 U.consume(", y)"), 471 }); 472 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 473 } 474 475 TEST_F(MacroCallReconstructorTest, NestedCallsMultipleLines) { 476 auto Macros = createExpander({"ID(x)=x"}); 477 // Test: ID({ID(a * b);}) 478 // 1. expand ID(a * b) 479 Expansion Exp1(Lex, *Macros); 480 TokenList Call1 = Exp1.expand("ID", {"a * b"}); 481 // 2. expand ID({ a * b; }) 482 Expansion Exp2(Lex, *Macros); 483 TokenList Arg2; 484 Arg2.push_back(Lex.id("{")); 485 Arg2.append(Exp1.getTokens().begin(), Exp1.getTokens().end()); 486 Arg2.push_back(Lex.id(";")); 487 Arg2.push_back(Lex.id("}")); 488 TokenList Call2 = Exp2.expand("ID", {Arg2}); 489 490 // Consume as-if formatted in three unwrapped lines: 491 // 0: { 492 // 1: a * b; 493 // 2: } 494 UnexpandedMap Unexpanded = 495 mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded()); 496 MacroCallReconstructor Unexp(0, Unexpanded); 497 Matcher E(Exp2.getTokens(), Lex); 498 Unexp.addLine(line(E.consume("{"))); 499 Unexp.addLine(line(E.consume("a * b;"))); 500 Unexp.addLine(line(E.consume("}"))); 501 EXPECT_TRUE(Unexp.finished()); 502 503 // Expect lines: 504 // ID( 505 // { 506 // ID(a * b); 507 // } 508 // ) 509 Matcher U1(Call1, Lex); 510 Matcher U2(Call2, Lex); 511 auto Chunk2Start = U2.consume("ID("); 512 auto Chunk2LBrace = U2.consume("{"); 513 U2.consume("a * b"); 514 auto Chunk2Semi = U2.consume(";"); 515 auto Chunk2RBrace = U2.consume("}"); 516 auto Chunk2End = U2.consume(")"); 517 auto Chunk1 = U1.consume("ID(a * b)"); 518 519 auto Expected = line({ 520 Chunk2Start, 521 children({ 522 line({Chunk2LBrace}), 523 line({Chunk1, Chunk2Semi}), 524 line({Chunk2RBrace}), 525 }), 526 Chunk2End, 527 }); 528 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 529 } 530 531 TEST_F(MacroCallReconstructorTest, ParentOutsideMacroCall) { 532 auto Macros = createExpander({"ID(a)=a"}); 533 Expansion Exp(Lex, *Macros); 534 TokenList Call = Exp.expand("ID", {std::string("x; y; z;")}); 535 536 auto Prefix = tokens("int a = []() {"); 537 auto Postfix = tokens("}();"); 538 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 539 Matcher E(Exp.getTokens(), Lex); 540 Unexp.addLine(line({ 541 Prefix, 542 children({ 543 line(E.consume("x;")), 544 line(E.consume("y;")), 545 line(E.consume("z;")), 546 }), 547 Postfix, 548 })); 549 EXPECT_TRUE(Unexp.finished()); 550 Matcher U(Call, Lex); 551 auto Expected = line({ 552 Prefix, 553 children({ 554 line({ 555 U.consume("ID("), 556 children({ 557 line(U.consume("x;")), 558 line(U.consume("y;")), 559 line(U.consume("z;")), 560 }), 561 U.consume(")"), 562 }), 563 }), 564 Postfix, 565 }); 566 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 567 } 568 569 TEST_F(MacroCallReconstructorTest, UnusedMacroArguments) { 570 auto Macros = createExpander({"X=x"}); 571 Expansion Exp(Lex, *Macros); 572 TokenList Call = Exp.expand("X", {"a", "b", "c"}); 573 574 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 575 Unexp.addLine(line(Exp.getTokens())); 576 EXPECT_TRUE(Unexp.finished()); 577 Matcher U(Call, Lex); 578 EXPECT_THAT(std::move(Unexp).takeResult(), 579 matchesLine(line(U.consume("X(a, b, c)")))); 580 } 581 582 TEST_F(MacroCallReconstructorTest, UnusedEmptyMacroArgument) { 583 auto Macros = createExpander({"X=x"}); 584 Expansion Exp(Lex, *Macros); 585 TokenList Call = Exp.expand("X", {std::string("")}); 586 587 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 588 Matcher E(Exp.getTokens(), Lex); 589 auto Semi = tokens(";"); 590 Unexp.addLine(line({E.consume("x"), Semi})); 591 EXPECT_TRUE(Unexp.finished()); 592 Matcher U(Call, Lex); 593 EXPECT_THAT(std::move(Unexp).takeResult(), 594 matchesLine(line({U.consume("X()"), Semi}))); 595 } 596 597 TEST_F(MacroCallReconstructorTest, ChildrenSplitAcrossArguments) { 598 auto Macros = createExpander({"CALL(a, b)=f([]() a b)"}); 599 Expansion Exp(Lex, *Macros); 600 TokenList Call = Exp.expand("CALL", {std::string("{ a;"), "b; }"}); 601 602 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 603 Matcher E(Exp.getTokens(), Lex); 604 Unexp.addLine(line({ 605 E.consume("f([]() {"), 606 children({ 607 line(E.consume("a;")), 608 line(E.consume("b;")), 609 }), 610 E.consume("})"), 611 })); 612 EXPECT_TRUE(Unexp.finished()); 613 Matcher U(Call, Lex); 614 auto Expected = line({ 615 U.consume("CALL({"), 616 children(line(U.consume("a;"))), 617 U.consume(", b; })"), 618 }); 619 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 620 } 621 622 TEST_F(MacroCallReconstructorTest, ChildrenAfterMacroCall) { 623 auto Macros = createExpander({"CALL(a, b)=f([]() a b"}); 624 Expansion Exp(Lex, *Macros); 625 TokenList Call = Exp.expand("CALL", {std::string("{ a"), "b"}); 626 627 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 628 Matcher E(Exp.getTokens(), Lex); 629 auto Semi = tokens(";"); 630 auto SecondLine = tokens("c d;"); 631 auto ThirdLine = tokens("e f;"); 632 auto Postfix = tokens("})"); 633 Unexp.addLine(line({ 634 E.consume("f([]() {"), 635 children({ 636 line({E.consume("a b"), Semi}), 637 line(SecondLine), 638 line(ThirdLine), 639 }), 640 Postfix, 641 })); 642 EXPECT_TRUE(Unexp.finished()); 643 Matcher U(Call, Lex); 644 auto Expected = line({ 645 U.consume("CALL({"), 646 children(line(U.consume("a"))), 647 U.consume(", b)"), 648 Semi, 649 children(line({ 650 SecondLine, 651 children(line({ 652 ThirdLine, 653 Postfix, 654 })), 655 })), 656 }); 657 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 658 } 659 660 TEST_F(MacroCallReconstructorTest, InvalidCodeSplittingBracesAcrossArgs) { 661 auto Macros = createExpander({"M(a, b)=(a) (b)"}); 662 Expansion Exp(Lex, *Macros); 663 TokenList Call = Exp.expand("M", {std::string("{"), "x", ""}); 664 665 MacroCallReconstructor Unexp(0, Exp.getUnexpanded()); 666 Matcher E(Exp.getTokens(), Lex); 667 auto Prefix = tokens("({"); 668 Unexp.addLine(line({ 669 Prefix, 670 children({ 671 line({ 672 E.consume("({"), 673 children({line(E.consume(")(x)"))}), 674 }), 675 }), 676 })); 677 EXPECT_TRUE(Unexp.finished()); 678 Matcher U(Call, Lex); 679 auto Expected = line({ 680 Prefix, 681 children({line(U.consume("M({,x,)"))}), 682 }); 683 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected)); 684 } 685 686 } // namespace 687 } // namespace format 688 } // namespace clang 689