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