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