150276Speter//===--- WhitespaceManager.cpp - Format C++ code --------------------------===//
2166124Srafan//
350276Speter// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
450276Speter// See https://llvm.org/LICENSE.txt for license information.
550276Speter// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
650276Speter//
750276Speter//===----------------------------------------------------------------------===//
850276Speter///
950276Speter/// \file
1050276Speter/// This file implements WhitespaceManager class.
1150276Speter///
1250276Speter//===----------------------------------------------------------------------===//
1350276Speter
1450276Speter#include "WhitespaceManager.h"
1550276Speter#include "llvm/ADT/STLExtras.h"
1650276Speter#include "llvm/ADT/SmallVector.h"
1750276Speter#include <algorithm>
1850276Speter
1950276Speternamespace clang {
2050276Speternamespace format {
2150276Speter
2250276Speterbool WhitespaceManager::Change::IsBeforeInFile::operator()(
2350276Speter    const Change &C1, const Change &C2) const {
2450276Speter  return SourceMgr.isBeforeInTranslationUnit(
2550276Speter             C1.OriginalWhitespaceRange.getBegin(),
2650276Speter             C2.OriginalWhitespaceRange.getBegin()) ||
2750276Speter         (C1.OriginalWhitespaceRange.getBegin() ==
2850276Speter              C2.OriginalWhitespaceRange.getBegin() &&
2950276Speter          SourceMgr.isBeforeInTranslationUnit(
30166124Srafan              C1.OriginalWhitespaceRange.getEnd(),
3150276Speter              C2.OriginalWhitespaceRange.getEnd()));
3250276Speter}
3350276Speter
3450276SpeterWhitespaceManager::Change::Change(const FormatToken &Tok,
3550276Speter                                  bool CreateReplacement,
3650276Speter                                  SourceRange OriginalWhitespaceRange,
3750276Speter                                  int Spaces, unsigned StartOfTokenColumn,
3850276Speter                                  unsigned NewlinesBefore,
3950276Speter                                  StringRef PreviousLinePostfix,
40166124Srafan                                  StringRef CurrentLinePrefix, bool IsAligned,
4150276Speter                                  bool ContinuesPPDirective, bool IsInsideToken)
4250276Speter    : Tok(&Tok), CreateReplacement(CreateReplacement),
4350276Speter      OriginalWhitespaceRange(OriginalWhitespaceRange),
4450276Speter      StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
4550276Speter      PreviousLinePostfix(PreviousLinePostfix),
4650276Speter      CurrentLinePrefix(CurrentLinePrefix), IsAligned(IsAligned),
4750276Speter      ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces),
4850276Speter      IsInsideToken(IsInsideToken), IsTrailingComment(false), TokenLength(0),
4950276Speter      PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
5050276Speter      StartOfBlockComment(nullptr), IndentationOffset(0), ConditionalsLevel(0) {
5150276Speter}
5250276Speter
5350276Spetervoid WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines,
5450276Speter                                          unsigned Spaces,
5550276Speter                                          unsigned StartOfTokenColumn,
5650276Speter                                          bool IsAligned, bool InPPDirective) {
5750276Speter  if (Tok.Finalized || (Tok.MacroCtx && Tok.MacroCtx->Role == MR_ExpandedArg))
5850276Speter    return;
5950276Speter  Tok.setDecision((Newlines > 0) ? FD_Break : FD_Continue);
6050276Speter  Changes.push_back(Change(Tok, /*CreateReplacement=*/true, Tok.WhitespaceRange,
6176726Speter                           Spaces, StartOfTokenColumn, Newlines, "", "",
62166124Srafan                           IsAligned, InPPDirective && !Tok.IsFirst,
6350276Speter                           /*IsInsideToken=*/false));
64166124Srafan}
6550276Speter
66166124Srafanvoid WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
67166124Srafan                                            bool InPPDirective) {
68166124Srafan  if (Tok.Finalized || (Tok.MacroCtx && Tok.MacroCtx->Role == MR_ExpandedArg))
6950276Speter    return;
70166124Srafan  Changes.push_back(Change(Tok, /*CreateReplacement=*/false,
71166124Srafan                           Tok.WhitespaceRange, /*Spaces=*/0,
7250276Speter                           Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
73166124Srafan                           /*IsAligned=*/false, InPPDirective && !Tok.IsFirst,
7450276Speter                           /*IsInsideToken=*/false));
75166124Srafan}
7650276Speter
7750276Speterllvm::Error
7850276SpeterWhitespaceManager::addReplacement(const tooling::Replacement &Replacement) {
7950276Speter  return Replaces.add(Replacement);
8050276Speter}
8150276Speter
8250276Speterbool WhitespaceManager::inputUsesCRLF(StringRef Text, bool DefaultToCRLF) {
8350276Speter  size_t LF = Text.count('\n');
8450276Speter  size_t CR = Text.count('\r') * 2;
8550276Speter  return LF == CR ? DefaultToCRLF : CR > LF;
8650276Speter}
8750276Speter
8876726Spetervoid WhitespaceManager::replaceWhitespaceInToken(
89166124Srafan    const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
9050276Speter    StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
91166124Srafan    unsigned Newlines, int Spaces) {
92166124Srafan  if (Tok.Finalized || (Tok.MacroCtx && Tok.MacroCtx->Role == MR_ExpandedArg))
9350276Speter    return;
9450276Speter  SourceLocation Start = Tok.getStartOfNonWhitespace().getLocWithOffset(Offset);
9550276Speter  Changes.push_back(
96      Change(Tok, /*CreateReplacement=*/true,
97             SourceRange(Start, Start.getLocWithOffset(ReplaceChars)), Spaces,
98             std::max(0, Spaces), Newlines, PreviousPostfix, CurrentPrefix,
99             /*IsAligned=*/true, InPPDirective && !Tok.IsFirst,
100             /*IsInsideToken=*/true));
101}
102
103const tooling::Replacements &WhitespaceManager::generateReplacements() {
104  if (Changes.empty())
105    return Replaces;
106
107  llvm::sort(Changes, Change::IsBeforeInFile(SourceMgr));
108  calculateLineBreakInformation();
109  alignConsecutiveMacros();
110  alignConsecutiveShortCaseStatements();
111  alignConsecutiveDeclarations();
112  alignConsecutiveBitFields();
113  alignConsecutiveAssignments();
114  alignChainedConditionals();
115  alignTrailingComments();
116  alignEscapedNewlines();
117  alignArrayInitializers();
118  generateChanges();
119
120  return Replaces;
121}
122
123void WhitespaceManager::calculateLineBreakInformation() {
124  Changes[0].PreviousEndOfTokenColumn = 0;
125  Change *LastOutsideTokenChange = &Changes[0];
126  for (unsigned i = 1, e = Changes.size(); i != e; ++i) {
127    SourceLocation OriginalWhitespaceStart =
128        Changes[i].OriginalWhitespaceRange.getBegin();
129    SourceLocation PreviousOriginalWhitespaceEnd =
130        Changes[i - 1].OriginalWhitespaceRange.getEnd();
131    unsigned OriginalWhitespaceStartOffset =
132        SourceMgr.getFileOffset(OriginalWhitespaceStart);
133    unsigned PreviousOriginalWhitespaceEndOffset =
134        SourceMgr.getFileOffset(PreviousOriginalWhitespaceEnd);
135    assert(PreviousOriginalWhitespaceEndOffset <=
136           OriginalWhitespaceStartOffset);
137    const char *const PreviousOriginalWhitespaceEndData =
138        SourceMgr.getCharacterData(PreviousOriginalWhitespaceEnd);
139    StringRef Text(PreviousOriginalWhitespaceEndData,
140                   SourceMgr.getCharacterData(OriginalWhitespaceStart) -
141                       PreviousOriginalWhitespaceEndData);
142    // Usually consecutive changes would occur in consecutive tokens. This is
143    // not the case however when analyzing some preprocessor runs of the
144    // annotated lines. For example, in this code:
145    //
146    // #if A // line 1
147    // int i = 1;
148    // #else B // line 2
149    // int i = 2;
150    // #endif // line 3
151    //
152    // one of the runs will produce the sequence of lines marked with line 1, 2
153    // and 3. So the two consecutive whitespace changes just before '// line 2'
154    // and before '#endif // line 3' span multiple lines and tokens:
155    //
156    // #else B{change X}[// line 2
157    // int i = 2;
158    // ]{change Y}#endif // line 3
159    //
160    // For this reason, if the text between consecutive changes spans multiple
161    // newlines, the token length must be adjusted to the end of the original
162    // line of the token.
163    auto NewlinePos = Text.find_first_of('\n');
164    if (NewlinePos == StringRef::npos) {
165      Changes[i - 1].TokenLength = OriginalWhitespaceStartOffset -
166                                   PreviousOriginalWhitespaceEndOffset +
167                                   Changes[i].PreviousLinePostfix.size() +
168                                   Changes[i - 1].CurrentLinePrefix.size();
169    } else {
170      Changes[i - 1].TokenLength =
171          NewlinePos + Changes[i - 1].CurrentLinePrefix.size();
172    }
173
174    // If there are multiple changes in this token, sum up all the changes until
175    // the end of the line.
176    if (Changes[i - 1].IsInsideToken && Changes[i - 1].NewlinesBefore == 0) {
177      LastOutsideTokenChange->TokenLength +=
178          Changes[i - 1].TokenLength + Changes[i - 1].Spaces;
179    } else {
180      LastOutsideTokenChange = &Changes[i - 1];
181    }
182
183    Changes[i].PreviousEndOfTokenColumn =
184        Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength;
185
186    Changes[i - 1].IsTrailingComment =
187        (Changes[i].NewlinesBefore > 0 || Changes[i].Tok->is(tok::eof) ||
188         (Changes[i].IsInsideToken && Changes[i].Tok->is(tok::comment))) &&
189        Changes[i - 1].Tok->is(tok::comment) &&
190        // FIXME: This is a dirty hack. The problem is that
191        // BreakableLineCommentSection does comment reflow changes and here is
192        // the aligning of trailing comments. Consider the case where we reflow
193        // the second line up in this example:
194        //
195        // // line 1
196        // // line 2
197        //
198        // That amounts to 2 changes by BreakableLineCommentSection:
199        //  - the first, delimited by (), for the whitespace between the tokens,
200        //  - and second, delimited by [], for the whitespace at the beginning
201        //  of the second token:
202        //
203        // // line 1(
204        // )[// ]line 2
205        //
206        // So in the end we have two changes like this:
207        //
208        // // line1()[ ]line 2
209        //
210        // Note that the OriginalWhitespaceStart of the second change is the
211        // same as the PreviousOriginalWhitespaceEnd of the first change.
212        // In this case, the below check ensures that the second change doesn't
213        // get treated as a trailing comment change here, since this might
214        // trigger additional whitespace to be wrongly inserted before "line 2"
215        // by the comment aligner here.
216        //
217        // For a proper solution we need a mechanism to say to WhitespaceManager
218        // that a particular change breaks the current sequence of trailing
219        // comments.
220        OriginalWhitespaceStart != PreviousOriginalWhitespaceEnd;
221  }
222  // FIXME: The last token is currently not always an eof token; in those
223  // cases, setting TokenLength of the last token to 0 is wrong.
224  Changes.back().TokenLength = 0;
225  Changes.back().IsTrailingComment = Changes.back().Tok->is(tok::comment);
226
227  const WhitespaceManager::Change *LastBlockComment = nullptr;
228  for (auto &Change : Changes) {
229    // Reset the IsTrailingComment flag for changes inside of trailing comments
230    // so they don't get realigned later. Comment line breaks however still need
231    // to be aligned.
232    if (Change.IsInsideToken && Change.NewlinesBefore == 0)
233      Change.IsTrailingComment = false;
234    Change.StartOfBlockComment = nullptr;
235    Change.IndentationOffset = 0;
236    if (Change.Tok->is(tok::comment)) {
237      if (Change.Tok->is(TT_LineComment) || !Change.IsInsideToken) {
238        LastBlockComment = &Change;
239      } else if ((Change.StartOfBlockComment = LastBlockComment)) {
240        Change.IndentationOffset =
241            Change.StartOfTokenColumn -
242            Change.StartOfBlockComment->StartOfTokenColumn;
243      }
244    } else {
245      LastBlockComment = nullptr;
246    }
247  }
248
249  // Compute conditional nesting level
250  // Level is increased for each conditional, unless this conditional continues
251  // a chain of conditional, i.e. starts immediately after the colon of another
252  // conditional.
253  SmallVector<bool, 16> ScopeStack;
254  int ConditionalsLevel = 0;
255  for (auto &Change : Changes) {
256    for (unsigned i = 0, e = Change.Tok->FakeLParens.size(); i != e; ++i) {
257      bool isNestedConditional =
258          Change.Tok->FakeLParens[e - 1 - i] == prec::Conditional &&
259          !(i == 0 && Change.Tok->Previous &&
260            Change.Tok->Previous->is(TT_ConditionalExpr) &&
261            Change.Tok->Previous->is(tok::colon));
262      if (isNestedConditional)
263        ++ConditionalsLevel;
264      ScopeStack.push_back(isNestedConditional);
265    }
266
267    Change.ConditionalsLevel = ConditionalsLevel;
268
269    for (unsigned i = Change.Tok->FakeRParens; i > 0 && ScopeStack.size(); --i)
270      if (ScopeStack.pop_back_val())
271        --ConditionalsLevel;
272  }
273}
274
275// Align a single sequence of tokens, see AlignTokens below.
276// Column - The token for which Matches returns true is moved to this column.
277// RightJustify - Whether it is the token's right end or left end that gets
278// moved to that column.
279template <typename F>
280static void
281AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
282                   unsigned Column, bool RightJustify, F &&Matches,
283                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
284  bool FoundMatchOnLine = false;
285  int Shift = 0;
286
287  // ScopeStack keeps track of the current scope depth. It contains indices of
288  // the first token on each scope.
289  // We only run the "Matches" function on tokens from the outer-most scope.
290  // However, we do need to pay special attention to one class of tokens
291  // that are not in the outer-most scope, and that is function parameters
292  // which are split across multiple lines, as illustrated by this example:
293  //   double a(int x);
294  //   int    b(int  y,
295  //          double z);
296  // In the above example, we need to take special care to ensure that
297  // 'double z' is indented along with it's owning function 'b'.
298  // The same holds for calling a function:
299  //   double a = foo(x);
300  //   int    b = bar(foo(y),
301  //            foor(z));
302  // Similar for broken string literals:
303  //   double x = 3.14;
304  //   auto s   = "Hello"
305  //          "World";
306  // Special handling is required for 'nested' ternary operators.
307  SmallVector<unsigned, 16> ScopeStack;
308
309  for (unsigned i = Start; i != End; ++i) {
310    auto &CurrentChange = Changes[i];
311    if (ScopeStack.size() != 0 &&
312        CurrentChange.indentAndNestingLevel() <
313            Changes[ScopeStack.back()].indentAndNestingLevel()) {
314      ScopeStack.pop_back();
315    }
316
317    // Compare current token to previous non-comment token to ensure whether
318    // it is in a deeper scope or not.
319    unsigned PreviousNonComment = i - 1;
320    while (PreviousNonComment > Start &&
321           Changes[PreviousNonComment].Tok->is(tok::comment)) {
322      --PreviousNonComment;
323    }
324    if (i != Start && CurrentChange.indentAndNestingLevel() >
325                          Changes[PreviousNonComment].indentAndNestingLevel()) {
326      ScopeStack.push_back(i);
327    }
328
329    bool InsideNestedScope = ScopeStack.size() != 0;
330    bool ContinuedStringLiteral = i > Start &&
331                                  CurrentChange.Tok->is(tok::string_literal) &&
332                                  Changes[i - 1].Tok->is(tok::string_literal);
333    bool SkipMatchCheck = InsideNestedScope || ContinuedStringLiteral;
334
335    if (CurrentChange.NewlinesBefore > 0 && !SkipMatchCheck) {
336      Shift = 0;
337      FoundMatchOnLine = false;
338    }
339
340    // If this is the first matching token to be aligned, remember by how many
341    // spaces it has to be shifted, so the rest of the changes on the line are
342    // shifted by the same amount
343    if (!FoundMatchOnLine && !SkipMatchCheck && Matches(CurrentChange)) {
344      FoundMatchOnLine = true;
345      Shift = Column - (RightJustify ? CurrentChange.TokenLength : 0) -
346              CurrentChange.StartOfTokenColumn;
347      CurrentChange.Spaces += Shift;
348      // FIXME: This is a workaround that should be removed when we fix
349      // http://llvm.org/PR53699. An assertion later below verifies this.
350      if (CurrentChange.NewlinesBefore == 0) {
351        CurrentChange.Spaces =
352            std::max(CurrentChange.Spaces,
353                     static_cast<int>(CurrentChange.Tok->SpacesRequiredBefore));
354      }
355    }
356
357    if (Shift == 0)
358      continue;
359
360    // This is for function parameters that are split across multiple lines,
361    // as mentioned in the ScopeStack comment.
362    if (InsideNestedScope && CurrentChange.NewlinesBefore > 0) {
363      unsigned ScopeStart = ScopeStack.back();
364      auto ShouldShiftBeAdded = [&] {
365        // Function declaration
366        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
367          return true;
368
369        // Lambda.
370        if (Changes[ScopeStart - 1].Tok->is(TT_LambdaLBrace))
371          return false;
372
373        // Continued function declaration
374        if (ScopeStart > Start + 1 &&
375            Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) {
376          return true;
377        }
378
379        // Continued (template) function call.
380        if (ScopeStart > Start + 1 &&
381            Changes[ScopeStart - 2].Tok->isOneOf(tok::identifier,
382                                                 TT_TemplateCloser) &&
383            Changes[ScopeStart - 1].Tok->is(tok::l_paren) &&
384            Changes[ScopeStart].Tok->isNot(TT_LambdaLSquare)) {
385          if (CurrentChange.Tok->MatchingParen &&
386              CurrentChange.Tok->MatchingParen->is(TT_LambdaLBrace)) {
387            return false;
388          }
389          if (Changes[ScopeStart].NewlinesBefore > 0)
390            return false;
391          if (CurrentChange.Tok->is(tok::l_brace) &&
392              CurrentChange.Tok->is(BK_BracedInit)) {
393            return true;
394          }
395          return Style.BinPackArguments;
396        }
397
398        // Ternary operator
399        if (CurrentChange.Tok->is(TT_ConditionalExpr))
400          return true;
401
402        // Period Initializer .XXX = 1.
403        if (CurrentChange.Tok->is(TT_DesignatedInitializerPeriod))
404          return true;
405
406        // Continued ternary operator
407        if (CurrentChange.Tok->Previous &&
408            CurrentChange.Tok->Previous->is(TT_ConditionalExpr)) {
409          return true;
410        }
411
412        // Continued direct-list-initialization using braced list.
413        if (ScopeStart > Start + 1 &&
414            Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
415            Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
416            CurrentChange.Tok->is(tok::l_brace) &&
417            CurrentChange.Tok->is(BK_BracedInit)) {
418          return true;
419        }
420
421        // Continued braced list.
422        if (ScopeStart > Start + 1 &&
423            Changes[ScopeStart - 2].Tok->isNot(tok::identifier) &&
424            Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
425            CurrentChange.Tok->isNot(tok::r_brace)) {
426          for (unsigned OuterScopeStart : llvm::reverse(ScopeStack)) {
427            // Lambda.
428            if (OuterScopeStart > Start &&
429                Changes[OuterScopeStart - 1].Tok->is(TT_LambdaLBrace)) {
430              return false;
431            }
432          }
433          if (Changes[ScopeStart].NewlinesBefore > 0)
434            return false;
435          return true;
436        }
437
438        // Continued template parameter.
439        if (Changes[ScopeStart - 1].Tok->is(TT_TemplateOpener))
440          return true;
441
442        return false;
443      };
444
445      if (ShouldShiftBeAdded())
446        CurrentChange.Spaces += Shift;
447    }
448
449    if (ContinuedStringLiteral)
450      CurrentChange.Spaces += Shift;
451
452    // We should not remove required spaces unless we break the line before.
453    assert(Shift > 0 || Changes[i].NewlinesBefore > 0 ||
454           CurrentChange.Spaces >=
455               static_cast<int>(Changes[i].Tok->SpacesRequiredBefore) ||
456           CurrentChange.Tok->is(tok::eof));
457
458    CurrentChange.StartOfTokenColumn += Shift;
459    if (i + 1 != Changes.size())
460      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
461
462    // If PointerAlignment is PAS_Right, keep *s or &s next to the token
463    if ((Style.PointerAlignment == FormatStyle::PAS_Right ||
464         Style.ReferenceAlignment == FormatStyle::RAS_Right) &&
465        CurrentChange.Spaces != 0) {
466      const bool ReferenceNotRightAligned =
467          Style.ReferenceAlignment != FormatStyle::RAS_Right &&
468          Style.ReferenceAlignment != FormatStyle::RAS_Pointer;
469      for (int Previous = i - 1;
470           Previous >= 0 &&
471           Changes[Previous].Tok->getType() == TT_PointerOrReference;
472           --Previous) {
473        assert(Changes[Previous].Tok->isPointerOrReference());
474        if (Changes[Previous].Tok->isNot(tok::star)) {
475          if (ReferenceNotRightAligned)
476            continue;
477        } else if (Style.PointerAlignment != FormatStyle::PAS_Right) {
478          continue;
479        }
480        Changes[Previous + 1].Spaces -= Shift;
481        Changes[Previous].Spaces += Shift;
482        Changes[Previous].StartOfTokenColumn += Shift;
483      }
484    }
485  }
486}
487
488// Walk through a subset of the changes, starting at StartAt, and find
489// sequences of matching tokens to align. To do so, keep track of the lines and
490// whether or not a matching token was found on a line. If a matching token is
491// found, extend the current sequence. If the current line cannot be part of a
492// sequence, e.g. because there is an empty line before it or it contains only
493// non-matching tokens, finalize the previous sequence.
494// The value returned is the token on which we stopped, either because we
495// exhausted all items inside Changes, or because we hit a scope level higher
496// than our initial scope.
497// This function is recursive. Each invocation processes only the scope level
498// equal to the initial level, which is the level of Changes[StartAt].
499// If we encounter a scope level greater than the initial level, then we call
500// ourselves recursively, thereby avoiding the pollution of the current state
501// with the alignment requirements of the nested sub-level. This recursive
502// behavior is necessary for aligning function prototypes that have one or more
503// arguments.
504// If this function encounters a scope level less than the initial level,
505// it returns the current position.
506// There is a non-obvious subtlety in the recursive behavior: Even though we
507// defer processing of nested levels to recursive invocations of this
508// function, when it comes time to align a sequence of tokens, we run the
509// alignment on the entire sequence, including the nested levels.
510// When doing so, most of the nested tokens are skipped, because their
511// alignment was already handled by the recursive invocations of this function.
512// However, the special exception is that we do NOT skip function parameters
513// that are split across multiple lines. See the test case in FormatTest.cpp
514// that mentions "split function parameter alignment" for an example of this.
515// When the parameter RightJustify is true, the operator will be
516// right-justified. It is used to align compound assignments like `+=` and `=`.
517// When RightJustify and ACS.PadOperators are true, operators in each block to
518// be aligned will be padded on the left to the same length before aligning.
519template <typename F>
520static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
521                            SmallVector<WhitespaceManager::Change, 16> &Changes,
522                            unsigned StartAt,
523                            const FormatStyle::AlignConsecutiveStyle &ACS = {},
524                            bool RightJustify = false) {
525  // We arrange each line in 3 parts. The operator to be aligned (the anchor),
526  // and text to its left and right. In the aligned text the width of each part
527  // will be the maximum of that over the block that has been aligned. Maximum
528  // widths of each part so far. When RightJustify is true and ACS.PadOperators
529  // is false, the part from start of line to the right end of the anchor.
530  // Otherwise, only the part to the left of the anchor. Including the space
531  // that exists on its left from the start. Not including the padding added on
532  // the left to right-justify the anchor.
533  unsigned WidthLeft = 0;
534  // The operator to be aligned when RightJustify is true and ACS.PadOperators
535  // is false. 0 otherwise.
536  unsigned WidthAnchor = 0;
537  // Width to the right of the anchor. Plus width of the anchor when
538  // RightJustify is false.
539  unsigned WidthRight = 0;
540
541  // Line number of the start and the end of the current token sequence.
542  unsigned StartOfSequence = 0;
543  unsigned EndOfSequence = 0;
544
545  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
546  // abort when we hit any token in a higher scope than the starting one.
547  auto IndentAndNestingLevel = StartAt < Changes.size()
548                                   ? Changes[StartAt].indentAndNestingLevel()
549                                   : std::tuple<unsigned, unsigned, unsigned>();
550
551  // Keep track of the number of commas before the matching tokens, we will only
552  // align a sequence of matching tokens if they are preceded by the same number
553  // of commas.
554  unsigned CommasBeforeLastMatch = 0;
555  unsigned CommasBeforeMatch = 0;
556
557  // Whether a matching token has been found on the current line.
558  bool FoundMatchOnLine = false;
559
560  // Whether the current line consists purely of comments.
561  bool LineIsComment = true;
562
563  // Aligns a sequence of matching tokens, on the MinColumn column.
564  //
565  // Sequences start from the first matching token to align, and end at the
566  // first token of the first line that doesn't need to be aligned.
567  //
568  // We need to adjust the StartOfTokenColumn of each Change that is on a line
569  // containing any matching token to be aligned and located after such token.
570  auto AlignCurrentSequence = [&] {
571    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) {
572      AlignTokenSequence(Style, StartOfSequence, EndOfSequence,
573                         WidthLeft + WidthAnchor, RightJustify, Matches,
574                         Changes);
575    }
576    WidthLeft = 0;
577    WidthAnchor = 0;
578    WidthRight = 0;
579    StartOfSequence = 0;
580    EndOfSequence = 0;
581  };
582
583  unsigned i = StartAt;
584  for (unsigned e = Changes.size(); i != e; ++i) {
585    auto &CurrentChange = Changes[i];
586    if (CurrentChange.indentAndNestingLevel() < IndentAndNestingLevel)
587      break;
588
589    if (CurrentChange.NewlinesBefore != 0) {
590      CommasBeforeMatch = 0;
591      EndOfSequence = i;
592
593      // Whether to break the alignment sequence because of an empty line.
594      bool EmptyLineBreak =
595          (CurrentChange.NewlinesBefore > 1) && !ACS.AcrossEmptyLines;
596
597      // Whether to break the alignment sequence because of a line without a
598      // match.
599      bool NoMatchBreak =
600          !FoundMatchOnLine && !(LineIsComment && ACS.AcrossComments);
601
602      if (EmptyLineBreak || NoMatchBreak)
603        AlignCurrentSequence();
604
605      // A new line starts, re-initialize line status tracking bools.
606      // Keep the match state if a string literal is continued on this line.
607      if (i == 0 || CurrentChange.Tok->isNot(tok::string_literal) ||
608          Changes[i - 1].Tok->isNot(tok::string_literal)) {
609        FoundMatchOnLine = false;
610      }
611      LineIsComment = true;
612    }
613
614    if (CurrentChange.Tok->isNot(tok::comment))
615      LineIsComment = false;
616
617    if (CurrentChange.Tok->is(tok::comma)) {
618      ++CommasBeforeMatch;
619    } else if (CurrentChange.indentAndNestingLevel() > IndentAndNestingLevel) {
620      // Call AlignTokens recursively, skipping over this scope block.
621      unsigned StoppedAt =
622          AlignTokens(Style, Matches, Changes, i, ACS, RightJustify);
623      i = StoppedAt - 1;
624      continue;
625    }
626
627    if (!Matches(CurrentChange))
628      continue;
629
630    // If there is more than one matching token per line, or if the number of
631    // preceding commas, do not match anymore, end the sequence.
632    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
633      AlignCurrentSequence();
634
635    CommasBeforeLastMatch = CommasBeforeMatch;
636    FoundMatchOnLine = true;
637
638    if (StartOfSequence == 0)
639      StartOfSequence = i;
640
641    unsigned ChangeWidthLeft = CurrentChange.StartOfTokenColumn;
642    unsigned ChangeWidthAnchor = 0;
643    unsigned ChangeWidthRight = 0;
644    if (RightJustify)
645      if (ACS.PadOperators)
646        ChangeWidthAnchor = CurrentChange.TokenLength;
647      else
648        ChangeWidthLeft += CurrentChange.TokenLength;
649    else
650      ChangeWidthRight = CurrentChange.TokenLength;
651    for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j) {
652      ChangeWidthRight += Changes[j].Spaces;
653      // Changes are generally 1:1 with the tokens, but a change could also be
654      // inside of a token, in which case it's counted more than once: once for
655      // the whitespace surrounding the token (!IsInsideToken) and once for
656      // each whitespace change within it (IsInsideToken).
657      // Therefore, changes inside of a token should only count the space.
658      if (!Changes[j].IsInsideToken)
659        ChangeWidthRight += Changes[j].TokenLength;
660    }
661
662    // If we are restricted by the maximum column width, end the sequence.
663    unsigned NewLeft = std::max(ChangeWidthLeft, WidthLeft);
664    unsigned NewAnchor = std::max(ChangeWidthAnchor, WidthAnchor);
665    unsigned NewRight = std::max(ChangeWidthRight, WidthRight);
666    // `ColumnLimit == 0` means there is no column limit.
667    if (Style.ColumnLimit != 0 &&
668        Style.ColumnLimit < NewLeft + NewAnchor + NewRight) {
669      AlignCurrentSequence();
670      StartOfSequence = i;
671      WidthLeft = ChangeWidthLeft;
672      WidthAnchor = ChangeWidthAnchor;
673      WidthRight = ChangeWidthRight;
674    } else {
675      WidthLeft = NewLeft;
676      WidthAnchor = NewAnchor;
677      WidthRight = NewRight;
678    }
679  }
680
681  EndOfSequence = i;
682  AlignCurrentSequence();
683  return i;
684}
685
686// Aligns a sequence of matching tokens, on the MinColumn column.
687//
688// Sequences start from the first matching token to align, and end at the
689// first token of the first line that doesn't need to be aligned.
690//
691// We need to adjust the StartOfTokenColumn of each Change that is on a line
692// containing any matching token to be aligned and located after such token.
693static void AlignMatchingTokenSequence(
694    unsigned &StartOfSequence, unsigned &EndOfSequence, unsigned &MinColumn,
695    std::function<bool(const WhitespaceManager::Change &C)> Matches,
696    SmallVector<WhitespaceManager::Change, 16> &Changes) {
697  if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) {
698    bool FoundMatchOnLine = false;
699    int Shift = 0;
700
701    for (unsigned I = StartOfSequence; I != EndOfSequence; ++I) {
702      if (Changes[I].NewlinesBefore > 0) {
703        Shift = 0;
704        FoundMatchOnLine = false;
705      }
706
707      // If this is the first matching token to be aligned, remember by how many
708      // spaces it has to be shifted, so the rest of the changes on the line are
709      // shifted by the same amount.
710      if (!FoundMatchOnLine && Matches(Changes[I])) {
711        FoundMatchOnLine = true;
712        Shift = MinColumn - Changes[I].StartOfTokenColumn;
713        Changes[I].Spaces += Shift;
714      }
715
716      assert(Shift >= 0);
717      Changes[I].StartOfTokenColumn += Shift;
718      if (I + 1 != Changes.size())
719        Changes[I + 1].PreviousEndOfTokenColumn += Shift;
720    }
721  }
722
723  MinColumn = 0;
724  StartOfSequence = 0;
725  EndOfSequence = 0;
726}
727
728void WhitespaceManager::alignConsecutiveMacros() {
729  if (!Style.AlignConsecutiveMacros.Enabled)
730    return;
731
732  auto AlignMacrosMatches = [](const Change &C) {
733    const FormatToken *Current = C.Tok;
734    unsigned SpacesRequiredBefore = 1;
735
736    if (Current->SpacesRequiredBefore == 0 || !Current->Previous)
737      return false;
738
739    Current = Current->Previous;
740
741    // If token is a ")", skip over the parameter list, to the
742    // token that precedes the "("
743    if (Current->is(tok::r_paren) && Current->MatchingParen) {
744      Current = Current->MatchingParen->Previous;
745      SpacesRequiredBefore = 0;
746    }
747
748    if (!Current || Current->isNot(tok::identifier))
749      return false;
750
751    if (!Current->Previous || Current->Previous->isNot(tok::pp_define))
752      return false;
753
754    // For a macro function, 0 spaces are required between the
755    // identifier and the lparen that opens the parameter list.
756    // For a simple macro, 1 space is required between the
757    // identifier and the first token of the defined value.
758    return Current->Next->SpacesRequiredBefore == SpacesRequiredBefore;
759  };
760
761  unsigned MinColumn = 0;
762
763  // Start and end of the token sequence we're processing.
764  unsigned StartOfSequence = 0;
765  unsigned EndOfSequence = 0;
766
767  // Whether a matching token has been found on the current line.
768  bool FoundMatchOnLine = false;
769
770  // Whether the current line consists only of comments
771  bool LineIsComment = true;
772
773  unsigned I = 0;
774  for (unsigned E = Changes.size(); I != E; ++I) {
775    if (Changes[I].NewlinesBefore != 0) {
776      EndOfSequence = I;
777
778      // Whether to break the alignment sequence because of an empty line.
779      bool EmptyLineBreak = (Changes[I].NewlinesBefore > 1) &&
780                            !Style.AlignConsecutiveMacros.AcrossEmptyLines;
781
782      // Whether to break the alignment sequence because of a line without a
783      // match.
784      bool NoMatchBreak =
785          !FoundMatchOnLine &&
786          !(LineIsComment && Style.AlignConsecutiveMacros.AcrossComments);
787
788      if (EmptyLineBreak || NoMatchBreak) {
789        AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
790                                   AlignMacrosMatches, Changes);
791      }
792
793      // A new line starts, re-initialize line status tracking bools.
794      FoundMatchOnLine = false;
795      LineIsComment = true;
796    }
797
798    if (Changes[I].Tok->isNot(tok::comment))
799      LineIsComment = false;
800
801    if (!AlignMacrosMatches(Changes[I]))
802      continue;
803
804    FoundMatchOnLine = true;
805
806    if (StartOfSequence == 0)
807      StartOfSequence = I;
808
809    unsigned ChangeMinColumn = Changes[I].StartOfTokenColumn;
810    MinColumn = std::max(MinColumn, ChangeMinColumn);
811  }
812
813  EndOfSequence = I;
814  AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
815                             AlignMacrosMatches, Changes);
816}
817
818void WhitespaceManager::alignConsecutiveAssignments() {
819  if (!Style.AlignConsecutiveAssignments.Enabled)
820    return;
821
822  AlignTokens(
823      Style,
824      [&](const Change &C) {
825        // Do not align on equal signs that are first on a line.
826        if (C.NewlinesBefore > 0)
827          return false;
828
829        // Do not align on equal signs that are last on a line.
830        if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
831          return false;
832
833        // Do not align operator= overloads.
834        FormatToken *Previous = C.Tok->getPreviousNonComment();
835        if (Previous && Previous->is(tok::kw_operator))
836          return false;
837
838        return Style.AlignConsecutiveAssignments.AlignCompound
839                   ? C.Tok->getPrecedence() == prec::Assignment
840                   : (C.Tok->is(tok::equal) ||
841                      // In Verilog the '<=' is not a compound assignment, thus
842                      // it is aligned even when the AlignCompound option is not
843                      // set.
844                      (Style.isVerilog() && C.Tok->is(tok::lessequal) &&
845                       C.Tok->getPrecedence() == prec::Assignment));
846      },
847      Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments,
848      /*RightJustify=*/true);
849}
850
851void WhitespaceManager::alignConsecutiveBitFields() {
852  if (!Style.AlignConsecutiveBitFields.Enabled)
853    return;
854
855  AlignTokens(
856      Style,
857      [&](Change const &C) {
858        // Do not align on ':' that is first on a line.
859        if (C.NewlinesBefore > 0)
860          return false;
861
862        // Do not align on ':' that is last on a line.
863        if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
864          return false;
865
866        return C.Tok->is(TT_BitFieldColon);
867      },
868      Changes, /*StartAt=*/0, Style.AlignConsecutiveBitFields);
869}
870
871void WhitespaceManager::alignConsecutiveShortCaseStatements() {
872  if (!Style.AlignConsecutiveShortCaseStatements.Enabled ||
873      !Style.AllowShortCaseLabelsOnASingleLine) {
874    return;
875  }
876
877  auto Matches = [&](const Change &C) {
878    if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons)
879      return C.Tok->is(TT_CaseLabelColon);
880
881    // Ignore 'IsInsideToken' to allow matching trailing comments which
882    // need to be reflowed as that causes the token to appear in two
883    // different changes, which will cause incorrect alignment as we'll
884    // reflow early due to detecting multiple aligning tokens per line.
885    return !C.IsInsideToken && C.Tok->Previous &&
886           C.Tok->Previous->is(TT_CaseLabelColon);
887  };
888
889  unsigned MinColumn = 0;
890
891  // Empty case statements don't break the alignment, but don't necessarily
892  // match our predicate, so we need to track their column so they can push out
893  // our alignment.
894  unsigned MinEmptyCaseColumn = 0;
895
896  // Start and end of the token sequence we're processing.
897  unsigned StartOfSequence = 0;
898  unsigned EndOfSequence = 0;
899
900  // Whether a matching token has been found on the current line.
901  bool FoundMatchOnLine = false;
902
903  bool LineIsComment = true;
904  bool LineIsEmptyCase = false;
905
906  unsigned I = 0;
907  for (unsigned E = Changes.size(); I != E; ++I) {
908    if (Changes[I].NewlinesBefore != 0) {
909      // Whether to break the alignment sequence because of an empty line.
910      bool EmptyLineBreak =
911          (Changes[I].NewlinesBefore > 1) &&
912          !Style.AlignConsecutiveShortCaseStatements.AcrossEmptyLines;
913
914      // Whether to break the alignment sequence because of a line without a
915      // match.
916      bool NoMatchBreak =
917          !FoundMatchOnLine &&
918          !(LineIsComment &&
919            Style.AlignConsecutiveShortCaseStatements.AcrossComments) &&
920          !LineIsEmptyCase;
921
922      if (EmptyLineBreak || NoMatchBreak) {
923        AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
924                                   Matches, Changes);
925        MinEmptyCaseColumn = 0;
926      }
927
928      // A new line starts, re-initialize line status tracking bools.
929      FoundMatchOnLine = false;
930      LineIsComment = true;
931      LineIsEmptyCase = false;
932    }
933
934    if (Changes[I].Tok->isNot(tok::comment))
935      LineIsComment = false;
936
937    if (Changes[I].Tok->is(TT_CaseLabelColon)) {
938      LineIsEmptyCase =
939          !Changes[I].Tok->Next || Changes[I].Tok->Next->isTrailingComment();
940
941      if (LineIsEmptyCase) {
942        if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons) {
943          MinEmptyCaseColumn =
944              std::max(MinEmptyCaseColumn, Changes[I].StartOfTokenColumn);
945        } else {
946          MinEmptyCaseColumn =
947              std::max(MinEmptyCaseColumn, Changes[I].StartOfTokenColumn + 2);
948        }
949      }
950    }
951
952    if (!Matches(Changes[I]))
953      continue;
954
955    if (LineIsEmptyCase)
956      continue;
957
958    FoundMatchOnLine = true;
959
960    if (StartOfSequence == 0)
961      StartOfSequence = I;
962
963    EndOfSequence = I + 1;
964
965    MinColumn = std::max(MinColumn, Changes[I].StartOfTokenColumn);
966
967    // Allow empty case statements to push out our alignment.
968    MinColumn = std::max(MinColumn, MinEmptyCaseColumn);
969  }
970
971  AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
972                             Changes);
973}
974
975void WhitespaceManager::alignConsecutiveDeclarations() {
976  if (!Style.AlignConsecutiveDeclarations.Enabled)
977    return;
978
979  AlignTokens(
980      Style,
981      [&](Change const &C) {
982        if (Style.AlignConsecutiveDeclarations.AlignFunctionPointers) {
983          for (const auto *Prev = C.Tok->Previous; Prev; Prev = Prev->Previous)
984            if (Prev->is(tok::equal))
985              return false;
986          if (C.Tok->is(TT_FunctionTypeLParen))
987            return true;
988        }
989        if (C.Tok->is(TT_FunctionDeclarationName))
990          return true;
991        if (C.Tok->isNot(TT_StartOfName))
992          return false;
993        if (C.Tok->Previous &&
994            C.Tok->Previous->is(TT_StatementAttributeLikeMacro))
995          return false;
996        // Check if there is a subsequent name that starts the same declaration.
997        for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) {
998          if (Next->is(tok::comment))
999            continue;
1000          if (Next->is(TT_PointerOrReference))
1001            return false;
1002          if (!Next->Tok.getIdentifierInfo())
1003            break;
1004          if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
1005                            tok::kw_operator)) {
1006            return false;
1007          }
1008        }
1009        return true;
1010      },
1011      Changes, /*StartAt=*/0, Style.AlignConsecutiveDeclarations);
1012}
1013
1014void WhitespaceManager::alignChainedConditionals() {
1015  if (Style.BreakBeforeTernaryOperators) {
1016    AlignTokens(
1017        Style,
1018        [](Change const &C) {
1019          // Align question operators and last colon
1020          return C.Tok->is(TT_ConditionalExpr) &&
1021                 ((C.Tok->is(tok::question) && !C.NewlinesBefore) ||
1022                  (C.Tok->is(tok::colon) && C.Tok->Next &&
1023                   (C.Tok->Next->FakeLParens.size() == 0 ||
1024                    C.Tok->Next->FakeLParens.back() != prec::Conditional)));
1025        },
1026        Changes, /*StartAt=*/0);
1027  } else {
1028    static auto AlignWrappedOperand = [](Change const &C) {
1029      FormatToken *Previous = C.Tok->getPreviousNonComment();
1030      return C.NewlinesBefore && Previous && Previous->is(TT_ConditionalExpr) &&
1031             (Previous->is(tok::colon) &&
1032              (C.Tok->FakeLParens.size() == 0 ||
1033               C.Tok->FakeLParens.back() != prec::Conditional));
1034    };
1035    // Ensure we keep alignment of wrapped operands with non-wrapped operands
1036    // Since we actually align the operators, the wrapped operands need the
1037    // extra offset to be properly aligned.
1038    for (Change &C : Changes)
1039      if (AlignWrappedOperand(C))
1040        C.StartOfTokenColumn -= 2;
1041    AlignTokens(
1042        Style,
1043        [this](Change const &C) {
1044          // Align question operators if next operand is not wrapped, as
1045          // well as wrapped operands after question operator or last
1046          // colon in conditional sequence
1047          return (C.Tok->is(TT_ConditionalExpr) && C.Tok->is(tok::question) &&
1048                  &C != &Changes.back() && (&C + 1)->NewlinesBefore == 0 &&
1049                  !(&C + 1)->IsTrailingComment) ||
1050                 AlignWrappedOperand(C);
1051        },
1052        Changes, /*StartAt=*/0);
1053  }
1054}
1055
1056void WhitespaceManager::alignTrailingComments() {
1057  if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Never)
1058    return;
1059
1060  const int Size = Changes.size();
1061  int MinColumn = 0;
1062  int StartOfSequence = 0;
1063  bool BreakBeforeNext = false;
1064  int NewLineThreshold = 1;
1065  if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Always)
1066    NewLineThreshold = Style.AlignTrailingComments.OverEmptyLines + 1;
1067
1068  for (int I = 0, MaxColumn = INT_MAX, Newlines = 0; I < Size; ++I) {
1069    auto &C = Changes[I];
1070    if (C.StartOfBlockComment)
1071      continue;
1072    Newlines += C.NewlinesBefore;
1073    if (!C.IsTrailingComment)
1074      continue;
1075
1076    if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Leave) {
1077      const int OriginalSpaces =
1078          C.OriginalWhitespaceRange.getEnd().getRawEncoding() -
1079          C.OriginalWhitespaceRange.getBegin().getRawEncoding() -
1080          C.Tok->LastNewlineOffset;
1081      assert(OriginalSpaces >= 0);
1082      const auto RestoredLineLength =
1083          C.StartOfTokenColumn + C.TokenLength + OriginalSpaces;
1084      // If leaving comments makes the line exceed the column limit, give up to
1085      // leave the comments.
1086      if (RestoredLineLength >= Style.ColumnLimit && Style.ColumnLimit > 0)
1087        break;
1088      C.Spaces = OriginalSpaces;
1089      continue;
1090    }
1091
1092    const int ChangeMinColumn = C.StartOfTokenColumn;
1093    int ChangeMaxColumn;
1094
1095    // If we don't create a replacement for this change, we have to consider
1096    // it to be immovable.
1097    if (!C.CreateReplacement)
1098      ChangeMaxColumn = ChangeMinColumn;
1099    else if (Style.ColumnLimit == 0)
1100      ChangeMaxColumn = INT_MAX;
1101    else if (Style.ColumnLimit >= C.TokenLength)
1102      ChangeMaxColumn = Style.ColumnLimit - C.TokenLength;
1103    else
1104      ChangeMaxColumn = ChangeMinColumn;
1105
1106    if (I + 1 < Size && Changes[I + 1].ContinuesPPDirective &&
1107        ChangeMaxColumn >= 2) {
1108      ChangeMaxColumn -= 2;
1109    }
1110
1111    bool WasAlignedWithStartOfNextLine = false;
1112    if (C.NewlinesBefore >= 1) { // A comment on its own line.
1113      const auto CommentColumn =
1114          SourceMgr.getSpellingColumnNumber(C.OriginalWhitespaceRange.getEnd());
1115      for (int J = I + 1; J < Size; ++J) {
1116        if (Changes[J].Tok->is(tok::comment))
1117          continue;
1118
1119        const auto NextColumn = SourceMgr.getSpellingColumnNumber(
1120            Changes[J].OriginalWhitespaceRange.getEnd());
1121        // The start of the next token was previously aligned with the
1122        // start of this comment.
1123        WasAlignedWithStartOfNextLine =
1124            CommentColumn == NextColumn ||
1125            CommentColumn == NextColumn + Style.IndentWidth;
1126        break;
1127      }
1128    }
1129
1130    // We don't want to align comments which end a scope, which are here
1131    // identified by most closing braces.
1132    auto DontAlignThisComment = [](const auto *Tok) {
1133      if (Tok->is(tok::semi)) {
1134        Tok = Tok->getPreviousNonComment();
1135        if (!Tok)
1136          return false;
1137      }
1138      if (Tok->is(tok::r_paren)) {
1139        // Back up past the parentheses and a `TT_DoWhile` that may precede.
1140        Tok = Tok->MatchingParen;
1141        if (!Tok)
1142          return false;
1143        Tok = Tok->getPreviousNonComment();
1144        if (!Tok)
1145          return false;
1146        if (Tok->is(TT_DoWhile)) {
1147          const auto *Prev = Tok->getPreviousNonComment();
1148          if (!Prev) {
1149            // A do-while-loop without braces.
1150            return true;
1151          }
1152          Tok = Prev;
1153        }
1154      }
1155
1156      if (Tok->isNot(tok::r_brace))
1157        return false;
1158
1159      while (Tok->Previous && Tok->Previous->is(tok::r_brace))
1160        Tok = Tok->Previous;
1161      return Tok->NewlinesBefore > 0;
1162    };
1163
1164    if (I > 0 && C.NewlinesBefore == 0 &&
1165        DontAlignThisComment(Changes[I - 1].Tok)) {
1166      alignTrailingComments(StartOfSequence, I, MinColumn);
1167      // Reset to initial values, but skip this change for the next alignment
1168      // pass.
1169      MinColumn = 0;
1170      MaxColumn = INT_MAX;
1171      StartOfSequence = I + 1;
1172    } else if (BreakBeforeNext || Newlines > NewLineThreshold ||
1173               (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) ||
1174               // Break the comment sequence if the previous line did not end
1175               // in a trailing comment.
1176               (C.NewlinesBefore == 1 && I > 0 &&
1177                !Changes[I - 1].IsTrailingComment) ||
1178               WasAlignedWithStartOfNextLine) {
1179      alignTrailingComments(StartOfSequence, I, MinColumn);
1180      MinColumn = ChangeMinColumn;
1181      MaxColumn = ChangeMaxColumn;
1182      StartOfSequence = I;
1183    } else {
1184      MinColumn = std::max(MinColumn, ChangeMinColumn);
1185      MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
1186    }
1187    BreakBeforeNext = (I == 0) || (C.NewlinesBefore > 1) ||
1188                      // Never start a sequence with a comment at the beginning
1189                      // of the line.
1190                      (C.NewlinesBefore == 1 && StartOfSequence == I);
1191    Newlines = 0;
1192  }
1193  alignTrailingComments(StartOfSequence, Size, MinColumn);
1194}
1195
1196void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
1197                                              unsigned Column) {
1198  for (unsigned i = Start; i != End; ++i) {
1199    int Shift = 0;
1200    if (Changes[i].IsTrailingComment)
1201      Shift = Column - Changes[i].StartOfTokenColumn;
1202    if (Changes[i].StartOfBlockComment) {
1203      Shift = Changes[i].IndentationOffset +
1204              Changes[i].StartOfBlockComment->StartOfTokenColumn -
1205              Changes[i].StartOfTokenColumn;
1206    }
1207    if (Shift <= 0)
1208      continue;
1209    Changes[i].Spaces += Shift;
1210    if (i + 1 != Changes.size())
1211      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
1212    Changes[i].StartOfTokenColumn += Shift;
1213  }
1214}
1215
1216void WhitespaceManager::alignEscapedNewlines() {
1217  if (Style.AlignEscapedNewlines == FormatStyle::ENAS_DontAlign)
1218    return;
1219
1220  bool AlignLeft = Style.AlignEscapedNewlines == FormatStyle::ENAS_Left;
1221  unsigned MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
1222  unsigned StartOfMacro = 0;
1223  for (unsigned i = 1, e = Changes.size(); i < e; ++i) {
1224    Change &C = Changes[i];
1225    if (C.NewlinesBefore > 0) {
1226      if (C.ContinuesPPDirective) {
1227        MaxEndOfLine = std::max(C.PreviousEndOfTokenColumn + 2, MaxEndOfLine);
1228      } else {
1229        alignEscapedNewlines(StartOfMacro + 1, i, MaxEndOfLine);
1230        MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
1231        StartOfMacro = i;
1232      }
1233    }
1234  }
1235  alignEscapedNewlines(StartOfMacro + 1, Changes.size(), MaxEndOfLine);
1236}
1237
1238void WhitespaceManager::alignEscapedNewlines(unsigned Start, unsigned End,
1239                                             unsigned Column) {
1240  for (unsigned i = Start; i < End; ++i) {
1241    Change &C = Changes[i];
1242    if (C.NewlinesBefore > 0) {
1243      assert(C.ContinuesPPDirective);
1244      if (C.PreviousEndOfTokenColumn + 1 > Column)
1245        C.EscapedNewlineColumn = 0;
1246      else
1247        C.EscapedNewlineColumn = Column;
1248    }
1249  }
1250}
1251
1252void WhitespaceManager::alignArrayInitializers() {
1253  if (Style.AlignArrayOfStructures == FormatStyle::AIAS_None)
1254    return;
1255
1256  for (unsigned ChangeIndex = 1U, ChangeEnd = Changes.size();
1257       ChangeIndex < ChangeEnd; ++ChangeIndex) {
1258    auto &C = Changes[ChangeIndex];
1259    if (C.Tok->IsArrayInitializer) {
1260      bool FoundComplete = false;
1261      for (unsigned InsideIndex = ChangeIndex + 1; InsideIndex < ChangeEnd;
1262           ++InsideIndex) {
1263        if (Changes[InsideIndex].Tok == C.Tok->MatchingParen) {
1264          alignArrayInitializers(ChangeIndex, InsideIndex + 1);
1265          ChangeIndex = InsideIndex + 1;
1266          FoundComplete = true;
1267          break;
1268        }
1269      }
1270      if (!FoundComplete)
1271        ChangeIndex = ChangeEnd;
1272    }
1273  }
1274}
1275
1276void WhitespaceManager::alignArrayInitializers(unsigned Start, unsigned End) {
1277
1278  if (Style.AlignArrayOfStructures == FormatStyle::AIAS_Right)
1279    alignArrayInitializersRightJustified(getCells(Start, End));
1280  else if (Style.AlignArrayOfStructures == FormatStyle::AIAS_Left)
1281    alignArrayInitializersLeftJustified(getCells(Start, End));
1282}
1283
1284void WhitespaceManager::alignArrayInitializersRightJustified(
1285    CellDescriptions &&CellDescs) {
1286  if (!CellDescs.isRectangular())
1287    return;
1288
1289  const int BracePadding = Style.Cpp11BracedListStyle ? 0 : 1;
1290  auto &Cells = CellDescs.Cells;
1291  // Now go through and fixup the spaces.
1292  auto *CellIter = Cells.begin();
1293  for (auto i = 0U; i < CellDescs.CellCounts[0]; ++i, ++CellIter) {
1294    unsigned NetWidth = 0U;
1295    if (isSplitCell(*CellIter))
1296      NetWidth = getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
1297    auto CellWidth = getMaximumCellWidth(CellIter, NetWidth);
1298
1299    if (Changes[CellIter->Index].Tok->is(tok::r_brace)) {
1300      // So in here we want to see if there is a brace that falls
1301      // on a line that was split. If so on that line we make sure that
1302      // the spaces in front of the brace are enough.
1303      const auto *Next = CellIter;
1304      do {
1305        const FormatToken *Previous = Changes[Next->Index].Tok->Previous;
1306        if (Previous && Previous->isNot(TT_LineComment)) {
1307          Changes[Next->Index].Spaces = BracePadding;
1308          Changes[Next->Index].NewlinesBefore = 0;
1309        }
1310        Next = Next->NextColumnElement;
1311      } while (Next);
1312      // Unless the array is empty, we need the position of all the
1313      // immediately adjacent cells
1314      if (CellIter != Cells.begin()) {
1315        auto ThisNetWidth =
1316            getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
1317        auto MaxNetWidth = getMaximumNetWidth(
1318            Cells.begin(), CellIter, CellDescs.InitialSpaces,
1319            CellDescs.CellCounts[0], CellDescs.CellCounts.size());
1320        if (ThisNetWidth < MaxNetWidth)
1321          Changes[CellIter->Index].Spaces = (MaxNetWidth - ThisNetWidth);
1322        auto RowCount = 1U;
1323        auto Offset = std::distance(Cells.begin(), CellIter);
1324        for (const auto *Next = CellIter->NextColumnElement; Next;
1325             Next = Next->NextColumnElement) {
1326          if (RowCount >= CellDescs.CellCounts.size())
1327            break;
1328          auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
1329          auto *End = Start + Offset;
1330          ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
1331          if (ThisNetWidth < MaxNetWidth)
1332            Changes[Next->Index].Spaces = (MaxNetWidth - ThisNetWidth);
1333          ++RowCount;
1334        }
1335      }
1336    } else {
1337      auto ThisWidth =
1338          calculateCellWidth(CellIter->Index, CellIter->EndIndex, true) +
1339          NetWidth;
1340      if (Changes[CellIter->Index].NewlinesBefore == 0) {
1341        Changes[CellIter->Index].Spaces = (CellWidth - (ThisWidth + NetWidth));
1342        Changes[CellIter->Index].Spaces += (i > 0) ? 1 : BracePadding;
1343      }
1344      alignToStartOfCell(CellIter->Index, CellIter->EndIndex);
1345      for (const auto *Next = CellIter->NextColumnElement; Next;
1346           Next = Next->NextColumnElement) {
1347        ThisWidth =
1348            calculateCellWidth(Next->Index, Next->EndIndex, true) + NetWidth;
1349        if (Changes[Next->Index].NewlinesBefore == 0) {
1350          Changes[Next->Index].Spaces = (CellWidth - ThisWidth);
1351          Changes[Next->Index].Spaces += (i > 0) ? 1 : BracePadding;
1352        }
1353        alignToStartOfCell(Next->Index, Next->EndIndex);
1354      }
1355    }
1356  }
1357}
1358
1359void WhitespaceManager::alignArrayInitializersLeftJustified(
1360    CellDescriptions &&CellDescs) {
1361
1362  if (!CellDescs.isRectangular())
1363    return;
1364
1365  const int BracePadding = Style.Cpp11BracedListStyle ? 0 : 1;
1366  auto &Cells = CellDescs.Cells;
1367  // Now go through and fixup the spaces.
1368  auto *CellIter = Cells.begin();
1369  // The first cell of every row needs to be against the left brace.
1370  for (const auto *Next = CellIter; Next; Next = Next->NextColumnElement) {
1371    auto &Change = Changes[Next->Index];
1372    Change.Spaces =
1373        Change.NewlinesBefore == 0 ? BracePadding : CellDescs.InitialSpaces;
1374  }
1375  ++CellIter;
1376  for (auto i = 1U; i < CellDescs.CellCounts[0]; i++, ++CellIter) {
1377    auto MaxNetWidth = getMaximumNetWidth(
1378        Cells.begin(), CellIter, CellDescs.InitialSpaces,
1379        CellDescs.CellCounts[0], CellDescs.CellCounts.size());
1380    auto ThisNetWidth =
1381        getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
1382    if (Changes[CellIter->Index].NewlinesBefore == 0) {
1383      Changes[CellIter->Index].Spaces =
1384          MaxNetWidth - ThisNetWidth +
1385          (Changes[CellIter->Index].Tok->isNot(tok::r_brace) ? 1
1386                                                             : BracePadding);
1387    }
1388    auto RowCount = 1U;
1389    auto Offset = std::distance(Cells.begin(), CellIter);
1390    for (const auto *Next = CellIter->NextColumnElement; Next;
1391         Next = Next->NextColumnElement) {
1392      if (RowCount >= CellDescs.CellCounts.size())
1393        break;
1394      auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
1395      auto *End = Start + Offset;
1396      auto ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
1397      if (Changes[Next->Index].NewlinesBefore == 0) {
1398        Changes[Next->Index].Spaces =
1399            MaxNetWidth - ThisNetWidth +
1400            (Changes[Next->Index].Tok->isNot(tok::r_brace) ? 1 : BracePadding);
1401      }
1402      ++RowCount;
1403    }
1404  }
1405}
1406
1407bool WhitespaceManager::isSplitCell(const CellDescription &Cell) {
1408  if (Cell.HasSplit)
1409    return true;
1410  for (const auto *Next = Cell.NextColumnElement; Next;
1411       Next = Next->NextColumnElement) {
1412    if (Next->HasSplit)
1413      return true;
1414  }
1415  return false;
1416}
1417
1418WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
1419                                                                unsigned End) {
1420
1421  unsigned Depth = 0;
1422  unsigned Cell = 0;
1423  SmallVector<unsigned> CellCounts;
1424  unsigned InitialSpaces = 0;
1425  unsigned InitialTokenLength = 0;
1426  unsigned EndSpaces = 0;
1427  SmallVector<CellDescription> Cells;
1428  const FormatToken *MatchingParen = nullptr;
1429  for (unsigned i = Start; i < End; ++i) {
1430    auto &C = Changes[i];
1431    if (C.Tok->is(tok::l_brace))
1432      ++Depth;
1433    else if (C.Tok->is(tok::r_brace))
1434      --Depth;
1435    if (Depth == 2) {
1436      if (C.Tok->is(tok::l_brace)) {
1437        Cell = 0;
1438        MatchingParen = C.Tok->MatchingParen;
1439        if (InitialSpaces == 0) {
1440          InitialSpaces = C.Spaces + C.TokenLength;
1441          InitialTokenLength = C.TokenLength;
1442          auto j = i - 1;
1443          for (; Changes[j].NewlinesBefore == 0 && j > Start; --j) {
1444            InitialSpaces += Changes[j].Spaces + Changes[j].TokenLength;
1445            InitialTokenLength += Changes[j].TokenLength;
1446          }
1447          if (C.NewlinesBefore == 0) {
1448            InitialSpaces += Changes[j].Spaces + Changes[j].TokenLength;
1449            InitialTokenLength += Changes[j].TokenLength;
1450          }
1451        }
1452      } else if (C.Tok->is(tok::comma)) {
1453        if (!Cells.empty())
1454          Cells.back().EndIndex = i;
1455        if (const auto *Next = C.Tok->getNextNonComment();
1456            Next && Next->isNot(tok::r_brace)) { // dangling comma
1457          ++Cell;
1458        }
1459      }
1460    } else if (Depth == 1) {
1461      if (C.Tok == MatchingParen) {
1462        if (!Cells.empty())
1463          Cells.back().EndIndex = i;
1464        Cells.push_back(CellDescription{i, ++Cell, i + 1, false, nullptr});
1465        CellCounts.push_back(C.Tok->Previous->isNot(tok::comma) ? Cell + 1
1466                                                                : Cell);
1467        // Go to the next non-comment and ensure there is a break in front
1468        const auto *NextNonComment = C.Tok->getNextNonComment();
1469        while (NextNonComment && NextNonComment->is(tok::comma))
1470          NextNonComment = NextNonComment->getNextNonComment();
1471        auto j = i;
1472        while (Changes[j].Tok != NextNonComment && j < End)
1473          ++j;
1474        if (j < End && Changes[j].NewlinesBefore == 0 &&
1475            Changes[j].Tok->isNot(tok::r_brace)) {
1476          Changes[j].NewlinesBefore = 1;
1477          // Account for the added token lengths
1478          Changes[j].Spaces = InitialSpaces - InitialTokenLength;
1479        }
1480      } else if (C.Tok->is(tok::comment) && C.Tok->NewlinesBefore == 0) {
1481        // Trailing comments stay at a space past the last token
1482        C.Spaces = Changes[i - 1].Tok->is(tok::comma) ? 1 : 2;
1483      } else if (C.Tok->is(tok::l_brace)) {
1484        // We need to make sure that the ending braces is aligned to the
1485        // start of our initializer
1486        auto j = i - 1;
1487        for (; j > 0 && !Changes[j].Tok->ArrayInitializerLineStart; --j)
1488          ; // Nothing the loop does the work
1489        EndSpaces = Changes[j].Spaces;
1490      }
1491    } else if (Depth == 0 && C.Tok->is(tok::r_brace)) {
1492      C.NewlinesBefore = 1;
1493      C.Spaces = EndSpaces;
1494    }
1495    if (C.Tok->StartsColumn) {
1496      // This gets us past tokens that have been split over multiple
1497      // lines
1498      bool HasSplit = false;
1499      if (Changes[i].NewlinesBefore > 0) {
1500        // So if we split a line previously and the tail line + this token is
1501        // less then the column limit we remove the split here and just put
1502        // the column start at a space past the comma
1503        //
1504        // FIXME This if branch covers the cases where the column is not
1505        // the first column. This leads to weird pathologies like the formatting
1506        // auto foo = Items{
1507        //     Section{
1508        //             0, bar(),
1509        //     }
1510        // };
1511        // Well if it doesn't lead to that it's indicative that the line
1512        // breaking should be revisited. Unfortunately alot of other options
1513        // interact with this
1514        auto j = i - 1;
1515        if ((j - 1) > Start && Changes[j].Tok->is(tok::comma) &&
1516            Changes[j - 1].NewlinesBefore > 0) {
1517          --j;
1518          auto LineLimit = Changes[j].Spaces + Changes[j].TokenLength;
1519          if (LineLimit < Style.ColumnLimit) {
1520            Changes[i].NewlinesBefore = 0;
1521            Changes[i].Spaces = 1;
1522          }
1523        }
1524      }
1525      while (Changes[i].NewlinesBefore > 0 && Changes[i].Tok == C.Tok) {
1526        Changes[i].Spaces = InitialSpaces;
1527        ++i;
1528        HasSplit = true;
1529      }
1530      if (Changes[i].Tok != C.Tok)
1531        --i;
1532      Cells.push_back(CellDescription{i, Cell, i, HasSplit, nullptr});
1533    }
1534  }
1535
1536  return linkCells({Cells, CellCounts, InitialSpaces});
1537}
1538
1539unsigned WhitespaceManager::calculateCellWidth(unsigned Start, unsigned End,
1540                                               bool WithSpaces) const {
1541  unsigned CellWidth = 0;
1542  for (auto i = Start; i < End; i++) {
1543    if (Changes[i].NewlinesBefore > 0)
1544      CellWidth = 0;
1545    CellWidth += Changes[i].TokenLength;
1546    CellWidth += (WithSpaces ? Changes[i].Spaces : 0);
1547  }
1548  return CellWidth;
1549}
1550
1551void WhitespaceManager::alignToStartOfCell(unsigned Start, unsigned End) {
1552  if ((End - Start) <= 1)
1553    return;
1554  // If the line is broken anywhere in there make sure everything
1555  // is aligned to the parent
1556  for (auto i = Start + 1; i < End; i++)
1557    if (Changes[i].NewlinesBefore > 0)
1558      Changes[i].Spaces = Changes[Start].Spaces;
1559}
1560
1561WhitespaceManager::CellDescriptions
1562WhitespaceManager::linkCells(CellDescriptions &&CellDesc) {
1563  auto &Cells = CellDesc.Cells;
1564  for (auto *CellIter = Cells.begin(); CellIter != Cells.end(); ++CellIter) {
1565    if (!CellIter->NextColumnElement && (CellIter + 1) != Cells.end()) {
1566      for (auto *NextIter = CellIter + 1; NextIter != Cells.end(); ++NextIter) {
1567        if (NextIter->Cell == CellIter->Cell) {
1568          CellIter->NextColumnElement = &(*NextIter);
1569          break;
1570        }
1571      }
1572    }
1573  }
1574  return std::move(CellDesc);
1575}
1576
1577void WhitespaceManager::generateChanges() {
1578  for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
1579    const Change &C = Changes[i];
1580    if (i > 0) {
1581      auto Last = Changes[i - 1].OriginalWhitespaceRange;
1582      auto New = Changes[i].OriginalWhitespaceRange;
1583      // Do not generate two replacements for the same location.  As a special
1584      // case, it is allowed if there is a replacement for the empty range
1585      // between 2 tokens and another non-empty range at the start of the second
1586      // token.  We didn't implement logic to combine replacements for 2
1587      // consecutive source ranges into a single replacement, because the
1588      // program works fine without it.
1589      //
1590      // We can't eliminate empty original whitespace ranges.  They appear when
1591      // 2 tokens have no whitespace in between in the input.  It does not
1592      // matter whether whitespace is to be added.  If no whitespace is to be
1593      // added, the replacement will be empty, and it gets eliminated after this
1594      // step in storeReplacement.  For example, if the input is `foo();`,
1595      // there will be a replacement for the range between every consecutive
1596      // pair of tokens.
1597      //
1598      // A replacement at the start of a token can be added by
1599      // BreakableStringLiteralUsingOperators::insertBreak when it adds braces
1600      // around the string literal.  Say Verilog code is being formatted and the
1601      // first line is to become the next 2 lines.
1602      //     x("long string");
1603      //     x({"long ",
1604      //        "string"});
1605      // There will be a replacement for the empty range between the parenthesis
1606      // and the string and another replacement for the quote character.  The
1607      // replacement for the empty range between the parenthesis and the quote
1608      // comes from ContinuationIndenter::addTokenOnCurrentLine when it changes
1609      // the original empty range between the parenthesis and the string to
1610      // another empty one.  The replacement for the quote character comes from
1611      // BreakableStringLiteralUsingOperators::insertBreak when it adds the
1612      // brace.  In the example, the replacement for the empty range is the same
1613      // as the original text.  However, eliminating replacements that are same
1614      // as the original does not help in general.  For example, a newline can
1615      // be inserted, causing the first line to become the next 3 lines.
1616      //     xxxxxxxxxxx("long string");
1617      //     xxxxxxxxxxx(
1618      //         {"long ",
1619      //          "string"});
1620      // In that case, the empty range between the parenthesis and the string
1621      // will be replaced by a newline and 4 spaces.  So we will still have to
1622      // deal with a replacement for an empty source range followed by a
1623      // replacement for a non-empty source range.
1624      if (Last.getBegin() == New.getBegin() &&
1625          (Last.getEnd() != Last.getBegin() ||
1626           New.getEnd() == New.getBegin())) {
1627        continue;
1628      }
1629    }
1630    if (C.CreateReplacement) {
1631      std::string ReplacementText = C.PreviousLinePostfix;
1632      if (C.ContinuesPPDirective) {
1633        appendEscapedNewlineText(ReplacementText, C.NewlinesBefore,
1634                                 C.PreviousEndOfTokenColumn,
1635                                 C.EscapedNewlineColumn);
1636      } else {
1637        appendNewlineText(ReplacementText, C.NewlinesBefore);
1638      }
1639      // FIXME: This assert should hold if we computed the column correctly.
1640      // assert((int)C.StartOfTokenColumn >= C.Spaces);
1641      appendIndentText(
1642          ReplacementText, C.Tok->IndentLevel, std::max(0, C.Spaces),
1643          std::max((int)C.StartOfTokenColumn, C.Spaces) - std::max(0, C.Spaces),
1644          C.IsAligned);
1645      ReplacementText.append(C.CurrentLinePrefix);
1646      storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
1647    }
1648  }
1649}
1650
1651void WhitespaceManager::storeReplacement(SourceRange Range, StringRef Text) {
1652  unsigned WhitespaceLength = SourceMgr.getFileOffset(Range.getEnd()) -
1653                              SourceMgr.getFileOffset(Range.getBegin());
1654  // Don't create a replacement, if it does not change anything.
1655  if (StringRef(SourceMgr.getCharacterData(Range.getBegin()),
1656                WhitespaceLength) == Text) {
1657    return;
1658  }
1659  auto Err = Replaces.add(tooling::Replacement(
1660      SourceMgr, CharSourceRange::getCharRange(Range), Text));
1661  // FIXME: better error handling. For now, just print an error message in the
1662  // release version.
1663  if (Err) {
1664    llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1665    assert(false);
1666  }
1667}
1668
1669void WhitespaceManager::appendNewlineText(std::string &Text,
1670                                          unsigned Newlines) {
1671  if (UseCRLF) {
1672    Text.reserve(Text.size() + 2 * Newlines);
1673    for (unsigned i = 0; i < Newlines; ++i)
1674      Text.append("\r\n");
1675  } else {
1676    Text.append(Newlines, '\n');
1677  }
1678}
1679
1680void WhitespaceManager::appendEscapedNewlineText(
1681    std::string &Text, unsigned Newlines, unsigned PreviousEndOfTokenColumn,
1682    unsigned EscapedNewlineColumn) {
1683  if (Newlines > 0) {
1684    unsigned Spaces =
1685        std::max<int>(1, EscapedNewlineColumn - PreviousEndOfTokenColumn - 1);
1686    for (unsigned i = 0; i < Newlines; ++i) {
1687      Text.append(Spaces, ' ');
1688      Text.append(UseCRLF ? "\\\r\n" : "\\\n");
1689      Spaces = std::max<int>(0, EscapedNewlineColumn - 1);
1690    }
1691  }
1692}
1693
1694void WhitespaceManager::appendIndentText(std::string &Text,
1695                                         unsigned IndentLevel, unsigned Spaces,
1696                                         unsigned WhitespaceStartColumn,
1697                                         bool IsAligned) {
1698  switch (Style.UseTab) {
1699  case FormatStyle::UT_Never:
1700    Text.append(Spaces, ' ');
1701    break;
1702  case FormatStyle::UT_Always: {
1703    if (Style.TabWidth) {
1704      unsigned FirstTabWidth =
1705          Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
1706
1707      // Insert only spaces when we want to end up before the next tab.
1708      if (Spaces < FirstTabWidth || Spaces == 1) {
1709        Text.append(Spaces, ' ');
1710        break;
1711      }
1712      // Align to the next tab.
1713      Spaces -= FirstTabWidth;
1714      Text.append("\t");
1715
1716      Text.append(Spaces / Style.TabWidth, '\t');
1717      Text.append(Spaces % Style.TabWidth, ' ');
1718    } else if (Spaces == 1) {
1719      Text.append(Spaces, ' ');
1720    }
1721    break;
1722  }
1723  case FormatStyle::UT_ForIndentation:
1724    if (WhitespaceStartColumn == 0) {
1725      unsigned Indentation = IndentLevel * Style.IndentWidth;
1726      Spaces = appendTabIndent(Text, Spaces, Indentation);
1727    }
1728    Text.append(Spaces, ' ');
1729    break;
1730  case FormatStyle::UT_ForContinuationAndIndentation:
1731    if (WhitespaceStartColumn == 0)
1732      Spaces = appendTabIndent(Text, Spaces, Spaces);
1733    Text.append(Spaces, ' ');
1734    break;
1735  case FormatStyle::UT_AlignWithSpaces:
1736    if (WhitespaceStartColumn == 0) {
1737      unsigned Indentation =
1738          IsAligned ? IndentLevel * Style.IndentWidth : Spaces;
1739      Spaces = appendTabIndent(Text, Spaces, Indentation);
1740    }
1741    Text.append(Spaces, ' ');
1742    break;
1743  }
1744}
1745
1746unsigned WhitespaceManager::appendTabIndent(std::string &Text, unsigned Spaces,
1747                                            unsigned Indentation) {
1748  // This happens, e.g. when a line in a block comment is indented less than the
1749  // first one.
1750  if (Indentation > Spaces)
1751    Indentation = Spaces;
1752  if (Style.TabWidth) {
1753    unsigned Tabs = Indentation / Style.TabWidth;
1754    Text.append(Tabs, '\t');
1755    Spaces -= Tabs * Style.TabWidth;
1756  }
1757  return Spaces;
1758}
1759
1760} // namespace format
1761} // namespace clang
1762