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:
Expansion(TestLexer & Lex,MacroExpander & Macros)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
expand(llvm::StringRef Name,const SmallVector<llvm::SmallVector<FormatToken *,8>,1> & Args)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 
expand(llvm::StringRef Name,const std::vector<std::string> & Args={})61   TokenList expand(llvm::StringRef Name,
62                    const std::vector<std::string> &Args = {}) {
63     return expand(Name, lexArgs(Args));
64   }
65 
getUnexpanded() const66   const UnexpandedMap &getUnexpanded() const { return Unexpanded; }
67 
getTokens() const68   const TokenList &getTokens() const { return Tokens; }
69 
70 private:
71   llvm::SmallVector<TokenList, 1>
lexArgs(const std::vector<std::string> & Args)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 {
Chunkclang::format::__anon35b0f3090111::Chunk86   Chunk(llvm::ArrayRef<FormatToken *> Tokens)
87       : Tokens(Tokens.begin(), Tokens.end()) {}
Chunkclang::format::__anon35b0f3090111::Chunk88   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 {
Matcherclang::format::__anon35b0f3090111::Matcher99   Matcher(const TokenList &Tokens, TestLexer &Lex)
100       : Tokens(Tokens), It(this->Tokens.begin()), Lex(Lex) {}
101 
consumeclang::format::__anon35b0f3090111::Matcher102   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 
mergeUnexpanded(const UnexpandedMap & M1,const UnexpandedMap & M2)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:
MacroCallReconstructorTest()133   MacroCallReconstructorTest() : Lex(Allocator, Buffers) {}
134 
135   std::unique_ptr<MacroExpander>
createExpander(const std::vector<std::string> & MacroDefinitions)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 
line(llvm::ArrayRef<FormatToken * > Tokens)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 
line(llvm::StringRef Text)150   UnwrappedLine line(llvm::StringRef Text) { return line({lex(Text)}); }
151 
line(llvm::ArrayRef<Chunk> Chunks)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 
lex(llvm::StringRef Text)164   TokenList lex(llvm::StringRef Text) { return uneof(Lex.lex(Text)); }
165 
tokens(llvm::StringRef Text)166   Chunk tokens(llvm::StringRef Text) { return Chunk(lex(Text)); }
167 
children(llvm::ArrayRef<UnwrappedLine> Children)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 
matchesTokens(const UnwrappedLine & L1,const UnwrappedLine & L2)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 
TEST_F(MacroCallReconstructorTest,Identifier)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 
TEST_F(MacroCallReconstructorTest,NestedLineWithinCall)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 
TEST_F(MacroCallReconstructorTest,MultipleLinesInNestedMultiParamsExpansion)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 
TEST_F(MacroCallReconstructorTest,StatementSequence)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 
TEST_F(MacroCallReconstructorTest,NestedBlock)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 
TEST_F(MacroCallReconstructorTest,NestedChildBlocks)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 
TEST_F(MacroCallReconstructorTest,NestedChildrenMultipleArguments)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 
TEST_F(MacroCallReconstructorTest,ReverseOrderArgumentsInExpansion)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 
TEST_F(MacroCallReconstructorTest,MultipleToplevelUnwrappedLines)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 
TEST_F(MacroCallReconstructorTest,NestedCallsMultipleLines)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 
TEST_F(MacroCallReconstructorTest,ParentOutsideMacroCall)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 
TEST_F(MacroCallReconstructorTest,UnusedMacroArguments)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 
TEST_F(MacroCallReconstructorTest,UnusedEmptyMacroArgument)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 
TEST_F(MacroCallReconstructorTest,ChildrenSplitAcrossArguments)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 
TEST_F(MacroCallReconstructorTest,ChildrenAfterMacroCall)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 
TEST_F(MacroCallReconstructorTest,InvalidCodeSplittingBracesAcrossArgs)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