Coverage Report

Created: 2021-06-15 06:44

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Format/WhitespaceManager.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- WhitespaceManager.cpp - Format C++ code --------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file implements WhitespaceManager class.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "WhitespaceManager.h"
15
#include "llvm/ADT/STLExtras.h"
16
#include "llvm/ADT/SmallVector.h"
17
#include <algorithm>
18
19
namespace clang {
20
namespace format {
21
22
bool WhitespaceManager::Change::IsBeforeInFile::operator()(
23
584k
    const Change &C1, const Change &C2) const {
24
584k
  return SourceMgr.isBeforeInTranslationUnit(
25
584k
      C1.OriginalWhitespaceRange.getBegin(),
26
584k
      C2.OriginalWhitespaceRange.getBegin());
27
584k
}
28
29
WhitespaceManager::Change::Change(const FormatToken &Tok,
30
                                  bool CreateReplacement,
31
                                  SourceRange OriginalWhitespaceRange,
32
                                  int Spaces, unsigned StartOfTokenColumn,
33
                                  unsigned NewlinesBefore,
34
                                  StringRef PreviousLinePostfix,
35
                                  StringRef CurrentLinePrefix, bool IsAligned,
36
                                  bool ContinuesPPDirective, bool IsInsideToken)
37
    : Tok(&Tok), CreateReplacement(CreateReplacement),
38
      OriginalWhitespaceRange(OriginalWhitespaceRange),
39
      StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
40
      PreviousLinePostfix(PreviousLinePostfix),
41
      CurrentLinePrefix(CurrentLinePrefix), IsAligned(IsAligned),
42
      ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces),
43
      IsInsideToken(IsInsideToken), IsTrailingComment(false), TokenLength(0),
44
      PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
45
297k
      StartOfBlockComment(nullptr), IndentationOffset(0), ConditionalsLevel(0) {
46
297k
}
47
48
void WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines,
49
                                          unsigned Spaces,
50
                                          unsigned StartOfTokenColumn,
51
274k
                                          bool IsAligned, bool InPPDirective) {
52
274k
  if (Tok.Finalized)
53
2.48k
    return;
54
271k
  Tok.setDecision((Newlines > 0) ? 
FD_Break35.5k
:
FD_Continue236k
);
55
271k
  Changes.push_back(Change(Tok, /*CreateReplacement=*/true, Tok.WhitespaceRange,
56
271k
                           Spaces, StartOfTokenColumn, Newlines, "", "",
57
271k
                           IsAligned, InPPDirective && 
!Tok.IsFirst1.78k
,
58
271k
                           /*IsInsideToken=*/false));
59
271k
}
60
61
void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
62
24.1k
                                            bool InPPDirective) {
63
24.1k
  if (Tok.Finalized)
64
24
    return;
65
24.1k
  Changes.push_back(Change(Tok, /*CreateReplacement=*/false,
66
24.1k
                           Tok.WhitespaceRange, /*Spaces=*/0,
67
24.1k
                           Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
68
24.1k
                           /*IsAligned=*/false, InPPDirective && 
!Tok.IsFirst1.86k
,
69
24.1k
                           /*IsInsideToken=*/false));
70
24.1k
}
71
72
llvm::Error
73
196
WhitespaceManager::addReplacement(const tooling::Replacement &Replacement) {
74
196
  return Replaces.add(Replacement);
75
196
}
76
77
void WhitespaceManager::replaceWhitespaceInToken(
78
    const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
79
    StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
80
1.45k
    unsigned Newlines, int Spaces) {
81
1.45k
  if (Tok.Finalized)
82
4
    return;
83
1.45k
  SourceLocation Start = Tok.getStartOfNonWhitespace().getLocWithOffset(Offset);
84
1.45k
  Changes.push_back(
85
1.45k
      Change(Tok, /*CreateReplacement=*/true,
86
1.45k
             SourceRange(Start, Start.getLocWithOffset(ReplaceChars)), Spaces,
87
1.45k
             std::max(0, Spaces), Newlines, PreviousPostfix, CurrentPrefix,
88
1.45k
             /*IsAligned=*/true, InPPDirective && 
!Tok.IsFirst21
,
89
1.45k
             /*IsInsideToken=*/true));
90
1.45k
}
91
92
17.7k
const tooling::Replacements &WhitespaceManager::generateReplacements() {
93
17.7k
  if (Changes.empty())
94
40
    return Replaces;
95
96
17.7k
  llvm::sort(Changes, Change::IsBeforeInFile(SourceMgr));
97
17.7k
  calculateLineBreakInformation();
98
17.7k
  alignConsecutiveMacros();
99
17.7k
  alignConsecutiveDeclarations();
100
17.7k
  alignConsecutiveBitFields();
101
17.7k
  alignConsecutiveAssignments();
102
17.7k
  alignChainedConditionals();
103
17.7k
  alignTrailingComments();
104
17.7k
  alignEscapedNewlines();
105
17.7k
  alignArrayInitializers();
106
17.7k
  generateChanges();
107
108
17.7k
  return Replaces;
109
17.7k
}
110
111
17.7k
void WhitespaceManager::calculateLineBreakInformation() {
112
17.7k
  Changes[0].PreviousEndOfTokenColumn = 0;
113
17.7k
  Change *LastOutsideTokenChange = &Changes[0];
114
297k
  for (unsigned i = 1, e = Changes.size(); i != e; 
++i279k
) {
115
279k
    SourceLocation OriginalWhitespaceStart =
116
279k
        Changes[i].OriginalWhitespaceRange.getBegin();
117
279k
    SourceLocation PreviousOriginalWhitespaceEnd =
118
279k
        Changes[i - 1].OriginalWhitespaceRange.getEnd();
119
279k
    unsigned OriginalWhitespaceStartOffset =
120
279k
        SourceMgr.getFileOffset(OriginalWhitespaceStart);
121
279k
    unsigned PreviousOriginalWhitespaceEndOffset =
122
279k
        SourceMgr.getFileOffset(PreviousOriginalWhitespaceEnd);
123
279k
    assert(PreviousOriginalWhitespaceEndOffset <=
124
279k
           OriginalWhitespaceStartOffset);
125
0
    const char *const PreviousOriginalWhitespaceEndData =
126
279k
        SourceMgr.getCharacterData(PreviousOriginalWhitespaceEnd);
127
279k
    StringRef Text(PreviousOriginalWhitespaceEndData,
128
279k
                   SourceMgr.getCharacterData(OriginalWhitespaceStart) -
129
279k
                       PreviousOriginalWhitespaceEndData);
130
    // Usually consecutive changes would occur in consecutive tokens. This is
131
    // not the case however when analyzing some preprocessor runs of the
132
    // annotated lines. For example, in this code:
133
    //
134
    // #if A // line 1
135
    // int i = 1;
136
    // #else B // line 2
137
    // int i = 2;
138
    // #endif // line 3
139
    //
140
    // one of the runs will produce the sequence of lines marked with line 1, 2
141
    // and 3. So the two consecutive whitespace changes just before '// line 2'
142
    // and before '#endif // line 3' span multiple lines and tokens:
143
    //
144
    // #else B{change X}[// line 2
145
    // int i = 2;
146
    // ]{change Y}#endif // line 3
147
    //
148
    // For this reason, if the text between consecutive changes spans multiple
149
    // newlines, the token length must be adjusted to the end of the original
150
    // line of the token.
151
279k
    auto NewlinePos = Text.find_first_of('\n');
152
279k
    if (NewlinePos == StringRef::npos) {
153
279k
      Changes[i - 1].TokenLength = OriginalWhitespaceStartOffset -
154
279k
                                   PreviousOriginalWhitespaceEndOffset +
155
279k
                                   Changes[i].PreviousLinePostfix.size() +
156
279k
                                   Changes[i - 1].CurrentLinePrefix.size();
157
279k
    } else {
158
177
      Changes[i - 1].TokenLength =
159
177
          NewlinePos + Changes[i - 1].CurrentLinePrefix.size();
160
177
    }
161
162
    // If there are multiple changes in this token, sum up all the changes until
163
    // the end of the line.
164
279k
    if (Changes[i - 1].IsInsideToken && 
Changes[i - 1].NewlinesBefore == 01.45k
)
165
405
      LastOutsideTokenChange->TokenLength +=
166
405
          Changes[i - 1].TokenLength + Changes[i - 1].Spaces;
167
279k
    else
168
279k
      LastOutsideTokenChange = &Changes[i - 1];
169
170
279k
    Changes[i].PreviousEndOfTokenColumn =
171
279k
        Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength;
172
173
279k
    Changes[i - 1].IsTrailingComment =
174
279k
        (Changes[i].NewlinesBefore > 0 || 
Changes[i].Tok->is(tok::eof)238k
||
175
279k
         
(222k
Changes[i].IsInsideToken222k
&&
Changes[i].Tok->is(tok::comment)405
)) &&
176
279k
        
Changes[i - 1].Tok->is(tok::comment)57.1k
&&
177
        // FIXME: This is a dirty hack. The problem is that
178
        // BreakableLineCommentSection does comment reflow changes and here is
179
        // the aligning of trailing comments. Consider the case where we reflow
180
        // the second line up in this example:
181
        //
182
        // // line 1
183
        // // line 2
184
        //
185
        // That amounts to 2 changes by BreakableLineCommentSection:
186
        //  - the first, delimited by (), for the whitespace between the tokens,
187
        //  - and second, delimited by [], for the whitespace at the beginning
188
        //  of the second token:
189
        //
190
        // // line 1(
191
        // )[// ]line 2
192
        //
193
        // So in the end we have two changes like this:
194
        //
195
        // // line1()[ ]line 2
196
        //
197
        // Note that the OriginalWhitespaceStart of the second change is the
198
        // same as the PreviousOriginalWhitespaceEnd of the first change.
199
        // In this case, the below check ensures that the second change doesn't
200
        // get treated as a trailing comment change here, since this might
201
        // trigger additional whitespace to be wrongly inserted before "line 2"
202
        // by the comment aligner here.
203
        //
204
        // For a proper solution we need a mechanism to say to WhitespaceManager
205
        // that a particular change breaks the current sequence of trailing
206
        // comments.
207
279k
        
OriginalWhitespaceStart != PreviousOriginalWhitespaceEnd5.33k
;
208
279k
  }
209
  // FIXME: The last token is currently not always an eof token; in those
210
  // cases, setting TokenLength of the last token to 0 is wrong.
211
17.7k
  Changes.back().TokenLength = 0;
212
17.7k
  Changes.back().IsTrailingComment = Changes.back().Tok->is(tok::comment);
213
214
17.7k
  const WhitespaceManager::Change *LastBlockComment = nullptr;
215
297k
  for (auto &Change : Changes) {
216
    // Reset the IsTrailingComment flag for changes inside of trailing comments
217
    // so they don't get realigned later. Comment line breaks however still need
218
    // to be aligned.
219
297k
    if (Change.IsInsideToken && 
Change.NewlinesBefore == 01.45k
)
220
405
      Change.IsTrailingComment = false;
221
297k
    Change.StartOfBlockComment = nullptr;
222
297k
    Change.IndentationOffset = 0;
223
297k
    if (Change.Tok->is(tok::comment)) {
224
5.77k
      if (Change.Tok->is(TT_LineComment) || 
!Change.IsInsideToken1.25k
)
225
5.22k
        LastBlockComment = &Change;
226
558
      else {
227
558
        if ((Change.StartOfBlockComment = LastBlockComment))
228
558
          Change.IndentationOffset =
229
558
              Change.StartOfTokenColumn -
230
558
              Change.StartOfBlockComment->StartOfTokenColumn;
231
558
      }
232
291k
    } else {
233
291k
      LastBlockComment = nullptr;
234
291k
    }
235
297k
  }
236
237
  // Compute conditional nesting level
238
  // Level is increased for each conditional, unless this conditional continues
239
  // a chain of conditional, i.e. starts immediately after the colon of another
240
  // conditional.
241
17.7k
  SmallVector<bool, 16> ScopeStack;
242
17.7k
  int ConditionalsLevel = 0;
243
297k
  for (auto &Change : Changes) {
244
319k
    for (unsigned i = 0, e = Change.Tok->FakeLParens.size(); i != e; 
++i22.4k
) {
245
22.4k
      bool isNestedConditional =
246
22.4k
          Change.Tok->FakeLParens[e - 1 - i] == prec::Conditional &&
247
22.4k
          
!(732
i == 0732
&&
Change.Tok->Previous728
&&
248
732
            
Change.Tok->Previous->is(TT_ConditionalExpr)701
&&
249
732
            
Change.Tok->Previous->is(tok::colon)209
);
250
22.4k
      if (isNestedConditional)
251
544
        ++ConditionalsLevel;
252
22.4k
      ScopeStack.push_back(isNestedConditional);
253
22.4k
    }
254
255
297k
    Change.ConditionalsLevel = ConditionalsLevel;
256
257
317k
    for (unsigned i = Change.Tok->FakeRParens; i > 0 && 
ScopeStack.size()20.6k
;
258
297k
         
--i20.6k
) {
259
20.6k
      if (ScopeStack.pop_back_val())
260
538
        --ConditionalsLevel;
261
20.6k
    }
262
297k
  }
263
17.7k
}
264
265
// Align a single sequence of tokens, see AlignTokens below.
266
template <typename F>
267
static void
268
AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
269
                   unsigned Column, F &&Matches,
270
1.59k
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
271
1.59k
  bool FoundMatchOnLine = false;
272
1.59k
  int Shift = 0;
273
274
  // ScopeStack keeps track of the current scope depth. It contains indices of
275
  // the first token on each scope.
276
  // We only run the "Matches" function on tokens from the outer-most scope.
277
  // However, we do need to pay special attention to one class of tokens
278
  // that are not in the outer-most scope, and that is function parameters
279
  // which are split across multiple lines, as illustrated by this example:
280
  //   double a(int x);
281
  //   int    b(int  y,
282
  //          double z);
283
  // In the above example, we need to take special care to ensure that
284
  // 'double z' is indented along with it's owning function 'b'.
285
  // The same holds for calling a function:
286
  //   double a = foo(x);
287
  //   int    b = bar(foo(y),
288
  //            foor(z));
289
  // Similar for broken string literals:
290
  //   double x = 3.14;
291
  //   auto s   = "Hello"
292
  //          "World";
293
  // Special handling is required for 'nested' ternary operators.
294
1.59k
  SmallVector<unsigned, 16> ScopeStack;
295
296
20.3k
  for (unsigned i = Start; i != End; 
++i18.7k
) {
297
18.7k
    if (ScopeStack.size() != 0 &&
298
18.7k
        Changes[i].indentAndNestingLevel() <
299
7.20k
            Changes[ScopeStack.back()].indentAndNestingLevel())
300
1.19k
      ScopeStack.pop_back();
301
302
    // Compare current token to previous non-comment token to ensure whether
303
    // it is in a deeper scope or not.
304
18.7k
    unsigned PreviousNonComment = i - 1;
305
19.0k
    while (PreviousNonComment > Start &&
306
19.0k
           
Changes[PreviousNonComment].Tok->is(tok::comment)15.8k
)
307
271
      PreviousNonComment--;
308
18.7k
    if (i != Start && Changes[i].indentAndNestingLevel() >
309
17.1k
                          Changes[PreviousNonComment].indentAndNestingLevel())
310
1.33k
      ScopeStack.push_back(i);
311
312
18.7k
    bool InsideNestedScope = ScopeStack.size() != 0;
313
18.7k
    bool ContinuedStringLiteral = i > Start &&
314
18.7k
                                  
Changes[i].Tok->is(tok::string_literal)17.1k
&&
315
18.7k
                                  
Changes[i - 1].Tok->is(tok::string_literal)411
;
316
18.7k
    bool SkipMatchCheck = InsideNestedScope || 
ContinuedStringLiteral11.4k
;
317
318
18.7k
    if (Changes[i].NewlinesBefore > 0 && 
!SkipMatchCheck2.49k
) {
319
1.60k
      Shift = 0;
320
1.60k
      FoundMatchOnLine = false;
321
1.60k
    }
322
323
    // If this is the first matching token to be aligned, remember by how many
324
    // spaces it has to be shifted, so the rest of the changes on the line are
325
    // shifted by the same amount
326
18.7k
    if (!FoundMatchOnLine && 
!SkipMatchCheck5.47k
&&
Matches(Changes[i])5.16k
) {
327
2.80k
      FoundMatchOnLine = true;
328
2.80k
      Shift = Column - Changes[i].StartOfTokenColumn;
329
2.80k
      Changes[i].Spaces += Shift;
330
2.80k
    }
331
332
    // This is for function parameters that are split across multiple lines,
333
    // as mentioned in the ScopeStack comment.
334
18.7k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 07.34k
) {
335
871
      unsigned ScopeStart = ScopeStack.back();
336
871
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
871
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
0
          return true;
340
341
        // Continued function declaration
342
871
        if (ScopeStart > Start + 1 &&
343
871
            
Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)844
)
344
30
          return true;
