Coverage Report

Created: 2020-09-15 12:33

/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
17
namespace clang {
18
namespace format {
19
20
bool WhitespaceManager::Change::IsBeforeInFile::operator()(
21
520k
    const Change &C1, const Change &C2) const {
22
520k
  return SourceMgr.isBeforeInTranslationUnit(
23
520k
      C1.OriginalWhitespaceRange.getBegin(),
24
520k
      C2.OriginalWhitespaceRange.getBegin());
25
520k
}
26
27
WhitespaceManager::Change::Change(const FormatToken &Tok,
28
                                  bool CreateReplacement,
29
                                  SourceRange OriginalWhitespaceRange,
30
                                  int Spaces, unsigned StartOfTokenColumn,
31
                                  unsigned NewlinesBefore,
32
                                  StringRef PreviousLinePostfix,
33
                                  StringRef CurrentLinePrefix, bool IsAligned,
34
                                  bool ContinuesPPDirective, bool IsInsideToken)
35
    : Tok(&Tok), CreateReplacement(CreateReplacement),
36
      OriginalWhitespaceRange(OriginalWhitespaceRange),
37
      StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
38
      PreviousLinePostfix(PreviousLinePostfix),
39
      CurrentLinePrefix(CurrentLinePrefix), IsAligned(IsAligned),
40
      ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces),
41
      IsInsideToken(IsInsideToken), IsTrailingComment(false), TokenLength(0),
42
      PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
43
265k
      StartOfBlockComment(nullptr), IndentationOffset(0), ConditionalsLevel(0) {
44
265k
}
45
46
void WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines,
47
                                          unsigned Spaces,
48
                                          unsigned StartOfTokenColumn,
49
242k
                                          bool IsAligned, bool InPPDirective) {
50
242k
  if (Tok.Finalized)
51
2.46k
    return;
52
240k
  Tok.setDecision((Newlines > 0) ? 
FD_Break30.2k
:
FD_Continue209k
);
53
240k
  Changes.push_back(Change(Tok, /*CreateReplacement=*/true, Tok.WhitespaceRange,
54
240k
                           Spaces, StartOfTokenColumn, Newlines, "", "",
55
240k
                           IsAligned, InPPDirective && 
!Tok.IsFirst1.68k
,
56
240k
                           /*IsInsideToken=*/false));
57
240k
}
58
59
void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
60
24.0k
                                            bool InPPDirective) {
61
24.0k
  if (Tok.Finalized)
62
24
    return;
63
24.0k
  Changes.push_back(Change(Tok, /*CreateReplacement=*/false,
64
24.0k
                           Tok.WhitespaceRange, /*Spaces=*/0,
65
24.0k
                           Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
66
24.0k
                           /*IsAligned=*/false, InPPDirective && 
!Tok.IsFirst1.86k
,
67
24.0k
                           /*IsInsideToken=*/false));
68
24.0k
}
69
70
llvm::Error
71
193
WhitespaceManager::addReplacement(const tooling::Replacement &Replacement) {
72
193
  return Replaces.add(Replacement);
73
193
}
74
75
void WhitespaceManager::replaceWhitespaceInToken(
76
    const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
77
    StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
78
1.15k
    unsigned Newlines, int Spaces) {
79
1.15k
  if (Tok.Finalized)
80
4
    return;
81
1.14k
  SourceLocation Start = Tok.getStartOfNonWhitespace().getLocWithOffset(Offset);
82
1.14k
  Changes.push_back(
83
1.14k
      Change(Tok, /*CreateReplacement=*/true,
84
1.14k
             SourceRange(Start, Start.getLocWithOffset(ReplaceChars)), Spaces,
85
1.14k
             std::max(0, Spaces), Newlines, PreviousPostfix, CurrentPrefix,
86
1.14k
             /*IsAligned=*/true, InPPDirective && 
!Tok.IsFirst21
,
87
1.14k
             /*IsInsideToken=*/true));
88
1.14k
}
89
90
16.3k
const tooling::Replacements &WhitespaceManager::generateReplacements() {
91
16.3k
  if (Changes.empty())
92
40
    return Replaces;
93
16.3k
94
16.3k
  llvm::sort(Changes, Change::IsBeforeInFile(SourceMgr));
95
16.3k
  calculateLineBreakInformation();
96
16.3k
  alignConsecutiveMacros();
97
16.3k
  alignConsecutiveDeclarations();
98
16.3k
  alignConsecutiveBitFields();
99
16.3k
  alignConsecutiveAssignments();
100
16.3k
  alignChainedConditionals();
101
16.3k
  alignTrailingComments();
102
16.3k
  alignEscapedNewlines();
103
16.3k
  generateChanges();
104
16.3k
105
16.3k
  return Replaces;
106
16.3k
}
107
108
16.3k
void WhitespaceManager::calculateLineBreakInformation() {
109
16.3k
  Changes[0].PreviousEndOfTokenColumn = 0;
110
16.3k
  Change *LastOutsideTokenChange = &Changes[0];
111
265k
  for (unsigned i = 1, e = Changes.size(); i != e; 
++i249k
) {
112
249k
    SourceLocation OriginalWhitespaceStart =
113
249k
        Changes[i].OriginalWhitespaceRange.getBegin();
114
249k
    SourceLocation PreviousOriginalWhitespaceEnd =
115
249k
        Changes[i - 1].OriginalWhitespaceRange.getEnd();
116
249k
    unsigned OriginalWhitespaceStartOffset =
117
249k
        SourceMgr.getFileOffset(OriginalWhitespaceStart);
118
249k
    unsigned PreviousOriginalWhitespaceEndOffset =
119
249k
        SourceMgr.getFileOffset(PreviousOriginalWhitespaceEnd);
120
249k
    assert(PreviousOriginalWhitespaceEndOffset <=
121
249k
           OriginalWhitespaceStartOffset);
122
249k
    const char *const PreviousOriginalWhitespaceEndData =
123
249k
        SourceMgr.getCharacterData(PreviousOriginalWhitespaceEnd);
124
249k
    StringRef Text(PreviousOriginalWhitespaceEndData,
125
249k
                   SourceMgr.getCharacterData(OriginalWhitespaceStart) -
126
249k
                       PreviousOriginalWhitespaceEndData);
127
    // Usually consecutive changes would occur in consecutive tokens. This is
128
    // not the case however when analyzing some preprocessor runs of the
129
    // annotated lines. For example, in this code:
130
    //
131
    // #if A // line 1
132
    // int i = 1;
133
    // #else B // line 2
134
    // int i = 2;
135
    // #endif // line 3
136
    //
137
    // one of the runs will produce the sequence of lines marked with line 1, 2
138
    // and 3. So the two consecutive whitespace changes just before '// line 2'
139
    // and before '#endif // line 3' span multiple lines and tokens:
140
    //
141
    // #else B{change X}[// line 2
142
    // int i = 2;
143
    // ]{change Y}#endif // line 3
144
    //
145
    // For this reason, if the text between consecutive changes spans multiple
146
    // newlines, the token length must be adjusted to the end of the original
147
    // line of the token.
148
249k
    auto NewlinePos = Text.find_first_of('\n');
149
249k
    if (NewlinePos == StringRef::npos) {
150
248k
      Changes[i - 1].TokenLength = OriginalWhitespaceStartOffset -
151
248k
                                   PreviousOriginalWhitespaceEndOffset +
152
248k
                                   Changes[i].PreviousLinePostfix.size() +
153
248k
                                   Changes[i - 1].CurrentLinePrefix.size();
154
183
    } else {
155
183
      Changes[i - 1].TokenLength =
156
183
          NewlinePos + Changes[i - 1].CurrentLinePrefix.size();
157
183
    }
158
249k
159
    // If there are multiple changes in this token, sum up all the changes until
160
    // the end of the line.
161
249k
    if (Changes[i - 1].IsInsideToken && 
Changes[i - 1].NewlinesBefore == 01.14k
)
162
250
      LastOutsideTokenChange->TokenLength +=
163
250
          Changes[i - 1].TokenLength + Changes[i - 1].Spaces;
164
248k
    else
165
248k
      LastOutsideTokenChange = &Changes[i - 1];
166
249k
167
249k
    Changes[i].PreviousEndOfTokenColumn =
168
249k
        Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength;
169
249k
170
249k
    Changes[i - 1].IsTrailingComment =
171
249k
        (Changes[i].NewlinesBefore > 0 || 
Changes[i].Tok->is(tok::eof)213k
||
172
198k
         (Changes[i].IsInsideToken && 
Changes[i].Tok->is(tok::comment)250
)) &&
173
50.5k
        Changes[i - 1].Tok->is(tok::comment) &&
174
        // FIXME: This is a dirty hack. The problem is that
175
        // BreakableLineCommentSection does comment reflow changes and here is
176
        // the aligning of trailing comments. Consider the case where we reflow
177
        // the second line up in this example:
178
        //
179
        // // line 1
180
        // // line 2
181
        //
182
        // That amounts to 2 changes by BreakableLineCommentSection:
183
        //  - the first, delimited by (), for the whitespace between the tokens,
184
        //  - and second, delimited by [], for the whitespace at the beginning
185
        //  of the second token:
186
        //
187
        // // line 1(
188
        // )[// ]line 2
189
        //
190
        // So in the end we have two changes like this:
191
        //
192
        // // line1()[ ]line 2
193
        //
194
        // Note that the OriginalWhitespaceStart of the second change is the
195
        // same as the PreviousOriginalWhitespaceEnd of the first change.
196
        // In this case, the below check ensures that the second change doesn't
197
        // get treated as a trailing comment change here, since this might
198
        // trigger additional whitespace to be wrongly inserted before "line 2"
199
        // by the comment aligner here.
200
        //
201
        // For a proper solution we need a mechanism to say to WhitespaceManager
202
        // that a particular change breaks the current sequence of trailing
203
        // comments.
204
4.43k
        OriginalWhitespaceStart != PreviousOriginalWhitespaceEnd;
205
249k
  }
206
  // FIXME: The last token is currently not always an eof token; in those
207
  // cases, setting TokenLength of the last token to 0 is wrong.
208
16.3k
  Changes.back().TokenLength = 0;
209
16.3k
  Changes.back().IsTrailingComment = Changes.back().Tok->is(tok::comment);
210
16.3k
211
16.3k
  const WhitespaceManager::Change *LastBlockComment = nullptr;
212
265k
  for (auto &Change : Changes) {
213
    // Reset the IsTrailingComment flag for changes inside of trailing comments
214
    // so they don't get realigned later. Comment line breaks however still need
215
    // to be aligned.
216
265k
    if (Change.IsInsideToken && 
Change.NewlinesBefore == 01.14k
)
217
250
      Change.IsTrailingComment = false;
218
265k
    Change.StartOfBlockComment = nullptr;
219
265k
    Change.IndentationOffset = 0;
220
265k
    if (Change.Tok->is(tok::comment)) {
221
4.84k
      if (Change.Tok->is(TT_LineComment) || 
!Change.IsInsideToken1.13k
)
222
4.32k
        LastBlockComment = &Change;
223
518
      else {
224
518
        if ((Change.StartOfBlockComment = LastBlockComment))
225
518
          Change.IndentationOffset =
226
518
              Change.StartOfTokenColumn -
227
518
              Change.StartOfBlockComment->StartOfTokenColumn;
228
518
      }
229
260k
    } else {
230
260k
      LastBlockComment = nullptr;
231
260k
    }
232
265k
  }
233
16.3k
234
  // Compute conditional nesting level
235
  // Level is increased for each conditional, unless this conditional continues
236
  // a chain of conditional, i.e. starts immediately after the colon of another
237
  // conditional.
238
16.3k
  SmallVector<bool, 16> ScopeStack;
239
16.3k
  int ConditionalsLevel = 0;
240
265k
  for (auto &Change : Changes) {
241
285k
    for (unsigned i = 0, e = Change.Tok->FakeLParens.size(); i != e; 
++i20.1k
) {
242
20.1k
      bool isNestedConditional =
243
20.1k
          Change.Tok->FakeLParens[e - 1 - i] == prec::Conditional &&
244
722
          !(i == 0 && 
Change.Tok->Previous718
&&
245
691
            Change.Tok->Previous->is(TT_ConditionalExpr) &&
246
209
            Change.Tok->Previous->is(tok::colon));
247
20.1k
      if (isNestedConditional)
248
534
        ++ConditionalsLevel;
249
20.1k
      ScopeStack.push_back(isNestedConditional);
250
20.1k
    }
251
265k
252
265k
    Change.ConditionalsLevel = ConditionalsLevel;
253
265k
254
283k
    for (unsigned i = Change.Tok->FakeRParens; i > 0 && 
ScopeStack.size()18.4k
;
255
18.4k
         --i) {
256
18.4k
      if (ScopeStack.pop_back_val())
257
528
        --ConditionalsLevel;
258
18.4k
    }
259
265k
  }
260
16.3k
}
261
262
// Align a single sequence of tokens, see AlignTokens below.
263
template <typename F>
264
static void
265
AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
266
1.19k
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
267
1.19k
  bool FoundMatchOnLine = false;
