xref: /freebsd/contrib/llvm-project/clang/lib/Format/MacroCallReconstructor.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===--- MacroCallReconstructor.cpp - Format C++ code -----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file contains the implementation of MacroCallReconstructor, which fits
12 /// an reconstructed macro call to a parsed set of UnwrappedLines.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "Macros.h"
17 
18 #include "UnwrappedLineParser.h"
19 #include "clang/Basic/TokenKinds.h"
20 #include "llvm/ADT/DenseSet.h"
21 #include "llvm/Support/Debug.h"
22 #include <cassert>
23 
24 #define DEBUG_TYPE "format-reconstruct"
25 
26 namespace clang {
27 namespace format {
28 
29 // Call \p Call for each token in the unwrapped line given, passing
30 // the token, its parent and whether it is the first token in the line.
31 template <typename T>
forEachToken(const UnwrappedLine & Line,const T & Call,FormatToken * Parent=nullptr)32 void forEachToken(const UnwrappedLine &Line, const T &Call,
33                   FormatToken *Parent = nullptr) {
34   bool First = true;
35   for (const auto &N : Line.Tokens) {
36     Call(N.Tok, Parent, First, Line.Level);
37     First = false;
38     for (const auto &Child : N.Children)
39       forEachToken(Child, Call, N.Tok);
40   }
41 }
42 
MacroCallReconstructor(unsigned Level,const llvm::DenseMap<FormatToken *,std::unique_ptr<UnwrappedLine>> & ActiveExpansions)43 MacroCallReconstructor::MacroCallReconstructor(
44     unsigned Level,
45     const llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>
46         &ActiveExpansions)
47     : Result(Level), IdToReconstructed(ActiveExpansions) {
48   Result.Tokens.push_back(std::make_unique<LineNode>());
49   ActiveReconstructedLines.push_back(&Result);
50 }
51 
addLine(const UnwrappedLine & Line)52 void MacroCallReconstructor::addLine(const UnwrappedLine &Line) {
53   assert(State != Finalized);
54   LLVM_DEBUG(llvm::dbgs() << "MCR: new line...\n");
55   forEachToken(Line, [&](FormatToken *Token, FormatToken *Parent, bool First,
56                          unsigned Level) { add(Token, Parent, First, Level); });
57   assert(InProgress || finished());
58 }
59 
takeResult()60 UnwrappedLine MacroCallReconstructor::takeResult() && {
61   finalize();
62   assert(Result.Tokens.size() == 1 &&
63          Result.Tokens.front()->Children.size() == 1);
64   UnwrappedLine Final = createUnwrappedLine(
65       *Result.Tokens.front()->Children.front(), Result.Level);
66   assert(!Final.Tokens.empty());
67   return Final;
68 }
69 
70 // Reconstruct the position of the next \p Token, given its parent \p
71 // ExpandedParent in the incoming unwrapped line. \p First specifies whether it
72 // is the first token in a given unwrapped line.
add(FormatToken * Token,FormatToken * ExpandedParent,bool First,unsigned Level)73 void MacroCallReconstructor::add(FormatToken *Token,
74                                  FormatToken *ExpandedParent, bool First,
75                                  unsigned Level) {
76   LLVM_DEBUG(
77       llvm::dbgs() << "MCR: Token: " << Token->TokenText << ", Parent: "
78                    << (ExpandedParent ? ExpandedParent->TokenText : "<null>")
79                    << ", First: " << First << "\n");
80   // In order to be able to find the correct parent in the reconstructed token
81   // stream, we need to continue the last open reconstruction until we find the
82   // given token if it is part of the reconstructed token stream.
83   //
84   // Note that hidden tokens can be part of the reconstructed stream in nested
85   // macro calls.
86   // For example, given
87   //   #define C(x, y) x y
88   //   #define B(x) {x}
89   // And the call:
90   //   C(a, B(b))
91   // The outer macro call will be C(a, {b}), and the hidden token '}' can be
92   // found in the reconstructed token stream of that expansion level.
93   // In the expanded token stream
94   //   a {b}
95   // 'b' is a child of '{'. We need to continue the open expansion of the ','
96   // in the call of 'C' in order to correctly set the ',' as the parent of '{',
97   // so we later set the spelled token 'b' as a child of the ','.
98   if (!ActiveExpansions.empty() && Token->MacroCtx &&
99       (Token->MacroCtx->Role != MR_Hidden ||
100        ActiveExpansions.size() != Token->MacroCtx->ExpandedFrom.size())) {
101     if (/*PassedMacroComma = */ reconstructActiveCallUntil(Token))
102       First = true;
103   }
104 
105   prepareParent(ExpandedParent, First, Level);
106 
107   if (Token->MacroCtx) {
108     // If this token was generated by a macro call, add the reconstructed
109     // equivalent of the token.
110     reconstruct(Token);
111   } else {
112     // Otherwise, we add it to the current line.
113     appendToken(Token);
114   }
115 }
116 
117 // Adjusts the stack of active reconstructed lines so we're ready to push
118 // tokens. The tokens to be pushed are children of ExpandedParent in the
119 // expanded code.
120 //
121 // This may entail:
122 // - creating a new line, if the parent is on the active line
123 // - popping active lines, if the parent is further up the stack
124 //
125 // Postcondition:
126 // ActiveReconstructedLines.back() is the line that has \p ExpandedParent or its
127 // reconstructed replacement token as a parent (when possible) - that is, the
128 // last token in \c ActiveReconstructedLines[ActiveReconstructedLines.size()-2]
129 // is the parent of ActiveReconstructedLines.back() in the reconstructed
130 // unwrapped line.
prepareParent(FormatToken * ExpandedParent,bool NewLine,unsigned Level)131 void MacroCallReconstructor::prepareParent(FormatToken *ExpandedParent,
132                                            bool NewLine, unsigned Level) {
133   LLVM_DEBUG({
134     llvm::dbgs() << "ParentMap:\n";
135     debugParentMap();
136   });
137   // We want to find the parent in the new unwrapped line, where the expanded
138   // parent might have been replaced during reconstruction.
139   FormatToken *Parent = getParentInResult(ExpandedParent);
140   LLVM_DEBUG(llvm::dbgs() << "MCR: New parent: "
141                           << (Parent ? Parent->TokenText : "<null>") << "\n");
142 
143   FormatToken *OpenMacroParent = nullptr;
144   if (!MacroCallStructure.empty()) {
145     // Inside a macro expansion, it is possible to lose track of the correct
146     // parent - either because it is already popped, for example because it was
147     // in a different macro argument (e.g. M({, })), or when we work on invalid
148     // code.
149     // Thus, we use the innermost macro call's parent as the parent at which
150     // we stop; this allows us to stay within the macro expansion and keeps
151     // any problems confined to the extent of the macro call.
152     OpenMacroParent =
153         getParentInResult(MacroCallStructure.back().MacroCallLParen);
154     LLVM_DEBUG(llvm::dbgs()
155                << "MacroCallLParen: "
156                << MacroCallStructure.back().MacroCallLParen->TokenText
157                << ", OpenMacroParent: "
158                << (OpenMacroParent ? OpenMacroParent->TokenText : "<null>")
159                << "\n");
160   }
161   if (NewLine ||
162       (!ActiveReconstructedLines.back()->Tokens.empty() &&
163        Parent == ActiveReconstructedLines.back()->Tokens.back()->Tok)) {
164     // If we are at the first token in a new line, we want to also
165     // create a new line in the resulting reconstructed unwrapped line.
166     while (ActiveReconstructedLines.back()->Tokens.empty() ||
167            (Parent != ActiveReconstructedLines.back()->Tokens.back()->Tok &&
168             ActiveReconstructedLines.back()->Tokens.back()->Tok !=
169                 OpenMacroParent)) {
170       ActiveReconstructedLines.pop_back();
171       assert(!ActiveReconstructedLines.empty());
172     }
173     assert(!ActiveReconstructedLines.empty());
174     ActiveReconstructedLines.back()->Tokens.back()->Children.push_back(
175         std::make_unique<ReconstructedLine>(Level));
176     ActiveReconstructedLines.push_back(
177         &*ActiveReconstructedLines.back()->Tokens.back()->Children.back());
178   } else if (parentLine().Tokens.back()->Tok != Parent) {
179     // If we're not the first token in a new line, pop lines until we find
180     // the child of \c Parent in the stack.
181     while (Parent != parentLine().Tokens.back()->Tok &&
182            parentLine().Tokens.back()->Tok &&
183            parentLine().Tokens.back()->Tok != OpenMacroParent) {
184       ActiveReconstructedLines.pop_back();
185       assert(!ActiveReconstructedLines.empty());
186     }
187   }
188   assert(!ActiveReconstructedLines.empty());
189 }
190 
191 // For a given \p Parent in the incoming expanded token stream, find the
192 // corresponding parent in the output.
getParentInResult(FormatToken * Parent)193 FormatToken *MacroCallReconstructor::getParentInResult(FormatToken *Parent) {
194   FormatToken *Mapped = SpelledParentToReconstructedParent.lookup(Parent);
195   if (!Mapped)
196     return Parent;
197   for (; Mapped; Mapped = SpelledParentToReconstructedParent.lookup(Parent))
198     Parent = Mapped;
199   // If we use a different token than the parent in the expanded token stream
200   // as parent, mark it as a special parent, so the formatting code knows it
201   // needs to have its children formatted.
202   Parent->MacroParent = true;
203   return Parent;
204 }
205 
206 // Reconstruct a \p Token that was expanded from a macro call.
reconstruct(FormatToken * Token)207 void MacroCallReconstructor::reconstruct(FormatToken *Token) {
208   assert(Token->MacroCtx);
209   // A single token can be the only result of a macro call:
210   // Given: #define ID(x, y) ;
211   // And the call: ID(<some>, <tokens>)
212   // ';' in the expanded stream will reconstruct all of ID(<some>, <tokens>).
213   if (Token->MacroCtx->StartOfExpansion) {
214     startReconstruction(Token);
215     // If the order of tokens in the expanded token stream is not the
216     // same as the order of tokens in the reconstructed stream, we need
217     // to reconstruct tokens that arrive later in the stream.
218     if (Token->MacroCtx->Role != MR_Hidden)
219       reconstructActiveCallUntil(Token);
220   }
221   assert(!ActiveExpansions.empty());
222   if (ActiveExpansions.back().SpelledI != ActiveExpansions.back().SpelledE) {
223     assert(ActiveExpansions.size() == Token->MacroCtx->ExpandedFrom.size());
224     if (Token->MacroCtx->Role != MR_Hidden) {
225       // The current token in the reconstructed token stream must be the token
226       // we're looking for - we either arrive here after startReconstruction,
227       // which initiates the stream to the first token, or after
228       // continueReconstructionUntil skipped until the expected token in the
229       // reconstructed stream at the start of add(...).
230       assert(ActiveExpansions.back().SpelledI->Tok == Token);
231       processNextReconstructed();
232     } else if (!currentLine()->Tokens.empty()) {
233       // Map all hidden tokens to the last visible token in the output.
234       // If the hidden token is a parent, we'll use the last visible
235       // token as the parent of the hidden token's children.
236       SpelledParentToReconstructedParent[Token] =
237           currentLine()->Tokens.back()->Tok;
238     } else {
239       for (auto I = ActiveReconstructedLines.rbegin(),
240                 E = ActiveReconstructedLines.rend();
241            I != E; ++I) {
242         if (!(*I)->Tokens.empty()) {
243           SpelledParentToReconstructedParent[Token] = (*I)->Tokens.back()->Tok;
244           break;
245         }
246       }
247     }
248   }
249   if (Token->MacroCtx->EndOfExpansion)
250     endReconstruction(Token);
251 }
252 
253 // Given a \p Token that starts an expansion, reconstruct the beginning of the
254 // macro call.
255 // For example, given: #define ID(x) x
256 // And the call: ID(int a)
257 // Reconstructs: ID(
startReconstruction(FormatToken * Token)258 void MacroCallReconstructor::startReconstruction(FormatToken *Token) {
259   assert(Token->MacroCtx);
260   assert(!Token->MacroCtx->ExpandedFrom.empty());
261   assert(ActiveExpansions.size() <= Token->MacroCtx->ExpandedFrom.size());
262 #ifndef NDEBUG
263   // Check that the token's reconstruction stack matches our current
264   // reconstruction stack.
265   for (size_t I = 0; I < ActiveExpansions.size(); ++I) {
266     assert(ActiveExpansions[I].ID ==
267            Token->MacroCtx
268                ->ExpandedFrom[Token->MacroCtx->ExpandedFrom.size() - 1 - I]);
269   }
270 #endif
271   // Start reconstruction for all calls for which this token is the first token
272   // generated by the call.
273   // Note that the token's expanded from stack is inside-to-outside, and the
274   // expansions for which this token is not the first are the outermost ones.
275   ArrayRef<FormatToken *> StartedMacros =
276       ArrayRef(Token->MacroCtx->ExpandedFrom)
277           .drop_back(ActiveExpansions.size());
278   assert(StartedMacros.size() == Token->MacroCtx->StartOfExpansion);
279   // We reconstruct macro calls outside-to-inside.
280   for (FormatToken *ID : llvm::reverse(StartedMacros)) {
281     // We found a macro call to be reconstructed; the next time our
282     // reconstruction stack is empty we know we finished an reconstruction.
283 #ifndef NDEBUG
284     State = InProgress;
285 #endif
286     // Put the reconstructed macro call's token into our reconstruction stack.
287     auto IU = IdToReconstructed.find(ID);
288     assert(IU != IdToReconstructed.end());
289     ActiveExpansions.push_back(
290         {ID, IU->second->Tokens.begin(), IU->second->Tokens.end()});
291     // Process the macro call's identifier.
292     processNextReconstructed();
293     if (ActiveExpansions.back().SpelledI == ActiveExpansions.back().SpelledE)
294       continue;
295     if (ActiveExpansions.back().SpelledI->Tok->is(tok::l_paren)) {
296       // Process the optional opening parenthesis.
297       processNextReconstructed();
298     }
299   }
300 }
301 
302 // Add all tokens in the reconstruction stream to the output until we find the
303 // given \p Token.
reconstructActiveCallUntil(FormatToken * Token)304 bool MacroCallReconstructor::reconstructActiveCallUntil(FormatToken *Token) {
305   assert(!ActiveExpansions.empty());
306   bool PassedMacroComma = false;
307   // FIXME: If Token was already expanded earlier, due to
308   // a change in order, we will not find it, but need to
309   // skip it.
310   while (ActiveExpansions.back().SpelledI != ActiveExpansions.back().SpelledE &&
311          ActiveExpansions.back().SpelledI->Tok != Token) {
312     PassedMacroComma = processNextReconstructed() || PassedMacroComma;
313   }
314   return PassedMacroComma;
315 }
316 
317 // End all reconstructions for which \p Token is the final token.
endReconstruction(FormatToken * Token)318 void MacroCallReconstructor::endReconstruction(FormatToken *Token) {
319   assert(Token->MacroCtx &&
320          (ActiveExpansions.size() >= Token->MacroCtx->EndOfExpansion));
321   for (size_t I = 0; I < Token->MacroCtx->EndOfExpansion; ++I) {
322     LLVM_DEBUG([&] {
323       // Check all remaining tokens but the final closing parenthesis and
324       // optional trailing comment were already reconstructed at an inner
325       // expansion level.
326       for (auto T = ActiveExpansions.back().SpelledI;
327            T != ActiveExpansions.back().SpelledE; ++T) {
328         FormatToken *Token = T->Tok;
329         bool ClosingParen = (std::next(T) == ActiveExpansions.back().SpelledE ||
330                              std::next(T)->Tok->isTrailingComment()) &&
331                             !Token->MacroCtx && Token->is(tok::r_paren);
332         bool TrailingComment = Token->isTrailingComment();
333         bool PreviousLevel =
334             Token->MacroCtx &&
335             (ActiveExpansions.size() < Token->MacroCtx->ExpandedFrom.size());
336         if (!ClosingParen && !TrailingComment && !PreviousLevel)
337           llvm::dbgs() << "At token: " << Token->TokenText << "\n";
338         // In addition to the following cases, we can also run into this
339         // when a macro call had more arguments than expected; in that case,
340         // the comma and the remaining tokens in the macro call will
341         // potentially end up in the line when we finish the expansion.
342         // FIXME: Add the information which arguments are unused, and assert
343         // one of the cases below plus reconstructed macro argument tokens.
344         // assert(ClosingParen || TrailingComment || PreviousLevel);
345       }
346     }());
347     // Handle the remaining open tokens:
348     // - expand the closing parenthesis, if it exists, including an optional
349     //   trailing comment
350     // - handle tokens that were already reconstructed at an inner expansion
351     //   level
352     // - handle tokens when a macro call had more than the expected number of
353     //   arguments, i.e. when #define M(x) is called as M(a, b, c) we'll end
354     //   up with the sequence ", b, c)" being open at the end of the
355     //   reconstruction; we want to gracefully handle that case
356     //
357     // FIXME: See the above debug-check for what we will need to do to be
358     // able to assert this.
359     for (auto T = ActiveExpansions.back().SpelledI;
360          T != ActiveExpansions.back().SpelledE; ++T) {
361       processNextReconstructed();
362     }
363     ActiveExpansions.pop_back();
364   }
365 }
366 
debugParentMap() const367 void MacroCallReconstructor::debugParentMap() const {
368   llvm::DenseSet<FormatToken *> Values;
369   for (const auto &P : SpelledParentToReconstructedParent)
370     Values.insert(P.second);
371 
372   for (const auto &P : SpelledParentToReconstructedParent) {
373     if (Values.contains(P.first))
374       continue;
375     llvm::dbgs() << (P.first ? P.first->TokenText : "<null>");
376     for (auto I = SpelledParentToReconstructedParent.find(P.first),
377               E = SpelledParentToReconstructedParent.end();
378          I != E; I = SpelledParentToReconstructedParent.find(I->second)) {
379       llvm::dbgs() << " -> " << (I->second ? I->second->TokenText : "<null>");
380     }
381     llvm::dbgs() << "\n";
382   }
383 }
384 
385 // If visible, add the next token of the reconstructed token sequence to the
386 // output. Returns whether reconstruction passed a comma that is part of a
387 // macro call.
processNextReconstructed()388 bool MacroCallReconstructor::processNextReconstructed() {
389   FormatToken *Token = ActiveExpansions.back().SpelledI->Tok;
390   ++ActiveExpansions.back().SpelledI;
391   if (Token->MacroCtx) {
392     // Skip tokens that are not part of the macro call.
393     if (Token->MacroCtx->Role == MR_Hidden)
394       return false;
395     // Skip tokens we already expanded during an inner reconstruction.
396     // For example, given: #define ID(x) {x}
397     // And the call: ID(ID(f))
398     // We get two reconstructions:
399     // ID(f) -> {f}
400     // ID({f}) -> {{f}}
401     // We reconstruct f during the first reconstruction, and skip it during the
402     // second reconstruction.
403     if (ActiveExpansions.size() < Token->MacroCtx->ExpandedFrom.size())
404       return false;
405   }
406   // Tokens that do not have a macro context are tokens in that are part of the
407   // macro call that have not taken part in expansion.
408   if (!Token->MacroCtx) {
409     // Put the parentheses and commas of a macro call into the same line;
410     // if the arguments produce new unwrapped lines, they will become children
411     // of the corresponding opening parenthesis or comma tokens in the
412     // reconstructed call.
413     if (Token->is(tok::l_paren)) {
414       MacroCallStructure.push_back(MacroCallState(
415           currentLine(), parentLine().Tokens.back()->Tok, Token));
416       // All tokens that are children of the previous line's last token in the
417       // reconstructed token stream will now be children of the l_paren token.
418       // For example, for the line containing the macro calls:
419       //   auto x = ID({ID(2)});
420       // We will build up a map <null> -> ( -> ( with the first and second
421       // l_paren of the macro call respectively. New lines that come in with a
422       // <null> parent will then become children of the l_paren token of the
423       // currently innermost macro call.
424       SpelledParentToReconstructedParent[MacroCallStructure.back()
425                                              .ParentLastToken] = Token;
426       appendToken(Token);
427       prepareParent(Token, /*NewLine=*/true,
428                     MacroCallStructure.back().Line->Level);
429       Token->MacroParent = true;
430       return false;
431     }
432     if (!MacroCallStructure.empty()) {
433       if (Token->is(tok::comma)) {
434         // Make new lines inside the next argument children of the comma token.
435         SpelledParentToReconstructedParent
436             [MacroCallStructure.back().Line->Tokens.back()->Tok] = Token;
437         Token->MacroParent = true;
438         appendToken(Token, MacroCallStructure.back().Line);
439         prepareParent(Token, /*NewLine=*/true,
440                       MacroCallStructure.back().Line->Level);
441         return true;
442       }
443       if (Token->is(tok::r_paren)) {
444         appendToken(Token, MacroCallStructure.back().Line);
445         SpelledParentToReconstructedParent.erase(
446             MacroCallStructure.back().ParentLastToken);
447         MacroCallStructure.pop_back();
448         return false;
449       }
450     }
451   }
452   // Note that any tokens that are tagged with MR_None have been passed as
453   // arguments to the macro that have not been expanded, for example:
454   // Given: #define ID(X) x
455   // When calling: ID(a, b)
456   // 'b' will be part of the reconstructed token stream, but tagged MR_None.
457   // Given that erroring out in this case would be disruptive, we continue
458   // pushing the (unformatted) token.
459   // FIXME: This can lead to unfortunate formatting decisions - give the user
460   // a hint that their macro definition is broken.
461   appendToken(Token);
462   return false;
463 }
464 
finalize()465 void MacroCallReconstructor::finalize() {
466 #ifndef NDEBUG
467   assert(State != Finalized && finished());
468   State = Finalized;
469 #endif
470 
471   // We created corresponding unwrapped lines for each incoming line as children
472   // the the toplevel null token.
473   assert(Result.Tokens.size() == 1 && !Result.Tokens.front()->Children.empty());
474   LLVM_DEBUG({
475     llvm::dbgs() << "Finalizing reconstructed lines:\n";
476     debug(Result, 0);
477   });
478 
479   // The first line becomes the top level line in the resulting unwrapped line.
480   LineNode &Top = *Result.Tokens.front();
481   auto *I = Top.Children.begin();
482   // Every subsequent line will become a child of the last token in the previous
483   // line, which is the token prior to the first token in the line.
484   LineNode *Last = (*I)->Tokens.back().get();
485   ++I;
486   for (auto *E = Top.Children.end(); I != E; ++I) {
487     assert(Last->Children.empty());
488     Last->Children.push_back(std::move(*I));
489 
490     // Mark the previous line's last token as generated by a macro expansion
491     // so the formatting algorithm can take that into account.
492     Last->Tok->MacroParent = true;
493 
494     Last = Last->Children.back()->Tokens.back().get();
495   }
496   Top.Children.resize(1);
497 }
498 
appendToken(FormatToken * Token,ReconstructedLine * L)499 void MacroCallReconstructor::appendToken(FormatToken *Token,
500                                          ReconstructedLine *L) {
501   L = L ? L : currentLine();
502   LLVM_DEBUG(llvm::dbgs() << "-> " << Token->TokenText << "\n");
503   L->Tokens.push_back(std::make_unique<LineNode>(Token));
504 }
505 
506 UnwrappedLine
createUnwrappedLine(const ReconstructedLine & Line,int Level)507 MacroCallReconstructor::createUnwrappedLine(const ReconstructedLine &Line,
508                                             int Level) {
509   UnwrappedLine Result;
510   Result.Level = Level;
511   for (const auto &N : Line.Tokens) {
512     Result.Tokens.push_back(N->Tok);
513     UnwrappedLineNode &Current = Result.Tokens.back();
514     auto NumChildren =
515         std::count_if(N->Children.begin(), N->Children.end(),
516                       [](const auto &Child) { return !Child->Tokens.empty(); });
517     if (NumChildren == 1 && Current.Tok->isOneOf(tok::l_paren, tok::comma)) {
518       // If we only have one child, and the child is due to a macro expansion
519       // (either attached to a left parenthesis or comma), merge the child into
520       // the current line to prevent forced breaks for macro arguments.
521       auto *Child = std::find_if(
522           N->Children.begin(), N->Children.end(),
523           [](const auto &Child) { return !Child->Tokens.empty(); });
524       auto Line = createUnwrappedLine(**Child, Level);
525       Result.Tokens.splice(Result.Tokens.end(), Line.Tokens);
526     } else if (NumChildren > 0) {
527       // When there are multiple children with different indent, make sure that
528       // we indent them:
529       // 1. One level below the current line's level.
530       // 2. At the correct level relative to each other.
531       unsigned MinChildLevel =
532           std::min_element(N->Children.begin(), N->Children.end(),
533                            [](const auto &E1, const auto &E2) {
534                              return E1->Level < E2->Level;
535                            })
536               ->get()
537               ->Level;
538       for (const auto &Child : N->Children) {
539         if (Child->Tokens.empty())
540           continue;
541         Current.Children.push_back(createUnwrappedLine(
542             *Child, Level + 1 + (Child->Level - MinChildLevel)));
543       }
544     }
545   }
546   return Result;
547 }
548 
debug(const ReconstructedLine & Line,int Level)549 void MacroCallReconstructor::debug(const ReconstructedLine &Line, int Level) {
550   for (int i = 0; i < Level; ++i)
551     llvm::dbgs() << " ";
552   for (const auto &N : Line.Tokens) {
553     if (!N)
554       continue;
555     if (N->Tok)
556       llvm::dbgs() << N->Tok->TokenText << " ";
557     for (const auto &Child : N->Children) {
558       llvm::dbgs() << "\n";
559       debug(*Child, Level + 1);
560       for (int i = 0; i < Level; ++i)
561         llvm::dbgs() << " ";
562     }
563   }
564   llvm::dbgs() << "\n";
565 }
566 
567 MacroCallReconstructor::ReconstructedLine &
parentLine()568 MacroCallReconstructor::parentLine() {
569   return **std::prev(std::prev(ActiveReconstructedLines.end()));
570 }
571 
572 MacroCallReconstructor::ReconstructedLine *
currentLine()573 MacroCallReconstructor::currentLine() {
574   return ActiveReconstructedLines.back();
575 }
576 
MacroCallState(MacroCallReconstructor::ReconstructedLine * Line,FormatToken * ParentLastToken,FormatToken * MacroCallLParen)577 MacroCallReconstructor::MacroCallState::MacroCallState(
578     MacroCallReconstructor::ReconstructedLine *Line,
579     FormatToken *ParentLastToken, FormatToken *MacroCallLParen)
580     : Line(Line), ParentLastToken(ParentLastToken),
581       MacroCallLParen(MacroCallLParen) {
582   LLVM_DEBUG(
583       llvm::dbgs() << "ParentLastToken: "
584                    << (ParentLastToken ? ParentLastToken->TokenText : "<null>")
585                    << "\n");
586 
587   assert(MacroCallLParen->is(tok::l_paren));
588 }
589 
590 } // namespace format
591 } // namespace clang
592