345
346
        // Continued function call
347
841
        if (ScopeStart > Start + 1 &&
348
841
            
Changes[ScopeStart - 2].Tok->is(tok::identifier)814
&&
349
841
            
Changes[ScopeStart - 1].Tok->is(tok::l_paren)172
)
350
90
          return true;
351
352
        // Ternary operator
353
751
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
66
          return true;
355
356
        // Continued ternary operator
357
685
        if (Changes[i].Tok->Previous &&
358
685
            
Changes[i].Tok->Previous->is(TT_ConditionalExpr)425
)
359
48
          return true;
360
361
637
        return false;
362
685
      };
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)::'lambda'()::operator()() const
Line
Count
Source
336
258
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
258
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
0
          return true;
340
341
        // Continued function declaration
342
258
        if (ScopeStart > Start + 1 &&
343
258
            Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))
344
0
          return true;
345
346
        // Continued function call
347
258
        if (ScopeStart > Start + 1 &&
348
258
            Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
349
258
            
Changes[ScopeStart - 1].Tok->is(tok::l_paren)67
)
350
18
          return true;
351
352
        // Ternary operator
353
240
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
0
          return true;
355
356
        // Continued ternary operator
357
240
        if (Changes[i].Tok->Previous &&
358
240
            
Changes[i].Tok->Previous->is(TT_ConditionalExpr)192
)
359
0
          return true;
360
361
240
        return false;
362
240
      };
Unexecuted instantiation: WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)::'lambda'()::operator()() const
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)::'lambda'()::operator()() const
Line
Count
Source
336
464
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
464
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
0
          return true;
340
341
        // Continued function declaration
342
464
        if (ScopeStart > Start + 1 &&
343
464
            Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))
344
30
          return true;
345
346
        // Continued function call
347
434
        if (ScopeStart > Start + 1 &&
348
434
            Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
349
434
            
Changes[ScopeStart - 1].Tok->is(tok::l_paren)78
)
350
54
          return true;
351
352
        // Ternary operator
353
380
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
0
          return true;
355
356
        // Continued ternary operator
357
380
        if (Changes[i].Tok->Previous &&
358
380
            
Changes[i].Tok->Previous->is(TT_ConditionalExpr)173
)
359
0
          return true;
360
361
380
        return false;
362
380
      };
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignChainedConditionals()::$_4&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignChainedConditionals()::$_4&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)::'lambda'()::operator()() const
Line
Count
Source
336
87
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
87
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
0
          return true;
340
341
        // Continued function declaration
342
87
        if (ScopeStart > Start + 1 &&
343
87
            
Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)75
)
344
0
          return true;
345
346
        // Continued function call
347
87
        if (ScopeStart > Start + 1 &&
348
87
            
Changes[ScopeStart - 2].Tok->is(tok::identifier)75
&&
349
87
            
Changes[ScopeStart - 1].Tok->is(tok::l_paren)18
)
350
9
          return true;
351
352
        // Ternary operator
353
78
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
66
          return true;
355
356
        // Continued ternary operator
357
12
        if (Changes[i].Tok->Previous &&
358
12
            
Changes[i].Tok->Previous->is(TT_ConditionalExpr)9
)
359
0
          return true;
360
361
12
        return false;
362
12
      };
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignChainedConditionals()::$_6&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignChainedConditionals()::$_6&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)::'lambda'()::operator()() const
Line
Count
Source
336
62
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
62
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
0
          return true;
340
341
        // Continued function declaration
342
62
        if (ScopeStart > Start + 1 &&
343
62
            
Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)47
)
344
0
          return true;
345
346
        // Continued function call
347
62
        if (ScopeStart > Start + 1 &&
348
62
            
Changes[ScopeStart - 2].Tok->is(tok::identifier)47
&&
349
62
            
Changes[ScopeStart - 1].Tok->is(tok::l_paren)9
)
350
9
          return true;
351
352
        // Ternary operator
353
53
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
0
          return true;
355
356
        // Continued ternary operator
357
53
        if (Changes[i].Tok->Previous &&
358
53
            
Changes[i].Tok->Previous->is(TT_ConditionalExpr)51
)
359
48
          return true;
360
361
5
        return false;
362
53
      };
363
364
871
      if (ShouldShiftBeAdded())
365
234
        Changes[i].Spaces += Shift;
366
871
    }
367
368
18.7k
    if (ContinuedStringLiteral)
369
47
      Changes[i].Spaces += Shift;
370
371
18.7k
    assert(Shift >= 0);
372
373
0
    Changes[i].StartOfTokenColumn += Shift;
374
18.7k
    if (i + 1 != Changes.size())
375
18.3k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
376
377
    // If PointerAlignment is PAS_Right, keep *s or &s next to the token
378
18.7k
    if (Style.PointerAlignment == FormatStyle::PAS_Right &&
379
18.7k
        
Changes[i].Spaces != 017.3k
) {
380
10.2k
      for (int Previous = i - 1;
381
10.3k
           Previous >= 0 &&
382
10.3k
           Changes[Previous].Tok->getType() == TT_PointerOrReference;
383
10.2k
           
--Previous26
) {
384
26
        Changes[Previous + 1].Spaces -= Shift;
385
26
        Changes[Previous].Spaces += Shift;
386
26
      }
387
10.2k
    }
388
18.7k
  }
389
1.59k
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
270
540
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
271
540
  bool FoundMatchOnLine = false;
272
540
  int Shift = 0;
273
274
  // ScopeStack keeps track of the current scope depth. It contains indices of
275
  // the first token on each scope.
276
  // We only run the "Matches" function on tokens from the outer-most scope.
277
  // However, we do need to pay special attention to one class of tokens
278
  // that are not in the outer-most scope, and that is function parameters
279
  // which are split across multiple lines, as illustrated by this example:
280
  //   double a(int x);
281
  //   int    b(int  y,
282
  //          double z);
283
  // In the above example, we need to take special care to ensure that
284
  // 'double z' is indented along with it's owning function 'b'.
285
  // The same holds for calling a function:
286
  //   double a = foo(x);
287
  //   int    b = bar(foo(y),
288
  //            foor(z));
289
  // Similar for broken string literals:
290
  //   double x = 3.14;
291
  //   auto s   = "Hello"
292
  //          "World";
293
  // Special handling is required for 'nested' ternary operators.
294
540
  SmallVector<unsigned, 16> ScopeStack;
295
296
7.17k
  for (unsigned i = Start; i != End; 
++i6.63k
) {
297
6.63k
    if (ScopeStack.size() != 0 &&
298
6.63k
        Changes[i].indentAndNestingLevel() <
299
2.53k
            Changes[ScopeStack.back()].indentAndNestingLevel())
300
444
      ScopeStack.pop_back();
301
302
    // Compare current token to previous non-comment token to ensure whether
303
    // it is in a deeper scope or not.
304
6.63k
    unsigned PreviousNonComment = i - 1;
305
6.79k
    while (PreviousNonComment > Start &&
306
6.79k
           
Changes[PreviousNonComment].Tok->is(tok::comment)5.71k
)
307
158
      PreviousNonComment--;
308
6.63k
    if (i != Start && Changes[i].indentAndNestingLevel() >
309
6.09k
                          Changes[PreviousNonComment].indentAndNestingLevel())
310
477
      ScopeStack.push_back(i);
311
312
6.63k
    bool InsideNestedScope = ScopeStack.size() != 0;
313
6.63k
    bool ContinuedStringLiteral = i > Start &&
314
6.63k
                                  
Changes[i].Tok->is(tok::string_literal)6.09k
&&
315
6.63k
                                  
Changes[i - 1].Tok->is(tok::string_literal)178
;
316
6.63k
    bool SkipMatchCheck = InsideNestedScope || 
ContinuedStringLiteral4.06k
;
317
318
6.63k
    if (Changes[i].NewlinesBefore > 0 && 
!SkipMatchCheck751
) {
319
481
      Shift = 0;
320
481
      FoundMatchOnLine = false;
321
481
    }
322
323
    // If this is the first matching token to be aligned, remember by how many
324
    // spaces it has to be shifted, so the rest of the changes on the line are
325
    // shifted by the same amount
326
6.63k
    if (!FoundMatchOnLine && 
!SkipMatchCheck2.10k
&&
Matches(Changes[i])1.88k
) {
327
863
      FoundMatchOnLine = true;
328
863
      Shift = Column - Changes[i].StartOfTokenColumn;
329
863
      Changes[i].Spaces += Shift;
330
863
    }
331
332
    // This is for function parameters that are split across multiple lines,
333
    // as mentioned in the ScopeStack comment.
334
6.63k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 02.57k
) {
335
258
      unsigned ScopeStart = ScopeStack.back();
336
258
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
258
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
258
          return true;
340
341
        // Continued function declaration
342
258
        if (ScopeStart > Start + 1 &&
343
258
            Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))
344
258
          return true;
345
346
        // Continued function call
347
258
        if (ScopeStart > Start + 1 &&
348
258
            Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
349
258
            Changes[ScopeStart - 1].Tok->is(tok::l_paren))
350
258
          return true;
351
352
        // Ternary operator
353
258
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
258
          return true;
355
356
        // Continued ternary operator
357
258
        if (Changes[i].Tok->Previous &&
358
258
            Changes[i].Tok->Previous->is(TT_ConditionalExpr))
359
258
          return true;
360
361
258
        return false;
362
258
      };
363
364
258
      if (ShouldShiftBeAdded())
365
18
        Changes[i].Spaces += Shift;
366
258
    }
367
368
6.63k
    if (ContinuedStringLiteral)
369
16
      Changes[i].Spaces += Shift;
370
371
6.63k
    assert(Shift >= 0);
372
373
0
    Changes[i].StartOfTokenColumn += Shift;
374
6.63k
    if (i + 1 != Changes.size())
375
6.46k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
376
377
    // If PointerAlignment is PAS_Right, keep *s or &s next to the token
378
6.63k
    if (Style.PointerAlignment == FormatStyle::PAS_Right &&
379
6.63k
        
Changes[i].Spaces != 06.45k
) {
380
3.44k
      for (int Previous = i - 1;
381
3.44k
           Previous >= 0 &&
382
3.44k
           Changes[Previous].Tok->getType() == TT_PointerOrReference;
383
3.44k
           
--Previous0
) {
384
0
        Changes[Previous + 1].Spaces -= Shift;
385
0
        Changes[Previous].Spaces += Shift;
386
0
      }
387
3.44k
    }
388
6.63k
  }
389
540
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
270
36
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
271
36
  bool FoundMatchOnLine = false;
272
36
  int Shift = 0;
273
274
  // ScopeStack keeps track of the current scope depth. It contains indices of
275
  // the first token on each scope.
276
  // We only run the "Matches" function on tokens from the outer-most scope.
277
  // However, we do need to pay special attention to one class of tokens
278
  // that are not in the outer-most scope, and that is function parameters
279
  // which are split across multiple lines, as illustrated by this example:
280
  //   double a(int x);
281
  //   int    b(int  y,
282
  //          double z);
283
  // In the above example, we need to take special care to ensure that
284
  // 'double z' is indented along with it's owning function 'b'.
285
  // The same holds for calling a function:
286
  //   double a = foo(x);
287
  //   int    b = bar(foo(y),
288
  //            foor(z));
289
  // Similar for broken string literals:
290
  //   double x = 3.14;
291
  //   auto s   = "Hello"
292
  //          "World";
293
  // Special handling is required for 'nested' ternary operators.
294
36
  SmallVector<unsigned, 16> ScopeStack;
295
296
439
  for (unsigned i = Start; i != End; 
++i403
) {
297
403
    if (ScopeStack.size() != 0 &&
298
403
        Changes[i].indentAndNestingLevel() <
299
6
            Changes[ScopeStack.back()].indentAndNestingLevel())
300
3
      ScopeStack.pop_back();
301
302
    // Compare current token to previous non-comment token to ensure whether
303
    // it is in a deeper scope or not.
304
403
    unsigned PreviousNonComment = i - 1;
305
413
    while (PreviousNonComment > Start &&
306
413
           
Changes[PreviousNonComment].Tok->is(tok::comment)341
)
307
10
      PreviousNonComment--;
308
403
    if (i != Start && Changes[i].indentAndNestingLevel() >
309
367
                          Changes[PreviousNonComment].indentAndNestingLevel())
310
3
      ScopeStack.push_back(i);
311
312
403
    bool InsideNestedScope = ScopeStack.size() != 0;
313
403
    bool ContinuedStringLiteral = i > Start &&
314
403
                                  
Changes[i].Tok->is(tok::string_literal)367
&&
315
403
                                  
Changes[i - 1].Tok->is(tok::string_literal)0
;
316
403
    bool SkipMatchCheck = InsideNestedScope || 
ContinuedStringLiteral397
;
317
318
403
    if (Changes[i].NewlinesBefore > 0 && 
!SkipMatchCheck43
) {
319
43
      Shift = 0;
320
43
      FoundMatchOnLine = false;
321
43
    }
322
323
    // If this is the first matching token to be aligned, remember by how many
324
    // spaces it has to be shifted, so the rest of the changes on the line are
325
    // shifted by the same amount
326
403
    if (!FoundMatchOnLine && 
!SkipMatchCheck157
&&
Matches(Changes[i])157
) {
327
75
      FoundMatchOnLine = true;
328
75
      Shift = Column - Changes[i].StartOfTokenColumn;
329
75
      Changes[i].Spaces += Shift;
330
75
    }
331
332
    // This is for function parameters that are split across multiple lines,
333
    // as mentioned in the ScopeStack comment.
334
403
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 06
) {
335
0
      unsigned ScopeStart = ScopeStack.back();
336
0
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
0
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
0
          return true;
340
341
        // Continued function declaration
342
0
        if (ScopeStart > Start + 1 &&
343
0
            Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))
344
0
          return true;
345
346
        // Continued function call
347
0
        if (ScopeStart > Start + 1 &&
348
0
            Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
349
0
            Changes[ScopeStart - 1].Tok->is(tok::l_paren))
350
0
          return true;
351
352
        // Ternary operator
353
0
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
0
          return true;
355
356
        // Continued ternary operator
357
0
        if (Changes[i].Tok->Previous &&
358
0
            Changes[i].Tok->Previous->is(TT_ConditionalExpr))
359
0
          return true;
360
361
0
        return false;
362
0
      };
363
364
0
      if (ShouldShiftBeAdded())
365
0
        Changes[i].Spaces += Shift;
366
0
    }
367
368
403
    if (ContinuedStringLiteral)
369
0
      Changes[i].Spaces += Shift;
370
371
403
    assert(Shift >= 0);
372
373
0
    Changes[i].StartOfTokenColumn += Shift;
374
403
    if (i + 1 != Changes.size())
375
367
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
376
377
    // If PointerAlignment is PAS_Right, keep *s or &s next to the token
378
403
    if (Style.PointerAlignment == FormatStyle::PAS_Right &&
379
403
        Changes[i].Spaces != 0) {
380
225
      for (int Previous = i - 1;
381
225
           Previous >= 0 &&
382
225
           Changes[Previous].Tok->getType() == TT_PointerOrReference;
383
225
           
--Previous0
) {
384
0
        Changes[Previous + 1].Spaces -= Shift;
385
0
        Changes[Previous].Spaces += Shift;
386
0
      }
387
225
    }
388
403
  }
389
36
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
270
451
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
271
451
  bool FoundMatchOnLine = false;
272
451
  int Shift = 0;
273
274
  // ScopeStack keeps track of the current scope depth. It contains indices of
275
  // the first token on each scope.
276
  // We only run the "Matches" function on tokens from the outer-most scope.
277
  // However, we do need to pay special attention to one class of tokens
278
  // that are not in the outer-most scope, and that is function parameters
279
  // which are split across multiple lines, as illustrated by this example:
280
  //   double a(int x);
281
  //   int    b(int  y,
282
  //          double z);
283
  // In the above example, we need to take special care to ensure that
284
  // 'double z' is indented along with it's owning function 'b'.
285
  // The same holds for calling a function:
286
  //   double a = foo(x);
287
  //   int    b = bar(foo(y),
288
  //            foor(z));
289
  // Similar for broken string literals:
290
  //   double x = 3.14;
291
  //   auto s   = "Hello"
292
  //          "World";
293
  // Special handling is required for 'nested' ternary operators.
294
451
  SmallVector<unsigned, 16> ScopeStack;