268
1.19k
  int Shift = 0;
269
1.19k
270
  // ScopeStack keeps track of the current scope depth. It contains indices of
271
  // the first token on each scope.
272
  // We only run the "Matches" function on tokens from the outer-most scope.
273
  // However, we do need to pay special attention to one class of tokens
274
  // that are not in the outer-most scope, and that is function parameters
275
  // which are split across multiple lines, as illustrated by this example:
276
  //   double a(int x);
277
  //   int    b(int  y,
278
  //          double z);
279
  // In the above example, we need to take special care to ensure that
280
  // 'double z' is indented along with it's owning function 'b'.
281
  // Special handling is required for 'nested' ternary operators.
282
1.19k
  SmallVector<unsigned, 16> ScopeStack;
283
1.19k
284
11.6k
  for (unsigned i = Start; i != End; 
++i10.4k
) {
285
10.4k
    if (ScopeStack.size() != 0 &&
286
2.60k
        Changes[i].indentAndNestingLevel() <
287
2.60k
            Changes[ScopeStack.back()].indentAndNestingLevel())
288
499
      ScopeStack.pop_back();
289
10.4k
290
    // Compare current token to previous non-comment token to ensure whether
291
    // it is in a deeper scope or not.
292
10.4k
    unsigned PreviousNonComment = i - 1;
293
10.6k
    while (PreviousNonComment > Start &&
294
8.21k
           Changes[PreviousNonComment].Tok->is(tok::comment))
295
124
      PreviousNonComment--;
296
10.4k
    if (i != Start && Changes[i].indentAndNestingLevel() >
297
9.28k
                          Changes[PreviousNonComment].indentAndNestingLevel())
298
607
      ScopeStack.push_back(i);
299
10.4k
300
10.4k
    bool InsideNestedScope = ScopeStack.size() != 0;
301
10.4k
302
10.4k
    if (Changes[i].NewlinesBefore > 0 && 
!InsideNestedScope1.63k
) {
303
1.19k
      Shift = 0;
304
1.19k
      FoundMatchOnLine = false;
305
1.19k
    }
306
10.4k
307
    // If this is the first matching token to be aligned, remember by how many
308
    // spaces it has to be shifted, so the rest of the changes on the line are
309
    // shifted by the same amount
310
10.4k
    if (!FoundMatchOnLine && 
!InsideNestedScope3.63k
&&
Matches(Changes[i])3.43k
) {
311
2.07k
      FoundMatchOnLine = true;
312
2.07k
      Shift = Column - Changes[i].StartOfTokenColumn;
313
2.07k
      Changes[i].Spaces += Shift;
314
2.07k
    }
315
10.4k
316
    // This is for function parameters that are split across multiple lines,
317
    // as mentioned in the ScopeStack comment.
318
10.4k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 02.70k
) {
319
436
      unsigned ScopeStart = ScopeStack.back();
320
436
      if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) ||
321
436
          (ScopeStart > Start + 1 &&
322
409
           Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) ||
323
406
          Changes[i].Tok->is(TT_ConditionalExpr) ||
324
340
          (Changes[i].Tok->Previous &&
325
189
           Changes[i].Tok->Previous->is(TT_ConditionalExpr)))
326
150
        Changes[i].Spaces += Shift;
327
436
    }
328
10.4k
329
10.4k
    assert(Shift >= 0);
330
10.4k
    Changes[i].StartOfTokenColumn += Shift;
331
10.4k
    if (i + 1 != Changes.size())
332
10.2k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
333
10.4k
  }
334
1.19k
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&>(unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveAssignments()::$_1&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
266
281
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
267
281
  bool FoundMatchOnLine = false;
268
281
  int Shift = 0;
269
281
270
  // ScopeStack keeps track of the current scope depth. It contains indices of
271
  // the first token on each scope.
272
  // We only run the "Matches" function on tokens from the outer-most scope.
273
  // However, we do need to pay special attention to one class of tokens
274
  // that are not in the outer-most scope, and that is function parameters
275
  // which are split across multiple lines, as illustrated by this example:
276
  //   double a(int x);
277
  //   int    b(int  y,
278
  //          double z);
279
  // In the above example, we need to take special care to ensure that
280
  // 'double z' is indented along with it's owning function 'b'.
281
  // Special handling is required for 'nested' ternary operators.
282
281
  SmallVector<unsigned, 16> ScopeStack;
283
281
284
2.86k
  for (unsigned i = Start; i != End; 
++i2.57k
) {
285
2.57k
    if (ScopeStack.size() != 0 &&
286
532
        Changes[i].indentAndNestingLevel() <
287
532
            Changes[ScopeStack.back()].indentAndNestingLevel())
288
115
      ScopeStack.pop_back();
289
2.57k
290
    // Compare current token to previous non-comment token to ensure whether
291
    // it is in a deeper scope or not.
292
2.57k
    unsigned PreviousNonComment = i - 1;
293
2.63k
    while (PreviousNonComment > Start &&
294
2.07k
           Changes[PreviousNonComment].Tok->is(tok::comment))
295
60
      PreviousNonComment--;
296
2.57k
    if (i != Start && Changes[i].indentAndNestingLevel() >
297
2.29k
                          Changes[PreviousNonComment].indentAndNestingLevel())
298
136
      ScopeStack.push_back(i);
299
2.57k
300
2.57k
    bool InsideNestedScope = ScopeStack.size() != 0;
301
2.57k
302
2.57k
    if (Changes[i].NewlinesBefore > 0 && 
!InsideNestedScope314
) {
303
239
      Shift = 0;
304
239
      FoundMatchOnLine = false;
305
239
    }
306
2.57k
307
    // If this is the first matching token to be aligned, remember by how many
308
    // spaces it has to be shifted, so the rest of the changes on the line are
309
    // shifted by the same amount
310
2.57k
    if (!FoundMatchOnLine && 
!InsideNestedScope1.08k
&&
Matches(Changes[i])961
) {
311
434
      FoundMatchOnLine = true;
312
434
      Shift = Column - Changes[i].StartOfTokenColumn;
313
434
      Changes[i].Spaces += Shift;
314
434
    }
315
2.57k
316
    // This is for function parameters that are split across multiple lines,
317
    // as mentioned in the ScopeStack comment.
318
2.57k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 0553
) {
319
75
      unsigned ScopeStart = ScopeStack.back();
320
75
      if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) ||
321
75
          (ScopeStart > Start + 1 &&
322
75
           Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) ||
323
75
          Changes[i].Tok->is(TT_ConditionalExpr) ||
324
75
          (Changes[i].Tok->Previous &&
325
39
           Changes[i].Tok->Previous->is(TT_ConditionalExpr)))
326
0
        Changes[i].Spaces += Shift;
327
75
    }
328
2.57k
329
2.57k
    assert(Shift >= 0);
330
2.57k
    Changes[i].StartOfTokenColumn += Shift;
331
2.57k
    if (i + 1 != Changes.size())
332
2.47k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
333
2.57k
  }
334
281
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&>(unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveBitFields()::$_2&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
266
30
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
267
30
  bool FoundMatchOnLine = false;
268
30
  int Shift = 0;
269
30
270
  // ScopeStack keeps track of the current scope depth. It contains indices of
271
  // the first token on each scope.
272
  // We only run the "Matches" function on tokens from the outer-most scope.
273
  // However, we do need to pay special attention to one class of tokens
274
  // that are not in the outer-most scope, and that is function parameters
275
  // which are split across multiple lines, as illustrated by this example:
276
  //   double a(int x);
277
  //   int    b(int  y,
278
  //          double z);
279
  // In the above example, we need to take special care to ensure that
280
  // 'double z' is indented along with it's owning function 'b'.
281
  // Special handling is required for 'nested' ternary operators.
282
30
  SmallVector<unsigned, 16> ScopeStack;
283
30
284
360
  for (unsigned i = Start; i != End; 
++i330
) {
285
330
    if (ScopeStack.size() != 0 &&
286
6
        Changes[i].indentAndNestingLevel() <
287
6
            Changes[ScopeStack.back()].indentAndNestingLevel())
288
3
      ScopeStack.pop_back();
289
330
290
    // Compare current token to previous non-comment token to ensure whether
291
    // it is in a deeper scope or not.
292
330
    unsigned PreviousNonComment = i - 1;
293
336
    while (PreviousNonComment > Start &&
294
276
           Changes[PreviousNonComment].Tok->is(tok::comment))
295
6
      PreviousNonComment--;
296
330
    if (i != Start && Changes[i].indentAndNestingLevel() >
297
300
                          Changes[PreviousNonComment].indentAndNestingLevel())
298
3
      ScopeStack.push_back(i);
299
330
300
330
    bool InsideNestedScope = ScopeStack.size() != 0;
301
330
302
330
    if (Changes[i].NewlinesBefore > 0 && 
!InsideNestedScope30
) {
303
30
      Shift = 0;
304
30
      FoundMatchOnLine = false;
305
30
    }
306
330
307
    // If this is the first matching token to be aligned, remember by how many
308
    // spaces it has to be shifted, so the rest of the changes on the line are
309
    // shifted by the same amount
310
330
    if (!FoundMatchOnLine && 
!InsideNestedScope120
&&
Matches(Changes[i])120
) {
311
60
      FoundMatchOnLine = true;
312
60
      Shift = Column - Changes[i].StartOfTokenColumn;
313
60
      Changes[i].Spaces += Shift;
314
60
    }
315
330
316
    // This is for function parameters that are split across multiple lines,
317
    // as mentioned in the ScopeStack comment.
318
330
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 06
) {
319
0
      unsigned ScopeStart = ScopeStack.back();
320
0
      if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) ||
321
0
          (ScopeStart > Start + 1 &&
322
0
           Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) ||
323
0
          Changes[i].Tok->is(TT_ConditionalExpr) ||
324
0
          (Changes[i].Tok->Previous &&
325
0
           Changes[i].Tok->Previous->is(TT_ConditionalExpr)))
326
0
        Changes[i].Spaces += Shift;
327
0
    }
328
330
329
330
    assert(Shift >= 0);
330
330
    Changes[i].StartOfTokenColumn += Shift;
331
330
    if (i + 1 != Changes.size())
332
300
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
333
330
  }
334
30
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&>(unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignConsecutiveDeclarations()::$_3&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
266
313
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
267
313
  bool FoundMatchOnLine = false;
268
313
  int Shift = 0;
269
313
270
  // ScopeStack keeps track of the current scope depth. It contains indices of
271
  // the first token on each scope.
272
  // We only run the "Matches" function on tokens from the outer-most scope.
273
  // However, we do need to pay special attention to one class of tokens
274
  // that are not in the outer-most scope, and that is function parameters
275
  // which are split across multiple lines, as illustrated by this example:
276
  //   double a(int x);
277
  //   int    b(int  y,
278
  //          double z);
279
  // In the above example, we need to take special care to ensure that
280
  // 'double z' is indented along with it's owning function 'b'.
281
  // Special handling is required for 'nested' ternary operators.
282
313
  SmallVector<unsigned, 16> ScopeStack;
283
313
284
4.40k
  for (unsigned i = Start; i != End; 
++i4.08k
) {
285
4.08k
    if (ScopeStack.size() != 0 &&
286
1.27k
        Changes[i].indentAndNestingLevel() <
287
1.27k
            Changes[ScopeStack.back()].indentAndNestingLevel())
288
245
      ScopeStack.pop_back();
289
4.08k
290
    // Compare current token to previous non-comment token to ensure whether
291
    // it is in a deeper scope or not.
292
4.08k
    unsigned PreviousNonComment = i - 1;
293
4.13k
    while (PreviousNonComment > Start &&
294
3.50k
           Changes[PreviousNonComment].Tok->is(tok::comment))
295
45
      PreviousNonComment--;
296
4.08k
    if (i != Start && Changes[i].indentAndNestingLevel() >
297
3.77k
                          Changes[PreviousNonComment].indentAndNestingLevel())
298
297
      ScopeStack.push_back(i);
299
4.08k
300
4.08k
    bool InsideNestedScope = ScopeStack.size() != 0;
301
4.08k
302
4.08k
    if (Changes[i].NewlinesBefore > 0 && 
!InsideNestedScope528
) {
303
328
      Shift = 0;
304
328
      FoundMatchOnLine = false;
305
328
    }
306
4.08k
307
    // If this is the first matching token to be aligned, remember by how many
308
    // spaces it has to be shifted, so the rest of the changes on the line are
309
    // shifted by the same amount
310
4.08k
    if (!FoundMatchOnLine && 
!InsideNestedScope1.12k
&&
Matches(Changes[i])1.05k
) {
311
556
      FoundMatchOnLine = true;
312
556
      Shift = Column - Changes[i].StartOfTokenColumn;
313
556
      Changes[i].Spaces += Shift;
314
556
    }
315
4.08k
316
    // This is for function parameters that are split across multiple lines,
317
    // as mentioned in the ScopeStack comment.
318
4.08k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 01.33k
) {
319
200
      unsigned ScopeStart = ScopeStack.back();
320
200
      if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) ||
321
200
          (ScopeStart > Start + 1 &&
322
200
           Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) ||
323
170
          Changes[i].Tok->is(TT_ConditionalExpr) ||
324
170
          (Changes[i].Tok->Previous &&
325
60
           Changes[i].Tok->Previous->is(TT_ConditionalExpr)))
