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