Bug Summary

File:clang/lib/Format/UnwrappedLineFormatter.cpp
Warning:line 1275, 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~++20220116100644+5f782d25a742/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~++20220116100644+5f782d25a742/clang/lib/Format -I /build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/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~++20220116100644+5f782d25a742/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/= -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~++20220116100644+5f782d25a742/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/= -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-16-232930-107970-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220116100644+5f782d25a742/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 return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never
362 ? tryMergeSimpleBlock(I, E, Limit)
363 : 0;
364 }
365 // Try to merge a control statement block with left brace wrapped
366 if (I[1]->First->is(tok::l_brace) &&
367 (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
368 tok::kw_for, tok::kw_switch, tok::kw_try,
369 tok::kw_do, TT_ForEachMacro) ||
370 (TheLine->First->is(tok::r_brace) && TheLine->First->Next &&
371 TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch))) &&
372 Style.BraceWrapping.AfterControlStatement ==
373 FormatStyle::BWACS_MultiLine) {
374 // If possible, merge the next line's wrapped left brace with the current
375 // line. Otherwise, leave it on the next line, as this is a multi-line
376 // control statement.
377 return (Style.ColumnLimit == 0 ||
378 TheLine->Last->TotalLength <= Style.ColumnLimit)
379 ? 1
380 : 0;
381 } else if (I[1]->First->is(tok::l_brace) &&
382 TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
383 tok::kw_for)) {
384 return (Style.BraceWrapping.AfterControlStatement ==
385 FormatStyle::BWACS_Always)
386 ? tryMergeSimpleBlock(I, E, Limit)
387 : 0;
388 } else if (I[1]->First->is(tok::l_brace) &&
389 TheLine->First->isOneOf(tok::kw_else, tok::kw_catch) &&
390 Style.BraceWrapping.AfterControlStatement ==
391 FormatStyle::BWACS_MultiLine) {
392 // This case if different from the upper BWACS_MultiLine processing
393 // in that a preceding r_brace is not on the same line as else/catch
394 // most likely because of BeforeElse/BeforeCatch set to true.
395 // If the line length doesn't fit ColumnLimit, leave l_brace on the
396 // next line to respect the BWACS_MultiLine.
397 return (Style.ColumnLimit == 0 ||
398 TheLine->Last->TotalLength <= Style.ColumnLimit)
399 ? 1
400 : 0;
401 }
402 // Don't merge block with left brace wrapped after ObjC special blocks
403 if (TheLine->First->is(tok::l_brace) && I != AnnotatedLines.begin() &&
404 I[-1]->First->is(tok::at) && I[-1]->First->Next) {
405 tok::ObjCKeywordKind kwId = I[-1]->First->Next->Tok.getObjCKeywordID();
406 if (kwId == clang::tok::objc_autoreleasepool ||
407 kwId == clang::tok::objc_synchronized)
408 return 0;
409 }
410 // Don't merge block with left brace wrapped after case labels
411 if (TheLine->First->is(tok::l_brace) && I != AnnotatedLines.begin() &&
412 I[-1]->First->isOneOf(tok::kw_case, tok::kw_default))
413 return 0;
414
415 // Don't merge an empty template class or struct if SplitEmptyRecords
416 // is defined.
417 if (Style.BraceWrapping.SplitEmptyRecord &&
418 TheLine->Last->is(tok::l_brace) && I != AnnotatedLines.begin() &&
419 I[-1]->Last) {
420 const FormatToken *Previous = I[-1]->Last;
421 if (Previous) {
422 if (Previous->is(tok::comment))
423 Previous = Previous->getPreviousNonComment();
424 if (Previous) {
425 if (Previous->is(tok::greater) && !I[-1]->InPPDirective)
426 return 0;
427 if (Previous->is(tok::identifier)) {
428 const FormatToken *PreviousPrevious =
429 Previous->getPreviousNonComment();
430 if (PreviousPrevious &&
431 PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct))
432 return 0;
433 }
434 }
435 }
436 }
437
438 // Try to merge a block with left brace unwrapped that wasn't yet covered
439 if (TheLine->Last->is(tok::l_brace)) {
440 const FormatToken *Tok = TheLine->First;
441 bool ShouldMerge = false;
442 if (Tok->is(tok::kw_typedef)) {
443 Tok = Tok->getNextNonComment();
444 assert(Tok)(static_cast <bool> (Tok) ? void (0) : __assert_fail ("Tok"
, "clang/lib/Format/UnwrappedLineFormatter.cpp", 444, __extension__
__PRETTY_FUNCTION__))
;
445 }
446 if (Tok->isOneOf(tok::kw_class, tok::kw_struct)) {
447 ShouldMerge = !Style.BraceWrapping.AfterClass ||
448 (I[1]->First->is(tok::r_brace) &&
449 !Style.BraceWrapping.SplitEmptyRecord);
450 } else if (Tok->is(tok::kw_enum)) {
451 ShouldMerge = Style.AllowShortEnumsOnASingleLine;
452 } else {
453 ShouldMerge = !Style.BraceWrapping.AfterFunction ||
454 (I[1]->First->is(tok::r_brace) &&
455 !Style.BraceWrapping.SplitEmptyFunction);
456 }
457 return ShouldMerge ? tryMergeSimpleBlock(I, E, Limit) : 0;
458 }
459 // Try to merge a function block with left brace wrapped
460 if (I[1]->First->is(TT_FunctionLBrace) &&
461 Style.BraceWrapping.AfterFunction) {
462 if (I[1]->Last->is(TT_LineComment))
463 return 0;
464
465 // Check for Limit <= 2 to account for the " {".
466 if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine)))
467 return 0;
468 Limit -= 2;
469
470 unsigned MergedLines = 0;
471 if (MergeShortFunctions ||
472 (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty &&
473 I[1]->First == I[1]->Last && I + 2 != E &&
474 I[2]->First->is(tok::r_brace))) {
475 MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
476 // If we managed to merge the block, count the function header, which is
477 // on a separate line.
478 if (MergedLines > 0)
479 ++MergedLines;
480 }
481 return MergedLines;
482 }
483 auto IsElseLine = [&TheLine]() -> bool {
484 const FormatToken *First = TheLine->First;
485 if (First->is(tok::kw_else))
486 return true;
487
488 return First->is(tok::r_brace) && First->Next &&
489 First->Next->is(tok::kw_else);
490 };
491 if (TheLine->First->is(tok::kw_if) ||
492 (IsElseLine() && (Style.AllowShortIfStatementsOnASingleLine ==
493 FormatStyle::SIS_AllIfsAndElse))) {
494 return Style.AllowShortIfStatementsOnASingleLine
495 ? tryMergeSimpleControlStatement(I, E, Limit)
496 : 0;
497 }
498 if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while, tok::kw_do)) {
499 return Style.AllowShortLoopsOnASingleLine
500 ? tryMergeSimpleControlStatement(I, E, Limit)
501 : 0;
502 }
503 if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) {
504 return Style.AllowShortCaseLabelsOnASingleLine
505 ? tryMergeShortCaseLabels(I, E, Limit)
506 : 0;
507 }
508 if (TheLine->InPPDirective &&
509 (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {
510 return tryMergeSimplePPDirective(I, E, Limit);
511 }
512 return 0;
513 }
514
515 unsigned
516 tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
517 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
518 unsigned Limit) {
519 if (Limit == 0)
520 return 0;
521 if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline)
522 return 0;
523 if (1 + I[1]->Last->TotalLength > Limit)
524 return 0;
525 return 1;
526 }
527
528 unsigned tryMergeSimpleControlStatement(
529 SmallVectorImpl<AnnotatedLine *>::const_iterator I,
530 SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {
531 if (Limit == 0)
532 return 0;
533 if (Style.BraceWrapping.AfterControlStatement ==
534 FormatStyle::BWACS_Always &&
535 I[1]->First->is(tok::l_brace) &&
536 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
537 return 0;
538 if (I[1]->InPPDirective != (*I)->InPPDirective ||
539 (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline))
540 return 0;
541 Limit = limitConsideringMacros(I + 1, E, Limit);
542 AnnotatedLine &Line = **I;
543 if (!Line.First->is(tok::kw_do) && !Line.First->is(tok::kw_else) &&
544 !Line.Last->is(tok::kw_else) && Line.Last->isNot(tok::r_paren))
545 return 0;
546 // Only merge do while if do is the only statement on the line.
547 if (Line.First->is(tok::kw_do) && !Line.Last->is(tok::kw_do))
548 return 0;
549 if (1 + I[1]->Last->TotalLength > Limit)
550 return 0;
551 if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, tok::kw_while,
552 TT_LineComment))
553 return 0;
554 // Only inline simple if's (no nested if or else), unless specified
555 if (Style.AllowShortIfStatementsOnASingleLine ==
556 FormatStyle::SIS_WithoutElse) {
557 if (I + 2 != E && Line.startsWith(tok::kw_if) &&
558 I[2]->First->is(tok::kw_else))
559 return 0;
560 }
561 return 1;
562 }
563
564 unsigned
565 tryMergeShortCaseLabels(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
566 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
567 unsigned Limit) {
568 if (Limit == 0 || I + 1 == E ||
569 I[1]->First->isOneOf(tok::kw_case, tok::kw_default))
570 return 0;
571 if (I[0]->Last->is(tok::l_brace) || I[1]->First->is(tok::l_brace))
572 return 0;
573 unsigned NumStmts = 0;
574 unsigned Length = 0;
575 bool EndsWithComment = false;
576 bool InPPDirective = I[0]->InPPDirective;
577 const unsigned Level = I[0]->Level;
578 for (; NumStmts < 3; ++NumStmts) {
579 if (I + 1 + NumStmts == E)
580 break;
581 const AnnotatedLine *Line = I[1 + NumStmts];
582 if (Line->InPPDirective != InPPDirective)
583 break;
584 if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
585 break;
586 if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,
587 tok::kw_while) ||
588 EndsWithComment)
589 return 0;
590 if (Line->First->is(tok::comment)) {
591 if (Level != Line->Level)
592 return 0;
593 SmallVectorImpl<AnnotatedLine *>::const_iterator J = I + 2 + NumStmts;
594 for (; J != E; ++J) {
595 Line = *J;
596 if (Line->InPPDirective != InPPDirective)
597 break;
598 if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
599 break;
600 if (Line->First->isNot(tok::comment) || Level != Line->Level)
601 return 0;
602 }
603 break;
604 }
605 if (Line->Last->is(tok::comment))
606 EndsWithComment = true;
607 Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.
608 }
609 if (NumStmts == 0 || NumStmts == 3 || Length > Limit)
610 return 0;
611 return NumStmts;
612 }
613
614 unsigned
615 tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
616 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
617 unsigned Limit) {
618 AnnotatedLine &Line = **I;
619
620 // Don't merge ObjC @ keywords and methods.
621 // FIXME: If an option to allow short exception handling clauses on a single
622 // line is added, change this to not return for @try and friends.
623 if (Style.Language != FormatStyle::LK_Java &&
624 Line.First->isOneOf(tok::at, tok::minus, tok::plus))
625 return 0;
626
627 // Check that the current line allows merging. This depends on whether we
628 // are in a control flow statements as well as several style flags.
629 if (Line.First->is(tok::kw_case) ||
630 (Line.First->Next && Line.First->Next->is(tok::kw_else)))
631 return 0;
632 // default: in switch statement
633 if (Line.First->is(tok::kw_default)) {
634 const FormatToken *Tok = Line.First->getNextNonComment();
635 if (Tok && Tok->is(tok::colon))
636 return 0;
637 }
638 if (Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, tok::kw_do,
639 tok::kw_try, tok::kw___try, tok::kw_catch,
640 tok::kw___finally, tok::kw_for, tok::r_brace,
641 Keywords.kw___except)) {
642 if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
643 return 0;
644 if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Empty &&
645 !I[1]->First->is(tok::r_brace))
646 return 0;
647 // Don't merge when we can't except the case when
648 // the control statement block is empty
649 if (!Style.AllowShortIfStatementsOnASingleLine &&
650 Line.First->isOneOf(tok::kw_if, tok::kw_else) &&
651 !Style.BraceWrapping.AfterControlStatement &&
652 !I[1]->First->is(tok::r_brace))
653 return 0;
654 if (!Style.AllowShortIfStatementsOnASingleLine &&
655 Line.First->isOneOf(tok::kw_if, tok::kw_else) &&
656 Style.BraceWrapping.AfterControlStatement ==
657 FormatStyle::BWACS_Always &&
658 I + 2 != E && !I[2]->First->is(tok::r_brace))
659 return 0;
660 if (!Style.AllowShortLoopsOnASingleLine &&
661 Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for) &&
662 !Style.BraceWrapping.AfterControlStatement &&
663 !I[1]->First->is(tok::r_brace))
664 return 0;
665 if (!Style.AllowShortLoopsOnASingleLine &&
666 Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for) &&
667 Style.BraceWrapping.AfterControlStatement ==
668 FormatStyle::BWACS_Always &&
669 I + 2 != E && !I[2]->First->is(tok::r_brace))
670 return 0;
671 // FIXME: Consider an option to allow short exception handling clauses on
672 // a single line.
673 // FIXME: This isn't covered by tests.
674 // FIXME: For catch, __except, __finally the first token on the line
675 // is '}', so this isn't correct here.
676 if (Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch,
677 Keywords.kw___except, tok::kw___finally))
678 return 0;
679 }
680
681 if (Line.Last->is(tok::l_brace)) {
682 FormatToken *Tok = I[1]->First;
683 if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&
684 (Tok->getNextNonComment() == nullptr ||
685 Tok->getNextNonComment()->is(tok::semi))) {
686 // We merge empty blocks even if the line exceeds the column limit.
687 Tok->SpacesRequiredBefore = Style.SpaceInEmptyBlock ? 1 : 0;
688 Tok->CanBreakBefore = true;
689 return 1;
690 } else if (Limit != 0 && !Line.startsWithNamespace() &&
691 !startsExternCBlock(Line)) {
692 // We don't merge short records.
693 FormatToken *RecordTok = Line.First;
694 // Skip record modifiers.
695 while (RecordTok->Next &&
696 RecordTok->isOneOf(tok::kw_typedef, tok::kw_export,
697 Keywords.kw_declare, Keywords.kw_abstract,
698 tok::kw_default, Keywords.kw_override,
699 tok::kw_public, tok::kw_private,
700 tok::kw_protected, Keywords.kw_internal))
701 RecordTok = RecordTok->Next;
702 if (RecordTok &&
703 RecordTok->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct,
704 Keywords.kw_interface))
705 return 0;
706
707 // Check that we still have three lines and they fit into the limit.
708 if (I + 2 == E || I[2]->Type == LT_Invalid)
709 return 0;
710 Limit = limitConsideringMacros(I + 2, E, Limit);
711
712 if (!nextTwoLinesFitInto(I, Limit))
713 return 0;
714
715 // Second, check that the next line does not contain any braces - if it
716 // does, readability declines when putting it into a single line.
717 if (I[1]->Last->is(TT_LineComment))
718 return 0;
719 do {
720 if (Tok->is(tok::l_brace) && Tok->isNot(BK_BracedInit))
721 return 0;
722 Tok = Tok->Next;
723 } while (Tok);
724
725 // Last, check that the third line starts with a closing brace.
726 Tok = I[2]->First;
727 if (Tok->isNot(tok::r_brace))
728 return 0;
729
730 // Don't merge "if (a) { .. } else {".
731 if (Tok->Next && Tok->Next->is(tok::kw_else))
732 return 0;
733
734 // Don't merge a trailing multi-line control statement block like:
735 // } else if (foo &&
736 // bar)
737 // { <-- current Line
738 // baz();
739 // }
740 if (Line.First == Line.Last && Line.First->isNot(TT_FunctionLBrace) &&
741 Style.BraceWrapping.AfterControlStatement ==
742 FormatStyle::BWACS_MultiLine)
743 return 0;
744
745 return 2;
746 }
747 } else if (I[1]->First->is(tok::l_brace)) {
748 if (I[1]->Last->is(TT_LineComment))
749 return 0;
750
751 // Check for Limit <= 2 to account for the " {".
752 if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(*I)))
753 return 0;
754 Limit -= 2;
755 unsigned MergedLines = 0;
756 if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never ||
757 (I[1]->First == I[1]->Last && I + 2 != E &&
758 I[2]->First->is(tok::r_brace))) {
759 MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
760 // If we managed to merge the block, count the statement header, which
761 // is on a separate line.
762 if (MergedLines > 0)
763 ++MergedLines;
764 }
765 return MergedLines;
766 }
767 return 0;
768 }
769
770 /// Returns the modified column limit for \p I if it is inside a macro and
771 /// needs a trailing '\'.
772 unsigned
773 limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
774 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
775 unsigned Limit) {
776 if (I[0]->InPPDirective && I + 1 != E &&
777 !I[1]->First->HasUnescapedNewline && !I[1]->First->is(tok::eof)) {
778 return Limit < 2 ? 0 : Limit - 2;
779 }
780 return Limit;
781 }
782
783 bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
784 unsigned Limit) {
785 if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore)
786 return false;
787 return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit;
788 }
789
790 bool containsMustBreak(const AnnotatedLine *Line) {
791 for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {
792 if (Tok->MustBreakBefore)
793 return true;
794 }
795 return false;
796 }
797
798 void join(AnnotatedLine &A, const AnnotatedLine &B) {
799 assert(!A.Last->Next)(static_cast <bool> (!A.Last->Next) ? void (0) : __assert_fail
("!A.Last->Next", "clang/lib/Format/UnwrappedLineFormatter.cpp"
, 799, __extension__ __PRETTY_FUNCTION__))
;
800 assert(!B.First->Previous)(static_cast <bool> (!B.First->Previous) ? void (0) :
__assert_fail ("!B.First->Previous", "clang/lib/Format/UnwrappedLineFormatter.cpp"
, 800, __extension__ __PRETTY_FUNCTION__))
;
801 if (B.Affected)
802 A.Affected = true;
803 A.Last->Next = B.First;
804 B.First->Previous = A.Last;
805 B.First->CanBreakBefore = true;
806 unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore;
807 for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) {
808 Tok->TotalLength += LengthA;
809 A.Last = Tok;
810 }
811 }
812
813 const FormatStyle &Style;
814 const AdditionalKeywords &Keywords;
815 const SmallVectorImpl<AnnotatedLine *>::const_iterator End;
816
817 SmallVectorImpl<AnnotatedLine *>::const_iterator Next;
818 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines;
819};
820
821static void markFinalized(FormatToken *Tok) {
822 for (; Tok; Tok = Tok->Next) {
823 Tok->Finalized = true;
824 for (AnnotatedLine *Child : Tok->Children)
825 markFinalized(Child->First);
826 }
827}
828
829#ifndef NDEBUG
830static void printLineState(const LineState &State) {
831 llvm::dbgs() << "State: ";
832 for (const ParenState &P : State.Stack) {
833 llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent << "|"
834 << P.LastSpace << "|" << P.NestedBlockIndent << " ";
835 }
836 llvm::dbgs() << State.NextToken->TokenText << "\n";
837}
838#endif
839
840/// Base class for classes that format one \c AnnotatedLine.
841class LineFormatter {
842public:
843 LineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces,
844 const FormatStyle &Style,
845 UnwrappedLineFormatter *BlockFormatter)
846 : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style),
847 BlockFormatter(BlockFormatter) {}
848 virtual ~LineFormatter() {}
849
850 /// Formats an \c AnnotatedLine and returns the penalty.
851 ///
852 /// If \p DryRun is \c false, directly applies the changes.
853 virtual unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
854 unsigned FirstStartColumn, bool DryRun) = 0;
855
856protected:
857 /// If the \p State's next token is an r_brace closing a nested block,
858 /// format the nested block before it.
859 ///
860 /// Returns \c true if all children could be placed successfully and adapts
861 /// \p Penalty as well as \p State. If \p DryRun is false, also directly
862 /// creates changes using \c Whitespaces.
863 ///
864 /// The crucial idea here is that children always get formatted upon
865 /// encountering the closing brace right after the nested block. Now, if we
866 /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is
867 /// \c false), the entire block has to be kept on the same line (which is only
868 /// possible if it fits on the line, only contains a single statement, etc.
869 ///
870 /// If \p NewLine is true, we format the nested block on separate lines, i.e.
871 /// break after the "{", format all lines with correct indentation and the put
872 /// the closing "}" on yet another new line.
873 ///
874 /// This enables us to keep the simple structure of the
875 /// \c UnwrappedLineFormatter, where we only have two options for each token:
876 /// break or don't break.
877 bool formatChildren(LineState &State, bool NewLine, bool DryRun,
878 unsigned &Penalty) {
879 const FormatToken *LBrace = State.NextToken->getPreviousNonComment();
880 FormatToken &Previous = *State.NextToken->Previous;
881 if (!LBrace
0.1
'LBrace' is non-null
|| LBrace->isNot(tok::l_brace) || LBrace->isNot(BK_Block) ||
2
Taking false branch
882 Previous.Children.size() == 0)
1
Assuming the condition is false
883 // The previous token does not open a block. Nothing to do. We don't
884 // assert so that we can simply call this function for all tokens.
885 return true;
886
887 if (NewLine) {
3
Assuming 'NewLine' is true
4
Taking true branch
888 const ParenState &P = State.Stack.back();
889
890 int AdditionalIndent =
891 P.Indent - Previous.Children[0]->Level * Style.IndentWidth;
892
893 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
5
Assuming field 'LambdaBodyIndentation' is not equal to LBI_OuterScope
894 P.NestedBlockIndent == P.LastSpace) {
895 if (State.NextToken->MatchingParen &&
896 State.NextToken->MatchingParen->is(TT_LambdaLBrace)) {
897 State.Stack.pop_back();
898 }
899 if (LBrace->is(TT_LambdaLBrace))
900 AdditionalIndent = 0;
901 }
902
903 Penalty +=
904 BlockFormatter->format(Previous.Children, DryRun, AdditionalIndent,
6
Calling 'UnwrappedLineFormatter::format'
905 /*FixBadIndentation=*/true);
906 return true;
907 }
908
909 if (Previous.Children[0]->First->MustBreakBefore)
910 return false;
911
912 // Cannot merge into one line if this line ends on a comment.
913 if (Previous.is(tok::comment))
914 return false;
915
916 // Cannot merge multiple statements into a single line.
917 if (Previous.Children.size() > 1)
918 return false;
919
920 const AnnotatedLine *Child = Previous.Children[0];
921 // We can't put the closing "}" on a line with a trailing comment.
922 if (Child->Last->isTrailingComment())
923 return false;
924
925 // If the child line exceeds the column limit, we wouldn't want to merge it.
926 // We add +2 for the trailing " }".
927 if (Style.ColumnLimit > 0 &&
928 Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit)
929 return false;
930
931 if (!DryRun) {
932 Whitespaces->replaceWhitespace(
933 *Child->First, /*Newlines=*/0, /*Spaces=*/1,
934 /*StartOfTokenColumn=*/State.Column, /*IsAligned=*/false,
935 State.Line->InPPDirective);
936 }
937 Penalty +=
938 formatLine(*Child, State.Column + 1, /*FirstStartColumn=*/0, DryRun);
939
940 State.Column += 1 + Child->Last->TotalLength;
941 return true;
942 }
943
944 ContinuationIndenter *Indenter;
945
946private:
947 WhitespaceManager *Whitespaces;
948 const FormatStyle &Style;
949 UnwrappedLineFormatter *BlockFormatter;
950};
951
952/// Formatter that keeps the existing line breaks.
953class NoColumnLimitLineFormatter : public LineFormatter {
954public:
955 NoColumnLimitLineFormatter(ContinuationIndenter *Indenter,
956 WhitespaceManager *Whitespaces,
957 const FormatStyle &Style,
958 UnwrappedLineFormatter *BlockFormatter)
959 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
960
961 /// Formats the line, simply keeping all of the input's line breaking
962 /// decisions.
963 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
964 unsigned FirstStartColumn, bool DryRun) override {
965 assert(!DryRun)(static_cast <bool> (!DryRun) ? void (0) : __assert_fail
("!DryRun", "clang/lib/Format/UnwrappedLineFormatter.cpp", 965
, __extension__ __PRETTY_FUNCTION__))
;
966 LineState State = Indenter->getInitialState(FirstIndent, FirstStartColumn,
967 &Line, /*DryRun=*/false);
968 while (State.NextToken) {
969 bool Newline =
970 Indenter->mustBreak(State) ||
971 (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
972 unsigned Penalty = 0;
973 formatChildren(State, Newline, /*DryRun=*/false, Penalty);
974 Indenter->addTokenToState(State, Newline, /*DryRun=*/false);
975 }
976 return 0;
977 }
978};
979
980/// Formatter that puts all tokens into a single line without breaks.
981class NoLineBreakFormatter : public LineFormatter {
982public:
983 NoLineBreakFormatter(ContinuationIndenter *Indenter,
984 WhitespaceManager *Whitespaces, const FormatStyle &Style,
985 UnwrappedLineFormatter *BlockFormatter)
986 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
987
988 /// Puts all tokens into a single line.
989 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
990 unsigned FirstStartColumn, bool DryRun) override {
991 unsigned Penalty = 0;
992 LineState State =
993 Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun);
994 while (State.NextToken) {
995 formatChildren(State, /*NewLine=*/false, DryRun, Penalty);
996 Indenter->addTokenToState(
997 State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun);
998 }
999 return Penalty;
1000 }
1001};
1002
1003/// Finds the best way to break lines.
1004class OptimizingLineFormatter : public LineFormatter {
1005public:
1006 OptimizingLineFormatter(ContinuationIndenter *Indenter,
1007 WhitespaceManager *Whitespaces,
1008 const FormatStyle &Style,
1009 UnwrappedLineFormatter *BlockFormatter)
1010 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
1011
1012 /// Formats the line by finding the best line breaks with line lengths
1013 /// below the column limit.
1014 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
1015 unsigned FirstStartColumn, bool DryRun) override {
1016 LineState State =
1017 Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun);
1018
1019 // If the ObjC method declaration does not fit on a line, we should format
1020 // it with one arg per line.
1021 if (State.Line->Type == LT_ObjCMethodDecl)
1022 State.Stack.back().BreakBeforeParameter = true;
1023
1024 // Find best solution in solution space.
1025 return analyzeSolutionSpace(State, DryRun);
1026 }
1027
1028private:
1029 struct CompareLineStatePointers {
1030 bool operator()(LineState *obj1, LineState *obj2) const {
1031 return *obj1 < *obj2;
1032 }
1033 };
1034
1035 /// A pair of <penalty, count> that is used to prioritize the BFS on.
1036 ///
1037 /// In case of equal penalties, we want to prefer states that were inserted
1038 /// first. During state generation we make sure that we insert states first
1039 /// that break the line as late as possible.
1040 typedef std::pair<unsigned, unsigned> OrderedPenalty;
1041
1042 /// An edge in the solution space from \c Previous->State to \c State,
1043 /// inserting a newline dependent on the \c NewLine.
1044 struct StateNode {
1045 StateNode(const LineState &State, bool NewLine, StateNode *Previous)
1046 : State(State), NewLine(NewLine), Previous(Previous) {}
1047 LineState State;
1048 bool NewLine;
1049 StateNode *Previous;
1050 };
1051
1052 /// An item in the prioritized BFS search queue. The \c StateNode's
1053 /// \c State has the given \c OrderedPenalty.
1054 typedef std::pair<OrderedPenalty, StateNode *> QueueItem;
1055
1056 /// The BFS queue type.
1057 typedef std::priority_queue<QueueItem, std::vector<QueueItem>,
1058 std::greater<QueueItem>>
1059 QueueType;
1060
1061 /// Analyze the entire solution space starting from \p InitialState.
1062 ///
1063 /// This implements a variant of Dijkstra's algorithm on the graph that spans
1064 /// the solution space (\c LineStates are the nodes). The algorithm tries to
1065 /// find the shortest path (the one with lowest penalty) from \p InitialState
1066 /// to a state where all tokens are placed. Returns the penalty.
1067 ///
1068 /// If \p DryRun is \c false, directly applies the changes.
1069 unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun) {
1070 std::set<LineState *, CompareLineStatePointers> Seen;
1071
1072 // Increasing count of \c StateNode items we have created. This is used to
1073 // create a deterministic order independent of the container.
1074 unsigned Count = 0;
1075 QueueType Queue;
1076
1077 // Insert start element into queue.
1078 StateNode *RootNode =
1079 new (Allocator.Allocate()) StateNode(InitialState, false, nullptr);
1080 Queue.push(QueueItem(OrderedPenalty(0, Count), RootNode));
1081 ++Count;
1082
1083 unsigned Penalty = 0;
1084
1085 // While not empty, take first element and follow edges.
1086 while (!Queue.empty()) {
1087 Penalty = Queue.top().first.first;
1088 StateNode *Node = Queue.top().second;
1089 if (!Node->State.NextToken) {
1090 LLVM_DEBUG(llvm::dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "\n---\nPenalty for line: "
<< Penalty << "\n"; } } while (false)
1091 << "\n---\nPenalty for line: " << Penalty << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "\n---\nPenalty for line: "
<< Penalty << "\n"; } } while (false)
;
1092 break;
1093 }
1094 Queue.pop();
1095
1096 // Cut off the analysis of certain solutions if the analysis gets too
1097 // complex. See description of IgnoreStackForComparison.
1098 if (Count > 50000)
1099 Node->State.IgnoreStackForComparison = true;
1100
1101 if (!Seen.insert(&Node->State).second)
1102 // State already examined with lower penalty.
1103 continue;
1104
1105 FormatDecision LastFormat = Node->State.NextToken->getDecision();
1106 if (LastFormat == FD_Unformatted || LastFormat == FD_Continue)
1107 addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue);
1108 if (LastFormat == FD_Unformatted || LastFormat == FD_Break)
1109 addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue);
1110 }
1111
1112 if (Queue.empty()) {
1113 // We were unable to find a solution, do nothing.
1114 // FIXME: Add diagnostic?
1115 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)
;
1116 return 0;
1117 }
1118
1119 // Reconstruct the solution.
1120 if (!DryRun)
1121 reconstructPath(InitialState, Queue.top().second);
1122
1123 LLVM_DEBUG(llvm::dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "Total number of analyzed states: "
<< Count << "\n"; } } while (false)
1124 << "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)
;
1125 LLVM_DEBUG(llvm::dbgs() << "---\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("format-formatter")) { llvm::dbgs() << "---\n"; } } while
(false)
;
1126
1127 return Penalty;
1128 }
1129
1130 /// Add the following state to the analysis queue \c Queue.
1131 ///
1132 /// Assume the current state is \p PreviousNode and has been reached with a
1133 /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true.
1134 void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode,
1135 bool NewLine, unsigned *Count, QueueType *Queue) {
1136 if (NewLine && !Indenter->canBreak(PreviousNode->State))
1137 return;
1138 if (!NewLine && Indenter->mustBreak(PreviousNode->State))
1139 return;
1140
1141 StateNode *Node = new (Allocator.Allocate())
1142 StateNode(PreviousNode->State, NewLine, PreviousNode);
1143 if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty))
1144 return;
1145
1146 Penalty += Indenter->addTokenToState(Node->State, NewLine, true);
1147
1148 Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node));
1149 ++(*Count);
1150 }
1151
1152 /// Applies the best formatting by reconstructing the path in the
1153 /// solution space that leads to \c Best.
1154 void reconstructPath(LineState &State, StateNode *Best) {
1155 llvm::SmallVector<StateNode *> Path;
1156 // We do not need a break before the initial token.
1157 while (Best->Previous) {
1158 Path.push_back(Best);
1159 Best = Best->Previous;
1160 }
1161 for (const auto &Node : llvm::reverse(Path)) {
1162 unsigned Penalty = 0;
1163 formatChildren(State, Node->NewLine, /*DryRun=*/false, Penalty);
1164 Penalty += Indenter->addTokenToState(State, Node->NewLine, false);
1165
1166 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)
1167 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)
1168 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)
1169 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)
1170 << 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)
1171 << " 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)
1172 }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 })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 }
1175 }
1176
1177 llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
1178};
1179
1180} // anonymous namespace
1181
1182unsigned UnwrappedLineFormatter::format(
1183 const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
1184 int AdditionalIndent, bool FixBadIndentation, unsigned FirstStartColumn,
1185 unsigned NextStartColumn, unsigned LastStartColumn) {
1186 LineJoiner Joiner(Style, Keywords, Lines);
1187
1188 // Try to look up already computed penalty in DryRun-mode.
1189 std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey(
1190 &Lines, AdditionalIndent);
1191 auto CacheIt = PenaltyCache.find(CacheKey);
1192 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
1193 return CacheIt->second;
1194
1195 assert(!Lines.empty())(static_cast <bool> (!Lines.empty()) ? void (0) : __assert_fail
("!Lines.empty()", "clang/lib/Format/UnwrappedLineFormatter.cpp"
, 1195, __extension__ __PRETTY_FUNCTION__))
;
9
'?' condition is true
20
'?' condition is true
38
'?' condition is true
1196 unsigned Penalty = 0;
1197 LevelIndentTracker IndentTracker(Style, Keywords, Lines[0]->Level,
1198 AdditionalIndent);
1199 const AnnotatedLine *PrevPrevLine = nullptr;
1200 const AnnotatedLine *PreviousLine = nullptr;
1201 const AnnotatedLine *NextLine = nullptr;
1202
1203 // The minimum level of consecutive lines that have been formatted.
1204 unsigned RangeMinLevel = UINT_MAX(2147483647 *2U +1U);
1205
1206 bool FirstLine = true;
1207 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
1208 Joiner.getNextMergedLine(DryRun, IndentTracker);
21
Calling 'LineJoiner::getNextMergedLine'
28
Returning from 'LineJoiner::getNextMergedLine'
39
Calling 'LineJoiner::getNextMergedLine'
46
Returning from 'LineJoiner::getNextMergedLine'
1209 Line; PrevPrevLine = PreviousLine, PreviousLine = Line, Line = NextLine,
1210 FirstLine = false) {
1211 const AnnotatedLine &TheLine = *Line;
1212 unsigned Indent = IndentTracker.getIndent();
1213
1214 // We continue formatting unchanged lines to adjust their indent, e.g. if a
1215 // scope was added. However, we need to carefully stop doing this when we
1216 // exit the scope of affected lines to prevent indenting a the entire
1217 // remaining file if it currently missing a closing brace.
1218 bool PreviousRBrace =
1219 PreviousLine
10.1
'PreviousLine' is null
29.1
'PreviousLine' is null
47.1
'PreviousLine' is null
&& PreviousLine->startsWith(tok::r_brace);
1220 bool ContinueFormatting =
1221 TheLine.Level > RangeMinLevel
10.2
'RangeMinLevel' is >= field 'Level'
29.2
'RangeMinLevel' is >= field 'Level'
47.2
'RangeMinLevel' is >= field 'Level'
||
1222 (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'
1223 !TheLine.startsWith(tok::r_brace));
1224
1225 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
) &&
1226 Indent != TheLine.First->OriginalColumn;
12
Assuming 'Indent' is equal to field 'OriginalColumn'
1227 bool ShouldFormat = TheLine.Affected || FixIndentation;
13
Assuming field 'Affected' is false
31
Assuming field 'Affected' is false
49
Assuming field 'Affected' is false
1228 // We cannot format this line; if the reason is that the line had a
1229 // parsing error, remember that.
1230 if (ShouldFormat
13.1
'ShouldFormat' is false
31.1
'ShouldFormat' is false
49.1
'ShouldFormat' is false
&& TheLine.Type == LT_Invalid && Status) {
1231 Status->FormatComplete = false;
1232 Status->Line =
1233 SourceMgr.getSpellingLineNumber(TheLine.First->Tok.getLocation());
1234 }
1235
1236 if (ShouldFormat
13.2
'ShouldFormat' is false
31.2
'ShouldFormat' is false
49.2
'ShouldFormat' is false
&& TheLine.Type != LT_Invalid) {
1237 if (!DryRun) {
1238 bool LastLine = Line->First->is(tok::eof);
1239 formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines, Indent,
1240 LastLine ? LastStartColumn : NextStartColumn + Indent);
1241 }
1242
1243 NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
1244 unsigned ColumnLimit = getColumnLimit(TheLine.InPPDirective, NextLine);
1245 bool FitsIntoOneLine =
1246 TheLine.Last->TotalLength + Indent <= ColumnLimit ||
1247 (TheLine.Type == LT_ImportStatement &&
1248 (!Style.isJavaScript() || !Style.JavaScriptWrapImports)) ||
1249 (Style.isCSharp() &&
1250 TheLine.InPPDirective); // don't split #regions in C#
1251 if (Style.ColumnLimit == 0)
1252 NoColumnLimitLineFormatter(Indenter, Whitespaces, Style, this)
1253 .formatLine(TheLine, NextStartColumn + Indent,
1254 FirstLine ? FirstStartColumn : 0, DryRun);
1255 else if (FitsIntoOneLine)
1256 Penalty += NoLineBreakFormatter(Indenter, Whitespaces, Style, this)
1257 .formatLine(TheLine, NextStartColumn + Indent,
1258 FirstLine ? FirstStartColumn : 0, DryRun);
1259 else
1260 Penalty += OptimizingLineFormatter(Indenter, Whitespaces, Style, this)
1261 .formatLine(TheLine, NextStartColumn + Indent,
1262 FirstLine ? FirstStartColumn : 0, DryRun);
1263 RangeMinLevel = std::min(RangeMinLevel, TheLine.Level);
1264 } else {
1265 // If no token in the current line is affected, we still need to format
1266 // affected children.
1267 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
1268 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
1269 if (!Tok->Children.empty())
17
Taking true branch
35
Taking true branch
1270 format(Tok->Children, DryRun);
18
Calling 'UnwrappedLineFormatter::format'
36
Calling 'UnwrappedLineFormatter::format'
1271
1272 // Adapt following lines on the current indent level to the same level
1273 // unless the current \c AnnotatedLine is not at the beginning of a line.
1274 bool StartsNewLine =
1275 TheLine.First->NewlinesBefore > 0 || TheLine.First->IsFirst;
53
Access to field 'NewlinesBefore' results in a dereference of a null pointer (loaded from field 'First')
1276 if (StartsNewLine)
1277 IndentTracker.adjustToUnmodifiedLine(TheLine);
1278 if (!DryRun) {
1279 bool ReformatLeadingWhitespace =
1280 StartsNewLine && ((PreviousLine && PreviousLine->Affected) ||
1281 TheLine.LeadingEmptyLinesAffected);
1282 // Format the first token.
1283 if (ReformatLeadingWhitespace)
1284 formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines,
1285 TheLine.First->OriginalColumn,
1286 TheLine.First->OriginalColumn);
1287 else
1288 Whitespaces->addUntouchableToken(*TheLine.First,
1289 TheLine.InPPDirective);
1290
1291 // Notify the WhitespaceManager about the unchanged whitespace.
1292 for (FormatToken *Tok = TheLine.First->Next; Tok; Tok = Tok->Next)
1293 Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
1294 }
1295 NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
1296 RangeMinLevel = UINT_MAX(2147483647 *2U +1U);
1297 }
1298 if (!DryRun)
1299 markFinalized(TheLine.First);
1300 }
1301 PenaltyCache[CacheKey] = Penalty;
1302 return Penalty;
1303}
1304
1305void UnwrappedLineFormatter::formatFirstToken(
1306 const AnnotatedLine &Line, const AnnotatedLine *PreviousLine,
1307 const AnnotatedLine *PrevPrevLine,
1308 const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent,
1309 unsigned NewlineIndent) {
1310 FormatToken &RootToken = *Line.First;
1311 if (RootToken.is(tok::eof)) {
1312 unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u);
1313 unsigned TokenIndent = Newlines ? NewlineIndent : 0;
1314 Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent,
1315 TokenIndent);
1316 return;
1317 }
1318 unsigned Newlines =
1319 std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
1320 // Remove empty lines before "}" where applicable.
1321 if (RootToken.is(tok::r_brace) &&
1322 (!RootToken.Next ||
1323 (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)) &&
1324 // Do not remove empty lines before namespace closing "}".
1325 !getNamespaceToken(&Line, Lines))
1326 Newlines = std::min(Newlines, 1u);
1327 // Remove empty lines at the start of nested blocks (lambdas/arrow functions)
1328 if (PreviousLine == nullptr && Line.Level > 0)
1329 Newlines = std::min(Newlines, 1u);
1330 if (Newlines == 0 && !RootToken.IsFirst)
1331 Newlines = 1;
1332 if (RootToken.IsFirst && !RootToken.HasUnescapedNewline)
1333 Newlines = 0;
1334
1335 // Remove empty lines after "{".
1336 if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
1337 PreviousLine->Last->is(tok::l_brace) &&
1338 !PreviousLine->startsWithNamespace() &&
1339 !(PrevPrevLine && PrevPrevLine->startsWithNamespace() &&
1340 PreviousLine->startsWith(tok::l_brace)) &&
1341 !startsExternCBlock(*PreviousLine))
1342 Newlines = 1;
1343
1344 // Insert or remove empty line before access specifiers.
1345 if (PreviousLine && RootToken.isAccessSpecifier()) {
1346 switch (Style.EmptyLineBeforeAccessModifier) {
1347 case FormatStyle::ELBAMS_Never:
1348 if (Newlines > 1)
1349 Newlines = 1;
1350 break;
1351 case FormatStyle::ELBAMS_Leave:
1352 Newlines = std::max(RootToken.NewlinesBefore, 1u);
1353 break;
1354 case FormatStyle::ELBAMS_LogicalBlock:
1355 if (PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && Newlines <= 1)
1356 Newlines = 2;
1357 if (PreviousLine->First->isAccessSpecifier())
1358 Newlines = 1; // Previous is an access modifier remove all new lines.
1359 break;
1360 case FormatStyle::ELBAMS_Always: {
1361 const FormatToken *previousToken;
1362 if (PreviousLine->Last->is(tok::comment))
1363 previousToken = PreviousLine->Last->getPreviousNonComment();
1364 else
1365 previousToken = PreviousLine->Last;
1366 if ((!previousToken || !previousToken->is(tok::l_brace)) && Newlines <= 1)
1367 Newlines = 2;
1368 } break;
1369 }
1370 }
1371
1372 // Insert or remove empty line after access specifiers.
1373 if (PreviousLine && PreviousLine->First->isAccessSpecifier() &&
1374 (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline)) {
1375 // EmptyLineBeforeAccessModifier is handling the case when two access
1376 // modifiers follow each other.
1377 if (!RootToken.isAccessSpecifier()) {
1378 switch (Style.EmptyLineAfterAccessModifier) {
1379 case FormatStyle::ELAAMS_Never:
1380 Newlines = 1;
1381 break;
1382 case FormatStyle::ELAAMS_Leave:
1383 Newlines = std::max(Newlines, 1u);
1384 break;
1385 case FormatStyle::ELAAMS_Always:
1386 if (RootToken.is(tok::r_brace)) // Do not add at end of class.
1387 Newlines = 1u;
1388 else
1389 Newlines = std::max(Newlines, 2u);
1390 break;
1391 }
1392 }
1393 }
1394
1395 if (Newlines)
1396 Indent = NewlineIndent;
1397
1398 // Preprocessor directives get indented before the hash only if specified
1399 if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
1400 (Line.Type == LT_PreprocessorDirective ||
1401 Line.Type == LT_ImportStatement))
1402 Indent = 0;
1403
1404 Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent,
1405 /*IsAligned=*/false,
1406 Line.InPPDirective &&
1407 !RootToken.HasUnescapedNewline);
1408}
1409
1410unsigned
1411UnwrappedLineFormatter::getColumnLimit(bool InPPDirective,
1412 const AnnotatedLine *NextLine) const {
1413 // In preprocessor directives reserve two chars for trailing " \" if the
1414 // next line continues the preprocessor directive.
1415 bool ContinuesPPDirective =
1416 InPPDirective &&
1417 // If there is no next line, this is likely a child line and the parent
1418 // continues the preprocessor directive.
1419 (!NextLine ||
1420 (NextLine->InPPDirective &&
1421 // If there is an unescaped newline between this line and the next, the
1422 // next line starts a new preprocessor directive.
1423 !NextLine->First->HasUnescapedNewline));
1424 return Style.ColumnLimit - (ContinuesPPDirective ? 2 : 0);
1425}
1426
1427} // namespace format
1428} // namespace clang