326
30
        Changes[i].Spaces += Shift;
327
200
    }
328
4.08k
329
4.08k
    assert(Shift >= 0);
330
4.08k
    Changes[i].StartOfTokenColumn += Shift;
331
4.08k
    if (i + 1 != Changes.size())
332
3.95k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
333
4.08k
  }
334
313
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignChainedConditionals()::$_4&>(unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignChainedConditionals()::$_4&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
266
361
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
267
361
  bool FoundMatchOnLine = false;
268
361
  int Shift = 0;
269
361
270
  // ScopeStack keeps track of the current scope depth. It contains indices of
271
  // the first token on each scope.
272
  // We only run the "Matches" function on tokens from the outer-most scope.
273
  // However, we do need to pay special attention to one class of tokens
274
  // that are not in the outer-most scope, and that is function parameters
275
  // which are split across multiple lines, as illustrated by this example:
276
  //   double a(int x);
277
  //   int    b(int  y,
278
  //          double z);
279
  // In the above example, we need to take special care to ensure that
280
  // 'double z' is indented along with it's owning function 'b'.
281
  // Special handling is required for 'nested' ternary operators.
282
361
  SmallVector<unsigned, 16> ScopeStack;
283
361
284
2.31k
  for (unsigned i = Start; i != End; 
++i1.95k
) {
285
1.95k
    if (ScopeStack.size() != 0 &&
286
427
        Changes[i].indentAndNestingLevel() <
287
427
            Changes[ScopeStack.back()].indentAndNestingLevel())
288
73
      ScopeStack.pop_back();
289
1.95k
290
    // Compare current token to previous non-comment token to ensure whether
291
    // it is in a deeper scope or not.
292
1.95k
    unsigned PreviousNonComment = i - 1;
293
1.96k
    while (PreviousNonComment > Start &&
294
1.23k
           Changes[PreviousNonComment].Tok->is(tok::comment))
295
9
      PreviousNonComment--;
296
1.95k
    if (i != Start && Changes[i].indentAndNestingLevel() >
297
1.59k
                          Changes[PreviousNonComment].indentAndNestingLevel())
298
94
      ScopeStack.push_back(i);
299
1.95k
300
1.95k
    bool InsideNestedScope = ScopeStack.size() != 0;
301
1.95k
302
1.95k
    if (Changes[i].NewlinesBefore > 0 && 
!InsideNestedScope388
) {
303
301
      Shift = 0;
304
301
      FoundMatchOnLine = false;
305
301
    }
306
1.95k
307
    // If this is the first matching token to be aligned, remember by how many
308
    // spaces it has to be shifted, so the rest of the changes on the line are
309
    // shifted by the same amount
310
1.95k
    if (!FoundMatchOnLine && 
!InsideNestedScope766
&&
Matches(Changes[i])766
) {
311
586
      FoundMatchOnLine = true;
312
586
      Shift = Column - Changes[i].StartOfTokenColumn;
313
586
      Changes[i].Spaces += Shift;
314
586
    }
315
1.95k
316
    // This is for function parameters that are split across multiple lines,
317
    // as mentioned in the ScopeStack comment.
318
1.95k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 0448
) {
319
87
      unsigned ScopeStart = ScopeStack.back();
320
87
      if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) ||
321
87
          (ScopeStart > Start + 1 &&
322
75
           Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) ||
323
87
          Changes[i].Tok->is(TT_ConditionalExpr) ||
324
21
          (Changes[i].Tok->Previous &&
325
18
           Changes[i].Tok->Previous->is(TT_ConditionalExpr)))
326
66
        Changes[i].Spaces += Shift;
327
87
    }
328
1.95k
329
1.95k
    assert(Shift >= 0);
330
1.95k
    Changes[i].StartOfTokenColumn += Shift;
331
1.95k
    if (i + 1 != Changes.size())
332
1.94k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
333
1.95k
  }
334
361
}
WhitespaceManager.cpp:void clang::format::AlignTokenSequence<clang::format::WhitespaceManager::alignChainedConditionals()::$_6&>(unsigned int, unsigned int, unsigned int, clang::format::WhitespaceManager::alignChainedConditionals()::$_6&, llvm::SmallVector<clang::format::WhitespaceManager::Change, 16u>&)
Line
Count
Source
266
208
                   SmallVector<WhitespaceManager::Change, 16> &Changes) {
267
208
  bool FoundMatchOnLine = false;
268
208
  int Shift = 0;
269
208
270
  // ScopeStack keeps track of the current scope depth. It contains indices of
271
  // the first token on each scope.
272
  // We only run the "Matches" function on tokens from the outer-most scope.
273
  // However, we do need to pay special attention to one class of tokens
274
  // that are not in the outer-most scope, and that is function parameters
275
  // which are split across multiple lines, as illustrated by this example:
276
  //   double a(int x);
277
  //   int    b(int  y,
278
  //          double z);
279
  // In the above example, we need to take special care to ensure that
280
  // 'double z' is indented along with it's owning function 'b'.
281
  // Special handling is required for 'nested' ternary operators.
282
208
  SmallVector<unsigned, 16> ScopeStack;
283
208
284
1.73k
  for (unsigned i = Start; i != End; 
++i1.52k
) {
285
1.52k
    if (ScopeStack.size() != 0 &&
286
356
        Changes[i].indentAndNestingLevel() <
287
356
            Changes[ScopeStack.back()].indentAndNestingLevel())
288
63
      ScopeStack.pop_back();
289
1.52k
290
    // Compare current token to previous non-comment token to ensure whether
291
    // it is in a deeper scope or not.
292
1.52k
    unsigned PreviousNonComment = i - 1;
293
1.53k
    while (PreviousNonComment > Start &&
294
1.11k
           Changes[PreviousNonComment].Tok->is(tok::comment))
295
4
      PreviousNonComment--;
296
1.52k
    if (i != Start && Changes[i].indentAndNestingLevel() >
297
1.32k
                          Changes[PreviousNonComment].indentAndNestingLevel())
298
77
      ScopeStack.push_back(i);
299
1.52k
300
1.52k
    bool InsideNestedScope = ScopeStack.size() != 0;
301
1.52k
302
1.52k
    if (Changes[i].NewlinesBefore > 0 && 
!InsideNestedScope374
) {
303
300
      Shift = 0;
304
300
      FoundMatchOnLine = false;
305
300
    }
306
1.52k
307
    // If this is the first matching token to be aligned, remember by how many
308
    // spaces it has to be shifted, so the rest of the changes on the line are
309
    // shifted by the same amount
310
1.52k
    if (!FoundMatchOnLine && 
!InsideNestedScope533
&&
Matches(Changes[i])533
) {
311
443
      FoundMatchOnLine = true;
312
443
      Shift = Column - Changes[i].StartOfTokenColumn;
313
443
      Changes[i].Spaces += Shift;
314
443
    }
315
1.52k
316
    // This is for function parameters that are split across multiple lines,
317
    // as mentioned in the ScopeStack comment.
318
1.52k
    if (InsideNestedScope && 
Changes[i].NewlinesBefore > 0370
) {
319
74
      unsigned ScopeStart = ScopeStack.back();
320
74
      if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) ||
321
74
          (ScopeStart > Start + 1 &&
322
59
           Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) ||
323
74
          Changes[i].Tok->is(TT_ConditionalExpr) ||
324
74
          (Changes[i].Tok->Previous &&
325
72
           Changes[i].Tok->Previous->is(TT_ConditionalExpr)))
326
54
        Changes[i].Spaces += Shift;
327
74
    }
328
1.52k
329
1.52k
    assert(Shift >= 0);
330
1.52k
    Changes[i].StartOfTokenColumn += Shift;
331
1.52k
    if (i + 1 != Changes.size())
332
1.52k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
333
1.52k
  }
334
208
}
335
336
// Walk through a subset of the changes, starting at StartAt, and find
337
// sequences of matching tokens to align. To do so, keep track of the lines and
338
// whether or not a matching token was found on a line. If a matching token is
339
// found, extend the current sequence. If the current line cannot be part of a
340
// sequence, e.g. because there is an empty line before it or it contains only
341
// non-matching tokens, finalize the previous sequence.
342
// The value returned is the token on which we stopped, either because we
343
// exhausted all items inside Changes, or because we hit a scope level higher
344
// than our initial scope.
345
// This function is recursive. Each invocation processes only the scope level
346
// equal to the initial level, which is the level of Changes[StartAt].
347
// If we encounter a scope level greater than the initial level, then we call
348
// ourselves recursively, thereby avoiding the pollution of the current state
349
// with the alignment requirements of the nested sub-level. This recursive
350
// behavior is necessary for aligning function prototypes that have one or more
351
// arguments.
352
// If this function encounters a scope level less than the initial level,
353
// it returns the current position.
354
// There is a non-obvious subtlety in the recursive behavior: Even though we
355
// defer processing of nested levels to recursive invocations of this
356
// function, when it comes time to align a sequence of tokens, we run the
357
// alignment on the entire sequence, including the nested levels.
358
// When doing so, most of the nested tokens are skipped, because their
359
// alignment was already handled by the recursive invocations of this function.
360
// However, the special exception is that we do NOT skip function parameters
361
// that are split across multiple lines. See the test case in FormatTest.cpp
362
// that mentions "split function parameter alignment" for an example of this.
363
template <typename F>
364
static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
365
                            SmallVector<WhitespaceManager::Change, 16> &Changes,
366
58.0k
                            unsigned StartAt) {
367
58.0k
  unsigned MinColumn = 0;
368
58.0k
  unsigned MaxColumn = UINT_MAX;
369
58.0k
370
  // Line number of the start and the end of the current token sequence.
371
58.0k
  unsigned StartOfSequence = 0;
372
58.0k
  unsigned EndOfSequence = 0;
373
58.0k
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
58.0k
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
58.0k
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
58.0k
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
58.0k
  unsigned CommasBeforeLastMatch = 0;
384
58.0k
  unsigned CommasBeforeMatch = 0;
385
58.0k
386
  // Whether a matching token has been found on the current line.
387
58.0k
  bool FoundMatchOnLine = false;
388
58.0k
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
103k
  auto AlignCurrentSequence = [&] {
397
103k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence1.35k
)
398
1.19k
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
1.19k
                         Changes);
400
103k
    MinColumn = 0;
401
103k
    MaxColumn = UINT_MAX;
402
103k
    StartOfSequence = 0;
403
103k
    EndOfSequence = 0;
404
103k
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
687
  auto AlignCurrentSequence = [&] {
397
687
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence169
)
398
166
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
166
                         Changes);
400
687
    MinColumn = 0;
401
687
    MaxColumn = UINT_MAX;
402
687
    StartOfSequence = 0;
403
687
    EndOfSequence = 0;
404
687
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
988
  auto AlignCurrentSequence = [&] {
397
988
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence127
)
398
115
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
115
                         Changes);
400
988
    MinColumn = 0;
401
988
    MaxColumn = UINT_MAX;
402
988
    StartOfSequence = 0;
403
988
    EndOfSequence = 0;
404
988
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
30
  auto AlignCurrentSequence = [&] {
397
30
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
30
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
30
                         Changes);