295
296
8.85k
  for (unsigned i = Start; i != End; 
++i8.39k
) {
297
8.39k
    if (ScopeStack.size() != 0 &&
298
8.39k
        Changes[i].indentAndNestingLevel() <
299
3.92k
            Changes[ScopeStack.back()].indentAndNestingLevel())
300
623
      ScopeStack.pop_back();
301
302
    // Compare current token to previous non-comment token to ensure whether
303
    // it is in a deeper scope or not.
304
8.39k
    unsigned PreviousNonComment = i - 1;
305
8.49k
    while (PreviousNonComment > Start &&
306
8.49k
           
Changes[PreviousNonComment].Tok->is(tok::comment)7.58k
)
307
91
      PreviousNonComment--;
308
8.39k
    if (i != Start && Changes[i].indentAndNestingLevel() >
309
7.94k
                          Changes[PreviousNonComment].indentAndNestingLevel())
310
698
      ScopeStack.push_back(i);
311
312
8.39k
    bool InsideNestedScope = ScopeStack.size() != 0;
313
8.39k
    bool ContinuedStringLiteral = i > Start &&
314
8.39k
                                  
Changes[i].Tok->is(tok::string_literal)7.94k
&&
315
8.39k
                                  
Changes[i - 1].Tok->is(tok::string_literal)205
;
316
8.39k
    bool SkipMatchCheck = InsideNestedScope || 
ContinuedStringLiteral4.39k
;
317
318
8.39k
    if (Changes[i].NewlinesBefore > 0 && 
!SkipMatchCheck1.00k
) {
319
531
      Shift = 0;
320
531
      FoundMatchOnLine = false;
321
531
    }
322
323
    // If this is the first matching token to be aligned, remember by how many
324
    // spaces it has to be shifted, so the rest of the changes on the line are
325
    // shifted by the same amount
326
8.39k
    if (!FoundMatchOnLine && 
!SkipMatchCheck1.96k
&&
Matches(Changes[i])1.87k
) {
327
877
      FoundMatchOnLine = true;
328
877
      Shift = Column - Changes[i].StartOfTokenColumn;
329
877
      Changes[i].Spaces += Shift;
330
877
    }
331
332
    // This is for function parameters that are split across multiple lines,
333
    // as mentioned in the ScopeStack comment.
334
8.39k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 04.00k
) {
335
464
      unsigned ScopeStart = ScopeStack.back();
336
464
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
464
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
464
          return true;
340
341
        // Continued function declaration
342
464
        if (ScopeStart > Start + 1 &&
343
464
            Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))
344
464
          return true;
345
346
        // Continued function call
347
464
        if (ScopeStart > Start + 1 &&
348
464
            Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
349
464
            Changes[ScopeStart - 1].Tok->is(tok::l_paren))
350
464
          return true;
351
352
        // Ternary operator
353
464
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
464
          return true;
355
356
        // Continued ternary operator
357
464
        if (Changes[i].Tok->Previous &&
358
464
            Changes[i].Tok->Previous->is(TT_ConditionalExpr))
359
464
          return true;
360
361
464
        return false;
362
464
      };
363
364
464
      if (ShouldShiftBeAdded())
365
84
        Changes[i].Spaces += Shift;
366
464
    }
367
368
8.39k
    if (ContinuedStringLiteral)
369
28
      Changes[i].Spaces += Shift;
370
371
8.39k
    assert(Shift >= 0);
372
373
0
    Changes[i].StartOfTokenColumn += Shift;
374
8.39k
    if (i + 1 != Changes.size())
375
8.23k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
376
377
    // If PointerAlignment is PAS_Right, keep *s or &s next to the token
378
8.39k
    if (Style.PointerAlignment == FormatStyle::PAS_Right &&
379
8.39k
        
Changes[i].Spaces != 07.39k
) {
380
3.81k
      for (int Previous = i - 1;
381
3.84k
           Previous >= 0 &&
382
3.84k
           Changes[Previous].Tok->getType() == TT_PointerOrReference;
383
3.81k
           
--Previous26
) {
384
26
        Changes[Previous + 1].Spaces -= Shift;
385
26
        Changes[Previous].Spaces += Shift;
386
26
      }
387
3.81k
    }
388
8.39k
  }
389
451
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignChainedConditionals()::$_4&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignChainedConditionals()::$_4&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
270
367
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
271
367
  bool FoundMatchOnLine = false;
272
367
  int Shift = 0;
273
274
  // ScopeStack keeps track of the current scope depth. It contains indices of
275
  // the first token on each scope.
276
  // We only run the "Matches" function on tokens from the outer-most scope.
277
  // However, we do need to pay special attention to one class of tokens
278
  // that are not in the outer-most scope, and that is function parameters
279
  // which are split across multiple lines, as illustrated by this example:
280
  //   double a(int x);
281
  //   int    b(int  y,
282
  //          double z);
283
  // In the above example, we need to take special care to ensure that
284
  // 'double z' is indented along with it's owning function 'b'.
285
  // The same holds for calling a function:
286
  //   double a = foo(x);
287
  //   int    b = bar(foo(y),
288
  //            foor(z));
289
  // Similar for broken string literals:
290
  //   double x = 3.14;
291
  //   auto s   = "Hello"
292
  //          "World";
293
  // Special handling is required for 'nested' ternary operators.
294
367
  SmallVector<unsigned, 16> ScopeStack;
295
296
2.33k
  for (unsigned i = Start; i != End; 
++i1.96k
) {
297
1.96k
    if (ScopeStack.size() != 0 &&
298
1.96k
        Changes[i].indentAndNestingLevel() <
299
427
            Changes[ScopeStack.back()].indentAndNestingLevel())
300
73
      ScopeStack.pop_back();
301
302
    // Compare current token to previous non-comment token to ensure whether
303
    // it is in a deeper scope or not.
304
1.96k
    unsigned PreviousNonComment = i - 1;
305
1.97k
    while (PreviousNonComment > Start &&
306
1.97k
           
Changes[PreviousNonComment].Tok->is(tok::comment)1.24k
)
307
9
      PreviousNonComment--;
308
1.96k
    if (i != Start && Changes[i].indentAndNestingLevel() >
309
1.60k
                          Changes[PreviousNonComment].indentAndNestingLevel())
310
94
      ScopeStack.push_back(i);
311
312
1.96k
    bool InsideNestedScope = ScopeStack.size() != 0;
313
1.96k
    bool ContinuedStringLiteral = i > Start &&
314
1.96k
                                  
Changes[i].Tok->is(tok::string_literal)1.60k
&&
315
1.96k
                                  
Changes[i - 1].Tok->is(tok::string_literal)20
;
316
1.96k
    bool SkipMatchCheck = InsideNestedScope || 
ContinuedStringLiteral1.52k
;
317
318
1.96k
    if (Changes[i].NewlinesBefore > 0 && 
!SkipMatchCheck388
) {
319
298
      Shift = 0;
320
298
      FoundMatchOnLine = false;
321
298
    }
322
323
    // If this is the first matching token to be aligned, remember by how many
324
    // spaces it has to be shifted, so the rest of the changes on the line are
325
    // shifted by the same amount
326
1.96k
    if (!FoundMatchOnLine && 
!SkipMatchCheck772
&&
Matches(Changes[i])772
) {
327
595
      FoundMatchOnLine = true;
328
595
      Shift = Column - Changes[i].StartOfTokenColumn;
329
595
      Changes[i].Spaces += Shift;
330
595
    }
331
332
    // This is for function parameters that are split across multiple lines,
333
    // as mentioned in the ScopeStack comment.
334
1.96k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 0448
) {
335
87
      unsigned ScopeStart = ScopeStack.back();
336
87
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
87
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
87
          return true;
340
341
        // Continued function declaration
342
87
        if (ScopeStart > Start + 1 &&
343
87
            Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))
344
87
          return true;
345
346
        // Continued function call
347
87
        if (ScopeStart > Start + 1 &&
348
87
            Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
349
87
            Changes[ScopeStart - 1].Tok->is(tok::l_paren))
350
87
          return true;
351
352
        // Ternary operator
353
87
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
87
          return true;
355
356
        // Continued ternary operator
357
87
        if (Changes[i].Tok->Previous &&
358
87
            Changes[i].Tok->Previous->is(TT_ConditionalExpr))
359
87
          return true;
360
361
87
        return false;
362
87
      };
363
364
87
      if (ShouldShiftBeAdded())
365
75
        Changes[i].Spaces += Shift;
366
87
    }
367
368
1.96k
    if (ContinuedStringLiteral)
369
3
      Changes[i].Spaces += Shift;
370
371
1.96k
    assert(Shift >= 0);
372
373
0
    Changes[i].StartOfTokenColumn += Shift;
374
1.96k
    if (i + 1 != Changes.size())
375
1.96k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
376
377
    // If PointerAlignment is PAS_Right, keep *s or &s next to the token
378
1.96k
    if (Style.PointerAlignment == FormatStyle::PAS_Right &&
379
1.96k
        
Changes[i].Spaces != 01.88k
) {
380
1.67k
      for (int Previous = i - 1;
381
1.67k
           Previous >= 0 &&
382
1.67k
           Changes[Previous].Tok->getType() == TT_PointerOrReference;
383
1.67k
           
--Previous0
) {
384
0
        Changes[Previous + 1].Spaces -= Shift;
385
0
        Changes[Previous].Spaces += Shift;
386
0
      }
387
1.67k
    }
388
1.96k
  }
389
367
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignChainedConditionals()::$_6&>(clang::format::FormatStyle const&, unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignChainedConditionals()::$_6&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
270
197
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
271
197
  bool FoundMatchOnLine = false;
272
197
  int Shift = 0;
273
274
  // ScopeStack keeps track of the current scope depth. It contains indices of
275
  // the first token on each scope.
276
  // We only run the "Matches" function on tokens from the outer-most scope.
277
  // However, we do need to pay special attention to one class of tokens
278
  // that are not in the outer-most scope, and that is function parameters
279
  // which are split across multiple lines, as illustrated by this example:
280
  //   double a(int x);
281
  //   int    b(int  y,
282
  //          double z);
283
  // In the above example, we need to take special care to ensure that
284
  // 'double z' is indented along with it's owning function 'b'.
285
  // The same holds for calling a function:
286
  //   double a = foo(x);
287
  //   int    b = bar(foo(y),
288
  //            foor(z));
289
  // Similar for broken string literals:
290
  //   double x = 3.14;
291
  //   auto s   = "Hello"
292
  //          "World";
293
  // Special handling is required for 'nested' ternary operators.
294
197
  SmallVector<unsigned, 16> ScopeStack;
295
296
1.54k
  for (unsigned i = Start; i != End; 
++i1.34k
) {
297
1.34k
    if (ScopeStack.size() != 0 &&
298
1.34k
        Changes[i].indentAndNestingLevel() <
299
302
            Changes[ScopeStack.back()].indentAndNestingLevel())
300
50
      ScopeStack.pop_back();
301
302
    // Compare current token to previous non-comment token to ensure whether
303
    // it is in a deeper scope or not.
304
1.34k
    unsigned PreviousNonComment = i - 1;
305
1.35k
    while (PreviousNonComment > Start &&
306
1.35k
           
Changes[PreviousNonComment].Tok->is(tok::comment)984
)
307
3
      PreviousNonComment--;
308
1.34k
    if (i != Start && Changes[i].indentAndNestingLevel() >
309
1.15k
                          Changes[PreviousNonComment].indentAndNestingLevel())
310
65
      ScopeStack.push_back(i);
311
312
1.34k
    bool InsideNestedScope = ScopeStack.size() != 0;
313
1.34k
    bool ContinuedStringLiteral = i > Start &&
314
1.34k
                                  
Changes[i].Tok->is(tok::string_literal)1.15k
&&
315
1.34k
                                  
Changes[i - 1].Tok->is(tok::string_literal)8
;
316
1.34k
    bool SkipMatchCheck = InsideNestedScope || 
ContinuedStringLiteral1.03k
;
317
318
1.34k
    if (Changes[i].NewlinesBefore > 0 && 
!SkipMatchCheck310
) {
319
248
      Shift = 0;
320
248
      FoundMatchOnLine = false;
321
248
    }
322
323
    // If this is the first matching token to be aligned, remember by how many
324
    // spaces it has to be shifted, so the rest of the changes on the line are
325
    // shifted by the same amount
326
1.34k
    if (!FoundMatchOnLine && 
!SkipMatchCheck475
&&
Matches(Changes[i])475
) {
327
394
      FoundMatchOnLine = true;
328
394
      Shift = Column - Changes[i].StartOfTokenColumn;
329
394
      Changes[i].Spaces += Shift;
330
394
    }
331
332
    // This is for function parameters that are split across multiple lines,
333
    // as mentioned in the ScopeStack comment.
334
1.34k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 0317
) {
335
62
      unsigned ScopeStart = ScopeStack.back();
336
62
      auto ShouldShiftBeAdded = [&] {
337
        // Function declaration
338
62
        if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
339
62
          return true;
340
341
        // Continued function declaration
342
62
        if (ScopeStart > Start + 1 &&
343
62
            Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))
344
62
          return true;
345
346
        // Continued function call
347
62
        if (ScopeStart > Start + 1 &&
348
62
            Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
349
62
            Changes[ScopeStart - 1].Tok->is(tok::l_paren))
350
62
          return true;
351
352
        // Ternary operator
353
62
        if (Changes[i].Tok->is(TT_ConditionalExpr))
354
62
          return true;
355
356
        // Continued ternary operator
357
62
        if (Changes[i].Tok->Previous &&
358
62
            Changes[i].Tok->Previous->is(TT_ConditionalExpr))
359
62
          return true;
360
361
62
        return false;
362
62
      };
363
364
62
      if (ShouldShiftBeAdded())
365
57
        Changes[i].Spaces += Shift;
366
62
    }
367
368
1.34k
    if (ContinuedStringLiteral)
369
0
      Changes[i].Spaces += Shift;
370
371
1.34k
    assert(Shift >= 0);
372
373
0
    Changes[i].StartOfTokenColumn += Shift;
374
1.34k
    if (i + 1 != Changes.size())
375
1.34k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
376
377
    // If PointerAlignment is PAS_Right, keep *s or &s next to the token
378
1.34k
    if (Style.PointerAlignment == FormatStyle::PAS_Right &&
379
1.34k
        
Changes[i].Spaces != 01.22k
) {
380
1.11k
      for (int Previous = i - 1;
381
1.11k
           Previous >= 0 &&
382
1.11k
           Changes[Previous].Tok->getType() == TT_PointerOrReference;
383
1.11k
           
--Previous0
) {
384
0
        Changes[Previous + 1].Spaces -= Shift;
385
0
        Changes[Previous].Spaces += Shift;
386
0
      }
387
1.11k
    }
388
1.34k
  }
389
197
}
390
391
// Walk through a subset of the changes, starting at StartAt, and find
392
// sequences of matching tokens to align. To do so, keep track of the lines and
393
// whether or not a matching token was found on a line. If a matching token is
394
// found, extend the current sequence. If the current line cannot be part of a
395
// sequence, e.g. because there is an empty line before it or it contains only
396
// non-matching tokens, finalize the previous sequence.
397
// The value returned is the token on which we stopped, either because we
398
// exhausted all items inside Changes, or because we hit a scope level higher
399
// than our initial scope.
400
// This function is recursive. Each invocation processes only the scope level
401
// equal to the initial level, which is the level of Changes[StartAt].
402
// If we encounter a scope level greater than the initial level, then we call
403
// ourselves recursively, thereby avoiding the pollution of the current state
404
// with the alignment requirements of the nested sub-level. This recursive
405
// behavior is necessary for aligning function prototypes that have one or more
406
// arguments.
407
// If this function encounters a scope level less than the initial level,
408
// it returns the current position.
409
// There is a non-obvious subtlety in the recursive behavior: Even though we
410
// defer processing of nested levels to recursive invocations of this
411
// function, when it comes time to align a sequence of tokens, we run the
412
// alignment on the entire sequence, including the nested levels.
413
// When doing so, most of the nested tokens are skipped, because their
414
// alignment was already handled by the recursive invocations of this function.
415
// However, the special exception is that we do NOT skip function parameters
416
// that are split across multiple lines. See the test case in FormatTest.cpp
417
// that mentions "split function parameter alignment" for an example of this.
418
template <typename F>
419
static unsigned AlignTokens(
420
    const FormatStyle &Style, F &&Matches,
421
    SmallVector<WhitespaceManager::Change, 16> &Changes, unsigned StartAt,
422
65.4k
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
65.4k
  unsigned MinColumn = 0;
424
65.4k
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
65.4k
  unsigned StartOfSequence = 0;
428
65.4k
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
65.4k
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
65.4k
                                   ? Changes[StartAt].indentAndNestingLevel()
434
65.4k
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
65.4k
  unsigned CommasBeforeLastMatch = 0;
440
65.4k
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
65.4k
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
65.4k
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
118k
  auto AlignCurrentSequence = [&] {
456
118k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence1.77k
)
457
1.59k
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
1.59k
                         Matches, Changes);
459
118k
    MinColumn = 0;
460
118k
    MaxColumn = UINT_MAX;
461
118k
    StartOfSequence = 0;
462
118k
    EndOfSequence = 0;
463
118k
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
1.11k
  auto AlignCurrentSequence = [&] {
456
1.11k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence336
)
457
330
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
330
                         Matches, Changes);
459
1.11k
    MinColumn = 0;
460
1.11k
    MaxColumn = UINT_MAX;
461
1.11k
    StartOfSequence = 0;
