Bug Summary

File:clang/lib/Format/UnwrappedLineFormatter.cpp
Warning:line 1280, column 11
Access to field 'NewlinesBefore' results in a dereference of a null pointer (loaded from field 'First')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name UnwrappedLineFormatter.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/lib/Format -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/clang/lib/Format -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-01-19-134126-35450-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/clang/lib/Format/UnwrappedLineFormatter.cpp
1//===--- UnwrappedLineFormatter.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#include "UnwrappedLineFormatter.h"
10#include "NamespaceEndCommentsFixer.h"
11#include "WhitespaceManager.h"
12#include "llvm/Support/Debug.h"
13#include <queue>
14
15#define DEBUG_TYPE"format-formatter" "format-formatter"
16
17namespace clang {
18namespace format {
19
20namespace {
21
22bool startsExternCBlock(const AnnotatedLine &Line) {
23 const FormatToken *Next = Line.First->getNextNonComment();
24 const FormatToken *NextNext = Next ? Next->getNextNonComment() : nullptr;
25 return Line.startsWith(tok::kw_extern) && Next && Next->isStringLiteral() &&
26 NextNext && NextNext->is(tok::l_brace);
27}
28
29/// Tracks the indent level of \c AnnotatedLines across levels.
30///
31/// \c nextLine must be called for each \c AnnotatedLine, after which \c
32/// getIndent() will return the indent for the last line \c nextLine was called
33/// with.
34/// If the line is not formatted (and thus the indent does not change), calling
35/// \c adjustToUnmodifiedLine after the call to \c nextLine will cause
36/// subsequent lines on the same level to be indented at the same level as the
37/// given line.
38class LevelIndentTracker {
39public:
40 LevelIndentTracker(const FormatStyle &Style,
41 const AdditionalKeywords &Keywords, unsigned StartLevel,
42 int AdditionalIndent)
43 : Style(Style), Keywords(Keywords), AdditionalIndent(AdditionalIndent) {
44 for (unsigned i = 0; i != StartLevel; ++i)
45 IndentForLevel.push_back(Style.IndentWidth * i + AdditionalIndent);
46 }
47
48 /// Returns the indent for the current line.
49 unsigned getIndent() const { return Indent; }
50
51 /// Update the indent state given that \p Line is going to be formatted
52 /// next.
53 void nextLine(const AnnotatedLine &Line) {
54 Offset = getIndentOffset(*Line.First);
55 // Update the indent level cache size so that we can rely on it
56 // having the right size in adjustToUnmodifiedline.
57 while (IndentForLevel.size() <= Line.Level)
58 IndentForLevel.push_back(-1);
59 if (Line.InPPDirective) {
60 unsigned IndentWidth =
61 (Style.PPIndentWidth >= 0) ? Style.PPIndentWidth : Style.IndentWidth;
62 Indent = Line.Level * IndentWidth + AdditionalIndent;
63 } else {
64 IndentForLevel.resize(Line.Level + 1);
65 Indent = getIndent(Line.Level);
66 }
67 if (static_cast<int>(Indent) + Offset >= 0)
68 Indent += Offset;
69 if (Line.First->is(TT_CSharpGenericTypeConstraint))
70 Indent = Line.Level * Style.IndentWidth + Style.ContinuationIndentWidth;
71 }
72
73 /// Update the indent state given that \p Line indent should be
74 /// skipped.
75 void skipLine(const AnnotatedLine &Line) {
76 while (IndentForLevel.size() <= Line.Level)
77 IndentForLevel.push_back(Indent);
78 }
79
80 /// Update the level indent to adapt to the given \p Line.
81 ///
82 /// When a line is not formatted, we move the subsequent lines on the same
83 /// level to the same indent.
84 /// Note that \c nextLine must have been called before this method.
85 void adjustToUnmodifiedLine(const AnnotatedLine &Line) {
86 unsigned LevelIndent = Line.First->OriginalColumn;
87 if (static_cast<int>(LevelIndent) - Offset >= 0)
88 LevelIndent -= Offset;
89 if ((!Line.First->is(tok::comment) || IndentForLevel[Line.Level] == -1) &&
90 !Line.InPPDirective)
91 IndentForLevel[Line.Level] = LevelIndent;
92 }
93
94private:
95 /// Get the offset of the line relatively to the level.
96 ///
97 /// For example, 'public:' labels in classes are offset by 1 or 2
98 /// characters to the left from their level.
99 int getIndentOffset(const FormatToken &RootToken) {
100 if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() ||
101 Style.isCSharp())
102 return 0;
103 if (RootToken.isAccessSpecifier(false) ||
104 RootToken.isObjCAccessSpecifier() ||
105 (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
106 RootToken.Next && RootToken.Next->is(tok::colon))) {
107 // The AccessModifierOffset may be overridden by IndentAccessModifiers,
108 // in which case we take a negative value of the IndentWidth to simulate
109 // the upper indent level.
110 return Style.IndentAccessModifiers ? -Style.IndentWidth
111 : Style.AccessModifierOffset;
112 }
113 return 0;
114 }
115
116 /// Get the indent of \p Level from \p IndentForLevel.
117 ///
118 /// \p IndentForLevel must contain the indent for the level \c l
119 /// at \p IndentForLevel[l], or a value < 0 if the indent for
120 /// that level is unknown.
121 unsigned getIndent(unsigned Level) const {
122 if (IndentForLevel[Level] != -1)
123 return IndentForLevel[Level];
124 if (Level == 0)
125 return 0;
126 return getIndent(Level - 1) + Style.IndentWidth;
127 }
128
129 const FormatStyle &Style;
130 const AdditionalKeywords &Keywords;
131 const unsigned AdditionalIndent;
132
133 /// The indent in characters for each level.
134 std::vector<int> IndentForLevel;
135
136 /// Offset of the current line relative to the indent level.
137 ///
138 /// For example, the 'public' keywords is often indented with a negative
139 /// offset.
140 int Offset = 0;
141
142 /// The current line's indent.
143 unsigned Indent = 0;
144};
145
146const FormatToken *getMatchingNamespaceToken(
147 const AnnotatedLine *Line,
148 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
149 if (!Line->startsWith(tok::r_brace))
150 return nullptr;
151 size_t StartLineIndex = Line->MatchingOpeningBlockLineIndex;
152 if (StartLineIndex == UnwrappedLine::kInvalidIndex)
153 return nullptr;
154 assert(StartLineIndex < AnnotatedLines.size())(static_cast <bool> (StartLineIndex < AnnotatedLines
.size()) ? void (0) : __assert_fail ("StartLineIndex < AnnotatedLines.size()"
, "clang/lib/Format/UnwrappedLineFormatter.cpp", 154, __extension__
__PRETTY_FUNCTION__))
;
155 return AnnotatedLines[StartLineIndex]->First->getNamespaceToken();
156}
157
158StringRef getNamespaceTokenText(const AnnotatedLine *Line) {
159 const FormatToken *NamespaceToken = Line->First->getNamespaceToken();
160 return NamespaceToken ? NamespaceToken->TokenText : StringRef();
161}
162
163StringRef getMatchingNamespaceTokenText(
164 const AnnotatedLine *Line,
165 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
166 const FormatToken *NamespaceToken =
167 getMatchingNamespaceToken(Line, AnnotatedLines);
168 return NamespaceToken ? NamespaceToken->TokenText : StringRef();
169}
170
171class LineJoiner {
172public:
173 LineJoiner(const FormatStyle &Style, const AdditionalKeywords &Keywords,
174 const SmallVectorImpl<AnnotatedLine *> &Lines)
175 : Style(Style), Keywords(Keywords), End(Lines.end()), Next(Lines.begin()),
176 AnnotatedLines(Lines) {}
177
178 /// Returns the next line, merging multiple lines into one if possible.
179 const AnnotatedLine *getNextMergedLine(bool DryRun,
180 LevelIndentTracker &IndentTracker) {
181 if (Next == End)
22
Assuming field 'Next' is not equal to field 'End'
23
Taking false branch
40
Assuming field 'Next' is not equal to field 'End'
41
Taking false branch
182 return nullptr;
183 const AnnotatedLine *Current = *Next;
184 IndentTracker.nextLine(*Current);
185 unsigned MergedLines = tryFitMultipleLinesInOne(IndentTracker, Next, End);
186 if (MergedLines > 0 && Style.ColumnLimit == 0)
24
Assuming 'MergedLines' is <= 0
42
Assuming 'MergedLines' is <= 0
187 // Disallow line merging if there is a break at the start of one of the
188 // input lines.
189 for (unsigned i = 0; i < MergedLines; ++i)
190 if (Next[i + 1]->First->NewlinesBefore > 0)
191 MergedLines = 0;
192 if (!DryRun
24.1
'DryRun' is false
42.1
'DryRun' is false
)
25
Taking true branch
43
Taking true branch
193 for (unsigned i = 0; i < MergedLines; ++i)
26
Loop condition is false. Execution continues on line 195
44
Loop condition is false. Execution continues on line 195
194 join(*Next[0], *Next[i + 1]);
195 Next = Next + MergedLines + 1;
196 return Current;
27
Returning pointer (loaded from 'Current'), which participates in a condition later
45
Returning pointer (loaded from 'Current'), which participates in a condition later
197 }
198
199private:
200 /// Calculates how many lines can be merged into 1 starting at \p I.
201 unsigned
202 tryFitMultipleLinesInOne(LevelIndentTracker &IndentTracker,
203 SmallVectorImpl<AnnotatedLine *>::const_iterator I,
204 SmallVectorImpl<AnnotatedLine *>::const_iterator E) {
205 const unsigned Indent = IndentTracker.getIndent();
206
207 // Can't join the last line with anything.
208 if (I + 1 == E)
209 return 0;
210 // We can never merge stuff if there are trailing line comments.
211 const AnnotatedLine *TheLine = *I;
212 if (TheLine->Last->is(TT_LineComment))
213 return 0;
214 if (I[1]->Type == LT_Invalid || I[1]->First->MustBreakBefore)
215 return 0;
216 if (TheLine->InPPDirective &&
217 (!I[1]->InPPDirective || I[1]->First->HasUnescapedNewline))
218 return 0;
219
220 if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit)
221 return 0;
222
223 unsigned Limit =
224 Style.ColumnLimit == 0 ? UINT_MAX(2147483647 *2U +1U) : Style.ColumnLimit - Indent;
225 // If we already exceed the column limit, we set 'Limit' to 0. The different
226 // tryMerge..() functions can then decide whether to still do merging.
227 Limit = TheLine->Last->TotalLength > Limit
228 ? 0
229 : Limit - TheLine->Last->TotalLength;
230
231 if (TheLine->Last->is(TT_FunctionLBrace) &&
232 TheLine->First == TheLine->Last &&
233 !Style.BraceWrapping.SplitEmptyFunction &&
234 I[1]->First->is(tok::r_brace))
235 return tryMergeSimpleBlock(I, E, Limit);
236
237 // Handle empty record blocks where the brace has already been wrapped
238 if (TheLine->Last->is(tok::l_brace) && TheLine->First == TheLine->Last &&
239 I != AnnotatedLines.begin()) {
240 bool EmptyBlock = I[1]->First->is(tok::r_brace);
241
242 const FormatToken *Tok = I[-1]->First;
243 if (Tok && Tok->is(tok::comment))
244 Tok = Tok->getNextNonComment();
245
246 if (Tok && Tok->getNamespaceToken())
247 return !Style.BraceWrapping.SplitEmptyNamespace && EmptyBlock
248 ? tryMergeSimpleBlock(I, E, Limit)
249 : 0;
250
251 if (Tok && Tok->is(tok::kw_typedef))
252 Tok = Tok->getNextNonComment();
253 if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
254 tok::kw_extern, Keywords.kw_interface))
255 return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock
256 ? tryMergeSimpleBlock(I, E, Limit)
257 : 0;
258
259 if (Tok && Tok->is(tok::kw_template) &&
260 Style.BraceWrapping.SplitEmptyRecord && EmptyBlock) {
261 return 0;
262 }
263 }
264
265 auto ShouldMergeShortFunctions =
266 [this, B = AnnotatedLines.begin()](
267 SmallVectorImpl<AnnotatedLine *>::const_iterator I) {
268 if (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
269 return true;
270 if (Style.AllowShortFunctionsOnASingleLine >=
271 FormatStyle::SFS_Empty &&
272 I[1]->First->is(tok::r_brace))
273 return true;
274
275 if (Style.AllowShortFunctionsOnASingleLine &
276 FormatStyle::SFS_InlineOnly) {
277 // Just checking TheLine->Level != 0 is not enough, because it
278 // provokes treating functions inside indented namespaces as short.
279 if ((*I)->Level != 0) {
280 if (I == B)
281 return false;
282
283 // TODO: Use IndentTracker to avoid loop?
284 // Find the last line with lower level.
285 auto J = I - 1;
286 for (; J != B; --J)
287 if ((*J)->Level < (*I)->Level)
288 break;
289
290 // Check if the found line starts a record.
291 auto *RecordTok = (*J)->First;
292 while (RecordTok) {
293 // TODO: Refactor to isRecord(RecordTok).
294 if (RecordTok->isOneOf(tok::kw_class, tok::kw_struct))
295 return true;
296 if (Style.isCpp() && RecordTok->is(tok::kw_union))
297 return true;
298 if (Style.isCSharp() && RecordTok->is(Keywords.kw_interface))
299 return true;
300 if (Style.Language == FormatStyle::LK_Java &&
301 RecordTok->is(tok::kw_enum))
302 return true;
303 if (Style.isJavaScript() && RecordTok->is(Keywords.kw_function))
304 return true;
305
306 RecordTok = RecordTok->Next;
307 }
308
309 return false;
310 }
311 }
312
313 return false;
314 };
315
316 bool MergeShortFunctions = ShouldMergeShortFunctions(I);
317
318 if (Style.CompactNamespaces) {
319 if (auto nsToken = TheLine->First->getNamespaceToken()) {
320 int i = 0;
321 unsigned closingLine = TheLine->MatchingClosingBlockLineIndex - 1;
322 for (; I + 1 + i != E &&
323 nsToken->TokenText == getNamespaceTokenText(I[i + 1]) &&
324 closingLine == I[i + 1]->MatchingClosingBlockLineIndex &&
325 I[i + 1]->Last->TotalLength < Limit;
326 i++, closingLine--) {
327 // No extra indent for compacted namespaces
328 IndentTracker.skipLine(*I[i + 1]);
329
330 Limit -= I[i + 1]->Last->TotalLength;
331 }
332 return i;
333 }
334
335 if (auto nsToken = getMatchingNamespaceToken(TheLine, AnnotatedLines)) {
336 int i = 0;
337 unsigned openingLine = TheLine->MatchingOpeningBlockLineIndex - 1;
338 for (; I + 1 + i != E &&
339 nsToken->TokenText ==
340 getMatchingNamespaceTokenText(I[i + 1], AnnotatedLines) &&
341 openingLine == I[i + 1]->MatchingOpeningBlockLineIndex;
342 i++, openingLine--) {
343 // No space between consecutive braces
344 I[i + 1]->First->SpacesRequiredBefore = !I[i]->Last->is(tok::r_brace);
345
346 // Indent like the outer-most namespace
347 IndentTracker.nextLine(*I[i + 1]);
348 }
349 return i;
350 }
351 }
352
353 // Try to merge a function block with left brace unwrapped
354 if (TheLine->Last->is(TT_FunctionLBrace) &&
355 TheLine->First != TheLine->Last) {
356 return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0;
357 }
358 // Try to merge a control statement block with left brace unwrapped
359 if (TheLine->Last->is(tok::l_brace) && TheLine->First != TheLine->Last &&
360 TheLine->First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for,
361 TT_ForEachMacro)) {
362 return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never
363 ? tryMergeSimpleBlock(I, E, Limit)
364 : 0;
365 }
366 // Try to merge a control statement block with left brace wrapped
367 if (I[1]->First->is(tok::l_brace) &&
368 (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
369 tok::kw_for, tok::kw_switch, tok::kw_try,
370 tok::kw_do, TT_ForEachMacro) ||
371 (TheLine->First->is(tok::r_brace) && TheLine->First->Next &&
372 TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch))) &&
373 Style.BraceWrapping.AfterControlStatement ==
374 FormatStyle::BWACS_MultiLine) {
375 // If possible, merge the next line's wrapped left brace with the current
376 // line. Otherwise, leave it on the next line, as this is a multi-line
377 // control statement.
378 return (Style.ColumnLimit == 0 ||
379 TheLine->Last->TotalLength <= Style.ColumnLimit)
380 ? 1
381 : 0;
382 } else if (I[1]->First->is(tok::l_brace) &&
383 TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
384 tok::kw_for, TT_ForEachMacro)) {
385 return (Style.BraceWrapping.AfterControlStatement ==
386 FormatStyle::BWACS_Always)
387 ? tryMergeSimpleBlock(I, E, Limit)
388 : 0;
389 } else if (I[1]->First->is(tok::l_brace) &&
390 TheLine->First->isOneOf(tok::kw_else, tok::kw_catch) &&
391 Style.BraceWrapping.AfterControlStatement ==
392 FormatStyle::BWACS_MultiLine) {
393 // This case if different from the upper BWACS_MultiLine processing
394 // in that a preceding r_brace is not on the same line as else/catch
395 // most likely because of BeforeElse/BeforeCatch set to true.
396 // If the line length doesn't fit ColumnLimit, leave l_brace on the
397 // next line to respect the BWACS_MultiLine.
398 return (Style.ColumnLimit == 0 ||
399 TheLine->Last->TotalLength <= Style.ColumnLimit)
400 ? 1
401 : 0;
402 }
403 // Don't merge block with left brace wrapped after ObjC special blocks
404 if (TheLine->First->is(tok::l_brace) && I != AnnotatedLines.begin() &&
405 I[-1]->First->is(tok::at) && I[-1]->First->Next) {
406 tok::ObjCKeywordKind kwId = I[-1]->First->Next->Tok.getObjCKeywordID();
407 if (kwId == clang::tok::objc_autoreleasepool ||
408 kwId == clang::tok::objc_synchronized)
409 return 0;
410 }
411 // Don't merge block with left brace wrapped after case labels
412 if (TheLine->First->is(tok::l_brace) && I != AnnotatedLines.begin() &&
413 I[-1]->First->isOneOf(tok::kw_case, tok::kw_default))
414 return 0;
415
416 // Don't merge an empty template class or struct if SplitEmptyRecords
417 // is defined.
418 if (Style.BraceWrapping.SplitEmptyRecord &&
419 TheLine->Last->is(tok::l_brace) && I != AnnotatedLines.begin() &&
420 I[-1]->Last) {
421 const FormatToken *Previous = I[-1]->Last;
422 if (Previous) {
423 if (Previous->is(tok::comment))
424 Previous = Previous->getPreviousNonComment();
425 if (Previous) {
426 if (Previous->is(tok::greater) && !I[-1]->InPPDirective)
427 return 0;
428 if (Previous->is(tok::identifier)) {
429 const FormatToken *PreviousPrevious =
430 Previous->getPreviousNonComment();
431 if (PreviousPrevious &&
432 PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct))
433 return 0;
434 }
435 }
436 }
437 }
438
439 // Try to merge a block with left brace unwrapped that wasn't yet covered
440 if (TheLine->Last->is(tok::l_brace)) {
441 const FormatToken *Tok = TheLine->First;
442 bool ShouldMerge = false;
443 if (Tok->is(tok::kw_typedef)) {
444 Tok = Tok->getNextNonComment();
445 assert(Tok)(static_cast <bool> (Tok) ? void (0) : __assert_fail ("Tok"
, "clang/lib/Format/UnwrappedLineFormatter.cpp", 445, __extension__
__PRETTY_FUNCTION__))
;
446 }
447 if (Tok->isOneOf(tok::kw_class, tok::kw_struct)) {
448 ShouldMerge = !Style.BraceWrapping.AfterClass ||
449 (I[1]->First->is(tok::r_brace) &&
450 !Style.BraceWrapping.SplitEmptyRecord);
451 } else if (Tok->is(tok::kw_enum)) {
452 ShouldMerge = Style.AllowShortEnumsOnASingleLine;
453 } else {
454 ShouldMerge = !Style.BraceWrapping.AfterFunction ||
455 (I[1]->First->is(tok::r_brace) &&
456 !Style.BraceWrapping.SplitEmptyFunction);
457 }
458 return ShouldMerge ? tryMergeSimpleBlock(I, E, Limit) : 0;
459 }
460 // Try to merge a function block with left brace wrapped
461 if (I[1]->First->is(TT_FunctionLBrace) &&
462 Style.BraceWrapping.AfterFunction) {
463 if (I[1]->Last->is(TT_LineComment))
464 return 0;
465
466 // Check for Limit <= 2 to account for the " {".
467 if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine)))
468 return 0;
469 Limit -= 2;
470
471 unsigned MergedLines = 0;
472 if (MergeShortFunctions ||
473 (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty &&
474 I[1]->First == I[1]->Last && I + 2 != E &&
475 I[2]->First->is(tok::r_brace))) {
476 MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
477 // If we managed to merge the block, count the function header, which is
478 // on a separate line.
479 if (MergedLines > 0)
480 ++MergedLines;
481 }
482 return MergedLines;
483 }
484 auto IsElseLine = [&TheLine]() -> bool {
485 const FormatToken *First = TheLine->First;
486 if (First->is(tok::kw_else))
487 return true;
488
489 return First->is(tok::r_brace) && First->Next &&
490 First->Next->is(tok::kw_else);
491 };
492 if (TheLine->First->is(tok::kw_if) ||
493 (IsElseLine() && (Style.AllowShortIfStatementsOnASingleLine ==
494 FormatStyle::SIS_AllIfsAndElse))) {
495 return Style.AllowShortIfStatementsOnASingleLine
496 ? tryMergeSimpleControlStatement(I, E, Limit)
497 : 0;
498 }
499 if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while, tok::kw_do,
500 TT_ForEachMacro)) {
501 return Style.AllowShortLoopsOnASingleLine
502 ? tryMergeSimpleControlStatement(I, E, Limit)
503 : 0;
504 }
505 if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) {
506 return Style.AllowShortCaseLabelsOnASingleLine
507 ? tryMergeShortCaseLabels(I, E, Limit)
508 : 0;
509 }
510 if (TheLine->InPPDirective &&
511 (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {
512 return tryMergeSimplePPDirective(I, E, Limit);
513 }
514 return 0;
515 }
516
517 unsigned
518 tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
519 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
520 unsigned Limit) {
521 if (Limit == 0)
522 return 0;
523 if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline)
524 return 0;
525 if (1 + I[1]->Last->TotalLength > Limit)
526 return 0;
527 return 1;
528 }
529
530 unsigned tryMergeSimpleControlStatement(
531 SmallVectorImpl<AnnotatedLine *>::const_iterator I,
532 SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {
533 if (Limit == 0)
534 return 0;
535 if (Style.BraceWrapping.AfterControlStatement ==
536 FormatStyle::BWACS_Always &&
537 I[1]->First->is(tok::l_brace) &&
538 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
539 return 0;
540 if (I[1]->InPPDirective != (*I)->InPPDirective ||
541 (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline))
542 return 0;
543 Limit = limitConsideringMacros(I + 1, E, Limit);
544 AnnotatedLine &Line = **I;
545 if (!Line.First->is(tok::kw_do) && !Line.First->is(tok::kw_else) &&
546 !Line.Last->is(tok::kw_else) && Line.Last->isNot(tok::r_paren))
547 return 0;
548 // Only merge `do while` if `do` is the only statement on the line.
549 if (Line.First->is(tok::kw_do) && !Line.Last->is(tok::kw_do))
550 return 0;
551 if (1 + I[1]->Last->TotalLength > Limit)
552 return 0;
553 // Don't merge with loops, ifs, a single semicolon or a line comment.
554 if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, tok::kw_while,
555 TT_ForEachMacro, TT_LineComment))
556 return 0;
557 // Only inline simple if's (no nested if or else), unless specified
558 if (Style.AllowShortIfStatementsOnASingleLine ==
559 FormatStyle::SIS_WithoutElse) {
560 if (I + 2 != E && Line.startsWith(tok::kw_if) &&
561 I[2]->First->is(tok::kw_else))
562 return 0;
563 }
564 return 1;
565 }
566
567 unsigned
568 tryMergeShortCaseLabels(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
569 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
570 unsigned Limit) {
571 if (Limit == 0 || I + 1 == E ||
572 I[1]->First->isOneOf(tok::kw_case, tok::kw_default))
573 return 0;
574 if (I[0]->Last->is(tok::l_brace) || I[1]->First->is(tok::l_brace))
575 return 0;
576 unsigned NumStmts = 0;
577 unsigned Length = 0;
578 bool EndsWithComment = false;
579 bool InPPDirective = I[0]->InPPDirective;
580 const unsigned Level = I[0]->Level;
581 for (; NumStmts < 3; ++NumStmts) {
582 if (I + 1 + NumStmts == E)
583 break;
584 const AnnotatedLine *Line = I[1 + NumStmts];
585 if (Line->InPPDirective != InPPDirective)
586 break;
587 if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
588 break;
589 if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,
590 tok::kw_while) ||
591 EndsWithComment)
592 return 0;
593 if (Line->First->is(tok::comment)) {
594 if (Level != Line->Level)
595 return 0;
596 SmallVectorImpl<AnnotatedLine *>::const_iterator J = I + 2 + NumStmts;
597 for (; J != E; ++J) {
598 Line = *J;
599 if (Line->InPPDirective != InPPDirective)
600 break;
601 if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
602 break;
603 if (Line->First->isNot(tok::comment) || Level != Line->Level)
604 return 0;
605 }
606 break;
607 }
608 if (Line->Last->is(tok::comment))
609 EndsWithComment = true;
610 Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.
611 }
612 if (NumStmts == 0 || NumStmts == 3 || Length > Limit)
613 return 0;
614 return NumStmts;
615 }
616
617 unsigned
618 tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
619 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
620 unsigned Limit) {
621 AnnotatedLine &Line = **I;
622
623 // Don't merge ObjC @ keywords and methods.
624 // FIXME: If an option to allow short exception handling clauses on a single
625 // line is added, change this to not return for @try and friends.
626 if (Style.Language != FormatStyle::LK_Java &&
627 Line.First->isOneOf(tok::at, tok::minus, tok::plus))
628 return 0;
629
630 // Check that the current line allows merging. This depends on whether we
631 // are in a control flow statements as well as several style flags.
632 if (Line.First->is(tok::kw_case) ||
633 (Line.First->Next && Line.First->Next->is(tok::kw_else)))
634 return 0;
635 // default: in switch statement
636 if (Line.First->is(tok::kw_default)) {
637 const FormatToken *Tok = Line.First->getNextNonComment();
638 if (Tok && Tok->is(tok::colon))
639 return 0;
640 }
641 if (Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, tok::kw_do,
642 tok::kw_try, tok::kw___try, tok::kw_catch,
643 tok::kw___finally, tok::kw_for, TT_ForEachMacro,
644 tok::r_brace, Keywords.kw___except)) {
645 if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
646 return 0;
647 if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Empty &&
648 !I[1]->First->is(tok::r_brace))
649 return 0;
650 // Don't merge when we can't except the case when
651 // the control statement block is empty
652 if (!Style.AllowShortIfStatementsOnASingleLine &&
653 Line.First->isOneOf(tok::kw_if, tok::kw_else) &&
654 !Style.BraceWrapping.AfterControlStatement &&
655 !I[1]->First->is(tok::r_brace))
656 return 0;
657 if (!Style.AllowShortIfStatementsOnASingleLine &&
658 Line.First->isOneOf(tok::kw_if, tok::kw_else) &&
659 Style.BraceWrapping.AfterControlStatement ==
660 FormatStyle::BWACS_Always &&
661 I + 2 != E && !I[2]->First->is(tok::r_brace))
662 return 0;
663 if (!Style.AllowShortLoopsOnASingleLine &&
664 Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for,
665 TT_ForEachMacro) &&
666 !Style.BraceWrapping.AfterControlStatement &&
667 !I[1]->First->is(tok::r_brace))
668 return 0;
669 if (!Style.AllowShortLoopsOnASingleLine &&
670 Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for,
671 TT_ForEachMacro) &&
672 Style.BraceWrapping.AfterControlStatement ==
673 FormatStyle::BWACS_Always &&
674 I + 2 != E && !I[2]->First->is(tok::r_brace))
675 return 0;
676 // FIXME: Consider an option to allow short exception handling clauses on
677 // a single line.
678 // FIXME: This isn't covered by tests.
679 // FIXME: For catch, __except, __finally the first token on the line
680 // is '}', so this isn't correct here.
681 if (Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch,
682 Keywords.kw___except, tok::kw___finally))
683 return 0;
684 }
685
686 if (Line.Last->is(tok::l_brace)) {
687 FormatToken *Tok = I[1]->First;
688 if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&
689 (Tok->getNextNonComment() == nullptr ||
690 Tok->getNextNonComment()->is(tok::semi))) {
691 // We merge empty blocks even if the line exceeds the column limit.
692 Tok->SpacesRequiredBefore = Style.SpaceInEmptyBlock ? 1 : 0;
693 Tok->CanBreakBefore = true;
694 return 1;
695 } else if (Limit != 0 && !Line.startsWithNamespace() &&
696 !startsExternCBlock(Line)) {
697 // We don't merge short records.
698 FormatToken *RecordTok = Line.First;
699 // Skip record modifiers.
700 while (RecordTok->Next &&
701 RecordTok->isOneOf(tok::kw_typedef, tok::kw_export,
702 Keywords.kw_declare, Keywords.kw_abstract,
703 tok::kw_default, Keywords.kw_override,
704 tok::kw_public, tok::kw_private,
705 tok::kw_protected, Keywords.kw_internal))
706 RecordTok = RecordTok->Next;
707 if (RecordTok &&
708 RecordTok->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct,
709 Keywords.kw_interface))
710 return 0;
711
712 // Check that we still have three lines and they fit into the limit.
713 if (I + 2 == E || I[2]->Type == LT_Invalid)
714 return 0;
715 Limit = limitConsideringMacros(I + 2, E, Limit);
716
717 if (!nextTwoLinesFitInto(I, Limit))
718 return 0;
719
720 // Second, check that the next line does not contain any braces - if it
721 // does, readability declines when putting it into a single line.
722 if (I[1]->Last->is(TT_LineComment))
723 return 0;
724 do {
725 if (Tok->is(tok::l_brace) && Tok->isNot(BK_BracedInit))
726 return 0;
727 Tok = Tok->Next;
728 } while (Tok);
729
730 // Last, check that the third line starts with a closing brace.
731 Tok = I[2]->First;
732 if (Tok->isNot(tok::r_brace))
733 return 0;
734
735 // Don't merge "if (a) { .. } else {".
736 if (Tok->Next && Tok->Next->is(tok::kw_else))
737 return 0;
738
739 // Don't merge a trailing multi-line control statement block like:
740 // } else if (foo &&
741 // bar)
742 // { <-- current Line
743 // baz();
744 // }
745 if (Line.First == Line.Last && Line.First->isNot(TT_FunctionLBrace) &&
746 Style.BraceWrapping.AfterControlStatement ==
747 FormatStyle::BWACS_MultiLine)
748 return 0;
749
750 return 2;
751 }
752 } else if (I[1]->First->is(tok::l_brace)) {
753 if (I[1]->Last->is(TT_LineComment))
754 return 0;
755
756 // Check for Limit <= 2 to account for the " {".
757 if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(*I)))
758 return 0;
759 Limit -= 2;
760 unsigned MergedLines = 0;
761 if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never ||
762 (I[1]->First == I[1]->Last && I + 2 != E &&
763 I[2]->First->is(tok::r_brace))) {
764 MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
765 // If we managed to merge the block, count the statement header, which
766 // is on a separate line.
767 if (MergedLines > 0)
768 ++MergedLines;
769 }
770 return MergedLines;
771 }
772 return 0;
773 }
774
775 /// Returns the modified column limit for \p I if it is inside a macro and
776 /// needs a trailing '\'.
777 unsigned
778 limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
779 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
780 unsigned Limit) {
781 if (I[0]->InPPDirective && I + 1 != E &&
782 !I[1]->First->HasUnescapedNewline && !I[1]->First->is(tok::eof)) {
783 return Limit < 2 ? 0 : Limit - 2;
784 }
785 return Limit;
786 }
787
788 bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
789 unsigned Limit) {
790 if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore)
791 return false;
792 return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit;
793 }
794
795 bool containsMustBreak(const AnnotatedLine *Line) {
796 for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {
797 if (Tok->MustBreakBefore)
798 return true;
799 }
800 return false;
801 }
802
803 void join(AnnotatedLine &A, const AnnotatedLine &B) {
804 assert(!A.Last->Next)(static_cast <bool> (!A.Last->Next) ? void (0) : __assert_fail
("!A.Last->Next", "clang/lib/Format/UnwrappedLineFormatter.cpp"
, 804, __extension__ __PRETTY_FUNCTION__))
;
805 assert(!B.First->Previous)(static_cast <bool> (!B.First->Previous) ? void (0) :
__assert_fail ("!B.First->Previous", "clang/lib/Format/UnwrappedLineFormatter.cpp"
, 805, __extension__ __PRETTY_FUNCTION__))
;
806 if (B.Affected)
807 A.Affected = true;
808 A.Last->Next = B.First;
809 B.First->Previous = A.Last;
810 B.First->CanBreakBefore = true;
811 unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore;
812 for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) {
813 Tok->TotalLength += LengthA;
814 A.Last = Tok;
815 }
816 }
817
818 const FormatStyle &Style;
819 const AdditionalKeywords &Keywords;
820 const SmallVectorImpl<AnnotatedLine *>::const_iterator End;
821
822 SmallVectorImpl<AnnotatedLine *>::const_iterator Next;
823 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines;
824};
825
826static void markFinalized(FormatToken *Tok) {
827 for (; Tok; Tok = Tok->Next) {
828 Tok->Finalized = true;
829 for (AnnotatedLine *Child : Tok->Children)
830 markFinalized(Child->First);
831 }
832}
833
834#ifndef NDEBUG
835static void printLineState(const LineState &State) {
836 llvm::dbgs() << "State: ";
837 for (const ParenState &P : State.Stack) {
838 llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent << "|"
839 << P.LastSpace << "|" << P.NestedBlockIndent << " ";
840 }
841 llvm::dbgs() << State.NextToken->TokenText << "\n";
842}
843#endif
844
845/// Base class for classes that format one \c AnnotatedLine.
846class LineFormatter {
847public:
848 LineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces,
849 const FormatStyle &Style,
850 UnwrappedLineFormatter *BlockFormatter)
851 : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style),
852 BlockFormatter(BlockFormatter) {}
853 virtual ~LineFormatter() {}
854
855 /// Formats an \c AnnotatedLine and returns the penalty.
856 ///
857 /// If \p DryRun is \c false, directly applies the changes.
858 virtual unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
859 unsigned FirstStartColumn, bool DryRun) = 0;
860
861protected:
862 /// If the \p State's next token is an r_brace closing a nested block,
863 /// format the nested block before it.
864 ///
865 /// Returns \c true if all children could be placed successfully and adapts
866 /// \p Penalty as well as \p State. If \p DryRun is false, also directly
867 /// creates changes using \c Whitespaces.
868 ///
869 /// The crucial idea here is that children always get formatted upon
870 /// encountering the closing brace right after the nested block. Now, if we
871 /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is
872 /// \c false), the entire block has to be kept on the same line (which is only
873 /// possible if it fits on the line, only contains a single statement, etc.
874 ///
875 /// If \p NewLine is true, we format the nested block on separate lines, i.e.
876 /// break after the "{", format all lines with correct indentation and the put
877 /// the closing "}" on yet another new line.
878 ///
879 /// This enables us to keep the simple structure of the
880 /// \c UnwrappedLineFormatter, where we only have two options for each token:
881 /// break or don't break.
882 bool formatChildren(LineState &State, bool NewLine, bool DryRun,
883 unsigned &Penalty) {
884 const FormatToken *LBrace = State.NextToken->getPreviousNonComment();
885 FormatToken &Previous = *State.NextToken->Previous;
886 if (!LBrace
0.1
'LBrace' is non-null
|| LBrace->isNot(tok::l_brace) || LBrace->isNot(BK_Block) ||
2
Taking false branch
887 Previous.Children.size() == 0)
1
Assuming the condition is false
888 // The previous token does not open a block. Nothing to do. We don't
889 // assert so that we can simply call this function for all tokens.
890 return true;
891
892 if (NewLine) {
3
Assuming 'NewLine' is true
4
Taking true branch
893 const ParenState &P = State.Stack.back();
894
895 int AdditionalIndent =
896 P.Indent - Previous.Children[0]->Level * Style.IndentWidth;
897
898 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
5
Assuming field 'LambdaBodyIndentation' is not equal to LBI_OuterScope
899 P.NestedBlockIndent == P.LastSpace) {
900 if (State.NextToken->MatchingParen &&
901 State.NextToken->MatchingParen->is(TT_LambdaLBrace)) {
902 State.Stack.pop_back();
903 }
904 if (LBrace->is(TT_LambdaLBrace))
905 AdditionalIndent = 0;
906 }
907
908 Penalty +=
909 BlockFormatter->format(Previous.Children, DryRun, AdditionalIndent,
6
Calling 'UnwrappedLineFormatter::format'
910 /*FixBadIndentation=*/true);
911 return true;
912 }
913
914 if (Previous.Children[0]->First->MustBreakBefore)
915 return false;
916
917 // Cannot merge into one line if this line ends on a comment.
918 if (Previous.is(tok::comment))
919 return false;
920
921 // Cannot merge multiple statements into a single line.
922 if (Previous.Children.size() > 1)
923 return false;
924
925 const AnnotatedLine *Child = Previous.Children[0];
926 // We can't put the closing "}" on a line with a trailing comment.
927 if (Child->Last->isTrailingComment())
928 return false;
929
930 // If the child line exceeds the column limit, we wouldn't want to merge it.
931 // We add +2 for the trailing " }".
932 if (Style.ColumnLimit > 0 &&
933 Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit)
934 return false;
935
936 if (!DryRun) {
937 Whitespaces->replaceWhitespace(
938 *Child->First, /*Newlines=*/0, /*Spaces=*/1,
939 /*StartOfTokenColumn=*/State.Column, /*IsAligned=*/false,
940 State.Line->InPPDirective);
941 }
942 Penalty +=
943 formatLine(*Child, State.Column + 1, /*FirstStartColumn=*/0, DryRun);
944
945 State.Column += 1 + Child->Last->TotalLength;
946 return true;
947 }
948
949 ContinuationIndenter *Indenter;
950
951private:
952 WhitespaceManager *Whitespaces;
953 const FormatStyle &Style;
954 UnwrappedLineFormatter *BlockFormatter;
955};
956
957/// Formatter that keeps the existing line breaks.
958class NoColumnLimitLineFormatter : public LineFormatter {
959public:
960 NoColumnLimitLineFormatter(ContinuationIndenter *Indenter,
961 WhitespaceManager *Whitespaces,
962 const FormatStyle &Style,
963 UnwrappedLineFormatter *BlockFormatter)
964 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
965
966 /// Formats the line, simply keeping all of the input's line breaking
967 /// decisions.
968 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
969 unsigned FirstStartColumn, bool DryRun) override {
970 assert(!DryRun)(static_cast <bool> (!DryRun) ? void (0) : __assert_fail
("!DryRun", "clang/lib/Format/UnwrappedLineFormatter.cpp", 970
, __extension__ __PRETTY_FUNCTION__))
;
971 LineState State = Indenter->getInitialState(FirstIndent, FirstStartColumn,
972 &Line, /*DryRun=*/false);
973 while (State.NextToken) {
974 bool Newline =
975 Indenter->mustBreak(State) ||
976 (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
977 unsigned Penalty = 0;
978 formatChildren(State, Newline, /*DryRun=*/false, Penalty);
979 Indenter->addTokenToState(State, Newline, /*DryRun=*/false);
980 }
981 return 0;
982 }
983};
984
985/// Formatter that puts all tokens into a single line without breaks.
986class NoLineBreakFormatter : public LineFormatter {
987public:
988 NoLineBreakFormatter(ContinuationIndenter *Indenter,
989 WhitespaceManager *Whitespaces, const FormatStyle &Style,
990 UnwrappedLineFormatter *BlockFormatter)
991 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
992
993 /// Puts all tokens into a single line.
994 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
995 unsigned FirstStartColumn, bool DryRun) override {
996 unsigned Penalty = 0;
997 LineState State =
998 Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun);
999 while (State.NextToken) {
1000 formatChildren(State, /*NewLine=*/false, DryRun, Penalty);
1001 Indenter->addTokenToState(
1002 State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun);
1003 }
1004 return Penalty;
1005 }
1006};
1007
1008/// Finds the best way to break lines.
1009class OptimizingLineFormatter : public LineFormatter {
1010public:
1011 OptimizingLineFormatter(ContinuationIndenter *Indenter,
1012 WhitespaceManager *Whitespaces,
1013 const FormatStyle &Style,
1014 UnwrappedLineFormatter *BlockFormatter)
1015 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
1016
1017 /// Formats the line by finding the best line breaks with line lengths
1018 /// below the column limit.
1019 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
1020 unsigned FirstStartColumn, bool DryRun) override {
1021 LineState State =
1022 Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun);
1023
1024 // If the ObjC method declaration does not fit on a line, we should format
1025 // it with one arg per line.
1026 if (State.Line->Type == LT_ObjCMethodDecl)
1027 State.Stack.back().BreakBeforeParameter = true;
1028
1029 // Find best solution in solution space.
1030 return analyzeSolutionSpace(State, DryRun);
1031 }
1032
1033private:
1034 struct CompareLineStatePointers {
1035 bool operator()(LineState *obj1, LineState *obj2) const {
1036 return *obj1 < *obj2;
1037 }
1038 };
1039
1040 /// A pair of <penalty, count> that is used to prioritize the BFS on.
1041 ///
1042 /// In case of equal penalties, we want to prefer states that were inserted
1043 /// first. During state generation we make sure that we insert states first
1044 /// that break the line as late as possible.
1045 typedef std::pair<unsigned, unsigned> OrderedPenalty;
1046
1047 /// An edge in the solution space from \c Previous->State to \c State,
1048 /// inserting a newline dependent on the \c NewLine.
1049 struct StateNode {
1050 StateNode(const LineState &State, bool NewLine, StateNode *Previous)
1051 : State(State), NewLine(NewLine), Previous(Previous) {}
1052 LineState State;
1053 bool NewLine;
1054 StateNode *Previous;
1055 };
1056
1057 /// An item in the prioritized BFS search queue. The \c StateNode's
1058 /// \c State has the given \c OrderedPenalty.
1059 typedef std::pair<OrderedPenalty, StateNode *> QueueItem;
1060
1061 /// The BFS queue type.
1062 typedef std::priority_queue<QueueItem, std::vector<QueueItem>,
1063 std::greater<QueueItem>>
1064 QueueType;
1065
1066 /// Analyze the entire solution space starting from \p InitialState.
1067 ///
1068 /// This implements a variant of Dijkstra's algorithm on the graph that spans
1069 /// the solution space (\c LineStates are the nodes). The algorithm tries to
1070 /// find the shortest path (the one with lowest penalty) from \p InitialState
1071 /// to a state where all tokens are placed. Returns the penalty.
1072 ///
1073 /// If \p DryRun is \c false, directly applies the changes.
1074 unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun) {
1075 std::set<LineState *, CompareLineStatePointers> Seen;
1076
1077 // Increasing count of \c StateNode items we have created. This is used to
1078 // create a deterministic order independent of the container.
1079 unsigned Count = 0;
1080 QueueType Queue;
1081
1082 // Insert start element into queue.
1083 StateNode *RootNode =
1084 new (Allocator.Allocate()) StateNode(InitialState, false, nullptr);
1085 Queue.push(QueueItem(OrderedPenalty(0, Count), RootNode));
1086 ++Count;
1087
1088 unsigned Penalty = 0;
1089
1090 // While not empty, take first element and follow edges.
1091 while (!Queue.empty()) {
1092 Penalty = Queue.top().first.first;
1093 StateNode *Node = Queue.top().second;
1094 if (!Node->State.NextToken) {
1095 LLVM_DEBUG(llvm::dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "\n---\nPenalty for line: "
<< Penalty << "\n"; } } while (false)
1096 << "\n---\nPenalty for line: " << Penalty << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "\n---\nPenalty for line: "
<< Penalty << "\n"; } } while (false)
;
1097 break;
1098 }
1099 Queue.pop();
1100
1101 // Cut off the analysis of certain solutions if the analysis gets too
1102 // complex. See description of IgnoreStackForComparison.
1103 if (Count > 50000)
1104 Node->State.IgnoreStackForComparison = true;
1105
1106 if (!Seen.insert(&Node->State).second)
1107 // State already examined with lower penalty.
1108 continue;
1109
1110 FormatDecision LastFormat = Node->State.NextToken->getDecision();
1111 if (LastFormat == FD_Unformatted || LastFormat == FD_Continue)
1112 addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue);
1113 if (LastFormat == FD_Unformatted || LastFormat == FD_Break)
1114 addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue);
1115 }
1116
1117 if (Queue.empty()) {
1118 // We were unable to find a solution, do nothing.
1119 // FIXME: Add diagnostic?
1120 LLVM_DEBUG(llvm::dbgs() << "Could not find a solution.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "Could not find a solution.\n"
; } } while (false)
;
1121 return 0;
1122 }
1123
1124 // Reconstruct the solution.
1125 if (!DryRun)
1126 reconstructPath(InitialState, Queue.top().second);
1127
1128 LLVM_DEBUG(llvm::dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "Total number of analyzed states: "
<< Count << "\n"; } } while (false)
1129 << "Total number of analyzed states: " << Count << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "Total number of analyzed states: "
<< Count << "\n"; } } while (false)
;
1130 LLVM_DEBUG(llvm::dbgs() << "---\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "---\n"; } } while
(false)
;
1131
1132 return Penalty;
1133 }
1134
1135 /// Add the following state to the analysis queue \c Queue.
1136 ///
1137 /// Assume the current state is \p PreviousNode and has been reached with a
1138 /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true.
1139 void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode,
1140 bool NewLine, unsigned *Count, QueueType *Queue) {
1141 if (NewLine && !Indenter->canBreak(PreviousNode->State))
1142 return;
1143 if (!NewLine && Indenter->mustBreak(PreviousNode->State))
1144 return;
1145
1146 StateNode *Node = new (Allocator.Allocate())
1147 StateNode(PreviousNode->State, NewLine, PreviousNode);
1148 if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty))
1149 return;
1150
1151 Penalty += Indenter->addTokenToState(Node->State, NewLine, true);
1152
1153 Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node));
1154 ++(*Count);
1155 }
1156
1157 /// Applies the best formatting by reconstructing the path in the
1158 /// solution space that leads to \c Best.
1159 void reconstructPath(LineState &State, StateNode *Best) {
1160 llvm::SmallVector<StateNode *> Path;
1161 // We do not need a break before the initial token.
1162 while (Best->Previous) {
1163 Path.push_back(Best);
1164 Best = Best->Previous;
1165 }
1166 for (const auto &Node : llvm::reverse(Path)) {
1167 unsigned Penalty = 0;
1168 formatChildren(State, Node->NewLine, /*DryRun=*/false, Penalty);
1169 Penalty += Indenter->addTokenToState(State, Node->NewLine, false);
1170
1171 LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { { printLineState(Node->Previous->
State); if (Node->NewLine) { llvm::dbgs() << "Penalty for placing "
<< Node->Previous->State.NextToken->Tok.getName
() << " on a new line: " << Penalty << "\n"
; } }; } } while (false)
1172 printLineState(Node->Previous->State);do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { { printLineState(Node->Previous->
State); if (Node->NewLine) { llvm::dbgs() << "Penalty for placing "
<< Node->Previous->State.NextToken->Tok.getName
() << " on a new line: " << Penalty << "\n"
; } }; } } while (false)
1173 if (Node->NewLine) {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { { printLineState(Node->Previous->
State); if (Node->NewLine) { llvm::dbgs() << "Penalty for placing "
<< Node->Previous->State.NextToken->Tok.getName
() << " on a new line: " << Penalty << "\n"
; } }; } } while (false)
1174 llvm::dbgs() << "Penalty for placing "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { { printLineState(Node->Previous->
State); if (Node->NewLine) { llvm::dbgs() << "Penalty for placing "
<< Node->Previous->State.NextToken->Tok.getName
() << " on a new line: " << Penalty << "\n"
; } }; } } while (false)
1175 << Node->Previous->State.NextToken->Tok.getName()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { { printLineState(Node->Previous->
State); if (Node->NewLine) { llvm::dbgs() << "Penalty for placing "
<< Node->Previous->State.NextToken->Tok.getName
() << " on a new line: " << Penalty << "\n"
; } }; } } while (false)
1176 << " on a new line: " << Penalty << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { { printLineState(Node->Previous->
State); if (Node->NewLine) { llvm::dbgs() << "Penalty for placing "
<< Node->Previous->State.NextToken->Tok.getName
() << " on a new line: " << Penalty << "\n"
; } }; } } while (false)
1177 }do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { { printLineState(Node->Previous->
State); if (Node->NewLine) { llvm::dbgs() << "Penalty for placing "
<< Node->Previous->State.NextToken->Tok.getName
() << " on a new line: " << Penalty << "\n"
; } }; } } while (false)
1178 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { { printLineState(Node->Previous->
State); if (Node->NewLine) { llvm::dbgs() << "Penalty for placing "
<< Node->Previous->State.NextToken->Tok.getName
() << " on a new line: " << Penalty << "\n"
; } }; } } while (false)
;
1179 }
1180 }
1181
1182 llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
1183};
1184
1185} // anonymous namespace
1186
1187unsigned UnwrappedLineFormatter::format(
1188 const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
1189 int AdditionalIndent, bool FixBadIndentation, unsigned FirstStartColumn,
1190 unsigned NextStartColumn, unsigned LastStartColumn) {
1191 LineJoiner Joiner(Style, Keywords, Lines);
1192
1193 // Try to look up already computed penalty in DryRun-mode.
1194 std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey(
1195 &Lines, AdditionalIndent);
1196 auto CacheIt = PenaltyCache.find(CacheKey);
1197 if (DryRun
18.1
'DryRun' is false
36.1
'DryRun' is false
&& CacheIt != PenaltyCache.end())
7
Assuming 'DryRun' is false
8
Taking false branch
19
Taking false branch
37
Taking false branch
1198 return CacheIt->second;
1199
1200 assert(!Lines.empty())(static_cast <bool> (!Lines.empty()) ? void (0) : __assert_fail
("!Lines.empty()", "clang/lib/Format/UnwrappedLineFormatter.cpp"
, 1200, __extension__ __PRETTY_FUNCTION__))
;
9
'?' condition is true
20
'?' condition is true
38
'?' condition is true
1201 unsigned Penalty = 0;
1202 LevelIndentTracker IndentTracker(Style, Keywords, Lines[0]->Level,
1203 AdditionalIndent);
1204 const AnnotatedLine *PrevPrevLine = nullptr;
1205 const AnnotatedLine *PreviousLine = nullptr;
1206 const AnnotatedLine *NextLine = nullptr;
1207
1208 // The minimum level of consecutive lines that have been formatted.
1209 unsigned RangeMinLevel = UINT_MAX(2147483647 *2U +1U);
1210
1211 bool FirstLine = true;
1212 for (const AnnotatedLine *Line =
10
Loop condition is true. Entering loop body
29
Loop condition is true. Entering loop body
47
Loop condition is true. Entering loop body
1213 Joiner.getNextMergedLine(DryRun, IndentTracker);
21
Calling 'LineJoiner::getNextMergedLine'
28
Returning from 'LineJoiner::getNextMergedLine'
39
Calling 'LineJoiner::getNextMergedLine'
46
Returning from 'LineJoiner::getNextMergedLine'
1214 Line; PrevPrevLine = PreviousLine, PreviousLine = Line, Line = NextLine,
1215 FirstLine = false) {
1216 const AnnotatedLine &TheLine = *Line;
1217 unsigned Indent = IndentTracker.getIndent();
1218
1219 // We continue formatting unchanged lines to adjust their indent, e.g. if a
1220 // scope was added. However, we need to carefully stop doing this when we
1221 // exit the scope of affected lines to prevent indenting a the entire
1222 // remaining file if it currently missing a closing brace.
1223 bool PreviousRBrace =
1224 PreviousLine
10.1
'PreviousLine' is null
29.1
'PreviousLine' is null
47.1
'PreviousLine' is null
&& PreviousLine->startsWith(tok::r_brace);
1225 bool ContinueFormatting =
1226 TheLine.Level > RangeMinLevel
10.2
'RangeMinLevel' is >= field 'Level'
29.2
'RangeMinLevel' is >= field 'Level'
47.2
'RangeMinLevel' is >= field 'Level'
||
1227 (TheLine.Level == RangeMinLevel && !PreviousRBrace &&
11
Assuming 'RangeMinLevel' is not equal to field 'Level'
30
Assuming 'RangeMinLevel' is not equal to field 'Level'
48
Assuming 'RangeMinLevel' is not equal to field 'Level'
1228 !TheLine.startsWith(tok::r_brace));
1229
1230 bool FixIndentation = (FixBadIndentation
11.1
'FixBadIndentation' is true
30.1
'FixBadIndentation' is false
48.1
'FixBadIndentation' is false
|| ContinueFormatting
30.2
'ContinueFormatting' is false
48.2
'ContinueFormatting' is false
) &&
1231 Indent != TheLine.First->OriginalColumn;
12
Assuming 'Indent' is equal to field 'OriginalColumn'
1232 bool ShouldFormat = TheLine.Affected || FixIndentation;
13
Assuming field 'Affected' is false
31
Assuming field 'Affected' is false
49
Assuming field 'Affected' is false
1233 // We cannot format this line; if the reason is that the line had a
1234 // parsing error, remember that.
1235 if (ShouldFormat
13.1
'ShouldFormat' is false
31.1
'ShouldFormat' is false
49.1
'ShouldFormat' is false
&& TheLine.Type == LT_Invalid && Status) {
1236 Status->FormatComplete = false;
1237 Status->Line =
1238 SourceMgr.getSpellingLineNumber(TheLine.First->Tok.getLocation());
1239 }
1240
1241 if (ShouldFormat
13.2
'ShouldFormat' is false
31.2
'ShouldFormat' is false
49.2
'ShouldFormat' is false
&& TheLine.Type != LT_Invalid) {
1242 if (!DryRun) {
1243 bool LastLine = Line->First->is(tok::eof);
1244 formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines, Indent,
1245 LastLine ? LastStartColumn : NextStartColumn + Indent);
1246 }
1247
1248 NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
1249 unsigned ColumnLimit = getColumnLimit(TheLine.InPPDirective, NextLine);
1250 bool FitsIntoOneLine =
1251 TheLine.Last->TotalLength + Indent <= ColumnLimit ||
1252 (TheLine.Type == LT_ImportStatement &&
1253 (!Style.isJavaScript() || !Style.JavaScriptWrapImports)) ||
1254 (Style.isCSharp() &&
1255 TheLine.InPPDirective); // don't split #regions in C#
1256 if (Style.ColumnLimit == 0)
1257 NoColumnLimitLineFormatter(Indenter, Whitespaces, Style, this)
1258 .formatLine(TheLine, NextStartColumn + Indent,
1259 FirstLine ? FirstStartColumn : 0, DryRun);
1260 else if (FitsIntoOneLine)
1261 Penalty += NoLineBreakFormatter(Indenter, Whitespaces, Style, this)
1262 .formatLine(TheLine, NextStartColumn + Indent,
1263 FirstLine ? FirstStartColumn : 0, DryRun);
1264 else
1265 Penalty += OptimizingLineFormatter(Indenter, Whitespaces, Style, this)
1266 .formatLine(TheLine, NextStartColumn + Indent,
1267 FirstLine ? FirstStartColumn : 0, DryRun);
1268 RangeMinLevel = std::min(RangeMinLevel, TheLine.Level);
1269 } else {
1270 // If no token in the current line is affected, we still need to format
1271 // affected children.
1272 if (TheLine.ChildrenAffected)
14
Assuming field 'ChildrenAffected' is true
15
Taking true branch
32
Assuming field 'ChildrenAffected' is true
33
Taking true branch
50
Assuming field 'ChildrenAffected' is true
51
Taking true branch
1273 for (const FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next)
16
Loop condition is true. Entering loop body
34
Loop condition is true. Entering loop body
52
Assuming pointer value is null
1274 if (!Tok->Children.empty())
17
Taking true branch
35
Taking true branch
1275 format(Tok->Children, DryRun);
18
Calling 'UnwrappedLineFormatter::format'
36
Calling 'UnwrappedLineFormatter::format'
1276
1277 // Adapt following lines on the current indent level to the same level
1278 // unless the current \c AnnotatedLine is not at the beginning of a line.
1279 bool StartsNewLine =
1280 TheLine.First->NewlinesBefore > 0 || TheLine.First->IsFirst;
53
Access to field 'NewlinesBefore' results in a dereference of a null pointer (loaded from field 'First')
1281 if (StartsNewLine)
1282 IndentTracker.adjustToUnmodifiedLine(TheLine);
1283 if (!DryRun) {
1284 bool ReformatLeadingWhitespace =
1285 StartsNewLine && ((PreviousLine && PreviousLine->Affected) ||
1286 TheLine.LeadingEmptyLinesAffected);
1287 // Format the first token.
1288 if (ReformatLeadingWhitespace)
1289 formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines,
1290 TheLine.First->OriginalColumn,
1291 TheLine.First->OriginalColumn);
1292 else
1293 Whitespaces->addUntouchableToken(*TheLine.First,
1294 TheLine.InPPDirective);
1295
1296 // Notify the WhitespaceManager about the unchanged whitespace.
1297 for (FormatToken *Tok = TheLine.First->Next; Tok; Tok = Tok->Next)
1298 Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
1299 }
1300 NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
1301 RangeMinLevel = UINT_MAX(2147483647 *2U +1U);
1302 }
1303 if (!DryRun)
1304 markFinalized(TheLine.First);
1305 }
1306 PenaltyCache[CacheKey] = Penalty;
1307 return Penalty;
1308}
1309
1310void UnwrappedLineFormatter::formatFirstToken(
1311 const AnnotatedLine &Line, const AnnotatedLine *PreviousLine,
1312 const AnnotatedLine *PrevPrevLine,
1313 const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent,
1314 unsigned NewlineIndent) {
1315 FormatToken &RootToken = *Line.First;
1316 if (RootToken.is(tok::eof)) {
1317 unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u);
1318 unsigned TokenIndent = Newlines ? NewlineIndent : 0;
1319 Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent,
1320 TokenIndent);
1321 return;
1322 }
1323 unsigned Newlines =
1324 std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
1325 // Remove empty lines before "}" where applicable.
1326 if (RootToken.is(tok::r_brace) &&
1327 (!RootToken.Next ||
1328 (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)) &&
1329 // Do not remove empty lines before namespace closing "}".
1330 !getNamespaceToken(&Line, Lines))
1331 Newlines = std::min(Newlines, 1u);
1332 // Remove empty lines at the start of nested blocks (lambdas/arrow functions)
1333 if (PreviousLine == nullptr && Line.Level > 0)
1334 Newlines = std::min(Newlines, 1u);
1335 if (Newlines == 0 && !RootToken.IsFirst)
1336 Newlines = 1;
1337 if (RootToken.IsFirst && !RootToken.HasUnescapedNewline)
1338 Newlines = 0;
1339
1340 // Remove empty lines after "{".
1341 if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
1342 PreviousLine->Last->is(tok::l_brace) &&
1343 !PreviousLine->startsWithNamespace() &&
1344 !(PrevPrevLine && PrevPrevLine->startsWithNamespace() &&
1345 PreviousLine->startsWith(tok::l_brace)) &&
1346 !startsExternCBlock(*PreviousLine))
1347 Newlines = 1;
1348
1349 // Insert or remove empty line before access specifiers.
1350 if (PreviousLine && RootToken.isAccessSpecifier()) {
1351 switch (Style.EmptyLineBeforeAccessModifier) {
1352 case FormatStyle::ELBAMS_Never:
1353 if (Newlines > 1)
1354 Newlines = 1;
1355 break;
1356 case FormatStyle::ELBAMS_Leave:
1357 Newlines = std::max(RootToken.NewlinesBefore, 1u);
1358 break;
1359 case FormatStyle::ELBAMS_LogicalBlock:
1360 if (PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && Newlines <= 1)
1361 Newlines = 2;
1362 if (PreviousLine->First->isAccessSpecifier())
1363 Newlines = 1; // Previous is an access modifier remove all new lines.
1364 break;
1365 case FormatStyle::ELBAMS_Always: {
1366 const FormatToken *previousToken;
1367 if (PreviousLine->Last->is(tok::comment))
1368 previousToken = PreviousLine->Last->getPreviousNonComment();
1369 else
1370 previousToken = PreviousLine->Last;
1371 if ((!previousToken || !previousToken->is(tok::l_brace)) && Newlines <= 1)
1372 Newlines = 2;
1373 } break;
1374 }
1375 }
1376
1377 // Insert or remove empty line after access specifiers.
1378 if (PreviousLine && PreviousLine->First->isAccessSpecifier() &&
1379 (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline)) {
1380 // EmptyLineBeforeAccessModifier is handling the case when two access
1381 // modifiers follow each other.
1382 if (!RootToken.isAccessSpecifier()) {
1383 switch (Style.EmptyLineAfterAccessModifier) {
1384 case FormatStyle::ELAAMS_Never:
1385 Newlines = 1;
1386 break;
1387 case FormatStyle::ELAAMS_Leave:
1388 Newlines = std::max(Newlines, 1u);
1389 break;
1390 case FormatStyle::ELAAMS_Always:
1391 if (RootToken.is(tok::r_brace)) // Do not add at end of class.
1392 Newlines = 1u;
1393 else
1394 Newlines = std::max(Newlines, 2u);
1395 break;
1396 }
1397 }
1398 }
1399
1400 if (Newlines)
1401 Indent = NewlineIndent;
1402
1403 // Preprocessor directives get indented before the hash only if specified
1404 if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
1405 (Line.Type == LT_PreprocessorDirective ||
1406 Line.Type == LT_ImportStatement))
1407 Indent = 0;
1408
1409 Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent,
1410 /*IsAligned=*/false,
1411 Line.InPPDirective &&
1412 !RootToken.HasUnescapedNewline);
1413}
1414
1415unsigned
1416UnwrappedLineFormatter::getColumnLimit(bool InPPDirective,
1417 const AnnotatedLine *NextLine) const {
1418 // In preprocessor directives reserve two chars for trailing " \" if the
1419 // next line continues the preprocessor directive.
1420 bool ContinuesPPDirective =
1421 InPPDirective &&
1422 // If there is no next line, this is likely a child line and the parent
1423 // continues the preprocessor directive.
1424 (!NextLine ||
1425 (NextLine->InPPDirective &&
1426 // If there is an unescaped newline between this line and the next, the
1427 // next line starts a new preprocessor directive.
1428 !NextLine->First->HasUnescapedNewline));
1429 return Style.ColumnLimit - (ContinuesPPDirective ? 2 : 0);
1430}
1431
1432} // namespace format
1433} // namespace clang