400
30
    MinColumn = 0;
401
30
    MaxColumn = UINT_MAX;
402
30
    StartOfSequence = 0;
403
30
    EndOfSequence = 0;
404
30
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
3
  auto AlignCurrentSequence = [&] {
397
3
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence0
)
398
0
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
0
                         Changes);
400
3
    MinColumn = 0;
401
3
    MaxColumn = UINT_MAX;
402
3
    StartOfSequence = 0;
403
3
    EndOfSequence = 0;
404
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)::'lambda'()::operator()() const
Line
Count
Source
396
544
  auto AlignCurrentSequence = [&] {
397
544
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence177
)
398
177
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
177
                         Changes);
400
544
    MinColumn = 0;
401
544
    MaxColumn = UINT_MAX;
402
544
    StartOfSequence = 0;
403
544
    EndOfSequence = 0;
404
544
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
984
  auto AlignCurrentSequence = [&] {
397
984
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence148
)
398
136
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
136
                         Changes);
400
984
    MinColumn = 0;
401
984
    MaxColumn = UINT_MAX;
402
984
    StartOfSequence = 0;
403
984
    EndOfSequence = 0;
404
984
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
36.7k
  auto AlignCurrentSequence = [&] {
397
36.7k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence23
)
398
16
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
16
                         Changes);
400
36.7k
    MinColumn = 0;
401
36.7k
    MaxColumn = UINT_MAX;
402
36.7k
    StartOfSequence = 0;
403
36.7k
    EndOfSequence = 0;
404
36.7k
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
55.8k
  auto AlignCurrentSequence = [&] {
397
55.8k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence470
)
398
345
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
345
                         Changes);
400
55.8k
    MinColumn = 0;
401
55.8k
    MaxColumn = UINT_MAX;
402
55.8k
    StartOfSequence = 0;
403
55.8k
    EndOfSequence = 0;
404
55.8k
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
2.88k
  auto AlignCurrentSequence = [&] {
397
2.88k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence14
)
398
14
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
14
                         Changes);
400
2.88k
    MinColumn = 0;
401
2.88k
    MaxColumn = UINT_MAX;
402
2.88k
    StartOfSequence = 0;
403
2.88k
    EndOfSequence = 0;
404
2.88k
  };
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)::'lambda'()::operator()() const
Line
Count
Source
396
4.66k
  auto AlignCurrentSequence = [&] {
397
4.66k
    if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence197
)
398
194
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
194
                         Changes);
400
4.66k
    MinColumn = 0;
401
4.66k
    MaxColumn = UINT_MAX;
402
4.66k
    StartOfSequence = 0;
403
4.66k
    EndOfSequence = 0;
404
4.66k
  };
405
58.0k
406
58.0k
  unsigned i = StartAt;
407
375k
  for (unsigned e = Changes.size(); i != e; 
++i317k
) {
408
358k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
41.2k
      break;
410
317k
411
317k
    if (Changes[i].NewlinesBefore != 0) {
412
46.2k
      CommasBeforeMatch = 0;
413
46.2k
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
46.2k
      if (Changes[i].NewlinesBefore > 1 ||
418
45.6k
          Changes[i].Tok->MustBreakAlignBefore || 
!FoundMatchOnLine45.1k
)
419
45.0k
        AlignCurrentSequence();
420
46.2k
421
46.2k
      FoundMatchOnLine = false;
422
46.2k
    }
423
317k
424
317k
    if (Changes[i].Tok->is(tok::comma)) {
425
8.37k
      ++CommasBeforeMatch;
426
309k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
41.2k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
41.2k
      i = StoppedAt - 1;
430
41.2k
      continue;
431
41.2k
    }
432
276k
433
276k
    if (!Matches(Changes[i]))
434
274k
      continue;
435
2.25k
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
2.25k
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch2.08k
)
439
208
      AlignCurrentSequence();
440
2.25k
441
2.25k
    CommasBeforeLastMatch = CommasBeforeMatch;
442
2.25k
    FoundMatchOnLine = true;
443
2.25k
444
2.25k
    if (StartOfSequence == 0)
445
1.33k
      StartOfSequence = i;
446
2.25k
447
2.25k
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
2.25k
    int LineLengthAfter = Changes[i].TokenLength;
449
10.1k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 09.52k
;
++j7.90k
) {
450
7.90k
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
7.90k
      if (!Changes[j].IsInsideToken)
457
7.90k
        LineLengthAfter += Changes[j].TokenLength;
458
7.90k
    }
459
2.25k
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
2.25k
461
    // If we are restricted by the maximum column width, end the sequence.
462
2.25k
    if (ChangeMinColumn > MaxColumn || 
ChangeMaxColumn < MinColumn2.24k
||
463
2.23k
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
18
      AlignCurrentSequence();
465
18
      StartOfSequence = i;
466
18
    }
467
2.25k
468
2.25k
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
2.25k
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
2.25k
  }
471
58.0k
472
58.0k
  EndOfSequence = i;
473
58.0k
  AlignCurrentSequence();
474
58.0k
  return i;
475
58.0k
}
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)
Line
Count
Source
366
240
                            unsigned StartAt) {
367
240
  unsigned MinColumn = 0;
368
240
  unsigned MaxColumn = UINT_MAX;
369
240
370
  // Line number of the start and the end of the current token sequence.
371
240
  unsigned StartOfSequence = 0;
372
240
  unsigned EndOfSequence = 0;
373
240
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
240
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
240
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
240
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
240
  unsigned CommasBeforeLastMatch = 0;
384
240
  unsigned CommasBeforeMatch = 0;
385
240
386
  // Whether a matching token has been found on the current line.
387
240
  bool FoundMatchOnLine = false;
388
240
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
240
  auto AlignCurrentSequence = [&] {
397
240
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
240
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
240
                         Changes);
400
240
    MinColumn = 0;
401
240
    MaxColumn = UINT_MAX;
402
240
    StartOfSequence = 0;
403
240
    EndOfSequence = 0;
404
240
  };
405
240
406
240
  unsigned i = StartAt;
407
3.36k
  for (unsigned e = Changes.size(); i != e; 
++i3.12k
) {
408
3.12k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
0
      break;
410
3.12k
411
3.12k
    if (Changes[i].NewlinesBefore != 0) {
412
600
      CommasBeforeMatch = 0;
413
600
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
600
      if (Changes[i].NewlinesBefore > 1 ||
418
597
          Changes[i].Tok->MustBreakAlignBefore || 
!FoundMatchOnLine561
)
419
408
        AlignCurrentSequence();
420
600
421
600
      FoundMatchOnLine = false;
422
600
    }
423
3.12k
424
3.12k
    if (Changes[i].Tok->is(tok::comma)) {
425
18
      ++CommasBeforeMatch;
426
3.10k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
330
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
330
      i = StoppedAt - 1;
430
330
      continue;
431
330
    }
432
2.79k
433
2.79k
    if (!Matches(Changes[i]))
434
2.52k
      continue;
435
270
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
270
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch258
)
439
33
      AlignCurrentSequence();
440
270
441
270
    CommasBeforeLastMatch = CommasBeforeMatch;
442
270
    FoundMatchOnLine = true;
443
270
444
270
    if (StartOfSequence == 0)
445
163
      StartOfSequence = i;
446
270
447
270
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
270
    int LineLengthAfter = Changes[i].TokenLength;
449
1.05k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 0998
;
++j785
) {
450
785
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
785
      if (!Changes[j].IsInsideToken)
457
784
        LineLengthAfter += Changes[j].TokenLength;
458
785
    }
459
270
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
270
461
    // If we are restricted by the maximum column width, end the sequence.
462
270
    if (ChangeMinColumn > MaxColumn || 
ChangeMaxColumn < MinColumn267
||
463
264
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
6
      AlignCurrentSequence();
465
6
      StartOfSequence = i;
466
6
    }
467
270
468
270
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
270
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
270
  }
471
240
472
240
  EndOfSequence = i;
473
240
  AlignCurrentSequence();
474
240
  return i;
475
240
}
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)
Line
Count
Source
366
607
                            unsigned StartAt) {
367
607
  unsigned MinColumn = 0;
368
607
  unsigned MaxColumn = UINT_MAX;
369
607
370
  // Line number of the start and the end of the current token sequence.
371
607
  unsigned StartOfSequence = 0;
372
607
  unsigned EndOfSequence = 0;
373
607
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
607
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
607
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
607
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
607
  unsigned CommasBeforeLastMatch = 0;
384
607
  unsigned CommasBeforeMatch = 0;
385
607
386
  // Whether a matching token has been found on the current line.
387
607
  bool FoundMatchOnLine = false;
388
607
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
607
  auto AlignCurrentSequence = [&] {
397
607
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
607
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
607
                         Changes);
400
607
    MinColumn = 0;
401
607
    MaxColumn = UINT_MAX;
402
607
    StartOfSequence = 0;
403
607
    EndOfSequence = 0;
404
607
  };
405
607
406
607
  unsigned i = StartAt;
407
3.40k
  for (unsigned e = Changes.size(); i != e; 
++i2.79k
) {
408
3.40k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
607
      break;
410
2.79k
411
2.79k
    if (Changes[i].NewlinesBefore != 0) {
412
473
      CommasBeforeMatch = 0;
413
473
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
473
      if (Changes[i].NewlinesBefore > 1 ||
418
472
          Changes[i].Tok->MustBreakAlignBefore || 
!FoundMatchOnLine469
)
419
360
        AlignCurrentSequence();
420
473
421
473
      FoundMatchOnLine = false;
422
473
    }
423
2.79k
424
2.79k
    if (Changes[i].Tok->is(tok::comma)) {
425
126
      ++CommasBeforeMatch;
426
2.67k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
277
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
277
      i = StoppedAt - 1;
430
277
      continue;
431
277
    }
432
2.52k
433
2.52k
    if (!Matches(Changes[i]))
434
2.33k
      continue;
435
188
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
188
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch176
)
439
21
      AlignCurrentSequence();
440
188
441
188
    CommasBeforeLastMatch = CommasBeforeMatch;
442
188
    FoundMatchOnLine = true;
443
188
444
188
    if (StartOfSequence == 0)
445
127
      StartOfSequence = i;
446
188
447
188
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
188
    int LineLengthAfter = Changes[i].TokenLength;
449
856
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 0847
;
++j668
) {
450
668
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
668
      if (!Changes[j].IsInsideToken)
457
668
        LineLengthAfter += Changes[j].TokenLength;
458
668
    }
459
188
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
188
461
    // If we are restricted by the maximum column width, end the sequence.
462
188
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
463
188
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
0
      AlignCurrentSequence();
465
0
      StartOfSequence = i;
466
0
    }
467
188
468
188
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
188
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
188
  }
471
607
472
607
  EndOfSequence = i;
473
607
  AlignCurrentSequence();
474
607
  return i;
475
607
}
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)
Line
Count
Source
366
30
                            unsigned StartAt) {
367
30
  unsigned MinColumn = 0;
368
30
  unsigned MaxColumn = UINT_MAX;
369
30
370
  // Line number of the start and the end of the current token sequence.
371
30
  unsigned StartOfSequence = 0;
372
30
  unsigned EndOfSequence = 0;
373
30
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
30
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
30
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
30
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
30
  unsigned CommasBeforeLastMatch = 0;
384
30
  unsigned CommasBeforeMatch = 0;
385
30
386
  // Whether a matching token has been found on the current line.
387
30
  bool FoundMatchOnLine = false;
388
30
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
30
  auto AlignCurrentSequence = [&] {
397
30
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
30
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
30
                         Changes);
400
30
    MinColumn = 0;
401
30
    MaxColumn = UINT_MAX;
402
30
    StartOfSequence = 0;
403
30
    EndOfSequence = 0;
404
30
  };
405
30
406
30
  unsigned i = StartAt;