462
1.11k
    EndOfSequence = 0;
463
1.11k
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
1.78k
  auto AlignCurrentSequence = [&] {
456
1.78k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence234
)
457
210
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
210
                         Matches, Changes);
459
1.78k
    MinColumn = 0;
460
1.78k
    MaxColumn = UINT_MAX;
461
1.78k
    StartOfSequence = 0;
462
1.78k
    EndOfSequence = 0;
463
1.78k
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
36
  auto AlignCurrentSequence = [&] {
456
36
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
36
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
36
                         Matches, Changes);
459
36
    MinColumn = 0;
460
36
    MaxColumn = UINT_MAX;
461
36
    StartOfSequence = 0;
462
36
    EndOfSequence = 0;
463
36
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
3
  auto AlignCurrentSequence = [&] {
456
3
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence0
)
457
0
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
0
                         Matches, Changes);
459
3
    MinColumn = 0;
460
3
    MaxColumn = UINT_MAX;
461
3
    StartOfSequence = 0;
462
3
    EndOfSequence = 0;
463
3
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
788
  auto AlignCurrentSequence = [&] {
456
788
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence280
)
457
280
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
280
                         Matches, Changes);
459
788
    MinColumn = 0;
460
788
    MaxColumn = UINT_MAX;
461
788
    StartOfSequence = 0;
462
788
    EndOfSequence = 0;
463
788
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
1.66k
  auto AlignCurrentSequence = [&] {
456
1.66k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence183
)
457
171
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
171
                         Matches, Changes);
459
1.66k
    MinColumn = 0;
460
1.66k
    MaxColumn = UINT_MAX;
461
1.66k
    StartOfSequence = 0;
462
1.66k
    EndOfSequence = 0;
463
1.66k
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignChainedConditionals()::$_4>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignChainedConditionals()::$_4&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
41.5k
  auto AlignCurrentSequence = [&] {
456
41.5k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence23
)
457
16
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
16
                         Matches, Changes);
459
41.5k
    MinColumn = 0;
460
41.5k
    MaxColumn = UINT_MAX;
461
41.5k
    StartOfSequence = 0;
462
41.5k
    EndOfSequence = 0;
463
41.5k
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignChainedConditionals()::$_4&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignChainedConditionals()::$_4&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
63.5k
  auto AlignCurrentSequence = [&] {
456
63.5k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence485
)
457
351
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
351
                         Matches, Changes);
459
63.5k
    MinColumn = 0;
460
63.5k
    MaxColumn = UINT_MAX;
461
63.5k
    StartOfSequence = 0;
462
63.5k
    EndOfSequence = 0;
463
63.5k
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignChainedConditionals()::$_6>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignChainedConditionals()::$_6&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
3.02k
  auto AlignCurrentSequence = [&] {
456
3.02k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence11
)
457
11
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
11
                         Matches, Changes);
459
3.02k
    MinColumn = 0;
460
3.02k
    MaxColumn = UINT_MAX;
461
3.02k
    StartOfSequence = 0;
462
3.02k
    EndOfSequence = 0;
463
3.02k
  };
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignChainedConditionals()::$_6&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignChainedConditionals()::$_6&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)::'lambda'()::operator()() const
Line
Count
Source
455
4.78k
  auto AlignCurrentSequence = [&] {
456
4.78k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence186
)
457
186
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
186
                         Matches, Changes);
459
4.78k
    MinColumn = 0;
460
4.78k
    MaxColumn = UINT_MAX;
461
4.78k
    StartOfSequence = 0;
462
4.78k
    EndOfSequence = 0;
463
4.78k
  };
464
465
65.4k
  unsigned i = StartAt;
466
430k
  for (unsigned e = Changes.size(); i != e; 
++i365k
) {
467
412k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
46.8k
      break;
469
470
365k
    if (Changes[i].NewlinesBefore != 0) {
471
54.4k
      CommasBeforeMatch = 0;
472
54.4k
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
54.4k
      bool EmptyLineBreak =
476
54.4k
          (Changes[i].NewlinesBefore > 1) &&
477
54.4k
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)1.07k
&&
478
54.4k
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)1.07k
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
54.4k
      bool NoMatchBreak =
483
54.4k
          !FoundMatchOnLine &&
484
54.4k
          
!(52.6k
LineIsComment52.6k
&&
485
52.6k
            
(13.5k
(ACS == FormatStyle::ACS_AcrossComments)13.5k
||
486
13.5k
             
(ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)13.4k
));
487
488
54.4k
      if (EmptyLineBreak || 
NoMatchBreak53.3k
)
489
52.5k
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
54.4k
      if (i == 0 || 
!Changes[i].Tok->is(tok::string_literal)53.8k
||
494
54.4k
          
!Changes[i - 1].Tok->is(tok::string_literal)947
)
495
54.0k
        FoundMatchOnLine = false;
496
54.4k
      LineIsComment = true;
497
54.4k
    }
498
499
365k
    if (!Changes[i].Tok->is(tok::comment)) {
500
358k
      LineIsComment = false;
501
358k
    }
502
503
365k
    if (Changes[i].Tok->is(tok::comma)) {
504
10.9k
      ++CommasBeforeMatch;
505
354k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
46.9k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
46.9k
      i = StoppedAt - 1;
509
46.9k
      continue;
510
46.9k
    }
511
512
318k
    if (!Matches(Changes[i]))
513
315k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
3.00k
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch2.80k
)
518
256
      AlignCurrentSequence();
519
520
3.00k
    CommasBeforeLastMatch = CommasBeforeMatch;
521
3.00k
    FoundMatchOnLine = true;
522
523
3.00k
    if (StartOfSequence == 0)
524
1.76k
      StartOfSequence = i;
525
526
3.00k
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
3.00k
    int LineLengthAfter = Changes[i].TokenLength;
528
13.3k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 012.6k
;
++j10.3k
) {
529
10.3k
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
10.3k
      if (!Changes[j].IsInsideToken)
536
10.3k
        LineLengthAfter += Changes[j].TokenLength;
537
10.3k
    }
538
3.00k
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
3.00k
    if (ChangeMinColumn > MaxColumn || 
ChangeMaxColumn < MinColumn2.99k
||
542
3.00k
        
CommasBeforeLastMatch != CommasBeforeMatch2.98k
) {
543
15
      AlignCurrentSequence();
544
15
      StartOfSequence = i;
545
15
    }
546
547
3.00k
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
3.00k
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
3.00k
  }
550
551
65.4k
  EndOfSequence = i;
552
65.4k
  AlignCurrentSequence();
553
65.4k
  return i;
554
65.4k
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
423
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
423
  unsigned MinColumn = 0;
424
423
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
423
  unsigned StartOfSequence = 0;
428
423
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
423
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
423
                                   ? Changes[StartAt].indentAndNestingLevel()
434
423
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
423
  unsigned CommasBeforeLastMatch = 0;
440
423
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
423
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
423
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
423
  auto AlignCurrentSequence = [&] {
456
423
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
423
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
423
                         Matches, Changes);
459
423
    MinColumn = 0;
460
423
    MaxColumn = UINT_MAX;
461
423
    StartOfSequence = 0;
462
423
    EndOfSequence = 0;
463
423
  };
464
465
423
  unsigned i = StartAt;
466
5.94k
  for (unsigned e = Changes.size(); i != e; 
++i5.52k
) {
467
5.52k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
0
      break;
469
470
5.52k
    if (Changes[i].NewlinesBefore != 0) {
471
1.03k
      CommasBeforeMatch = 0;
472
1.03k
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
1.03k
      bool EmptyLineBreak =
476
1.03k
          (Changes[i].NewlinesBefore > 1) &&
477
1.03k
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)31
&&
478
1.03k
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)26
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
1.03k
      bool NoMatchBreak =
483
1.03k
          !FoundMatchOnLine &&
484
1.03k
          
!(649
LineIsComment649
&&
485
649
            
(52
(ACS == FormatStyle::ACS_AcrossComments)52
||
486
52
             
(ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)42
));
487
488
1.03k
      if (EmptyLineBreak || 
NoMatchBreak1.01k
)
489
634
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
1.03k
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
1.03k
          
!Changes[i - 1].Tok->is(tok::string_literal)18
)
495
1.03k
        FoundMatchOnLine = false;
496
1.03k
      LineIsComment = true;
497
1.03k
    }
498
499
5.52k
    if (!Changes[i].Tok->is(tok::comment)) {
500
5.44k
      LineIsComment = false;
501
5.44k
    }
502
503
5.52k
    if (Changes[i].Tok->is(tok::comma)) {
504
30
      ++CommasBeforeMatch;
505
5.49k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
604
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
604
      i = StoppedAt - 1;
509
604
      continue;
510
604
    }
511
512
4.92k
    if (!Matches(Changes[i]))
513
4.40k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
515
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch494
)
518
54
      AlignCurrentSequence();
519
520
515
    CommasBeforeLastMatch = CommasBeforeMatch;
521
515
    FoundMatchOnLine = true;
522
523
515
    if (StartOfSequence == 0)
524
330
      StartOfSequence = i;
525
526
515
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
515
    int LineLengthAfter = Changes[i].TokenLength;
528
1.93k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 01.82k
;
++j1.41k
) {
529
1.41k
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
1.41k
      if (!Changes[j].IsInsideToken)
536
1.41k
        LineLengthAfter += Changes[j].TokenLength;
537
1.41k
    }
538
515
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
515
    if (ChangeMinColumn > MaxColumn || 
ChangeMaxColumn < MinColumn512
||
542
515
        
CommasBeforeLastMatch != CommasBeforeMatch509
) {
543
6
      AlignCurrentSequence();
544
6
      StartOfSequence = i;
545
6
    }
546
547
515
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
515
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
515
  }
550
551
423
  EndOfSequence = i;
552
423
  AlignCurrentSequence();
553
423
  return i;
554
423
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
1.16k
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
1.16k
  unsigned MinColumn = 0;
424
1.16k
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
1.16k
  unsigned StartOfSequence = 0;
428
1.16k
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
1.16k
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
1.16k
                                   ? Changes[StartAt].indentAndNestingLevel()
434
1.16k
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
1.16k
  unsigned CommasBeforeLastMatch = 0;
440
1.16k
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
1.16k
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
1.16k
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
1.16k
  auto AlignCurrentSequence = [&] {
456
1.16k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
1.16k
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
1.16k
                         Matches, Changes);
459
1.16k
    MinColumn = 0;
460
1.16k
    MaxColumn = UINT_MAX;
461
1.16k
    StartOfSequence = 0;
462
1.16k
    EndOfSequence = 0;
463
1.16k
  };
464
465
1.16k
  unsigned i = StartAt;
466
7.67k
  for (unsigned e = Changes.size(); i != e; 
++i6.51k
) {
467
7.67k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
1.16k
      break;
469
470
6.51k
    if (Changes[i].NewlinesBefore != 0) {
471
871
      CommasBeforeMatch = 0;
472
871
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
871
      bool EmptyLineBreak =
476
871
          (Changes[i].NewlinesBefore > 1) &&
477
871
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)6
&&
478
871
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)6
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
871
      bool NoMatchBreak =
483
871
          !FoundMatchOnLine &&
484
871
          
!(616
LineIsComment616
&&
485
616
            
(303
(ACS == FormatStyle::ACS_AcrossComments)303
||
486
303
             
(ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)296
));
487
488
871
      if (EmptyLineBreak || 
NoMatchBreak865
)
489
582
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
871
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
871
          
!Changes[i - 1].Tok->is(tok::string_literal)78
)
495
824
        FoundMatchOnLine = false;
496
871
      LineIsComment = true;
497
871
    }
498
499
6.51k
    if (!Changes[i].Tok->is(tok::comment)) {
500
6.40k
      LineIsComment = false;
501
6.40k
    }
502
503
6.51k
    if (Changes[i].Tok->is(tok::comma)) {
504
729
      ++CommasBeforeMatch;
505
5.78k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
556
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
556
      i = StoppedAt - 1;
509
556
      continue;
510
556
    }
511
512
5.96k
    if (!Matches(Changes[i]))
513
5.56k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
393
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch369
)
518
42
      AlignCurrentSequence();
519
520
393
    CommasBeforeLastMatch = CommasBeforeMatch;
521
393
    FoundMatchOnLine = true;
522
523
393
    if (StartOfSequence == 0)
524
234
      StartOfSequence = i;
525
526
393
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
393
    int LineLengthAfter = Changes[i].TokenLength;
528
1.90k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 01.89k
;
++j1.51k
) {
529
1.51k
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
1.51k
      if (!Changes[j].IsInsideToken)
536
1.51k
        LineLengthAfter += Changes[j].TokenLength;
537
1.51k
    }
538
393
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
393
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
542
393
        CommasBeforeLastMatch != CommasBeforeMatch) {
543
0
      AlignCurrentSequence();
544
0
      StartOfSequence = i;
545
0
    }
546
547
393
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
393
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
393
  }
550
551
1.16k
  EndOfSequence = i;
552
1.16k
  AlignCurrentSequence();
553
1.16k
  return i;
554
1.16k
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
36
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
36
  unsigned MinColumn = 0;
424
36
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
36
  unsigned StartOfSequence = 0;
428
36
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
36
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
36
                                   ? Changes[StartAt].indentAndNestingLevel()
434
36
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
36
  unsigned CommasBeforeLastMatch = 0;
440
36
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
36
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
36
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
36
  auto AlignCurrentSequence = [&] {
456
36
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
36
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
36
                         Matches, Changes);
459
36
    MinColumn = 0;
460
36
    MaxColumn = UINT_MAX;
461
36
    StartOfSequence = 0;
462
36
    EndOfSequence = 0;
463
36
  };
464
465
36
  unsigned i = StartAt;
466
538
  for (unsigned e = Changes.size(); i != e; 
++i502
) {
467
502
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
0
      break;
469
470
502
    if (Changes[i].NewlinesBefore != 0) {
471
43
      CommasBeforeMatch = 0;
472
43
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
43
      bool EmptyLineBreak =
476
43
          (Changes[i].NewlinesBefore > 1) &&
477
43
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)5
&&
478
43
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)5
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
43
      bool NoMatchBreak =
483
43
          !FoundMatchOnLine &&
484
43
          
!(4
LineIsComment4
&&
485
4
            ((ACS == FormatStyle::ACS_AcrossComments) ||
486
4
             (ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)));
487
488
43
      if (EmptyLineBreak || NoMatchBreak)
489
0
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
43
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
43
          
!Changes[i - 1].Tok->is(tok::string_literal)0
)
495
43
        FoundMatchOnLine = false;
496
43
      LineIsComment = true;
497
43
    }
498
499
502
    if (!Changes[i].Tok->is(tok::comment)) {
500
492
      LineIsComment = false;
501
492
    }
502
503
502
    if (Changes[i].Tok->is(tok::comma)) {
504
0
      ++CommasBeforeMatch;
505
502
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
3
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
3
      i = StoppedAt - 1;
509
3
      continue;
510
3
    }
511
512
499
    if (!Matches(Changes[i]))
513
424
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
75
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
518
0
      AlignCurrentSequence();
519
520
75
    CommasBeforeLastMatch = CommasBeforeMatch;
521
75
    FoundMatchOnLine = true;
522
523
75
    if (StartOfSequence == 0)
524
36
      StartOfSequence = i;
525
526
75
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
75
    int LineLengthAfter = Changes[i].TokenLength;
528
321
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 0285
;
++j246
) {
529
246
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
246
      if (!Changes[j].IsInsideToken)
536
246
        LineLengthAfter += Changes[j].TokenLength;
537
246
    }
538
75
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
75
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
542
75
        CommasBeforeLastMatch != CommasBeforeMatch) {
543
0
      AlignCurrentSequence();
544
0
      StartOfSequence = i;
545
0
    }
546
547
75
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
75
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
75
  }
550
551
36
  EndOfSequence = i;
552
36
  AlignCurrentSequence();
553
36
  return i;
554
36
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
3
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
3
  unsigned MinColumn = 0;
424
3
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
3
  unsigned StartOfSequence = 0;
428
3
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
3
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
3
                                   ? Changes[StartAt].indentAndNestingLevel()
434
3
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
3
  unsigned CommasBeforeLastMatch = 0;
440
3
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
3
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
3
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
3
  auto AlignCurrentSequence = [&] {
456
3
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
3
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
3
                         Matches, Changes);
459
3
    MinColumn = 0;
460
3
    MaxColumn = UINT_MAX;
461
3
    StartOfSequence = 0;
462
3
    EndOfSequence = 0;
463
3
  };
464
465
3
  unsigned i = StartAt;
