[GlobalISel] Add G_ABDS and G_ABDU instructions (#118122)
[llvm-project.git] / clang / unittests / Format / MacroCallReconstructorTest.cpp
blobb4ee8d0e37efa813d9be5e3677692bb99dd2c64d
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"
8 #include "gmock/gmock.h"
9 #include "gtest/gtest.h"
10 #include <map>
11 #include <memory>
12 #include <vector>
14 namespace clang {
15 namespace format {
16 namespace {
18 using UnexpandedMap =
19 llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>;
21 // Keeps track of a sequence of macro expansions.
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) {}
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(StringRef Name,
34 const SmallVector<SmallVector<FormatToken *, 8>, 1> &Args) {
35 return expandInternal(Name, Args);
38 TokenList expand(StringRef Name) { return expandInternal(Name, {}); }
40 TokenList expand(StringRef Name, const std::vector<std::string> &Args) {
41 return expandInternal(Name, lexArgs(Args));
44 const UnexpandedMap &getUnexpanded() const { return Unexpanded; }
46 const TokenList &getTokens() const { return Tokens; }
48 private:
49 TokenList expandInternal(
50 StringRef Name,
51 const std::optional<SmallVector<SmallVector<FormatToken *, 8>, 1>>
52 &Args) {
53 auto *ID = Lex.id(Name);
54 auto UnexpandedLine = std::make_unique<UnwrappedLine>();
55 UnexpandedLine->Tokens.push_back(ID);
56 if (Args && !Args->empty()) {
57 UnexpandedLine->Tokens.push_back(Lex.id("("));
58 for (auto I = Args->begin(), E = Args->end(); I != E; ++I) {
59 if (I != Args->begin())
60 UnexpandedLine->Tokens.push_back(Lex.id(","));
61 UnexpandedLine->Tokens.insert(UnexpandedLine->Tokens.end(), I->begin(),
62 I->end());
64 UnexpandedLine->Tokens.push_back(Lex.id(")"));
66 Unexpanded[ID] = std::move(UnexpandedLine);
68 auto Expanded = uneof(Macros.expand(ID, Args));
69 Tokens.append(Expanded.begin(), Expanded.end());
71 TokenList UnexpandedTokens;
72 for (const UnwrappedLineNode &Node : Unexpanded[ID]->Tokens)
73 UnexpandedTokens.push_back(Node.Tok);
74 return UnexpandedTokens;
77 SmallVector<TokenList, 1> lexArgs(const std::vector<std::string> &Args) {
78 SmallVector<TokenList, 1> Result;
79 for (const auto &Arg : Args)
80 Result.push_back(uneof(Lex.lex(Arg)));
81 return Result;
83 llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>> Unexpanded;
84 SmallVector<FormatToken *, 8> Tokens;
85 TestLexer &Lex;
86 MacroExpander &Macros;
89 struct Chunk {
90 Chunk(ArrayRef<FormatToken *> Tokens) : Tokens(Tokens) {}
91 Chunk(ArrayRef<UnwrappedLine> Children) : Children(Children) {}
92 SmallVector<UnwrappedLineNode, 1> Tokens;
93 SmallVector<UnwrappedLine, 0> Children;
96 // Allows to produce chunks of a token list by typing the code of equal tokens.
98 // Created from a list of tokens, users call "consume" to get the next chunk
99 // of tokens, checking that they match the written code.
100 struct Matcher {
101 Matcher(const TokenList &Tokens, TestLexer &Lex)
102 : Tokens(Tokens), It(this->Tokens.begin()), Lex(Lex) {}
104 bool tokenMatches(const FormatToken *Left, const FormatToken *Right) {
105 if (Left->getType() == Right->getType() &&
106 Left->TokenText == Right->TokenText) {
107 return true;
109 llvm::dbgs() << Left->TokenText << " != " << Right->TokenText << "\n";
110 return false;
113 Chunk consume(StringRef Tokens) {
114 TokenList Result;
115 for (const FormatToken *Token : uneof(Lex.lex(Tokens))) {
116 (void)Token; // Fix unused variable warning when asserts are disabled.
117 assert(tokenMatches(*It, Token));
118 Result.push_back(*It);
119 ++It;
121 return Chunk(Result);
124 TokenList Tokens;
125 TokenList::iterator It;
126 TestLexer &Lex;
129 UnexpandedMap mergeUnexpanded(const UnexpandedMap &M1,
130 const UnexpandedMap &M2) {
131 UnexpandedMap Result;
132 for (const auto &KV : M1)
133 Result[KV.first] = std::make_unique<UnwrappedLine>(*KV.second);
134 for (const auto &KV : M2)
135 Result[KV.first] = std::make_unique<UnwrappedLine>(*KV.second);
136 return Result;
139 class MacroCallReconstructorTest : public testing::Test {
140 public:
141 MacroCallReconstructorTest() : Lex(Allocator, Buffers) {}
143 std::unique_ptr<MacroExpander>
144 createExpander(const std::vector<std::string> &MacroDefinitions) {
145 return std::make_unique<MacroExpander>(MacroDefinitions,
146 Lex.SourceMgr.get(), Lex.Style,
147 Lex.Allocator, Lex.IdentTable);
150 UnwrappedLine line(ArrayRef<FormatToken *> Tokens, unsigned Level = 0) {
151 UnwrappedLine Result;
152 Result.Level = Level;
153 for (FormatToken *Tok : Tokens)
154 Result.Tokens.push_back(UnwrappedLineNode(Tok));
155 return Result;
158 UnwrappedLine line(StringRef Text, unsigned Level = 0) {
159 return line({lex(Text)}, Level);
162 UnwrappedLine line(ArrayRef<Chunk> Chunks, unsigned Level = 0) {
163 UnwrappedLine Result;
164 Result.Level = Level;
165 for (const Chunk &Chunk : Chunks) {
166 Result.Tokens.insert(Result.Tokens.end(), Chunk.Tokens.begin(),
167 Chunk.Tokens.end());
168 assert(!Result.Tokens.empty());
169 Result.Tokens.back().Children.append(Chunk.Children.begin(),
170 Chunk.Children.end());
172 return Result;
175 TokenList lex(StringRef Text) { return uneof(Lex.lex(Text)); }
177 Chunk tokens(StringRef Text) { return Chunk(lex(Text)); }
179 Chunk children(ArrayRef<UnwrappedLine> Children) { return Chunk(Children); }
181 llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
182 std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;
183 TestLexer Lex;
186 bool matchesTokens(const UnwrappedLine &L1, const UnwrappedLine &L2) {
187 if (L1.Level != L2.Level)
188 return false;
189 if (L1.Tokens.size() != L2.Tokens.size())
190 return false;
191 for (auto L1It = L1.Tokens.begin(), L2It = L2.Tokens.begin();
192 L1It != L1.Tokens.end(); ++L1It, ++L2It) {
193 if (L1It->Tok != L2It->Tok)
194 return false;
195 if (L1It->Children.size() != L2It->Children.size())
196 return false;
197 for (auto L1ChildIt = L1It->Children.begin(),
198 L2ChildIt = L2It->Children.begin();
199 L1ChildIt != L1It->Children.end(); ++L1ChildIt, ++L2ChildIt) {
200 if (!matchesTokens(*L1ChildIt, *L2ChildIt))
201 return false;
204 return true;
206 MATCHER_P(matchesLine, line, "") { return matchesTokens(arg, line); }
208 TEST_F(MacroCallReconstructorTest, Identifier) {
209 auto Macros = createExpander({"X=x"});
210 Expansion Exp(Lex, *Macros);
211 TokenList Call = Exp.expand("X");
213 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
214 Unexp.addLine(line(Exp.getTokens()));
215 EXPECT_TRUE(Unexp.finished());
216 Matcher U(Call, Lex);
217 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(line(U.consume("X"))));
220 TEST_F(MacroCallReconstructorTest, NestedLineWithinCall) {
221 auto Macros = createExpander({"C(a)=class X { a; };"});
222 Expansion Exp(Lex, *Macros);
223 TokenList Call = Exp.expand("C", {"void f()"});
225 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
226 Matcher E(Exp.getTokens(), Lex);
227 Unexp.addLine(line(E.consume("class X {")));
228 EXPECT_FALSE(Unexp.finished());
229 Unexp.addLine(line(E.consume("void f();")));
230 EXPECT_FALSE(Unexp.finished());
231 Unexp.addLine(line(E.consume("};")));
232 EXPECT_TRUE(Unexp.finished());
233 Matcher U(Call, Lex);
234 EXPECT_THAT(std::move(Unexp).takeResult(),
235 matchesLine(line(U.consume("C(void f())"))));
238 TEST_F(MacroCallReconstructorTest, MultipleLinesInNestedMultiParamsExpansion) {
239 auto Macros = createExpander({"C(a, b)=a b", "B(a)={a}"});
240 Expansion Exp1(Lex, *Macros);
241 TokenList Call1 = Exp1.expand("B", {"b"});
242 Expansion Exp2(Lex, *Macros);
243 TokenList Call2 = Exp2.expand("C", {uneof(Lex.lex("a")), Exp1.getTokens()});
245 UnexpandedMap Unexpanded =
246 mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded());
247 MacroCallReconstructor Unexp(0, Unexpanded);
248 Matcher E(Exp2.getTokens(), Lex);
249 Unexp.addLine(line(E.consume("a")));
250 EXPECT_FALSE(Unexp.finished());
251 Unexp.addLine(line(E.consume("{")));
252 EXPECT_FALSE(Unexp.finished());
253 Unexp.addLine(line(E.consume("b")));
254 EXPECT_FALSE(Unexp.finished());
255 Unexp.addLine(line(E.consume("}")));
256 EXPECT_TRUE(Unexp.finished());
258 Matcher U1(Call1, Lex);
259 auto Middle = U1.consume("B(b)");
260 Matcher U2(Call2, Lex);
261 auto Chunk1 = U2.consume("C(a, ");
262 auto Chunk2 = U2.consume("{ b }");
263 auto Chunk3 = U2.consume(")");
265 EXPECT_THAT(std::move(Unexp).takeResult(),
266 matchesLine(line({Chunk1, Middle, Chunk3})));
269 TEST_F(MacroCallReconstructorTest, StatementSequence) {
270 auto Macros = createExpander({"SEMI=;"});
271 Expansion Exp(Lex, *Macros);
272 TokenList Call1 = Exp.expand("SEMI");
273 TokenList Call2 = Exp.expand("SEMI");
274 TokenList Call3 = Exp.expand("SEMI");
276 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
277 Matcher E(Exp.getTokens(), Lex);
278 Unexp.addLine(line(E.consume(";")));
279 EXPECT_TRUE(Unexp.finished());
280 Unexp.addLine(line(E.consume(";")));
281 EXPECT_TRUE(Unexp.finished());
282 Unexp.addLine(line(E.consume(";")));
283 EXPECT_TRUE(Unexp.finished());
284 Matcher U1(Call1, Lex);
285 Matcher U2(Call2, Lex);
286 Matcher U3(Call3, Lex);
287 EXPECT_THAT(std::move(Unexp).takeResult(),
288 matchesLine(line(
289 {U1.consume("SEMI"),
290 children({line({U2.consume("SEMI"),
291 children({line(U3.consume("SEMI"), 2)})},
292 1)})})));
295 TEST_F(MacroCallReconstructorTest, NestedBlock) {
296 auto Macros = createExpander({"ID(x)=x"});
297 // Test: ID({ ID(a *b); })
298 // 1. expand ID(a *b) -> a *b
299 Expansion Exp1(Lex, *Macros);
300 TokenList Call1 = Exp1.expand("ID", {"a *b"});
301 // 2. expand ID({ a *b; })
302 TokenList Arg;
303 Arg.push_back(Lex.id("{"));
304 Arg.append(Exp1.getTokens().begin(), Exp1.getTokens().end());
305 Arg.push_back(Lex.id(";"));
306 Arg.push_back(Lex.id("}"));
307 Expansion Exp2(Lex, *Macros);
308 TokenList Call2 = Exp2.expand("ID", {Arg});
310 // Consume as-if formatted:
311 // {
312 // a *b;
313 // }
314 UnexpandedMap Unexpanded =
315 mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded());
316 MacroCallReconstructor Unexp(0, Unexpanded);
317 Matcher E(Exp2.getTokens(), Lex);
318 Unexp.addLine(line(E.consume("{")));
319 EXPECT_FALSE(Unexp.finished());
320 Unexp.addLine(line(E.consume("a *b;")));
321 EXPECT_FALSE(Unexp.finished());
322 Unexp.addLine(line(E.consume("}")));
323 EXPECT_TRUE(Unexp.finished());
325 // Expect lines:
326 // ID({
327 // ID(a *b);
328 // })
329 Matcher U1(Call1, Lex);
330 Matcher U2(Call2, Lex);
331 auto Chunk2Start = U2.consume("ID(");
332 auto Chunk2LBrace = U2.consume("{");
333 U2.consume("a *b");
334 auto Chunk2Mid = U2.consume(";");
335 auto Chunk2RBrace = U2.consume("}");
336 auto Chunk2End = U2.consume(")");
337 auto Chunk1 = U1.consume("ID(a *b)");
339 auto Expected = line({Chunk2Start,
340 children({
341 line(Chunk2LBrace, 1),
342 line({Chunk1, Chunk2Mid}, 1),
343 line(Chunk2RBrace, 1),
345 Chunk2End});
346 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
349 TEST_F(MacroCallReconstructorTest, NestedChildBlocks) {
350 auto Macros = createExpander({"ID(x)=x", "CALL(x)=f([] { x })"});
351 // Test: ID(CALL(CALL(return a * b;)))
352 // 1. expand CALL(return a * b;)
353 Expansion Exp1(Lex, *Macros);
354 TokenList Call1 = Exp1.expand("CALL", {"return a * b;"});
355 // 2. expand CALL(f([] { return a * b; }))
356 Expansion Exp2(Lex, *Macros);
357 TokenList Call2 = Exp2.expand("CALL", {Exp1.getTokens()});
358 // 3. expand ID({ f([] { f([] { return a * b; }) }) })
359 TokenList Arg3;
360 Arg3.push_back(Lex.id("{"));
361 Arg3.append(Exp2.getTokens().begin(), Exp2.getTokens().end());
362 Arg3.push_back(Lex.id("}"));
363 Expansion Exp3(Lex, *Macros);
364 TokenList Call3 = Exp3.expand("ID", {Arg3});
366 // Consume as-if formatted in three unwrapped lines:
367 // 0: {
368 // 1: f([] {
369 // f([] {
370 // return a * b;
371 // })
372 // })
373 // 2: }
374 UnexpandedMap Unexpanded = mergeUnexpanded(
375 Exp1.getUnexpanded(),
376 mergeUnexpanded(Exp2.getUnexpanded(), Exp3.getUnexpanded()));
377 MacroCallReconstructor Unexp(0, Unexpanded);
378 Matcher E(Exp3.getTokens(), Lex);
379 Unexp.addLine(line(E.consume("{")));
380 Unexp.addLine(
381 line({E.consume("f([] {"),
382 children({line({E.consume("f([] {"),
383 children({line(E.consume("return a * b;"), 3)}),
384 E.consume("})")},
385 2)}),
386 E.consume("})")},
387 1));
388 Unexp.addLine(line(E.consume("}")));
389 EXPECT_TRUE(Unexp.finished());
391 // Expect lines:
392 // ID(
393 // {
394 // CALL(CALL(return a * b;))
395 // }
396 // )
397 Matcher U1(Call1, Lex);
398 Matcher U2(Call2, Lex);
399 Matcher U3(Call3, Lex);
400 auto Chunk3Start = U3.consume("ID(");
401 auto Chunk3LBrace = U3.consume("{");
402 U3.consume("f([] { f([] { return a * b; }) })");
403 auto Chunk3RBrace = U3.consume("}");
404 auto Chunk3End = U3.consume(")");
405 auto Chunk2Start = U2.consume("CALL(");
406 U2.consume("f([] { return a * b; })");
407 auto Chunk2End = U2.consume(")");
408 auto Chunk1 = U1.consume("CALL(return a * b;)");
410 auto Expected = line({
411 Chunk3Start,
412 children({
413 line(Chunk3LBrace, 1),
414 line(
416 Chunk2Start,
417 Chunk1,
418 Chunk2End,
421 line(Chunk3RBrace, 1),
423 Chunk3End,
425 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
428 TEST_F(MacroCallReconstructorTest, NestedChildrenMultipleArguments) {
429 auto Macros = createExpander({"CALL(a, b)=f([] { a; b; })"});
430 Expansion Exp(Lex, *Macros);
431 TokenList Call = Exp.expand("CALL", {std::string("int a"), "int b"});
433 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
434 Matcher E(Exp.getTokens(), Lex);
435 Unexp.addLine(line({
436 E.consume("f([] {"),
437 children({
438 line(E.consume("int a;")),
439 line(E.consume("int b;")),
441 E.consume("})"),
442 }));
443 EXPECT_TRUE(Unexp.finished());
444 Matcher U(Call, Lex);
445 auto Expected = line(U.consume("CALL(int a, int b)"));
446 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
449 TEST_F(MacroCallReconstructorTest, ReverseOrderArgumentsInExpansion) {
450 auto Macros = createExpander({"CALL(a, b)=b + a"});
451 Expansion Exp(Lex, *Macros);
452 TokenList Call = Exp.expand("CALL", {std::string("x"), "y"});
454 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
455 Matcher E(Exp.getTokens(), Lex);
456 Unexp.addLine(line(E.consume("y + x")));
457 EXPECT_TRUE(Unexp.finished());
458 Matcher U(Call, Lex);
459 auto Expected = line(U.consume("CALL(x, y)"));
460 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
463 TEST_F(MacroCallReconstructorTest, MultipleToplevelUnwrappedLines) {
464 auto Macros = createExpander({"ID(a, b)=a b"});
465 Expansion Exp(Lex, *Macros);
466 TokenList Call = Exp.expand("ID", {std::string("x; x"), "y"});
468 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
469 Matcher E(Exp.getTokens(), Lex);
470 Unexp.addLine(line(E.consume("x;")));
471 Unexp.addLine(line(E.consume("x y")));
472 EXPECT_TRUE(Unexp.finished());
473 Matcher U(Call, Lex);
474 auto Expected = line({
475 U.consume("ID("),
476 children({
477 line(U.consume("x;"), 1),
478 line(U.consume("x"), 1),
480 U.consume(", y)"),
482 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
485 TEST_F(MacroCallReconstructorTest, NestedCallsMultipleLines) {
486 auto Macros = createExpander({"ID(x)=x"});
487 // Test: ID({ID(a * b);})
488 // 1. expand ID(a * b)
489 Expansion Exp1(Lex, *Macros);
490 TokenList Call1 = Exp1.expand("ID", {"a * b"});
491 // 2. expand ID({ a * b; })
492 Expansion Exp2(Lex, *Macros);
493 TokenList Arg2;
494 Arg2.push_back(Lex.id("{"));
495 Arg2.append(Exp1.getTokens().begin(), Exp1.getTokens().end());
496 Arg2.push_back(Lex.id(";"));
497 Arg2.push_back(Lex.id("}"));
498 TokenList Call2 = Exp2.expand("ID", {Arg2});
500 // Consume as-if formatted in three unwrapped lines:
501 // 0: {
502 // 1: a * b;
503 // 2: }
504 UnexpandedMap Unexpanded =
505 mergeUnexpanded(Exp1.getUnexpanded(), Exp2.getUnexpanded());
506 MacroCallReconstructor Unexp(0, Unexpanded);
507 Matcher E(Exp2.getTokens(), Lex);
508 Unexp.addLine(line(E.consume("{")));
509 Unexp.addLine(line(E.consume("a * b;")));
510 Unexp.addLine(line(E.consume("}")));
511 EXPECT_TRUE(Unexp.finished());
513 // Expect lines:
514 // ID(
515 // {
516 // ID(a * b);
517 // }
518 // )
519 Matcher U1(Call1, Lex);
520 Matcher U2(Call2, Lex);
521 auto Chunk2Start = U2.consume("ID(");
522 auto Chunk2LBrace = U2.consume("{");
523 U2.consume("a * b");
524 auto Chunk2Semi = U2.consume(";");
525 auto Chunk2RBrace = U2.consume("}");
526 auto Chunk2End = U2.consume(")");
527 auto Chunk1 = U1.consume("ID(a * b)");
529 auto Expected = line({
530 Chunk2Start,
531 children({
532 line({Chunk2LBrace}, 1),
533 line({Chunk1, Chunk2Semi}, 1),
534 line({Chunk2RBrace}, 1),
536 Chunk2End,
538 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
541 TEST_F(MacroCallReconstructorTest, ParentOutsideMacroCall) {
542 auto Macros = createExpander({"ID(a)=a"});
543 Expansion Exp(Lex, *Macros);
544 TokenList Call = Exp.expand("ID", {std::string("x; y; z;")});
546 auto Prefix = tokens("int a = []() {");
547 auto Postfix = tokens("}();");
548 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
549 Matcher E(Exp.getTokens(), Lex);
550 Unexp.addLine(line({
551 Prefix,
552 children({
553 line(E.consume("x;")),
554 line(E.consume("y;")),
555 line(E.consume("z;")),
557 Postfix,
558 }));
559 EXPECT_TRUE(Unexp.finished());
560 Matcher U(Call, Lex);
561 auto Expected = line({
562 Prefix,
563 children({
564 line(
566 U.consume("ID("),
567 children({
568 line(U.consume("x;"), 2),
569 line(U.consume("y;"), 2),
570 line(U.consume("z;"), 2),
572 U.consume(")"),
576 Postfix,
578 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
581 TEST_F(MacroCallReconstructorTest, ChildrenSplitAcrossArguments) {
582 auto Macros = createExpander({"CALL(a, b)=f([]() a b)"});
583 Expansion Exp(Lex, *Macros);
584 TokenList Call = Exp.expand("CALL", {std::string("{ a;"), "b; }"});
586 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
587 Matcher E(Exp.getTokens(), Lex);
588 Unexp.addLine(line({
589 E.consume("f([]() {"),
590 children({
591 line(E.consume("a;")),
592 line(E.consume("b;")),
594 E.consume("})"),
595 }));
596 EXPECT_TRUE(Unexp.finished());
597 Matcher U(Call, Lex);
598 auto Expected = line({
599 U.consume("CALL({"),
600 children(line(U.consume("a;"), 1)),
601 U.consume(", b; })"),
603 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
606 TEST_F(MacroCallReconstructorTest, ChildrenAfterMacroCall) {
607 auto Macros = createExpander({"CALL(a, b)=f([]() a b"});
608 Expansion Exp(Lex, *Macros);
609 TokenList Call = Exp.expand("CALL", {std::string("{ a"), "b"});
611 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
612 Matcher E(Exp.getTokens(), Lex);
613 auto Semi = tokens(";");
614 auto SecondLine = tokens("c d;");
615 auto ThirdLine = tokens("e f;");
616 auto Postfix = tokens("})");
617 Unexp.addLine(line({
618 E.consume("f([]() {"),
619 children({
620 line({E.consume("a b"), Semi}),
621 line(SecondLine),
622 line(ThirdLine),
624 Postfix,
625 }));
626 EXPECT_TRUE(Unexp.finished());
627 Matcher U(Call, Lex);
628 auto Expected = line({
629 U.consume("CALL({"),
630 children(line(U.consume("a"), 1)),
631 U.consume(", b)"),
632 Semi,
633 children(line(
635 SecondLine,
636 children(line(
638 ThirdLine,
639 Postfix,
641 2)),
643 1)),
645 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
648 TEST_F(MacroCallReconstructorTest, InvalidCodeSplittingBracesAcrossArgs) {
649 auto Macros = createExpander({"M(a, b, c)=(a) (b) c"});
650 Expansion Exp(Lex, *Macros);
651 TokenList Call = Exp.expand("M", {std::string("{"), "x", ""});
653 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
654 Matcher E(Exp.getTokens(), Lex);
655 auto Prefix = tokens("({");
656 Unexp.addLine(line({
657 Prefix,
658 children({
659 line({
660 E.consume("({"),
661 children({line(E.consume(")(x)"))}),
664 }));
665 EXPECT_TRUE(Unexp.finished());
666 Matcher U(Call, Lex);
667 auto Expected = line({
668 Prefix,
669 children({line(U.consume("M({,x,)"), 1)}),
671 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
674 TEST_F(MacroCallReconstructorTest, IndentLevelInExpandedCode) {
675 auto Macros = createExpander({"ID(a)=a"});
676 Expansion Exp(Lex, *Macros);
677 TokenList Call = Exp.expand("ID", {std::string("[] { { x; } }")});
679 MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
680 Matcher E(Exp.getTokens(), Lex);
681 Unexp.addLine(line({
682 E.consume("[] {"),
683 children({
684 line(E.consume("{"), 1),
685 line(E.consume("x;"), 2),
686 line(E.consume("}"), 1),
688 E.consume("}"),
689 }));
690 EXPECT_TRUE(Unexp.finished());
691 Matcher U(Call, Lex);
692 auto Expected = line({
693 U.consume("ID([] {"),
694 children({
695 line(U.consume("{"), 1),
696 line(U.consume("x;"), 2),
697 line(U.consume("}"), 1),
699 U.consume("})"),
701 EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(Expected));
704 } // namespace
705 } // namespace format
706 } // namespace clang