407
447
  for (unsigned e = Changes.size(); i != e; 
++i417
) {
408
417
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
0
      break;
410
417
411
417
    if (Changes[i].NewlinesBefore != 0) {
412
30
      CommasBeforeMatch = 0;
413
30
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
30
      if (Changes[i].NewlinesBefore > 1 ||
418
30
          Changes[i].Tok->MustBreakAlignBefore || !FoundMatchOnLine)
419
0
        AlignCurrentSequence();
420
30
421
30
      FoundMatchOnLine = false;
422
30
    }
423
417
424
417
    if (Changes[i].Tok->is(tok::comma)) {
425
0
      ++CommasBeforeMatch;
426
417
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
3
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
3
      i = StoppedAt - 1;
430
3
      continue;
431
3
    }
432
414
433
414
    if (!Matches(Changes[i]))
434
354
      continue;
435
60
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
60
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
439
0
      AlignCurrentSequence();
440
60
441
60
    CommasBeforeLastMatch = CommasBeforeMatch;
442
60
    FoundMatchOnLine = true;
443
60
444
60
    if (StartOfSequence == 0)
445
30
      StartOfSequence = i;
446
60
447
60
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
60
    int LineLengthAfter = Changes[i].TokenLength;
449
270
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 0240
;
++j210
) {
450
210
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
210
      if (!Changes[j].IsInsideToken)
457
210
        LineLengthAfter += Changes[j].TokenLength;
458
210
    }
459
60
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
60
461
    // If we are restricted by the maximum column width, end the sequence.
462
60
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
463
60
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
0
      AlignCurrentSequence();
465
0
      StartOfSequence = i;
466
0
    }
467
60
468
60
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
60
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
60
  }
471
30
472
30
  EndOfSequence = i;
473
30
  AlignCurrentSequence();
474
30
  return i;
475
30
}
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)
Line
Count
Source
366
3
                            unsigned StartAt) {
367
3
  unsigned MinColumn = 0;
368
3
  unsigned MaxColumn = UINT_MAX;
369
3
370
  // Line number of the start and the end of the current token sequence.
371
3
  unsigned StartOfSequence = 0;
372
3
  unsigned EndOfSequence = 0;
373
3
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
3
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
3
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
3
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
3
  unsigned CommasBeforeLastMatch = 0;
384
3
  unsigned CommasBeforeMatch = 0;
385
3
386
  // Whether a matching token has been found on the current line.
387
3
  bool FoundMatchOnLine = false;
388
3
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
3
  auto AlignCurrentSequence = [&] {
397
3
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
3
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
3
                         Changes);
400
3
    MinColumn = 0;
401
3
    MaxColumn = UINT_MAX;
402
3
    StartOfSequence = 0;
403
3
    EndOfSequence = 0;
404
3
  };
405
3
406
3
  unsigned i = StartAt;
407
9
  for (unsigned e = Changes.size(); i != e; 
++i6
) {
408
9
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
3
      break;
410
6
411
6
    if (Changes[i].NewlinesBefore != 0) {
412
0
      CommasBeforeMatch = 0;
413
0
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
0
      if (Changes[i].NewlinesBefore > 1 ||
418
0
          Changes[i].Tok->MustBreakAlignBefore || !FoundMatchOnLine)
419
0
        AlignCurrentSequence();
420
0
421
0
      FoundMatchOnLine = false;
422
0
    }
423
6
424
6
    if (Changes[i].Tok->is(tok::comma)) {
425
0
      ++CommasBeforeMatch;
426
6
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
0
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
0
      i = StoppedAt - 1;
430
0
      continue;
431
0
    }
432
6
433
6
    if (!Matches(Changes[i]))
434
6
      continue;
435
0
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
0
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
439
0
      AlignCurrentSequence();
440
0
441
0
    CommasBeforeLastMatch = CommasBeforeMatch;
442
0
    FoundMatchOnLine = true;
443
0
444
0
    if (StartOfSequence == 0)
445
0
      StartOfSequence = i;
446
0
447
0
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
0
    int LineLengthAfter = Changes[i].TokenLength;
449
0
    for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j) {
450
0
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
0
      if (!Changes[j].IsInsideToken)
457
0
        LineLengthAfter += Changes[j].TokenLength;
458
0
    }
459
0
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
0
461
    // If we are restricted by the maximum column width, end the sequence.
462
0
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
463
0
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
0
      AlignCurrentSequence();
465
0
      StartOfSequence = i;
466
0
    }
467
0
468
0
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
0
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
0
  }
471
3
472
3
  EndOfSequence = i;
473
3
  AlignCurrentSequence();
474
3
  return i;
475
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)
Line
Count
Source
366
243
                            unsigned StartAt) {
367
243
  unsigned MinColumn = 0;
368
243
  unsigned MaxColumn = UINT_MAX;
369
243
370
  // Line number of the start and the end of the current token sequence.
371
243
  unsigned StartOfSequence = 0;
372
243
  unsigned EndOfSequence = 0;
373
243
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
243
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
243
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
243
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
243
  unsigned CommasBeforeLastMatch = 0;
384
243
  unsigned CommasBeforeMatch = 0;
385
243
386
  // Whether a matching token has been found on the current line.
387
243
  bool FoundMatchOnLine = false;
388
243
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
243
  auto AlignCurrentSequence = [&] {
397
243
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
243
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
243
                         Changes);
400
243
    MinColumn = 0;
401
243
    MaxColumn = UINT_MAX;
402
243
    StartOfSequence = 0;
403
243
    EndOfSequence = 0;
404
243
  };
405
243
406
243
  unsigned i = StartAt;
407
3.32k
  for (unsigned e = Changes.size(); i != e; 
++i3.08k
) {
408
3.08k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
0
      break;
410
3.08k
411
3.08k
    if (Changes[i].NewlinesBefore != 0) {
412
531
      CommasBeforeMatch = 0;
413
531
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
531
      if (Changes[i].NewlinesBefore > 1 ||
418
528
          Changes[i].Tok->MustBreakAlignBefore || !FoundMatchOnLine)
419
295
        AlignCurrentSequence();
420
531
421
531
      FoundMatchOnLine = false;
422
531
    }
423
3.08k
424
3.08k
    if (Changes[i].Tok->is(tok::comma)) {
425
18
      ++CommasBeforeMatch;
426
3.06k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
353
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
353
      i = StoppedAt - 1;
430
353
      continue;
431
353
    }
432
2.72k
433
2.72k
    if (!Matches(Changes[i]))
434
2.41k
      continue;
435
314
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
314
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
439
0
      AlignCurrentSequence();
440
314
441
314
    CommasBeforeLastMatch = CommasBeforeMatch;
442
314
    FoundMatchOnLine = true;
443
314
444
314
    if (StartOfSequence == 0)
445
171
      StartOfSequence = i;
446
314
447
314
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
314
    int LineLengthAfter = Changes[i].TokenLength;
449
1.76k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 01.68k
;
++j1.44k
) {
450
1.44k
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
1.44k
      if (!Changes[j].IsInsideToken)
457
1.44k
        LineLengthAfter += Changes[j].TokenLength;
458
1.44k
    }
459
314
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
314
461
    // If we are restricted by the maximum column width, end the sequence.
462
314
    if (ChangeMinColumn > MaxColumn || 
ChangeMaxColumn < MinColumn311
||
463
308
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
6
      AlignCurrentSequence();
465
6
      StartOfSequence = i;
466
6
    }
467
314
468
314
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
314
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
314
  }
471
243
472
243
  EndOfSequence = i;
473
243
  AlignCurrentSequence();
474
243
  return i;
475
243
}
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)
Line
Count
Source
366
639
                            unsigned StartAt) {
367
639
  unsigned MinColumn = 0;
368
639
  unsigned MaxColumn = UINT_MAX;
369
639
370
  // Line number of the start and the end of the current token sequence.
371
639
  unsigned StartOfSequence = 0;
372
639
  unsigned EndOfSequence = 0;
373
639
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
639
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
639
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
639
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
639
  unsigned CommasBeforeLastMatch = 0;
384
639
  unsigned CommasBeforeMatch = 0;
385
639
386
  // Whether a matching token has been found on the current line.
387
639
  bool FoundMatchOnLine = false;
388
639
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
639
  auto AlignCurrentSequence = [&] {
397
639
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
639
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
639
                         Changes);
400
639
    MinColumn = 0;
401
639
    MaxColumn = UINT_MAX;
402
639
    StartOfSequence = 0;
403
639
    EndOfSequence = 0;
404
639
  };
405
639
406
639
  unsigned i = StartAt;
407
3.58k
  for (unsigned e = Changes.size(); i != e; 
++i2.94k
) {
408
3.58k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
639
      break;
410
2.94k
411
2.94k
    if (Changes[i].NewlinesBefore != 0) {
412
491
      CommasBeforeMatch = 0;
413
491
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
491
      if (Changes[i].NewlinesBefore > 1 ||
418
490
          Changes[i].Tok->MustBreakAlignBefore || !FoundMatchOnLine)
419
330
        AlignCurrentSequence();
420
491
421
491
      FoundMatchOnLine = false;
422
491
    }
423
2.94k
424
2.94k
    if (Changes[i].Tok->is(tok::comma)) {
425
150
      ++CommasBeforeMatch;
426
2.79k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
286
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
286
      i = StoppedAt - 1;
430
286
      continue;
431
286
    }
432
2.65k
433
2.65k
    if (!Matches(Changes[i]))
434
2.40k
      continue;
435
254
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
254
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch242
)
439
15
      AlignCurrentSequence();
440
254
441
254
    CommasBeforeLastMatch = CommasBeforeMatch;
442
254
    FoundMatchOnLine = true;
443
254
444
254
    if (StartOfSequence == 0)
445
148
      StartOfSequence = i;
446
254
447
254
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
254
    int LineLengthAfter = Changes[i].TokenLength;
449
1.19k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 01.17k
;
++j939
) {
450
939
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
939
      if (!Changes[j].IsInsideToken)
457
939
        LineLengthAfter += Changes[j].TokenLength;
458
939
    }
459
254
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
254
461
    // If we are restricted by the maximum column width, end the sequence.
462
254
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
463
254
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
0
      AlignCurrentSequence();
465
0
      StartOfSequence = i;
466
0
    }
467
254
468
254
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
254
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
254
  }
471
639
472
639
  EndOfSequence = i;
473
639
  AlignCurrentSequence();
474
639
  return i;
475
639
}
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)
Line
Count
Source
366
14.8k
                            unsigned StartAt) {
367
14.8k
  unsigned MinColumn = 0;
368
14.8k
  unsigned MaxColumn = UINT_MAX;
369
14.8k
370
  // Line number of the start and the end of the current token sequence.
371
14.8k
  unsigned StartOfSequence = 0;
372
14.8k
  unsigned EndOfSequence = 0;
373
14.8k
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
14.8k
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
14.8k
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
14.8k
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
14.8k
  unsigned CommasBeforeLastMatch = 0;
384
14.8k
  unsigned CommasBeforeMatch = 0;
385
14.8k
386
  // Whether a matching token has been found on the current line.
387
14.8k
  bool FoundMatchOnLine = false;
388
14.8k
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
14.8k
  auto AlignCurrentSequence = [&] {
397
14.8k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
14.8k
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
14.8k
                         Changes);
400
14.8k
    MinColumn = 0;
401
14.8k
    MaxColumn = UINT_MAX;
402
14.8k
    StartOfSequence = 0;
403
14.8k
    EndOfSequence = 0;
404
14.8k
  };
405
14.8k
406
14.8k
  unsigned i = StartAt;
407
159k
  for (unsigned e = Changes.size(); i != e; 
++i144k
) {
408
144k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
24
      break;
410
144k
411
144k
    if (Changes[i].NewlinesBefore != 0) {
412
21.8k
      CommasBeforeMatch = 0;
413
21.8k
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
21.8k
      if (Changes[i].NewlinesBefore > 1 ||
418
21.4k
          Changes[i].Tok->MustBreakAlignBefore || 
!FoundMatchOnLine20.9k
)
419
21.8k
        AlignCurrentSequence();
420
21.8k
421
21.8k
      FoundMatchOnLine = false;
422
21.8k
    }
423
144k
424
144k
    if (Changes[i].Tok->is(tok::comma)) {
425
778
      ++CommasBeforeMatch;
426
144k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
22.7k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
22.7k
      i = StoppedAt - 1;
430
22.7k
      continue;
431
22.7k
    }
432
122k
433
122k
    if (!Matches(Changes[i]))
434
122k
      continue;
435
24
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
24
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch17
)
439
7
      AlignCurrentSequence();
440
24
441
24
    CommasBeforeLastMatch = CommasBeforeMatch;
442
24
    FoundMatchOnLine = true;
443
24
444
24
    if (StartOfSequence == 0)
445
24
      StartOfSequence = i;
446
24
447
24
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
24
    int LineLengthAfter = Changes[i].TokenLength;
449
158
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 0137
;
++j134
) {
450
134
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
134
      if (!Changes[j].IsInsideToken)
457
134
        LineLengthAfter += Changes[j].TokenLength;
458
134
    }