466
9
  for (unsigned e = Changes.size(); i != e; 
++i6
) {
467
9
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
3
      break;
469
470
6
    if (Changes[i].NewlinesBefore != 0) {
471
0
      CommasBeforeMatch = 0;
472
0
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
0
      bool EmptyLineBreak =
476
0
          (Changes[i].NewlinesBefore > 1) &&
477
0
          (ACS != FormatStyle::ACS_AcrossEmptyLines) &&
478
0
          (ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments);
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
0
      bool NoMatchBreak =
483
0
          !FoundMatchOnLine &&
484
0
          !(LineIsComment &&
485
0
            ((ACS == FormatStyle::ACS_AcrossComments) ||
486
0
             (ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)));
487
488
0
      if (EmptyLineBreak || NoMatchBreak)
489
0
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
0
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
0
          !Changes[i - 1].Tok->is(tok::string_literal))
495
0
        FoundMatchOnLine = false;
496
0
      LineIsComment = true;
497
0
    }
498
499
6
    if (!Changes[i].Tok->is(tok::comment)) {
500
6
      LineIsComment = false;
501
6
    }
502
503
6
    if (Changes[i].Tok->is(tok::comma)) {
504
0
      ++CommasBeforeMatch;
505
6
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
0
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
0
      i = StoppedAt - 1;
509
0
      continue;
510
0
    }
511
512
6
    if (!Matches(Changes[i]))
513
6
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
0
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
518
0
      AlignCurrentSequence();
519
520
0
    CommasBeforeLastMatch = CommasBeforeMatch;
521
0
    FoundMatchOnLine = true;
522
523
0
    if (StartOfSequence == 0)
524
0
      StartOfSequence = i;
525
526
0
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
0
    int LineLengthAfter = Changes[i].TokenLength;
528
0
    for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j) {
529
0
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
0
      if (!Changes[j].IsInsideToken)
536
0
        LineLengthAfter += Changes[j].TokenLength;
537
0
    }
538
0
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
0
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
542
0
        CommasBeforeLastMatch != CommasBeforeMatch) {
543
0
      AlignCurrentSequence();
544
0
      StartOfSequence = i;
545
0
    }
546
547
0
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
0
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
0
  }
550
551
3
  EndOfSequence = i;
552
3
  AlignCurrentSequence();
553
3
  return i;
554
3
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
360
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
360
  unsigned MinColumn = 0;
424
360
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
360
  unsigned StartOfSequence = 0;
428
360
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
360
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
360
                                   ? Changes[StartAt].indentAndNestingLevel()
434
360
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
360
  unsigned CommasBeforeLastMatch = 0;
440
360
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
360
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
360
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
360
  auto AlignCurrentSequence = [&] {
456
360
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
360
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
360
                         Matches, Changes);
459
360
    MinColumn = 0;
460
360
    MaxColumn = UINT_MAX;
461
360
    StartOfSequence = 0;
462
360
    EndOfSequence = 0;
463
360
  };
464
465
360
  unsigned i = StartAt;
466
5.19k
  for (unsigned e = Changes.size(); i != e; 
++i4.83k
) {
467
4.83k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
0
      break;
469
470
4.83k
    if (Changes[i].NewlinesBefore != 0) {
471
865
      CommasBeforeMatch = 0;
472
865
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
865
      bool EmptyLineBreak =
476
865
          (Changes[i].NewlinesBefore > 1) &&
477
865
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)17
&&
478
865
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)17
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
865
      bool NoMatchBreak =
483
865
          !FoundMatchOnLine &&
484
865
          
!(423
LineIsComment423
&&
485
423
            
(30
(ACS == FormatStyle::ACS_AcrossComments)30
||
486
30
             (ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)));
487
488
865
      if (EmptyLineBreak || 
NoMatchBreak852
)
489
422
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
865
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
865
          
!Changes[i - 1].Tok->is(tok::string_literal)18
)
495
865
        FoundMatchOnLine = false;
496
865
      LineIsComment = true;
497
865
    }
498
499
4.83k
    if (!Changes[i].Tok->is(tok::comment)) {
500
4.76k
      LineIsComment = false;
501
4.76k
    }
502
503
4.83k
    if (Changes[i].Tok->is(tok::comma)) {
504
18
      ++CommasBeforeMatch;
505
4.81k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
546
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
546
      i = StoppedAt - 1;
509
546
      continue;
510
546
    }
511
512
4.28k
    if (!Matches(Changes[i]))
513
3.74k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
541
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
518
0
      AlignCurrentSequence();
519
520
541
    CommasBeforeLastMatch = CommasBeforeMatch;
521
541
    FoundMatchOnLine = true;
522
523
541
    if (StartOfSequence == 0)
524
274
      StartOfSequence = i;
525
526
541
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
541
    int LineLengthAfter = Changes[i].TokenLength;
528
2.48k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 02.39k
;
++j1.94k
) {
529
1.94k
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
1.94k
      if (!Changes[j].IsInsideToken)
536
1.94k
        LineLengthAfter += Changes[j].TokenLength;
537
1.94k
    }
538
541
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
541
    if (ChangeMinColumn > MaxColumn || 
ChangeMaxColumn < MinColumn538
||
542
541
        
CommasBeforeLastMatch != CommasBeforeMatch535
) {
543
6
      AlignCurrentSequence();
544
6
      StartOfSequence = i;
545
6
    }
546
547
541
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
541
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
541
  }
550
551
360
  EndOfSequence = i;
552
360
  AlignCurrentSequence();
553
360
  return i;
554
360
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
1.09k
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
1.09k
  unsigned MinColumn = 0;
424
1.09k
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
1.09k
  unsigned StartOfSequence = 0;
428
1.09k
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
1.09k
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
1.09k
                                   ? Changes[StartAt].indentAndNestingLevel()
434
1.09k
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
1.09k
  unsigned CommasBeforeLastMatch = 0;
440
1.09k
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
1.09k
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
1.09k
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
1.09k
  auto AlignCurrentSequence = [&] {
456
1.09k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
1.09k
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
1.09k
                         Matches, Changes);
459
1.09k
    MinColumn = 0;
460
1.09k
    MaxColumn = UINT_MAX;
461
1.09k
    StartOfSequence = 0;
462
1.09k
    EndOfSequence = 0;
463
1.09k
  };
464
465
1.09k
  unsigned i = StartAt;
466
7.02k
  for (unsigned e = Changes.size(); i != e; 
++i5.93k
) {
467
7.02k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
1.09k
      break;
469
470
5.93k
    if (Changes[i].NewlinesBefore != 0) {
471
796
      CommasBeforeMatch = 0;
472
796
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
796
      bool EmptyLineBreak =
476
796
          (Changes[i].NewlinesBefore > 1) &&
477
796
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)6
&&
478
796
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)6
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
796
      bool NoMatchBreak =
483
796
          !FoundMatchOnLine &&
484
796
          
!(551
LineIsComment551
&&
485
551
            
(273
(ACS == FormatStyle::ACS_AcrossComments)273
||
486
273
             
(ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)266
));
487
488
796
      if (EmptyLineBreak || 
NoMatchBreak790
)
489
550
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
796
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
796
          
!Changes[i - 1].Tok->is(tok::string_literal)78
)
495
749
        FoundMatchOnLine = false;
496
796
      LineIsComment = true;
497
796
    }
498
499
5.93k
    if (!Changes[i].Tok->is(tok::comment)) {
500
5.83k
      LineIsComment = false;
501
5.83k
    }
502
503
5.93k
    if (Changes[i].Tok->is(tok::comma)) {
504
720
      ++CommasBeforeMatch;
505
5.21k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
550
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
550
      i = StoppedAt - 1;
509
550
      continue;
510
550
    }
511
512
5.38k
    if (!Matches(Changes[i]))
513
5.03k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
348
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch336
)
518
15
      AlignCurrentSequence();
519
520
348
    CommasBeforeLastMatch = CommasBeforeMatch;
521
348
    FoundMatchOnLine = true;
522
523
348
    if (StartOfSequence == 0)
524
183
      StartOfSequence = i;
525
526
348
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
348
    int LineLengthAfter = Changes[i].TokenLength;
528
1.76k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 01.74k
;
++j1.41k
) {
529
1.41k
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
1.41k
      if (!Changes[j].IsInsideToken)
536
1.41k
        LineLengthAfter += Changes[j].TokenLength;
537
1.41k
    }
538
348
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
348
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
542
348
        CommasBeforeLastMatch != CommasBeforeMatch) {
543
0
      AlignCurrentSequence();
544
0
      StartOfSequence = i;
545
0
    }
546
547
348
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
348
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
348
  }
550
551
1.09k
  EndOfSequence = i;
552
1.09k
  AlignCurrentSequence();
553
1.09k
  return i;
554
1.09k
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignChainedConditionals()::$_4>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignChainedConditionals()::$_4&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
16.2k
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
16.2k
  unsigned MinColumn = 0;
424
16.2k
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
16.2k
  unsigned StartOfSequence = 0;
428
16.2k
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
16.2k
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
16.2k
                                   ? Changes[StartAt].indentAndNestingLevel()
434
16.2k
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
16.2k
  unsigned CommasBeforeLastMatch = 0;
440
16.2k
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
16.2k
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
16.2k
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
16.2k
  auto AlignCurrentSequence = [&] {
456
16.2k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
16.2k
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
16.2k
                         Matches, Changes);
459
16.2k
    MinColumn = 0;
460
16.2k
    MaxColumn = UINT_MAX;
461
16.2k
    StartOfSequence = 0;
462
16.2k
    EndOfSequence = 0;
463
16.2k
  };
464
465
16.2k
  unsigned i = StartAt;
466
177k
  for (unsigned e = Changes.size(); i != e; 
++i160k
) {
467
160k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
24
      break;
469
470
160k
    if (Changes[i].NewlinesBefore != 0) {
471
25.3k
      CommasBeforeMatch = 0;
472
25.3k
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
25.3k
      bool EmptyLineBreak =
476
25.3k
          (Changes[i].NewlinesBefore > 1) &&
477
25.3k
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)721
&&
478
25.3k
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)721
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
25.3k
      bool NoMatchBreak =
483
25.3k
          !FoundMatchOnLine &&
484
25.3k
          
!(25.3k
LineIsComment25.3k
&&
485
25.3k
            
(2.25k
(ACS == FormatStyle::ACS_AcrossComments)2.25k
||
486
2.25k
             (ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)));
487
488
25.3k
      if (EmptyLineBreak || 
NoMatchBreak24.5k
)
489
25.3k
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
25.3k
      if (i == 0 || 
!Changes[i].Tok->is(tok::string_literal)24.7k
||
494
25.3k
          
!Changes[i - 1].Tok->is(tok::string_literal)214
)
495
25.2k
        FoundMatchOnLine = false;
496
25.3k
      LineIsComment = true;
497
25.3k
    }
498
499
160k
    if (!Changes[i].Tok->is(tok::comment)) {
500
156k
      LineIsComment = false;
501
156k
    }
502
503
160k
    if (Changes[i].Tok->is(tok::comma)) {
504
820
      ++CommasBeforeMatch;
505
160k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
25.2k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
25.2k
      i = StoppedAt - 1;
509
25.2k
      continue;
510
25.2k
    }
511
512
135k
    if (!Matches(Changes[i]))
513
135k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
24
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch17
)
518
7
      AlignCurrentSequence();
519
520
24
    CommasBeforeLastMatch = CommasBeforeMatch;
521
24
    FoundMatchOnLine = true;
522
523
24
    if (StartOfSequence == 0)
524
24
      StartOfSequence = i;
525
526
24
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
24
    int LineLengthAfter = Changes[i].TokenLength;
528
158
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 0137
;
++j134
) {
529
134
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
134
      if (!Changes[j].IsInsideToken)
536
134
        LineLengthAfter += Changes[j].TokenLength;
537
134
    }
538
24
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
24
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
542
24
        CommasBeforeLastMatch != CommasBeforeMatch) {
543
0
      AlignCurrentSequence();
544
0
      StartOfSequence = i;
545
0
    }
546
547
24
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
24
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
24
  }
550
551
16.2k
  EndOfSequence = i;
552
16.2k
  AlignCurrentSequence();
553
16.2k
  return i;
554
16.2k
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignChainedConditionals()::$_4&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignChainedConditionals()::$_4&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
41.7k
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
41.7k
  unsigned MinColumn = 0;
424
41.7k
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
41.7k
  unsigned StartOfSequence = 0;
428
41.7k
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
41.7k
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
41.7k
                                   ? Changes[StartAt].indentAndNestingLevel()
434
41.7k
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
41.7k
  unsigned CommasBeforeLastMatch = 0;
440
41.7k
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
41.7k
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
41.7k
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
41.7k
  auto AlignCurrentSequence = [&] {
456
41.7k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
41.7k
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
41.7k
                         Matches, Changes);
459
41.7k
    MinColumn = 0;
460
41.7k
    MaxColumn = UINT_MAX;
461
41.7k
    StartOfSequence = 0;
462
41.7k
    EndOfSequence = 0;
463
41.7k
  };
464
465
41.7k
  unsigned i = StartAt;
466
200k
  for (unsigned e = Changes.size(); i != e; 
++i158k
) {
467
200k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
41.6k
      break;
469
470
158k
    if (Changes[i].NewlinesBefore != 0) {
471
21.9k
      CommasBeforeMatch = 0;
472
21.9k
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
21.9k
      bool EmptyLineBreak =
476
21.9k
          (Changes[i].NewlinesBefore > 1) &&
477
21.9k
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)263
&&
478
21.9k
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)263
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
21.9k
      bool NoMatchBreak =
483
21.9k
          !FoundMatchOnLine &&
484
21.9k
          
!(21.7k
LineIsComment21.7k
&&
485
21.7k
            
(9.41k
(ACS == FormatStyle::ACS_AcrossComments)9.41k
||
486
9.41k
             (ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)));
487
488
21.9k
      if (EmptyLineBreak || 
NoMatchBreak21.7k
)
489
21.7k
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
21.9k
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
21.9k
          
!Changes[i - 1].Tok->is(tok::string_literal)475
)
495
21.7k
        FoundMatchOnLine = false;
496
21.9k
      LineIsComment = true;
497
21.9k
    }
498
499
158k
    if (!Changes[i].Tok->is(tok::comment)) {
500
156k
      LineIsComment = false;
501
156k
    }
502
503
158k
    if (Changes[i].Tok->is(tok::comma)) {
504
8.05k
      ++CommasBeforeMatch;
505
150k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
16.4k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
16.4k
      i = StoppedAt - 1;
509
16.4k
      continue;
510
16.4k
    }
511
512
142k
    if (!Matches(Changes[i]))
513
141k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
713
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch579
)
518
138
      AlignCurrentSequence();
519
520
713
    CommasBeforeLastMatch = CommasBeforeMatch;
521
713
    FoundMatchOnLine = true;
522
523
713
    if (StartOfSequence == 0)
524
485
      StartOfSequence = i;
525
526
713
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
713
    int LineLengthAfter = Changes[i].TokenLength;
528
3.33k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 03.01k
;
++j2.61k
) {
529
2.61k
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
2.61k
      if (!Changes[j].IsInsideToken)
536
2.61k
        LineLengthAfter += Changes[j].TokenLength;
537
2.61k
    }
538
713
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
713
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
542
713
        CommasBeforeLastMatch != CommasBeforeMatch) {
543
0
      AlignCurrentSequence();
544
0
      StartOfSequence = i;
545
0
    }
546
547
713
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
713
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
713
  }
550
551
41.7k
  EndOfSequence = i;
552
41.7k
  AlignCurrentSequence();
553
41.7k
  return i;
554
41.7k
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignChainedConditionals()::$_6>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignChainedConditionals()::$_6&&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
1.53k
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
1.53k
  unsigned MinColumn = 0;
424
1.53k
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
1.53k
  unsigned StartOfSequence = 0;
428
1.53k
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
1.53k
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
1.53k
                                   ? Changes[StartAt].indentAndNestingLevel()
434
1.53k
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
1.53k
  unsigned CommasBeforeLastMatch = 0;
440
1.53k
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
1.53k
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
1.53k
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
1.53k
  auto AlignCurrentSequence = [&] {
456
1.53k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
1.53k
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
1.53k
                         Matches, Changes);
459
1.53k
    MinColumn = 0;
460
1.53k
    MaxColumn = UINT_MAX;
461
1.53k
    StartOfSequence = 0;
462
1.53k
    EndOfSequence = 0;
463
1.53k
  };
464
465
1.53k
  unsigned i = StartAt;
466
13.0k
  for (unsigned e = Changes.size(); i != e; 
++i11.5k
) {
467
11.5k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
11
      break;
469
470
11.5k
    if (Changes[i].NewlinesBefore != 0) {
471
1.48k
      CommasBeforeMatch = 0;
472
1.48k
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
1.48k
      bool EmptyLineBreak =
476
1.48k
          (Changes[i].NewlinesBefore > 1) &&
477
1.48k
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)28
&&
478
1.48k
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)28
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
1.48k
      bool NoMatchBreak =
483
1.48k
          !FoundMatchOnLine &&
484
1.48k
          
!(1.48k
LineIsComment1.48k
&&
485
1.48k
            
(176
(ACS == FormatStyle::ACS_AcrossComments)176
||
486
176
             (ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)));
487
488
1.48k
      if (EmptyLineBreak || 
NoMatchBreak1.46k
)
489
1.48k
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
1.48k
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
1.48k
          
!Changes[i - 1].Tok->is(tok::string_literal)38
)
495
1.48k
        FoundMatchOnLine = false;
496
1.48k
      LineIsComment = true;
497
1.48k
    }
498
499
11.5k
    if (!Changes[i].Tok->is(tok::comment)) {
500
11.2k
      LineIsComment = false;
501
11.2k
    }
502
503
11.5k
    if (Changes[i].Tok->is(tok::comma)) {
504
8
      ++CommasBeforeMatch;
505
11.5k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
1.71k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
1.71k
      i = StoppedAt - 1;
509
1.71k
      continue;
510
1.71k
    }
511
512
9.80k
    if (!Matches(Changes[i]))
513
9.79k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
11
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
518
0
      AlignCurrentSequence();
519
520
11
    CommasBeforeLastMatch = CommasBeforeMatch;
521
11
    FoundMatchOnLine = true;
522
523
11
    if (StartOfSequence == 0)
524
11
      StartOfSequence = i;
525
526
11
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
11
    int LineLengthAfter = Changes[i].TokenLength;
528
36
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 028
;
++j25
) {
529
25
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
25
      if (!Changes[j].IsInsideToken)
536
25
        LineLengthAfter += Changes[j].TokenLength;
537
25
    }
538
11
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
11
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
542
11
        CommasBeforeLastMatch != CommasBeforeMatch) {
543
0
      AlignCurrentSequence();
544
0
      StartOfSequence = i;
545
0
    }
546
547
11
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
11
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
11
  }
550
551
1.53k
  EndOfSequence = i;
552
1.53k
  AlignCurrentSequence();
553
1.53k
  return i;
554
1.53k
}
WhitespaceManager.cpp:unsigned int clang::format::AlignTokens<clang::format::WhitespaceManager::alignChainedConditionals()::$_6&>(clang::format::FormatStyle const&, clang::format::WhitespaceManager::alignChainedConditionals()::$_6&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&, unsigned int, clang::format::FormatStyle::AlignConsecutiveStyle const&)
Line
Count
Source
422
2.94k
    const FormatStyle::AlignConsecutiveStyle &ACS = FormatStyle::ACS_None) {
423
2.94k
  unsigned MinColumn = 0;
424
2.94k
  unsigned MaxColumn = UINT_MAX;
425
426
  // Line number of the start and the end of the current token sequence.
427
2.94k
  unsigned StartOfSequence = 0;
428
2.94k
  unsigned EndOfSequence = 0;
429
430
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
431
  // abort when we hit any token in a higher scope than the starting one.
432
2.94k
  auto IndentAndNestingLevel = StartAt < Changes.size()
433
2.94k
                                   ? Changes[StartAt].indentAndNestingLevel()
434
2.94k
                                   : 
std::tuple<unsigned, unsigned, unsigned>()0
;
435
436
  // Keep track of the number of commas before the matching tokens, we will only
437
  // align a sequence of matching tokens if they are preceded by the same number
438
  // of commas.
439
2.94k
  unsigned CommasBeforeLastMatch = 0;
440
2.94k
  unsigned CommasBeforeMatch = 0;
441
442
  // Whether a matching token has been found on the current line.
443
2.94k
  bool FoundMatchOnLine = false;
444
445
  // Whether the current line consists purely of comments.
446
2.94k
  bool LineIsComment = true;
447
448
  // Aligns a sequence of matching tokens, on the MinColumn column.
449
  //
450
  // Sequences start from the first matching token to align, and end at the
451
  // first token of the first line that doesn't need to be aligned.
452
  //
453
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
454
  // containing any matching token to be aligned and located after such token.
455
2.94k
  auto AlignCurrentSequence = [&] {
456
2.94k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
457
2.94k
      AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn,
458
2.94k
                         Matches, Changes);
459
2.94k
    MinColumn = 0;
460
2.94k
    MaxColumn = UINT_MAX;
461
2.94k
    StartOfSequence = 0;
462
2.94k
    EndOfSequence = 0;
463
2.94k
  };
464
465
2.94k
  unsigned i = StartAt;
466
13.5k
  for (unsigned e = Changes.size(); i != e; 
++i10.6k
) {
467
13.5k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
468
2.94k
      break;
469
470
10.6k
    if (Changes[i].NewlinesBefore != 0) {
471
2.04k
      CommasBeforeMatch = 0;
472
2.04k
      EndOfSequence = i;
473
474
      // Whether to break the alignment sequence because of an empty line.
475
2.04k
      bool EmptyLineBreak =
476
2.04k
          (Changes[i].NewlinesBefore > 1) &&
477
2.04k
          
(ACS != FormatStyle::ACS_AcrossEmptyLines)0
&&
478
2.04k
          
(ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments)0
;
479
480
      // Whether to break the alignment sequence because of a line without a
481
      // match.
482
2.04k
      bool NoMatchBreak =
483
2.04k
          !FoundMatchOnLine &&
484
2.04k
          
!(1.83k
LineIsComment1.83k
&&
485
1.83k
            
(1.00k
(ACS == FormatStyle::ACS_AcrossComments)1.00k
||
486
1.00k
             (ACS == FormatStyle::ACS_AcrossEmptyLinesAndComments)));
487
488
2.04k
      if (EmptyLineBreak || NoMatchBreak)
489
1.83k
        AlignCurrentSequence();
490
491
      // A new line starts, re-initialize line status tracking bools.
492
      // Keep the match state if a string literal is continued on this line.
493
2.04k
      if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
494
2.04k
          
!Changes[i - 1].Tok->is(tok::string_literal)28
)
495
2.04k
        FoundMatchOnLine = false;
496
2.04k
      LineIsComment = true;
497
2.04k
    }
498
499
10.6k
    if (!Changes[i].Tok->is(tok::comment)) {
500
10.4k
      LineIsComment = false;
501
10.4k
    }
502
503
10.6k
    if (Changes[i].Tok->is(tok::comma)) {
504
611
      ++CommasBeforeMatch;
505
9.99k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
506
      // Call AlignTokens recursively, skipping over this scope block.
507
1.23k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
508
1.23k
      i = StoppedAt - 1;
509
1.23k
      continue;
510
1.23k
    }
511
512
9.37k
    if (!Matches(Changes[i]))
513
8.98k
      continue;
514
515
    // If there is more than one matching token per line, or if the number of
516
    // preceding commas, do not match anymore, end the sequence.
517
383
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
518
0
      AlignCurrentSequence();
519
520
383
    CommasBeforeLastMatch = CommasBeforeMatch;
521
383
    FoundMatchOnLine = true;
522
523
383
    if (StartOfSequence == 0)
524
183
      StartOfSequence = i;
525
526
383
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
527
383
    int LineLengthAfter = Changes[i].TokenLength;
528
1.44k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 01.33k
;
++j1.06k
) {
529
1.06k
      LineLengthAfter += Changes[j].Spaces;
530
      // Changes are generally 1:1 with the tokens, but a change could also be
531
      // inside of a token, in which case it's counted more than once: once for
532
      // the whitespace surrounding the token (!IsInsideToken) and once for
533
      // each whitespace change within it (IsInsideToken).
534
      // Therefore, changes inside of a token should only count the space.
535
1.06k
      if (!Changes[j].IsInsideToken)
536
1.06k
        LineLengthAfter += Changes[j].TokenLength;
537
1.06k
    }
538
383
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
539
540
    // If we are restricted by the maximum column width, end the sequence.
541
383
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
542
383
        
CommasBeforeLastMatch != CommasBeforeMatch380
) {
543
3
      AlignCurrentSequence();
544
3
      StartOfSequence = i;
545
3
    }
546
547
383
    MinColumn = std::max(MinColumn, ChangeMinColumn);
548
383
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
549
383
  }
550
551
2.94k
  EndOfSequence = i;
552
2.94k
  AlignCurrentSequence();
553
2.94k
  return i;
554
2.94k
}
555
556
// Aligns a sequence of matching tokens, on the MinColumn column.
557
//
558
// Sequences start from the first matching token to align, and end at the
559
// first token of the first line that doesn't need to be aligned.
560
//
561
// We need to adjust the StartOfTokenColumn of each Change that is on a line
562
// containing any matching token to be aligned and located after such token.
563
static void AlignMacroSequence(
564
    unsigned &StartOfSequence, unsigned &EndOfSequence, unsigned &MinColumn,
565
    unsigned &MaxColumn, bool &FoundMatchOnLine,
566
    std::function<bool(const WhitespaceManager::Change &C)> AlignMacrosMatches,
567
1.66k
    SmallVector<WhitespaceManager::Change, 16> &Changes) {
568
1.66k
  if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence30
) {
569
570
30
    FoundMatchOnLine = false;
571
30
    int Shift = 0;
572
573
636
    for (unsigned I = StartOfSequence; I != EndOfSequence; 
++I606
) {
574
606
      if (Changes[I].NewlinesBefore > 0) {
575
75
        Shift = 0;
576
75
        FoundMatchOnLine = false;
577
75
      }
578
579
      // If this is the first matching token to be aligned, remember by how many
580
      // spaces it has to be shifted, so the rest of the changes on the line are
581
      // shifted by the same amount
582
606
      if (!FoundMatchOnLine && 
AlignMacrosMatches(Changes[I])402
) {
583
90
        FoundMatchOnLine = true;
584
90
        Shift = MinColumn - Changes[I].StartOfTokenColumn;
585
90
        Changes[I].Spaces += Shift;
586
90
      }
587
588
606
      assert(Shift >= 0);
589
0
      Changes[I].StartOfTokenColumn += Shift;
590
606
      if (I + 1 != Changes.size())
591
581
        Changes[I + 1].PreviousEndOfTokenColumn += Shift;
592
606
    }
593
30
  }
594
595
1.66k
  MinColumn = 0;
596
1.66k
  MaxColumn = UINT_MAX;
597
1.66k
  StartOfSequence = 0;
598
1.66k
  EndOfSequence = 0;
599
1.66k
}
600
601
17.7k
void WhitespaceManager::alignConsecutiveMacros() {
602
17.7k
  if (Style.AlignConsecutiveMacros == FormatStyle::ACS_None)
603
17.3k
    return;
604
605
9.60k
  
auto AlignMacrosMatches = [](const Change &C) 385
{
606
9.60k
    const FormatToken *Current = C.Tok;
607
9.60k
    unsigned SpacesRequiredBefore = 1;
608
609
9.60k
    if (Current->SpacesRequiredBefore == 0 || 
!Current->Previous6.75k
)
610
4.79k
      return false;
611
612
4.81k
    Current = Current->Previous;
613
614
    // If token is a ")", skip over the parameter list, to the
615
    // token that precedes the "("
616
4.81k
    if (Current->is(tok::r_paren) && 
Current->MatchingParen150
) {
617
150
      Current = Current->MatchingParen->Previous;
618
150
      SpacesRequiredBefore = 0;
619
150
    }
620
621
4.81k
    if (!Current || !Current->is(tok::identifier))
622
3.15k
      return false;
623
624
1.65k
    if (!Current->Previous || 
!Current->Previous->is(tok::pp_define)1.48k
)
625
1.47k
      return false;
626
627
    // For a macro function, 0 spaces are required between the
628
    // identifier and the lparen that opens the parameter list.
629
    // For a simple macro, 1 space is required between the
630
    // identifier and the first token of the defined value.
631
180
    return Current->Next->SpacesRequiredBefore == SpacesRequiredBefore;
632
1.65k
  };
633
634
385
  unsigned MinColumn = 0;
635
385
  unsigned MaxColumn = UINT_MAX;
636
637
  // Start and end of the token sequence we're processing.
638
385
  unsigned StartOfSequence = 0;
639
385
  unsigned EndOfSequence = 0;
640
641
  // Whether a matching token has been found on the current line.
642
385
  bool FoundMatchOnLine = false;
643
644
  // Whether the current line consists only of comments
645
385
  bool LineIsComment = true;
646
647
385
  unsigned I = 0;
648
9.59k
  for (unsigned E = Changes.size(); I != E; 
++I9.20k
) {
649
9.20k
    if (Changes[I].NewlinesBefore != 0) {
650
1.35k
      EndOfSequence = I;
651
652
      // Whether to break the alignment sequence because of an empty line.
653
1.35k
      bool EmptyLineBreak =
654
1.35k
          (Changes[I].NewlinesBefore > 1) &&
655
1.35k
          
(Style.AlignConsecutiveMacros != FormatStyle::ACS_AcrossEmptyLines)40
&&
656
1.35k
          (Style.AlignConsecutiveMacros !=
657
38
           FormatStyle::ACS_AcrossEmptyLinesAndComments);
658
659
      // Whether to break the alignment sequence because of a line without a
660
      // match.
661
1.35k
      bool NoMatchBreak =
662
1.35k
          !FoundMatchOnLine &&
663
1.35k
          
!(1.29k
LineIsComment1.29k
&&
(39
(Style.AlignConsecutiveMacros ==
664
39
                               FormatStyle::ACS_AcrossComments) ||
665
39
                              (Style.AlignConsecutiveMacros ==
666
33
                               FormatStyle::ACS_AcrossEmptyLinesAndComments)));
667
668
1.35k
      if (EmptyLineBreak || 
NoMatchBreak1.32k
)
669
1.28k
        AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
670
1.28k
                           FoundMatchOnLine, AlignMacrosMatches, Changes);
671
672
      // A new line starts, re-initialize line status tracking bools.
673
1.35k
      FoundMatchOnLine = false;
674
1.35k
      LineIsComment = true;
675
1.35k
    }
676
677
9.20k
    if (!Changes[I].Tok->is(tok::comment)) {
678
9.10k
      LineIsComment = false;
679
9.10k
    }
680
681
9.20k
    if (!AlignMacrosMatches(Changes[I]))
682
9.11k
      continue;
683
684
90
    FoundMatchOnLine = true;
685
686
90
    if (StartOfSequence == 0)
687
30
      StartOfSequence = I;
688
689
90
    unsigned ChangeMinColumn = Changes[I].StartOfTokenColumn;
690
90
    int LineLengthAfter = -Changes[I].Spaces;
691
384
    for (unsigned j = I; j != E && 
Changes[j].NewlinesBefore == 0359
;
++j294
)
692
294
      LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength;
693
90
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
694
695
90
    MinColumn = std::max(MinColumn, ChangeMinColumn);
696
90
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
697
90
  }
698
699
385
  EndOfSequence = I;
700
385
  AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
701
385
                     FoundMatchOnLine, AlignMacrosMatches, Changes);
702
385
}
703
704
17.7k
void WhitespaceManager::alignConsecutiveAssignments() {
705
17.7k
  if (Style.AlignConsecutiveAssignments == FormatStyle::ACS_None)
706
17.3k
    return;
707
708
423
  AlignTokens(
709
423
      Style,
710
12.7k
      [&](const Change &C) {
711
        // Do not align on equal signs that are first on a line.
712
12.7k
        if (C.NewlinesBefore > 0)
713
2.10k
          return false;
714
715
        // Do not align on equal signs that are last on a line.
716
10.6k
        if (&C != &Changes.back() && 
(&C + 1)->NewlinesBefore > 010.3k
)
717
1.53k
          return false;
718
719
9.14k
        return C.Tok->is(tok::equal);
720
10.6k
      },
721
423
      Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments);
722
423
}
723
724
17.7k
void WhitespaceManager::alignConsecutiveBitFields() {
725
17.7k
  if (Style.AlignConsecutiveBitFields == FormatStyle::ACS_None)
726
17.7k
    return;
727
728
36
  AlignTokens(
729
36
      Style,
730
662
      [&](Change const &C) {
731
        // Do not align on ':' that is first on a line.
732
662
        if (C.NewlinesBefore > 0)
733
86
          return false;
734
735
        // Do not align on ':' that is last on a line.
736
576
        if (&C != &Changes.back() && 
(&C + 1)->NewlinesBefore > 0540
)
737
39
          return false;
738
739
537
        return C.Tok->is(TT_BitFieldColon);
740
576
      },
741
36
      Changes, /*StartAt=*/0, Style.AlignConsecutiveBitFields);
742
36
}
743
744
17.7k
void WhitespaceManager::alignConsecutiveDeclarations() {
745
17.7k
  if (Style.AlignConsecutiveDeclarations == FormatStyle::ACS_None)
746
17.3k
    return;
747
748
360
  AlignTokens(
749
360
      Style,
750
11.5k
      [](Change const &C) {
751
        // tok::kw_operator is necessary for aligning operator overload
752
        // definitions.
753
11.5k
        if (C.Tok->isOneOf(TT_FunctionDeclarationName, tok::kw_operator))
754
226
          return true;
755
11.3k
        if (C.Tok->isNot(TT_StartOfName))
756
9.73k
          return false;
757
1.58k
        if (C.Tok->Previous &&
758
1.58k
            C.Tok->Previous->is(TT_StatementAttributeLikeMacro))
759
5
          return false;
760
        // Check if there is a subsequent name that starts the same declaration.
761
1.58k
        
for (FormatToken *Next = C.Tok->Next; 1.57k
Next;
Next = Next->Next2
) {
762
1.58k
          if (Next->is(tok::comment))
763
2
            continue;
764
1.57k
          if (Next->is(TT_PointerOrReference))
765
36
            return false;
766
1.54k
          if (!Next->Tok.getIdentifierInfo())
767
1.54k
            break;
768
2
          if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
769
2
                            tok::kw_operator))
770
2
            return false;
771
2
        }
772
1.54k
        return true;
773
1.57k
      },