459
24
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
24
461
    // If we are restricted by the maximum column width, end the sequence.
462
24
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
463
24
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
0
      AlignCurrentSequence();
465
0
      StartOfSequence = i;
466
0
    }
467
24
468
24
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
24
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
24
  }
471
14.8k
472
14.8k
  EndOfSequence = i;
473
14.8k
  AlignCurrentSequence();
474
14.8k
  return i;
475
14.8k
}
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)
Line
Count
Source
366
37.1k
                            unsigned StartAt) {
367
37.1k
  unsigned MinColumn = 0;
368
37.1k
  unsigned MaxColumn = UINT_MAX;
369
37.1k
370
  // Line number of the start and the end of the current token sequence.
371
37.1k
  unsigned StartOfSequence = 0;
372
37.1k
  unsigned EndOfSequence = 0;
373
37.1k
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
37.1k
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
37.1k
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
37.1k
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
37.1k
  unsigned CommasBeforeLastMatch = 0;
384
37.1k
  unsigned CommasBeforeMatch = 0;
385
37.1k
386
  // Whether a matching token has been found on the current line.
387
37.1k
  bool FoundMatchOnLine = false;
388
37.1k
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
37.1k
  auto AlignCurrentSequence = [&] {
397
37.1k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
37.1k
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
37.1k
                         Changes);
400
37.1k
    MinColumn = 0;
401
37.1k
    MaxColumn = UINT_MAX;
402
37.1k
    StartOfSequence = 0;
403
37.1k
    EndOfSequence = 0;
404
37.1k
  };
405
37.1k
406
37.1k
  unsigned i = StartAt;
407
175k
  for (unsigned e = Changes.size(); i != e; 
++i138k
) {
408
175k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
37.0k
      break;
410
138k
411
138k
    if (Changes[i].NewlinesBefore != 0) {
412
18.8k
      CommasBeforeMatch = 0;
413
18.8k
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
18.8k
      if (Changes[i].NewlinesBefore > 1 ||
418
18.7k
          Changes[i].Tok->MustBreakAlignBefore || 
!FoundMatchOnLine18.6k
)
419
18.5k
        AlignCurrentSequence();
420
18.8k
421
18.8k
      FoundMatchOnLine = false;
422
18.8k
    }
423
138k
424
138k
    if (Changes[i].Tok->is(tok::comma)) {
425
6.66k
      ++CommasBeforeMatch;
426
132k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
14.3k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
14.3k
      i = StoppedAt - 1;
430
14.3k
      continue;
431
14.3k
    }
432
124k
433
124k
    if (!Matches(Changes[i]))
434
123k
      continue;
435
695
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
695
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch570
)
439
129
      AlignCurrentSequence();
440
695
441
695
    CommasBeforeLastMatch = CommasBeforeMatch;
442
695
    FoundMatchOnLine = true;
443
695
444
695
    if (StartOfSequence == 0)
445
470
      StartOfSequence = i;
446
695
447
695
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
695
    int LineLengthAfter = Changes[i].TokenLength;
449
3.24k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 02.93k
;
++j2.54k
) {
450
2.54k
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
2.54k
      if (!Changes[j].IsInsideToken)
457
2.54k
        LineLengthAfter += Changes[j].TokenLength;
458
2.54k
    }
459
695
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
695
461
    // If we are restricted by the maximum column width, end the sequence.
462
695
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
463
695
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
0
      AlignCurrentSequence();
465
0
      StartOfSequence = i;
466
0
    }
467
695
468
695
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
695
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
695
  }
471
37.1k
472
37.1k
  EndOfSequence = i;
473
37.1k
  AlignCurrentSequence();
474
37.1k
  return i;
475
37.1k
}
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)
Line
Count
Source
366
1.48k
                            unsigned StartAt) {
367
1.48k
  unsigned MinColumn = 0;
368
1.48k
  unsigned MaxColumn = UINT_MAX;
369
1.48k
370
  // Line number of the start and the end of the current token sequence.
371
1.48k
  unsigned StartOfSequence = 0;
372
1.48k
  unsigned EndOfSequence = 0;
373
1.48k
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
1.48k
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
1.48k
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
1.48k
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
1.48k
  unsigned CommasBeforeLastMatch = 0;
384
1.48k
  unsigned CommasBeforeMatch = 0;
385
1.48k
386
  // Whether a matching token has been found on the current line.
387
1.48k
  bool FoundMatchOnLine = false;
388
1.48k
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
1.48k
  auto AlignCurrentSequence = [&] {
397
1.48k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
1.48k
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
1.48k
                         Changes);
400
1.48k
    MinColumn = 0;
401
1.48k
    MaxColumn = UINT_MAX;
402
1.48k
    StartOfSequence = 0;
403
1.48k
    EndOfSequence = 0;
404
1.48k
  };
405
1.48k
406
1.48k
  unsigned i = StartAt;
407
12.6k
  for (unsigned e = Changes.size(); i != e; 
++i11.1k
) {
408
11.1k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
11
      break;
410
11.1k
411
11.1k
    if (Changes[i].NewlinesBefore != 0) {
412
1.40k
      CommasBeforeMatch = 0;
413
1.40k
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
1.40k
      if (Changes[i].NewlinesBefore > 1 ||
418
1.38k
          Changes[i].Tok->MustBreakAlignBefore || !FoundMatchOnLine)
419
1.39k
        AlignCurrentSequence();
420
1.40k
421
1.40k
      FoundMatchOnLine = false;
422
1.40k
    }
423
11.1k
424
11.1k
    if (Changes[i].Tok->is(tok::comma)) {
425
8
      ++CommasBeforeMatch;
426
11.1k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
1.66k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
1.66k
      i = StoppedAt - 1;
430
1.66k
      continue;
431
1.66k
    }
432
9.49k
433
9.49k
    if (!Matches(Changes[i]))
434
9.47k
      continue;
435
20
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
20
    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
439
0
      AlignCurrentSequence();
440
20
441
20
    CommasBeforeLastMatch = CommasBeforeMatch;
442
20
    FoundMatchOnLine = true;
443
20
444
20
    if (StartOfSequence == 0)
445
14
      StartOfSequence = i;
446
20
447
20
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
20
    int LineLengthAfter = Changes[i].TokenLength;
449
54
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 046
;
++j34
) {
450
34
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
34
      if (!Changes[j].IsInsideToken)
457
34
        LineLengthAfter += Changes[j].TokenLength;
458
34
    }
459
20
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
20
461
    // If we are restricted by the maximum column width, end the sequence.
462
20
    if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
463
20
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
0
      AlignCurrentSequence();
465
0
      StartOfSequence = i;
466
0
    }
467
20
468
20
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
20
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
20
  }
471
1.48k
472
1.48k
  EndOfSequence = i;
473
1.48k
  AlignCurrentSequence();
474
1.48k
  return i;
475
1.48k
}
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)
Line
Count
Source
366
2.88k
                            unsigned StartAt) {
367
2.88k
  unsigned MinColumn = 0;
368
2.88k
  unsigned MaxColumn = UINT_MAX;
369
2.88k
370
  // Line number of the start and the end of the current token sequence.
371
2.88k
  unsigned StartOfSequence = 0;
372
2.88k
  unsigned EndOfSequence = 0;
373
2.88k
374
  // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
375
  // abort when we hit any token in a higher scope than the starting one.
376
2.88k
  auto IndentAndNestingLevel = StartAt < Changes.size()
377
2.88k
                                   ? Changes[StartAt].indentAndNestingLevel()
378
0
                                   : std::tuple<unsigned, unsigned, unsigned>();
379
2.88k
380
  // Keep track of the number of commas before the matching tokens, we will only
381
  // align a sequence of matching tokens if they are preceded by the same number
382
  // of commas.
383
2.88k
  unsigned CommasBeforeLastMatch = 0;
384
2.88k
  unsigned CommasBeforeMatch = 0;
385
2.88k
386
  // Whether a matching token has been found on the current line.
387
2.88k
  bool FoundMatchOnLine = false;
388
2.88k
389
  // Aligns a sequence of matching tokens, on the MinColumn column.
390
  //
391
  // Sequences start from the first matching token to align, and end at the
392
  // first token of the first line that doesn't need to be aligned.
393
  //
394
  // We need to adjust the StartOfTokenColumn of each Change that is on a line
395
  // containing any matching token to be aligned and located after such token.
396
2.88k
  auto AlignCurrentSequence = [&] {
397
2.88k
    if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
398
2.88k
      AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
399
2.88k
                         Changes);
400
2.88k
    MinColumn = 0;
401
2.88k
    MaxColumn = UINT_MAX;
402
2.88k
    StartOfSequence = 0;
403
2.88k
    EndOfSequence = 0;
404
2.88k
  };
405
2.88k
406
2.88k
  unsigned i = StartAt;
407
13.3k
  for (unsigned e = Changes.size(); i != e; 
++i10.4k
) {
408
13.3k
    if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
409
2.87k
      break;
410
10.4k
411
10.4k
    if (Changes[i].NewlinesBefore != 0) {
412
2.02k
      CommasBeforeMatch = 0;
413
2.02k
      EndOfSequence = i;
414
      // If there is a blank line, there is a forced-align-break (eg,
415
      // preprocessor), or if the last line didn't contain any matching token,
416
      // the sequence ends here.
417
2.02k
      if (Changes[i].NewlinesBefore > 1 ||
418
2.02k
          Changes[i].Tok->MustBreakAlignBefore || !FoundMatchOnLine)
419
1.77k
        AlignCurrentSequence();
420
2.02k
421
2.02k
      FoundMatchOnLine = false;
422
2.02k
    }
423
10.4k
424
10.4k
    if (Changes[i].Tok->is(tok::comma)) {
425
603
      ++CommasBeforeMatch;
426
9.83k
    } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
427
      // Call AlignTokens recursively, skipping over this scope block.
428
1.21k
      unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
429
1.21k
      i = StoppedAt - 1;
430
1.21k
      continue;
431
1.21k
    }
432
9.21k
433
9.21k
    if (!Matches(Changes[i]))
434
8.79k
      continue;
435
426
436
    // If there is more than one matching token per line, or if the number of
437
    // preceding commas, do not match anymore, end the sequence.
438
426
    if (FoundMatchOnLine || 
CommasBeforeMatch != CommasBeforeLastMatch423
)
439
3
      AlignCurrentSequence();
440
426
441
426
    CommasBeforeLastMatch = CommasBeforeMatch;
442
426
    FoundMatchOnLine = true;
443
426
444
426
    if (StartOfSequence == 0)
445
191
      StartOfSequence = i;
446
426
447
426
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
448
426
    int LineLengthAfter = Changes[i].TokenLength;
449
1.56k
    for (unsigned j = i + 1; j != e && 
Changes[j].NewlinesBefore == 01.46k
;
++j1.14k
) {
450
1.14k
      LineLengthAfter += Changes[j].Spaces;
451
      // Changes are generally 1:1 with the tokens, but a change could also be
452
      // inside of a token, in which case it's counted more than once: once for
453
      // the whitespace surrounding the token (!IsInsideToken) and once for
454
      // each whitespace change within it (IsInsideToken).
455
      // Therefore, changes inside of a token should only count the space.
456
1.14k
      if (!Changes[j].IsInsideToken)
457
1.14k
        LineLengthAfter += Changes[j].TokenLength;
458
1.14k
    }
459
426
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
460
426
461
    // If we are restricted by the maximum column width, end the sequence.
462
426
    if (ChangeMinColumn > MaxColumn || 
ChangeMaxColumn < MinColumn423
||
463
420
        CommasBeforeLastMatch != CommasBeforeMatch) {
464
6
      AlignCurrentSequence();
465
6
      StartOfSequence = i;
466
6
    }
467
426
468
426
    MinColumn = std::max(MinColumn, ChangeMinColumn);
469
426
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
470
426
  }
471
2.88k
472
2.88k
  EndOfSequence = i;
473
2.88k
  AlignCurrentSequence();
474
2.88k
  return i;