774
360
      Changes, /*StartAt=*/0, Style.AlignConsecutiveDeclarations);
775
360
}
776
777
17.7k
void WhitespaceManager::alignChainedConditionals() {
778
17.7k
  if (Style.BreakBeforeTernaryOperators) {
779
16.2k
    AlignTokens(
780
16.2k
        Style,
781
278k
        [](Change const &C) {
782
          // Align question operators and last colon
783
278k
          return C.Tok->is(TT_ConditionalExpr) &&
784
278k
                 
(1.60k
(1.60k
C.Tok->is(tok::question)1.60k
&&
!C.NewlinesBefore714
) ||
785
1.60k
                  
(970
C.Tok->is(tok::colon)970
&&
C.Tok->Next888
&&
786
970
                   
(888
C.Tok->Next->FakeLParens.size() == 0888
||
787
888
                    
C.Tok->Next->FakeLParens.back() != prec::Conditional254
)));
788
278k
        },
789
16.2k
        Changes, /*StartAt=*/0);
790
16.2k
  } else {
791
38.3k
    static auto AlignWrappedOperand = [](Change const &C) {
792
38.3k
      FormatToken *Previous = C.Tok->getPreviousNonComment();
793
38.3k
      return C.NewlinesBefore && 
Previous5.39k
&&
Previous->is(TT_ConditionalExpr)2.90k
&&
794
38.3k
             
(865
Previous->is(tok::colon)865
&&
795
865
              
(753
C.Tok->FakeLParens.size() == 0753
||
796
753
               
C.Tok->FakeLParens.back() != prec::Conditional279
));
797
38.3k
    };
798
    // Ensure we keep alignment of wrapped operands with non-wrapped operands
799
    // Since we actually align the operators, the wrapped operands need the
800
    // extra offset to be properly aligned.
801
19.1k
    for (Change &C : Changes) {
802
19.1k
      if (AlignWrappedOperand(C))
803
167
        C.StartOfTokenColumn -= 2;
804
19.1k
    }
805
1.53k
    AlignTokens(
806
1.53k
        Style,
807
19.6k
        [this](Change const &C) {
808
          // Align question operators if next operand is not wrapped, as
809
          // well as wrapped operands after question operator or last
810
          // colon in conditional sequence
811
19.6k
          return (C.Tok->is(TT_ConditionalExpr) && 
C.Tok->is(tok::question)789
&&
812
19.6k
                  
&C != &Changes.back()508
&&
(&C + 1)->NewlinesBefore == 0508
&&
813
19.6k
                  
!(&C + 1)->IsTrailingComment466
) ||
814
19.6k
                 
AlignWrappedOperand(C)19.1k
;
815
19.6k
        },
816
1.53k
        Changes, /*StartAt=*/0);
817
1.53k
  }
818
17.7k
}
819
820
17.7k
void WhitespaceManager::alignTrailingComments() {
821
17.7k
  unsigned MinColumn = 0;
822
17.7k
  unsigned MaxColumn = UINT_MAX;
823
17.7k
  unsigned StartOfSequence = 0;
824
17.7k
  bool BreakBeforeNext = false;
825
17.7k
  unsigned Newlines = 0;
826
315k
  for (unsigned i = 0, e = Changes.size(); i != e; 
++i297k
) {
827
297k
    if (Changes[i].StartOfBlockComment)
828
558
      continue;
829
296k
    Newlines += Changes[i].NewlinesBefore;
830
296k
    if (!Changes[i].IsTrailingComment)
831
292k
      continue;
832
833
4.25k
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
834
4.25k
    unsigned ChangeMaxColumn;
835
836
4.25k
    if (Style.ColumnLimit == 0)
837
286
      ChangeMaxColumn = UINT_MAX;
838
3.97k
    else if (Style.ColumnLimit >= Changes[i].TokenLength)
839
3.91k
      ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
840
59
    else
841
59
      ChangeMaxColumn = ChangeMinColumn;
842
843
    // If we don't create a replacement for this change, we have to consider
844
    // it to be immovable.
845
4.25k
    if (!Changes[i].CreateReplacement)
846
469
      ChangeMaxColumn = ChangeMinColumn;
847
848
4.25k
    if (i + 1 != e && 
Changes[i + 1].ContinuesPPDirective4.24k
)
849
68
      ChangeMaxColumn -= 2;
850
    // If this comment follows an } in column 0, it probably documents the
851
    // closing of a namespace and we don't want to align it.
852
4.25k
    bool FollowsRBraceInColumn0 = i > 0 && 
Changes[i].NewlinesBefore == 03.82k
&&
853
4.25k
                                  
Changes[i - 1].Tok->is(tok::r_brace)2.04k
&&
854
4.25k
                                  
Changes[i - 1].StartOfTokenColumn == 0901
;
855
4.25k
    bool WasAlignedWithStartOfNextLine = false;
856
4.25k
    if (Changes[i].NewlinesBefore == 1) { // A comment on its own line.
857
1.63k
      unsigned CommentColumn = SourceMgr.getSpellingColumnNumber(
858
1.63k
          Changes[i].OriginalWhitespaceRange.getEnd());
859
6.57k
      for (unsigned j = i + 1; j != e; 
++j4.93k
) {
860
6.57k
        if (Changes[j].Tok->is(tok::comment))
861
4.93k
          continue;
862
863
1.63k
        unsigned NextColumn = SourceMgr.getSpellingColumnNumber(
864
1.63k
            Changes[j].OriginalWhitespaceRange.getEnd());
865
        // The start of the next token was previously aligned with the
866
        // start of this comment.
867
1.63k
        WasAlignedWithStartOfNextLine =
868
1.63k
            CommentColumn == NextColumn ||
869
1.63k
            
CommentColumn == NextColumn + Style.IndentWidth767
;
870
1.63k
        break;
871
6.57k
      }
872
1.63k
    }
873
4.25k
    if (!Style.AlignTrailingComments || 
FollowsRBraceInColumn04.16k
) {
874
439
      alignTrailingComments(StartOfSequence, i, MinColumn);
875
439
      MinColumn = ChangeMinColumn;
876
439
      MaxColumn = ChangeMinColumn;
877
439
      StartOfSequence = i;
878
3.81k
    } else if (BreakBeforeNext || 
Newlines > 12.79k
||
879
3.81k
               
(1.93k
ChangeMinColumn > MaxColumn1.93k
||
ChangeMaxColumn < MinColumn1.92k
) ||
880
               // Break the comment sequence if the previous line did not end
881
               // in a trailing comment.
882
3.81k
               
(1.91k
Changes[i].NewlinesBefore == 11.91k
&&
i > 0484
&&
883
1.91k
                
!Changes[i - 1].IsTrailingComment471
) ||
884
3.81k
               
WasAlignedWithStartOfNextLine1.56k
) {
885
2.31k
      alignTrailingComments(StartOfSequence, i, MinColumn);
886
2.31k
      MinColumn = ChangeMinColumn;
887
2.31k
      MaxColumn = ChangeMaxColumn;
888
2.31k
      StartOfSequence = i;
889
2.31k
    } else {
890
1.50k
      MinColumn = std::max(MinColumn, ChangeMinColumn);
891
1.50k
      MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
892
1.50k
    }
893
4.25k
    BreakBeforeNext = (i == 0) || 
(Changes[i].NewlinesBefore > 1)3.82k
||
894
                      // Never start a sequence with a comment at the beginning
895
                      // of the line.
896
4.25k
                      
(3.66k
Changes[i].NewlinesBefore == 13.66k
&&
StartOfSequence == i1.62k
);
897
4.25k
    Newlines = 0;
898
4.25k
  }
899
17.7k
  alignTrailingComments(StartOfSequence, Changes.size(), MinColumn);
900
17.7k
}
901
902
void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
903
20.5k
                                              unsigned Column) {
904
317k
  for (unsigned i = Start; i != End; 
++i297k
) {
905
297k
    int Shift = 0;
906
297k
    if (Changes[i].IsTrailingComment) {
907
4.75k
      Shift = Column - Changes[i].StartOfTokenColumn;
908
4.75k
    }
909
297k
    if (Changes[i].StartOfBlockComment) {
910
558
      Shift = Changes[i].IndentationOffset +
911
558
              Changes[i].StartOfBlockComment->StartOfTokenColumn -
912
558
              Changes[i].StartOfTokenColumn;
913
558
    }
914
297k
    assert(Shift >= 0);
915
0
    Changes[i].Spaces += Shift;
916
297k
    if (i + 1 != Changes.size())
917
279k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
918
297k
    Changes[i].StartOfTokenColumn += Shift;
919
297k
  }
920
20.5k
}
921
922
17.7k
void WhitespaceManager::alignEscapedNewlines() {
923
17.7k
  if (Style.AlignEscapedNewlines == FormatStyle::ENAS_DontAlign)
924
10
    return;
925
926
17.7k
  bool AlignLeft = Style.AlignEscapedNewlines == FormatStyle::ENAS_Left;
927
17.7k
  unsigned MaxEndOfLine = AlignLeft ? 
03.70k
:
Style.ColumnLimit14.0k
;
928
17.7k
  unsigned StartOfMacro = 0;
929
297k
  for (unsigned i = 1, e = Changes.size(); i < e; 
++i279k
) {
930
279k
    Change &C = Changes[i];
931
279k
    if (C.NewlinesBefore > 0) {
932
40.6k
      if (C.ContinuesPPDirective) {
933
624
        MaxEndOfLine = std::max(C.PreviousEndOfTokenColumn + 2, MaxEndOfLine);
934
40.0k
      } else {
935
40.0k
        alignEscapedNewlines(StartOfMacro + 1, i, MaxEndOfLine);
936
40.0k
        MaxEndOfLine = AlignLeft ? 
07.62k
:
Style.ColumnLimit32.4k
;
937
40.0k
        StartOfMacro = i;
938
40.0k
      }
939
40.6k
    }
940
279k
  }
941
17.7k
  alignEscapedNewlines(StartOfMacro + 1, Changes.size(), MaxEndOfLine);
942
17.7k
}
943
944
void WhitespaceManager::alignEscapedNewlines(unsigned Start, unsigned End,
945
57.8k
                                             unsigned Column) {
946
297k
  for (unsigned i = Start; i < End; 
++i239k
) {
947
239k
    Change &C = Changes[i];
948
239k
    if (C.NewlinesBefore > 0) {
949
624
      assert(C.ContinuesPPDirective);
950
624
      if (C.PreviousEndOfTokenColumn + 1 > Column)
951
0
        C.EscapedNewlineColumn = 0;
952
624
      else
953
624
        C.EscapedNewlineColumn = Column;
954
624
    }
955
239k
  }
956
57.8k
}
957
958
17.7k
void WhitespaceManager::alignArrayInitializers() {
959
17.7k
  if (Style.AlignArrayOfStructures == FormatStyle::AIAS_None)
960
17.6k
    return;
961
962
105
  for (unsigned ChangeIndex = 1U, ChangeEnd = Changes.size();
963
1.11k
       ChangeIndex < ChangeEnd; 
++ChangeIndex1.01k
) {
964
1.01k
    auto &C = Changes[ChangeIndex];
965
1.01k
    if (C.Tok->IsArrayInitializer) {
966
117
      bool FoundComplete = false;
967
3.31k
      for (unsigned InsideIndex = ChangeIndex + 1; InsideIndex < ChangeEnd;
968
3.31k
           
++InsideIndex3.20k
) {
969
3.31k
        if (Changes[InsideIndex].Tok == C.Tok->MatchingParen) {
970
117
          alignArrayInitializers(ChangeIndex, InsideIndex + 1);
971
117
          ChangeIndex = InsideIndex + 1;
972
117
          FoundComplete = true;
973
117
          break;
974
117
        }
975
3.31k
      }
976
117
      if (!FoundComplete)
977
0
        ChangeIndex = ChangeEnd;
978
117
    }
979
1.01k
  }
980
105
}
981
982
117
void WhitespaceManager::alignArrayInitializers(unsigned Start, unsigned End) {
983
984
117
  if (Style.AlignArrayOfStructures == FormatStyle::AIAS_Right)
985
65
    alignArrayInitializersRightJustified(getCells(Start, End));
986
52
  else if (Style.AlignArrayOfStructures == FormatStyle::AIAS_Left)
987
52
    alignArrayInitializersLeftJustified(getCells(Start, End));
988
117
}
989
990
void WhitespaceManager::alignArrayInitializersRightJustified(
991
65
    CellDescriptions &&CellDescs) {
992
65
  auto &Cells = CellDescs.Cells;
993
994
  // Now go through and fixup the spaces.
995
65
  auto *CellIter = Cells.begin();
996
327
  for (auto i = 0U; i < CellDescs.CellCount; 
i++, ++CellIter262
) {
997
262
    unsigned NetWidth = 0U;
998
262
    if (isSplitCell(*CellIter))
999
13
      NetWidth = getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
1000
262
    auto CellWidth = getMaximumCellWidth(CellIter, NetWidth);
1001
1002
262
    if (Changes[CellIter->Index].Tok->is(tok::r_brace)) {
1003
      // So in here we want to see if there is a brace that falls
1004
      // on a line that was split. If so on that line we make sure that
1005
      // the spaces in front of the brace are enough.
1006
65
      Changes[CellIter->Index].NewlinesBefore = 0;
1007
65
      Changes[CellIter->Index].Spaces = 0;
1008
186
      for (const auto *Next = CellIter->NextColumnElement; Next != nullptr;
1009
121
           Next = Next->NextColumnElement) {
1010
121
        Changes[Next->Index].Spaces = 0;
1011
121
        Changes[Next->Index].NewlinesBefore = 0;
1012
121
      }
1013
      // Unless the array is empty, we need the position of all the
1014
      // immediately adjacent cells
1015
65
      if (CellIter != Cells.begin()) {
1016
65
        auto ThisNetWidth =
1017
65
            getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
1018
65
        auto MaxNetWidth =
1019
65
            getMaximumNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces,
1020
65
                               CellDescs.CellCount);
1021
65
        if (ThisNetWidth < MaxNetWidth)
1022
1
          Changes[CellIter->Index].Spaces = (MaxNetWidth - ThisNetWidth);
1023
65
        auto RowCount = 1U;
1024
65
        auto Offset = std::distance(Cells.begin(), CellIter);
1025
186
        for (const auto *Next = CellIter->NextColumnElement; Next != nullptr;
1026
121
             Next = Next->NextColumnElement) {
1027
121
          auto *Start = (Cells.begin() + RowCount * CellDescs.CellCount);
1028
121
          auto *End = Start + Offset;
1029
121
          ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
1030
121
          if (ThisNetWidth < MaxNetWidth)
1031
1
            Changes[Next->Index].Spaces = (MaxNetWidth - ThisNetWidth);
1032
121
          ++RowCount;
1033
121
        }
1034
65
      }
1035
197
    } else {
1036
197
      auto ThisWidth =
1037
197
          calculateCellWidth(CellIter->Index, CellIter->EndIndex, true) +
1038
197
          NetWidth;
1039
197
      if (Changes[CellIter->Index].NewlinesBefore == 0) {
1040
184
        Changes[CellIter->Index].Spaces = (CellWidth - (ThisWidth + NetWidth));
1041
184
        Changes[CellIter->Index].Spaces += (i > 0) ? 
1120
:
064
;
1042
184
      }
1043
197
      alignToStartOfCell(CellIter->Index, CellIter->EndIndex);
1044
582
      for (const auto *Next = CellIter->NextColumnElement; Next != nullptr;
1045
385
           Next = Next->NextColumnElement) {
1046
385
        ThisWidth =
1047
385
            calculateCellWidth(Next->Index, Next->EndIndex, true) + NetWidth;
1048
385
        if (Changes[Next->Index].NewlinesBefore == 0) {
1049
383
          Changes[Next->Index].Spaces = (CellWidth - ThisWidth);
1050
383
          Changes[Next->Index].Spaces += (i > 0) ? 
1262
:
0121
;
1051
383
        }
1052
385
        alignToStartOfCell(Next->Index, Next->EndIndex);
1053
385
      }
1054
197
    }
1055
262
  }
1056
65
}
1057
1058
void WhitespaceManager::alignArrayInitializersLeftJustified(
1059
52
    CellDescriptions &&CellDescs) {
1060
52
  auto &Cells = CellDescs.Cells;
1061
1062
  // Now go through and fixup the spaces.
1063
52
  auto *CellIter = Cells.begin();
1064
  // The first cell needs to be against the left brace.
1065
52
  if (Changes[CellIter->Index].NewlinesBefore == 0)
1066
51
    Changes[CellIter->Index].Spaces = 0;
1067
1
  else
1068
1
    Changes[CellIter->Index].Spaces = CellDescs.InitialSpaces;
1069
52
  ++CellIter;
1070
210
  for (auto i = 1U; i < CellDescs.CellCount; 
i++, ++CellIter158
) {
1071
158
    auto MaxNetWidth = getMaximumNetWidth(
1072
158
        Cells.begin(), CellIter, CellDescs.InitialSpaces, CellDescs.CellCount);
1073
158
    auto ThisNetWidth =
1074
158
        getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
1075
158
    if (Changes[CellIter->Index].NewlinesBefore == 0) {
1076
150
      Changes[CellIter->Index].Spaces =
1077
150
          MaxNetWidth - ThisNetWidth +
1078
150
          (Changes[CellIter->Index].Tok->isNot(tok::r_brace) ? 
198
:
052
);
1079
150
    }
1080
158
    auto RowCount = 1U;
1081
158
    auto Offset = std::distance(Cells.begin(), CellIter);
1082
465
    for (const auto *Next = CellIter->NextColumnElement; Next != nullptr;
1083
307
         Next = Next->NextColumnElement) {
1084
307
      auto *Start = (Cells.begin() + RowCount * CellDescs.CellCount);
1085
307
      auto *End = Start + Offset;
1086
307
      auto ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
1087
307
      if (Changes[Next->Index].NewlinesBefore == 0) {
1088
305
        Changes[Next->Index].Spaces =
1089
305
            MaxNetWidth - ThisNetWidth +
1090
305
            (Changes[Next->Index].Tok->isNot(tok::r_brace) ? 
1207
:
098
);
1091
305
      }
1092
307
      ++RowCount;
1093
307
    }
1094
158
  }
1095
52
}
1096
1097
262
bool WhitespaceManager::isSplitCell(const CellDescription &Cell) {
1098
262
  if (Cell.HasSplit)
1099
13
    return true;
1100
741
  
for (const auto *Next = Cell.NextColumnElement; 249
Next != nullptr;
1101
492
       Next = Next->NextColumnElement) {
1102
492
    if (Next->HasSplit)
1103
0
      return true;
1104
492
  }
1105
249
  return false;
1106
249
}
1107
1108
WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
1109
117
                                                                unsigned End) {
1110
1111
117
  unsigned Depth = 0;
1112
117
  unsigned Cell = 0;
1113
117
  unsigned CellCount = 0;
1114
117
  unsigned InitialSpaces = 0;
1115
117
  unsigned InitialTokenLength = 0;
1116
117
  unsigned EndSpaces = 0;
1117
117
  SmallVector<CellDescription> Cells;
1118
117
  const FormatToken *MatchingParen = nullptr;
1119
3.52k
  for (unsigned i = Start; i < End; 
++i3.40k
) {
1120
3.40k
    auto &C = Changes[i];
1121
3.40k
    if (C.Tok->is(tok::l_brace))
1122
513
      ++Depth;
1123
2.89k
    else if (C.Tok->is(tok::r_brace))
1124
513
      --Depth;
1125
3.40k
    if (Depth == 2) {
1126
2.22k
      if (C.Tok->is(tok::l_brace)) {
1127
336
        Cell = 0;
1128
336
        MatchingParen = C.Tok->MatchingParen;
1129
336
        if (InitialSpaces == 0) {
1130
117
          InitialSpaces = C.Spaces + C.TokenLength;
1131
117
          InitialTokenLength = C.TokenLength;
1132
117
          auto j = i - 1;
1133
117
          for (; Changes[j].NewlinesBefore == 0 && 
j > Start109
;
--j0
) {
1134
0
            InitialSpaces += Changes[j].Spaces + Changes[j].TokenLength;
1135
0
            InitialTokenLength += Changes[j].TokenLength;
1136
0
          }
1137
117
          if (C.NewlinesBefore == 0) {
1138
8
            InitialSpaces += Changes[j].Spaces + Changes[j].TokenLength;
1139
8
            InitialTokenLength += Changes[j].TokenLength;
1140
8
          }
1141
117
        }
1142
1.89k
      } else if (C.Tok->is(tok::comma)) {
1143
711
        if (!Cells.empty())
1144
711
          Cells.back().EndIndex = i;
1145
711
        Cell++;
1146
711
      }
1147
2.22k
    } else 
if (1.17k
Depth == 11.17k
) {
1148
802
      if (C.Tok == MatchingParen) {
1149
336
        if (!Cells.empty())
1150
336
          Cells.back().EndIndex = i;
1151
336
        Cells.push_back(CellDescription{i, ++Cell, i + 1, false, nullptr});
1152
336
        CellCount = Cell + 1;
1153
        // Go to the next non-comment and ensure there is a break in front
1154
336
        const auto *NextNonComment = C.Tok->getNextNonComment();
1155
577
        while (NextNonComment->is(tok::comma))
1156
241
          NextNonComment = NextNonComment->getNextNonComment();
1157
336
        auto j = i;
1158
997
        while (Changes[j].Tok != NextNonComment && 
j < End661
)
1159
661
          j++;
1160
336
        if (j < End && Changes[j].NewlinesBefore == 0 &&
1161
336
            
Changes[j].Tok->isNot(tok::r_brace)157
) {
1162
86
          Changes[j].NewlinesBefore = 1;
1163
          // Account for the added token lengths
1164
86
          Changes[j].Spaces = InitialSpaces - InitialTokenLength;
1165
86
        }
1166
466
      } else if (C.Tok->is(tok::comment)) {
1167
        // Trailing comments stay at a space past the last token
1168
54
        C.Spaces = Changes[i - 1].Tok->is(tok::comma) ? 
130
:
224
;
1169
412
      } else if (C.Tok->is(tok::l_brace)) {
1170
        // We need to make sure that the ending braces is aligned to the
1171
        // start of our initializer
1172
117
        auto j = i - 1;
1173
698
        for (; j > 0 && 
!Changes[j].Tok->ArrayInitializerLineStart595
;
--j581
)
1174
581
          ; // Nothing the loop does the work
1175
117
        EndSpaces = Changes[j].Spaces;
1176
117
      }
1177
802
    } else 
if (375
Depth == 0375
&&
C.Tok->is(tok::r_brace)117
) {
1178
117
      C.NewlinesBefore = 1;
1179
117
      C.Spaces = EndSpaces;
1180
117
    }
1181
3.40k
    if (C.Tok->StartsColumn) {
1182
      // This gets us past tokens that have been split over multiple
1183
      // lines
1184
1.04k
      bool HasSplit = false;
1185
1.04k
      if (Changes[i].NewlinesBefore > 0) {
1186
        // So if we split a line previously and the tail line + this token is
1187
        // less then the column limit we remove the split here and just put
1188
        // the column start at a space past the comma
1189
27
        auto j = i - 1;
1190
27
        if ((j - 1) > Start && Changes[j].Tok->is(tok::comma) &&
1191
27
            
Changes[j - 1].NewlinesBefore > 025
) {
1192
1
          --j;
1193
1
          auto LineLimit = Changes[j].Spaces + Changes[j].TokenLength;
1194
1
          if (LineLimit < Style.ColumnLimit) {
1195
1
            Changes[i].NewlinesBefore = 0;
1196
1
            Changes[i].Spaces = 1;
1197
1
          }
1198
1
        }
1199
27
      }
1200
1.10k
      while (Changes[i].NewlinesBefore > 0 && 
Changes[i].Tok == C.Tok61
) {
1201
55
        Changes[i].Spaces = InitialSpaces;
1202
55
        ++i;
1203
55
        HasSplit = true;
1204
55
      }
1205
1.04k
      if (Changes[i].Tok != C.Tok)
1206
26
        --i;
1207
1.04k
      Cells.push_back(CellDescription{i, Cell, i, HasSplit, nullptr});
1208
1.04k
    }
1209
3.40k
  }
1210
1211
117
  return linkCells({Cells, CellCount, InitialSpaces});
1212
117
}
1213
1214
unsigned WhitespaceManager::calculateCellWidth(unsigned Start, unsigned End,
1215
4.45k
                                               bool WithSpaces) const {
1216
4.45k
  unsigned CellWidth = 0;
1217
10.5k
  for (auto i = Start; i < End; 
i++6.13k
) {
1218
6.13k
    if (Changes[i].NewlinesBefore > 0)
1219
105
      CellWidth = 0;
1220
6.13k
    CellWidth += Changes[i].TokenLength;
1221
6.13k
    CellWidth += (WithSpaces ? Changes[i].Spaces : 
00
);
1222
6.13k
  }
1223
4.45k
  return CellWidth;
1224
4.45k
}
1225
1226
582
void WhitespaceManager::alignToStartOfCell(unsigned Start, unsigned End) {
1227
582
  if ((End - Start) <= 1)
1228
486
    return;
1229
  // If the line is broken anywhere in there make sure everything
1230
  // is aligned to the parent
1231
321
  
for (auto i = Start + 1; 96
i < End;
i++225
) {
1232
225
    if (Changes[i].NewlinesBefore > 0)
1233
3
      Changes[i].Spaces = Changes[Start].Spaces;
1234
225
  }
1235
96
}
1236
1237
WhitespaceManager::CellDescriptions
1238
117
WhitespaceManager::linkCells(CellDescriptions &&CellDesc) {
1239
117
  auto &Cells = CellDesc.Cells;
1240
1.50k
  for (auto *CellIter = Cells.begin(); CellIter != Cells.end(); 
++CellIter1.38k
) {
1241
1.38k
    if (CellIter->NextColumnElement == nullptr &&
1242
1.38k
        ((CellIter + 1) != Cells.end())) {
1243
4.90k
      for (auto *NextIter = CellIter + 1; NextIter != Cells.end(); 
++NextIter3.63k
) {
1244
4.54k
        if (NextIter->Cell == CellIter->Cell) {
1245
911
          CellIter->NextColumnElement = &(*NextIter);
1246
911
          break;
1247
911
        }
1248
4.54k
      }
1249
1.26k
    }
1250
1.38k
  }
1251
117
  return std::move(CellDesc);
1252
117
}
1253
1254
17.7k
void WhitespaceManager::generateChanges() {
1255
315k
  for (unsigned i = 0, e = Changes.size(); i != e; 
++i297k
) {
1256
297k
    const Change &C = Changes[i];
1257
297k
    if (i > 0) {
1258
279k
      assert(Changes[i - 1].OriginalWhitespaceRange.getBegin() !=
1259
279k
                 C.OriginalWhitespaceRange.getBegin() &&
1260
279k
             "Generating two replacements for the same location");
1261
279k
    }
1262
297k
    if (C.CreateReplacement) {
1263
273k
      std::string ReplacementText = C.PreviousLinePostfix;
1264
273k
      if (C.ContinuesPPDirective)
1265
605
        appendEscapedNewlineText(ReplacementText, C.NewlinesBefore,
1266
605
                                 C.PreviousEndOfTokenColumn,
1267
605
                                 C.EscapedNewlineColumn);
1268
272k
      else
1269
272k
        appendNewlineText(ReplacementText, C.NewlinesBefore);
1270
273k
      appendIndentText(
1271
273k
          ReplacementText, C.Tok->IndentLevel, std::max(0, C.Spaces),
1272
273k
          C.StartOfTokenColumn - std::max(0, C.Spaces), C.IsAligned);
1273
273k
      ReplacementText.append(C.CurrentLinePrefix);
1274
273k
      storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
1275
273k
    }
1276
297k
  }
1277
17.7k
}
1278
1279
273k
void WhitespaceManager::storeReplacement(SourceRange Range, StringRef Text) {
1280
273k
  unsigned WhitespaceLength = SourceMgr.getFileOffset(Range.getEnd()) -
1281
273k
                              SourceMgr.getFileOffset(Range.getBegin());
1282
  // Don't create a replacement, if it does not change anything.
1283
273k
  if (StringRef(SourceMgr.getCharacterData(Range.getBegin()),
1284
273k
                WhitespaceLength) == Text)
1285
249k
    return;
1286
24.1k
  auto Err = Replaces.add(tooling::Replacement(
1287
24.1k
      SourceMgr, CharSourceRange::getCharRange(Range), Text));
1288
  // FIXME: better error handling. For now, just print an error message in the
1289
  // release version.
1290
24.1k
  if (Err) {
1291
0
    llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1292
0
    assert(false);
1293
0
  }
1294
24.1k
}
1295
1296
void WhitespaceManager::appendNewlineText(std::string &Text,
1297
272k
                                          unsigned Newlines) {
1298
309k
  for (unsigned i = 0; i < Newlines; 
++i36.9k
)
1299
36.9k
    Text.append(UseCRLF ? 
"\r\n"67
:
"\n"36.8k
);
1300
272k
}
1301
1302
void WhitespaceManager::appendEscapedNewlineText(
1303
    std::string &Text, unsigned Newlines, unsigned PreviousEndOfTokenColumn,
1304
605
    unsigned EscapedNewlineColumn) {
1305
605
  if (Newlines > 0) {
1306
602
    unsigned Spaces =
1307
602
        std::max<int>(1, EscapedNewlineColumn - PreviousEndOfTokenColumn - 1);
1308
1.20k
    for (unsigned i = 0; i < Newlines; 
++i607
) {
1309
607
      Text.append(Spaces, ' ');
1310
607
      Text.append(UseCRLF ? 
"\\\r\n"7
:
"\\\n"600
);
1311
607
      Spaces = std::max<int>(0, EscapedNewlineColumn - 1);
1312
607
    }
1313
602
  }
1314
605
}
1315
1316
void WhitespaceManager::appendIndentText(std::string &Text,
1317
                                         unsigned IndentLevel, unsigned Spaces,
1318
                                         unsigned WhitespaceStartColumn,
1319
273k
                                         bool IsAligned) {
1320
273k
  switch (Style.UseTab) {
1321
270k
  case FormatStyle::UT_Never:
1322
270k
    Text.append(Spaces, ' ');
1323
270k
    break;
1324
481
  case FormatStyle::UT_Always: {
1325
481
    if (Style.TabWidth) {
1326
463
      unsigned FirstTabWidth =
1327
463
          Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
1328
1329
      // Insert only spaces when we want to end up before the next tab.
1330
463
      if (Spaces < FirstTabWidth || 
Spaces == 1116
) {
1331
368
        Text.append(Spaces, ' ');
1332
368
        break;
1333
368
      }
1334
      // Align to the next tab.
1335
95
      Spaces -= FirstTabWidth;
1336
95
      Text.append("\t");
1337
1338
95
      Text.append(Spaces / Style.TabWidth, '\t');
1339
95
      Text.append(Spaces % Style.TabWidth, ' ');
1340
95
    } else 
if (18
Spaces == 118
) {
1341
2
      Text.append(Spaces, ' ');
1342
2
    }
1343
113
    break;
1344
481
  }
1345
304
  case FormatStyle::UT_ForIndentation:
1346
304
    if (WhitespaceStartColumn == 0) {
1347
144
      unsigned Indentation = IndentLevel * Style.IndentWidth;
1348
144
      Spaces = appendTabIndent(Text, Spaces, Indentation);
1349
144
    }
1350
304
    Text.append(Spaces, ' ');
1351
304
    break;
1352
738
  case FormatStyle::UT_ForContinuationAndIndentation:
1353
738
    if (WhitespaceStartColumn == 0)
1354
319
      Spaces = appendTabIndent(Text, Spaces, Spaces);
1355
738
    Text.append(Spaces, ' ');
1356
738
    break;
1357
840
  case FormatStyle::UT_AlignWithSpaces:
1358
840
    if (WhitespaceStartColumn == 0) {
1359
358
      unsigned Indentation =
1360
358
          IsAligned ? 
IndentLevel * Style.IndentWidth57
:
Spaces301
;
1361
358
      Spaces = appendTabIndent(Text, Spaces, Indentation);
1362
358
    }
1363
840
    Text.append(Spaces, ' ');
1364
840
    break;
1365
273k
  }
1366
273k
}
1367
1368
unsigned WhitespaceManager::appendTabIndent(std::string &Text, unsigned Spaces,
1369
821
                                            unsigned Indentation) {
1370
  // This happens, e.g. when a line in a block comment is indented less than the
1371
  // first one.
1372
821
  if (Indentation > Spaces)
1373
4
    Indentation = Spaces;
1374
821
  if (Style.TabWidth) {
1375
797
    unsigned Tabs = Indentation / Style.TabWidth;
1376
797
    Text.append(Tabs, '\t');
1377
797
    Spaces -= Tabs * Style.TabWidth;
1378
797
  }
1379
821
  return Spaces;
1380
821
}
1381
1382
} // namespace format
1383
} // namespace clang