475
2.88k
}
476
477
// Aligns a sequence of matching tokens, on the MinColumn column.
478
//
479
// Sequences start from the first matching token to align, and end at the
480
// first token of the first line that doesn't need to be aligned.
481
//
482
// We need to adjust the StartOfTokenColumn of each Change that is on a line
483
// containing any matching token to be aligned and located after such token.
484
static void AlignMacroSequence(
485
    unsigned &StartOfSequence, unsigned &EndOfSequence, unsigned &MinColumn,
486
    unsigned &MaxColumn, bool &FoundMatchOnLine,
487
    std::function<bool(const WhitespaceManager::Change &C)> AlignMacrosMatches,
488
1.07k
    SmallVector<WhitespaceManager::Change, 16> &Changes) {
489
1.07k
  if (StartOfSequence > 0 && 
StartOfSequence < EndOfSequence15
) {
490
15
491
15
    FoundMatchOnLine = false;
492
15
    int Shift = 0;
493
15
494
459
    for (unsigned I = StartOfSequence; I != EndOfSequence; 
++I444
) {
495
444
      if (Changes[I].NewlinesBefore > 0) {
496
39
        Shift = 0;
497
39
        FoundMatchOnLine = false;
498
39
      }
499
444
500
      // If this is the first matching token to be aligned, remember by how many
501
      // spaces it has to be shifted, so the rest of the changes on the line are
502
      // shifted by the same amount
503
444
      if (!FoundMatchOnLine && 
AlignMacrosMatches(Changes[I])279
) {
504
51
        FoundMatchOnLine = true;
505
51
        Shift = MinColumn - Changes[I].StartOfTokenColumn;
506
51
        Changes[I].Spaces += Shift;
507
51
      }
508
444
509
444
      assert(Shift >= 0);
510
444
      Changes[I].StartOfTokenColumn += Shift;
511
444
      if (I + 1 != Changes.size())
512
432
        Changes[I + 1].PreviousEndOfTokenColumn += Shift;
513
444
    }
514
15
  }
515
1.07k
516
1.07k
  MinColumn = 0;
517
1.07k
  MaxColumn = UINT_MAX;
518
1.07k
  StartOfSequence = 0;
519
1.07k
  EndOfSequence = 0;
520
1.07k
}
521
522
16.3k
void WhitespaceManager::alignConsecutiveMacros() {
523
16.3k
  if (!Style.AlignConsecutiveMacros)
524
16.0k
    return;
525
247
526
6.14k
  
auto AlignMacrosMatches = [](const Change &C) 247
{
527
6.14k
    const FormatToken *Current = C.Tok;
528
6.14k
    unsigned SpacesRequiredBefore = 1;
529
6.14k
530
6.14k
    if (Current->SpacesRequiredBefore == 0 || 
!Current->Previous4.22k
)
531
3.10k
      return false;
532
3.03k
533
3.03k
    Current = Current->Previous;
534
3.03k
535
    // If token is a ")", skip over the parameter list, to the
536
    // token that precedes the "("
537
3.03k
    if (Current->is(tok::r_paren) && 
Current->MatchingParen121
) {
538
121
      Current = Current->MatchingParen->Previous;
539
121
      SpacesRequiredBefore = 0;
540
121
    }
541
3.03k
542
3.03k
    if (!Current || !Current->is(tok::identifier))
543
1.98k
      return false;
544
1.05k
545
1.05k
    if (!Current->Previous || 
!Current->Previous->is(tok::pp_define)960
)
546
948
      return false;
547
102
548
    // For a macro function, 0 spaces are required between the
549
    // identifier and the lparen that opens the parameter list.
550
    // For a simple macro, 1 space is required between the
551
    // identifier and the first token of the defined value.
552
102
    return Current->Next->SpacesRequiredBefore == SpacesRequiredBefore;
553
102
  };
554
247
555
247
  unsigned MinColumn = 0;
556
247
  unsigned MaxColumn = UINT_MAX;
557
247
558
  // Start and end of the token sequence we're processing.
559
247
  unsigned StartOfSequence = 0;
560
247
  unsigned EndOfSequence = 0;
561
247
562
  // Whether a matching token has been found on the current line.
563
247
  bool FoundMatchOnLine = false;
564
247
565
247
  unsigned I = 0;
566
6.11k
  for (unsigned E = Changes.size(); I != E; 
++I5.86k
) {
567
5.86k
    if (Changes[I].NewlinesBefore != 0) {
568
863
      EndOfSequence = I;
569
      // If there is a blank line, or if the last line didn't contain any
570
      // matching token, the sequence ends here.
571
863
      if (Changes[I].NewlinesBefore > 1 || 
!FoundMatchOnLine856
)
572
824
        AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
573
824
                           FoundMatchOnLine, AlignMacrosMatches, Changes);
574
863
575
863
      FoundMatchOnLine = false;
576
863
    }
577
5.86k
578
5.86k
    if (!AlignMacrosMatches(Changes[I]))
579
5.81k
      continue;
580
51
581
51
    FoundMatchOnLine = true;
582
51
583
51
    if (StartOfSequence == 0)
584
15
      StartOfSequence = I;
585
51
586
51
    unsigned ChangeMinColumn = Changes[I].StartOfTokenColumn;
587
51
    int LineLengthAfter = -Changes[I].Spaces;
588
267
    for (unsigned j = I; j != E && 
Changes[j].NewlinesBefore == 0255
;
++j216
)
589
216
      LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength;
590
51
    unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
591
51
592
51
    MinColumn = std::max(MinColumn, ChangeMinColumn);
593
51
    MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
594
51
  }
595
247
596
247
  EndOfSequence = I;
597
247
  AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
598
247
                     FoundMatchOnLine, AlignMacrosMatches, Changes);
599
247
}
600
601
16.3k
void WhitespaceManager::alignConsecutiveAssignments() {
602
16.3k
  if (!Style.AlignConsecutiveAssignments)
603
16.0k
    return;
604
240
605
240
  AlignTokens(
606
240
      Style,
607
6.27k
      [&](const Change &C) {
608
        // Do not align on equal signs that are first on a line.
609
6.27k
        if (C.NewlinesBefore > 0)
610
1.14k
          return false;
611
5.13k
612
        // Do not align on equal signs that are last on a line.
613
5.13k
        if (&C != &Changes.back() && 
(&C + 1)->NewlinesBefore > 04.94k
)
614
840
          return false;
615
4.29k
616
4.29k
        return C.Tok->is(tok::equal);
617
4.29k
      },
618
240
      Changes, /*StartAt=*/0);
619
240
}
620
621
16.3k
void WhitespaceManager::alignConsecutiveBitFields() {
622
16.3k
  if (!Style.AlignConsecutiveBitFields)
623
16.2k
    return;
624
30
625
30
  AlignTokens(
626
30
      Style,
627
540
      [&](Change const &C) {
628
        // Do not align on ':' that is first on a line.
629
540
        if (C.NewlinesBefore > 0)
630
60
          return false;
631
480
632
        // Do not align on ':' that is last on a line.
633
480
        if (&C != &Changes.back() && 
(&C + 1)->NewlinesBefore > 0450
)
634
30
          return false;
635
450
636
450
        return C.Tok->is(TT_BitFieldColon);
637
450
      },
638
30
      Changes, /*StartAt=*/0);
639
30
}
640
641
16.3k
void WhitespaceManager::alignConsecutiveDeclarations() {
642
16.3k
  if (!Style.AlignConsecutiveDeclarations)
643
16.0k
    return;
644
243
645
  // FIXME: Currently we don't handle properly the PointerAlignment: Right
646
  // The * and & are not aligned and are left dangling. Something has to be done
647
  // about it, but it raises the question of alignment of code like:
648
  //   const char* const* v1;
649
  //   float const* v2;
650
  //   SomeVeryLongType const& v3;
651
243
  AlignTokens(
652
243
      Style,
653
6.43k
      [](Change const &C) {
654
        // tok::kw_operator is necessary for aligning operator overload
655
        // definitions.
656
6.43k
        if (C.Tok->isOneOf(TT_FunctionDeclarationName, tok::kw_operator))
657
186
          return true;
658
6.24k
        if (C.Tok->isNot(TT_StartOfName))
659
5.30k
          return false;
660
        // Check if there is a subsequent name that starts the same declaration.
661
942
        
for (FormatToken *Next = C.Tok->Next; 940
Next;
Next = Next->Next2
) {
662
942
          if (Next->is(tok::comment))
663
2
            continue;
664
940
          if (!Next->Tok.getIdentifierInfo())
665
938
            break;
666
2
          if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
667
2
                            tok::kw_operator))
668
2
            return false;
669
2
        }
670
938
        return true;
671
940
      },
672
243
      Changes, /*StartAt=*/0);
673
243
}
674
675
16.3k
void WhitespaceManager::alignChainedConditionals() {
676
16.3k
  if (Style.BreakBeforeTernaryOperators) {
677
14.8k
    AlignTokens(
678
14.8k
        Style,
679
247k
        [](Change const &C) {
680
          // Align question operators and last colon
681
247k
          return C.Tok->is(TT_ConditionalExpr) &&
682
1.57k
                 ((C.Tok->is(tok::question) && 
!C.NewlinesBefore705
) ||
683
952
                  (C.Tok->is(tok::colon) && 
C.Tok->Next870
&&
684
870
                   (C.Tok->Next->FakeLParens.size() == 0 ||
685
254
                    C.Tok->Next->FakeLParens.back() != prec::Conditional)));
686
247k
        },
687
14.8k
        Changes, /*StartAt=*/0);
688
1.48k
  } else {
689
37.5k
    static auto AlignWrappedOperand = [](Change const &C) {
690
37.5k
      auto Previous = C.Tok->getPreviousNonComment(); // Previous;
691
37.5k
      return C.NewlinesBefore && 
Previous5.25k
&&
Previous->is(TT_ConditionalExpr)2.93k
&&
692
909
             (Previous->is(tok::question) ||
693
753
              (Previous->is(tok::colon) &&
694
753
               (C.Tok->FakeLParens.size() == 0 ||
695
282
                C.Tok->FakeLParens.back() != prec::Conditional)));
696
37.5k
    };
697
    // Ensure we keep alignment of wrapped operands with non-wrapped operands
698
    // Since we actually align the operators, the wrapped operands need the
699
    // extra offset to be properly aligned.
700
18.7k
    for (Change &C : Changes) {
701
18.7k
      if (AlignWrappedOperand(C))
702
219
        C.StartOfTokenColumn -= 2;
703
18.7k
    }
704
1.48k
    AlignTokens(
705
1.48k
        Style,
706
19.2k
        [this](Change const &C) {
707
          // Align question operators if next operand is not wrapped, as
708
          // well as wrapped operands after question operator or last
709
          // colon in conditional sequence
710
19.2k
          return (C.Tok->is(TT_ConditionalExpr) && 
C.Tok->is(tok::question)790
&&
711
510
                  &C != &Changes.back() && (&C + 1)->NewlinesBefore == 0 &&
712
469
                  !(&C + 1)->IsTrailingComment) ||
713
18.7k
                 AlignWrappedOperand(C);
714
19.2k
        },
715
1.48k
        Changes, /*StartAt=*/0);
716
1.48k
  }
717
16.3k
}
718
719
16.3k
void WhitespaceManager::alignTrailingComments() {
720
16.3k
  unsigned MinColumn = 0;
721
16.3k
  unsigned MaxColumn = UINT_MAX;
722
16.3k
  unsigned StartOfSequence = 0;
723
16.3k
  bool BreakBeforeNext = false;
724
16.3k
  unsigned Newlines = 0;
725
281k
  for (unsigned i = 0, e = Changes.size(); i != e; 
++i265k
) {
726
265k
    if (Changes[i].StartOfBlockComment)
727
518
      continue;
728
264k
    Newlines += Changes[i].NewlinesBefore;
729
264k
    if (Changes[i].Tok->MustBreakAlignBefore)
730
577
      BreakBeforeNext = true;
731
264k
    if (!Changes[i].IsTrailingComment)
732
261k
      continue;
733
3.55k
734
3.55k
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
735
3.55k
    unsigned ChangeMaxColumn;
736
3.55k
737
3.55k
    if (Style.ColumnLimit == 0)
738
158
      ChangeMaxColumn = UINT_MAX;
739
3.40k
    else if (Style.ColumnLimit >= Changes[i].TokenLength)
740
3.35k
      ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
741
49
    else
742
49
      ChangeMaxColumn = ChangeMinColumn;
743
3.55k
744
    // If we don't create a replacement for this change, we have to consider
745
    // it to be immovable.
746
3.55k
    if (!Changes[i].CreateReplacement)
747
469
      ChangeMaxColumn = ChangeMinColumn;
748
3.55k
749
3.55k
    if (i + 1 != e && 
Changes[i + 1].ContinuesPPDirective3.55k
)
750
68
      ChangeMaxColumn -= 2;
751
    // If this comment follows an } in column 0, it probably documents the
752
    // closing of a namespace and we don't want to align it.
753
3.55k
    bool FollowsRBraceInColumn0 = i > 0 && 
Changes[i].NewlinesBefore == 03.18k
&&
754
1.87k
                                  Changes[i - 1].Tok->is(tok::r_brace) &&
755
840
                                  Changes[i - 1].StartOfTokenColumn == 0;
756
3.55k
    bool WasAlignedWithStartOfNextLine = false;
757
3.55k
    if (Changes[i].NewlinesBefore == 1) { // A comment on its own line.
758
1.28k
      unsigned CommentColumn = SourceMgr.getSpellingColumnNumber(
759
1.28k
          Changes[i].OriginalWhitespaceRange.getEnd());
760
4.78k
      for (unsigned j = i + 1; j != e; 
++j3.50k
) {
761
4.78k
        if (Changes[j].Tok->is(tok::comment))
762
3.50k
          continue;
763
1.28k
764
1.28k
        unsigned NextColumn = SourceMgr.getSpellingColumnNumber(
765
1.28k
            Changes[j].OriginalWhitespaceRange.getEnd());
766
        // The start of the next token was previously aligned with the
767
        // start of this comment.
768
1.28k
        WasAlignedWithStartOfNextLine =
769
1.28k
            CommentColumn == NextColumn ||
770
613
            CommentColumn == NextColumn + Style.IndentWidth;
771
1.28k
        break;
772
1.28k
      }
773
1.28k
    }
774
3.55k
    if (!Style.AlignTrailingComments || 
FollowsRBraceInColumn03.47k
) {
775
426
      alignTrailingComments(StartOfSequence, i, MinColumn);
776
426
      MinColumn = ChangeMinColumn;
777
426
      MaxColumn = ChangeMinColumn;
778
426
      StartOfSequence = i;
779
3.13k
    } else if (BreakBeforeNext || 
Newlines > 12.45k
||
780
1.70k
               (ChangeMinColumn > MaxColumn || 
ChangeMaxColumn < MinColumn1.70k
) ||
781
               // Break the comment sequence if the previous line did not end
782
               // in a trailing comment.
783
1.69k
               (Changes[i].NewlinesBefore == 1 && 
i > 0422
&&
784
411
                !Changes[i - 1].IsTrailingComment) ||
785
1.79k
               
WasAlignedWithStartOfNextLine1.38k
) {
786
1.79k
      alignTrailingComments(StartOfSequence, i, MinColumn);
787
1.79k
      MinColumn = ChangeMinColumn;
788
1.79k
      MaxColumn = ChangeMaxColumn;
789
1.79k
      StartOfSequence = i;
790
1.33k
    } else {
791
1.33k
      MinColumn = std::max(MinColumn, ChangeMinColumn);
792
1.33k
      MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
793
1.33k
    }
794
3.55k
    BreakBeforeNext = (i == 0) || 
(Changes[i].NewlinesBefore > 1)3.18k
||
795
                      // Never start a sequence with a comment at the beginning
796
                      // of the line.
797
3.14k
                      (Changes[i].NewlinesBefore == 1 && 
StartOfSequence == i1.27k
);
798
3.55k
    Newlines = 0;
799
3.55k
  }
800
16.3k
  alignTrailingComments(StartOfSequence, Changes.size(), MinColumn);
801
16.3k
}
802
803
void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
804
18.5k
                                              unsigned Column) {
805
283k
  for (unsigned i = Start; i != End; 
++i265k
) {
806
265k
    int Shift = 0;
807
265k
    if (Changes[i].IsTrailingComment) {
808
4.02k
      Shift = Column - Changes[i].StartOfTokenColumn;
809
4.02k
    }
810
265k
    if (Changes[i].StartOfBlockComment) {
811
518
      Shift = Changes[i].IndentationOffset +
812
518
              Changes[i].StartOfBlockComment->StartOfTokenColumn -
813
518
              Changes[i].StartOfTokenColumn;
814
518
    }
815
265k
    assert(Shift >= 0);
816
265k
    Changes[i].Spaces += Shift;
817
265k
    if (i + 1 != Changes.size())
818
249k
      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
819
265k
    Changes[i].StartOfTokenColumn += Shift;
820
265k
  }
821
18.5k
}
822
823
16.3k
void WhitespaceManager::alignEscapedNewlines() {
824
16.3k
  if (Style.AlignEscapedNewlines == FormatStyle::ENAS_DontAlign)
825
7
    return;
826
16.3k
827
16.3k
  bool AlignLeft = Style.AlignEscapedNewlines == FormatStyle::ENAS_Left;
828
12.8k
  unsigned MaxEndOfLine = AlignLeft ? 
03.49k
: Style.ColumnLimit;
829
16.3k
  unsigned StartOfMacro = 0;
830
265k
  for (unsigned i = 1, e = Changes.size(); i < e; 
++i248k
) {
831
248k
    Change &C = Changes[i];
832
248k
    if (C.NewlinesBefore > 0) {
833
35.3k
      if (C.ContinuesPPDirective) {
834
600
        MaxEndOfLine = std::max(C.PreviousEndOfTokenColumn + 2, MaxEndOfLine);
835
34.7k
      } else {
836
34.7k
        alignEscapedNewlines(StartOfMacro + 1, i, MaxEndOfLine);
837
27.7k
        MaxEndOfLine = AlignLeft ? 
06.94k
: Style.ColumnLimit;
838
34.7k
        StartOfMacro = i;
839
34.7k
      }
840
35.3k
    }
841
248k
  }
842
16.3k
  alignEscapedNewlines(StartOfMacro + 1, Changes.size(), MaxEndOfLine);
843
16.3k
}
844
845
void WhitespaceManager::alignEscapedNewlines(unsigned Start, unsigned End,
846
51.0k
                                             unsigned Column) {
847
265k
  for (unsigned i = Start; i < End; 
++i214k
) {
848
214k
    Change &C = Changes[i];
849
214k
    if (C.NewlinesBefore > 0) {
850
600
      assert(C.ContinuesPPDirective);
851
600
      if (C.PreviousEndOfTokenColumn + 1 > Column)
852
0
        C.EscapedNewlineColumn = 0;
853
600
      else
854
600
        C.EscapedNewlineColumn = Column;
855
600
    }
856
214k
  }
857
51.0k
}
858
859
16.3k
void WhitespaceManager::generateChanges() {
860
281k
  for (unsigned i = 0, e = Changes.size(); i != e; 
++i265k
) {
861
265k
    const Change &C = Changes[i];
862
265k
    if (i > 0) {
863
249k
      assert(Changes[i - 1].OriginalWhitespaceRange.getBegin() !=
864
249k
                 C.OriginalWhitespaceRange.getBegin() &&
865
249k
             "Generating two replacements for the same location");
866
249k
    }
867
265k
    if (C.CreateReplacement) {
868
241k
      std::string ReplacementText = C.PreviousLinePostfix;
869
241k
      if (C.ContinuesPPDirective)
870
569
        appendEscapedNewlineText(ReplacementText, C.NewlinesBefore,
871
569
                                 C.PreviousEndOfTokenColumn,
872
569
                                 C.EscapedNewlineColumn);
873
240k
      else
874
240k
        appendNewlineText(ReplacementText, C.NewlinesBefore);
875
241k
      appendIndentText(
876
241k
          ReplacementText, C.Tok->IndentLevel, std::max(0, C.Spaces),
877
241k
          C.StartOfTokenColumn - std::max(0, C.Spaces), C.IsAligned);
878
241k
      ReplacementText.append(C.CurrentLinePrefix);
879
241k
      storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
880
241k
    }
881
265k
  }
882
16.3k
}
883
884
241k
void WhitespaceManager::storeReplacement(SourceRange Range, StringRef Text) {
885
241k
  unsigned WhitespaceLength = SourceMgr.getFileOffset(Range.getEnd()) -
886
241k
                              SourceMgr.getFileOffset(Range.getBegin());
887
  // Don't create a replacement, if it does not change anything.
888
241k
  if (StringRef(SourceMgr.getCharacterData(Range.getBegin()),
889
241k
                WhitespaceLength) == Text)
890
221k
    return;
891
20.2k
  auto Err = Replaces.add(tooling::Replacement(
892
20.2k
      SourceMgr, CharSourceRange::getCharRange(Range), Text));
893
  // FIXME: better error handling. For now, just print an error message in the
894
  // release version.
895
20.2k
  if (Err) {
896
0
    llvm::errs() << llvm::toString(std::move(Err)) << "\n";
897
0
    assert(false);
898
0
  }
899
20.2k
}
900
901
void WhitespaceManager::appendNewlineText(std::string &Text,
902
240k
                                          unsigned Newlines) {
903
271k
  for (unsigned i = 0; i < Newlines; 
++i30.9k
)
904
30.9k
    Text.append(UseCRLF ? 
"\r\n"40
:
"\n"30.9k
);
905
240k
}
906
907
void WhitespaceManager::appendEscapedNewlineText(
908
    std::string &Text, unsigned Newlines, unsigned PreviousEndOfTokenColumn,
909
569
    unsigned EscapedNewlineColumn) {
910
569
  if (Newlines > 0) {
911
566
    unsigned Spaces =
912
566
        std::max<int>(1, EscapedNewlineColumn - PreviousEndOfTokenColumn - 1);
913
1.13k
    for (unsigned i = 0; i < Newlines; 
++i571
) {
914
571
      Text.append(Spaces, ' ');
915
564
      Text.append(UseCRLF ? 
"\\\r\n"7
: "\\\n");
916
571
      Spaces = std::max<int>(0, EscapedNewlineColumn - 1);
917
571
    }
918
566
  }
919
569
}
920
921
void WhitespaceManager::appendIndentText(std::string &Text,
922
                                         unsigned IndentLevel, unsigned Spaces,
923
                                         unsigned WhitespaceStartColumn,
924
241k
                                         bool IsAligned) {
925
241k
  switch (Style.UseTab) {
926
239k
  case FormatStyle::UT_Never:
927
239k
    Text.append(Spaces, ' ');
928
239k
    break;
929
481
  case FormatStyle::UT_Always: {
930
481
    if (Style.TabWidth) {
931
463
      unsigned FirstTabWidth =
932
463
          Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
933
463
934
      // Insert only spaces when we want to end up before the next tab.
935
463
      if (Spaces < FirstTabWidth || 
Spaces == 1116
) {
936
368
        Text.append(Spaces, ' ');
937
368
        break;
938
368
      }
939
      // Align to the next tab.
940
95
      Spaces -= FirstTabWidth;
941
95
      Text.append("\t");
942
95
943
95
      Text.append(Spaces / Style.TabWidth, '\t');
944
95
      Text.append(Spaces % Style.TabWidth, ' ');
945
18
    } else if (Spaces == 1) {
946
2
      Text.append(Spaces, ' ');
947
2
    }
948
113
    break;
949
481
  }
950
304
  case FormatStyle::UT_ForIndentation:
951
304
    if (WhitespaceStartColumn == 0) {
952
144
      unsigned Indentation = IndentLevel * Style.IndentWidth;
953
144
      Spaces = appendTabIndent(Text, Spaces, Indentation);
954
144
    }
955
304
    Text.append(Spaces, ' ');
956
304
    break;
957
738
  case FormatStyle::UT_ForContinuationAndIndentation:
958
738
    if (WhitespaceStartColumn == 0)
959
319
      Spaces = appendTabIndent(Text, Spaces, Spaces);
960
738
    Text.append(Spaces, ' ');
961
738
    break;
962
840
  case FormatStyle::UT_AlignWithSpaces:
963
840
    if (WhitespaceStartColumn == 0) {
964
358
      unsigned Indentation =
965
301
          IsAligned ? 
IndentLevel * Style.IndentWidth57
: Spaces;
966
358
      Spaces = appendTabIndent(Text, Spaces, Indentation);
967
358
    }
968
840
    Text.append(Spaces, ' ');
969
840
    break;
970
241k
  }
971
241k
}
972
973
unsigned WhitespaceManager::appendTabIndent(std::string &Text, unsigned Spaces,
974
821
                                            unsigned Indentation) {
975
  // This happens, e.g. when a line in a block comment is indented less than the
976
  // first one.
977
821
  if (Indentation > Spaces)
978
4
    Indentation = Spaces;
979
821
  if (Style.TabWidth) {
980
797
    unsigned Tabs = Indentation / Style.TabWidth;
981
797
    Text.append(Tabs, '\t');
982
797
    Spaces -= Tabs * Style.TabWidth;
983
797
  }
984
821
  return Spaces;
985
821
}
986
987
} // namespace format
988
} // namespace clang