clang 19.0.0git
UnwrappedLineFormatter.cpp
Go to the documentation of this file.
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
11#include "WhitespaceManager.h"
12#include <queue>
13
14#define DEBUG_TYPE "format-formatter"
15
16namespace clang {
17namespace format {
18
19namespace {
20
21bool startsExternCBlock(const AnnotatedLine &Line) {
22 const FormatToken *Next = Line.First->getNextNonComment();
23 const FormatToken *NextNext = Next ? Next->getNextNonComment() : nullptr;
24 return Line.startsWith(tok::kw_extern) && Next && Next->isStringLiteral() &&
25 NextNext && NextNext->is(tok::l_brace);
26}
27
28bool isRecordLBrace(const FormatToken &Tok) {
29 return Tok.isOneOf(TT_ClassLBrace, TT_EnumLBrace, TT_RecordLBrace,
30 TT_StructLBrace, TT_UnionLBrace);
31}
32
33/// Tracks the indent level of \c AnnotatedLines across levels.
34///
35/// \c nextLine must be called for each \c AnnotatedLine, after which \c
36/// getIndent() will return the indent for the last line \c nextLine was called
37/// with.
38/// If the line is not formatted (and thus the indent does not change), calling
39/// \c adjustToUnmodifiedLine after the call to \c nextLine will cause
40/// subsequent lines on the same level to be indented at the same level as the
41/// given line.
42class LevelIndentTracker {
43public:
44 LevelIndentTracker(const FormatStyle &Style,
45 const AdditionalKeywords &Keywords, unsigned StartLevel,
46 int AdditionalIndent)
47 : Style(Style), Keywords(Keywords), AdditionalIndent(AdditionalIndent) {
48 for (unsigned i = 0; i != StartLevel; ++i)
49 IndentForLevel.push_back(Style.IndentWidth * i + AdditionalIndent);
50 }
51
52 /// Returns the indent for the current line.
53 unsigned getIndent() const { return Indent; }
54
55 /// Update the indent state given that \p Line is going to be formatted
56 /// next.
57 void nextLine(const AnnotatedLine &Line) {
58 Offset = getIndentOffset(*Line.First);
59 // Update the indent level cache size so that we can rely on it
60 // having the right size in adjustToUnmodifiedline.
61 if (Line.Level >= IndentForLevel.size())
62 IndentForLevel.resize(Line.Level + 1, -1);
63 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None &&
64 (Line.InPPDirective ||
65 (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
67 unsigned PPIndentWidth =
68 (Style.PPIndentWidth >= 0) ? Style.PPIndentWidth : Style.IndentWidth;
69 Indent = Line.InMacroBody
70 ? Line.PPLevel * PPIndentWidth +
71 (Line.Level - Line.PPLevel) * Style.IndentWidth
72 : Line.Level * PPIndentWidth;
73 Indent += AdditionalIndent;
74 } else {
75 // When going to lower levels, forget previous higher levels so that we
76 // recompute future higher levels. But don't forget them if we enter a PP
77 // directive, since these do not terminate a C++ code block.
78 if (!Line.InPPDirective) {
79 assert(Line.Level <= IndentForLevel.size());
80 IndentForLevel.resize(Line.Level + 1);
81 }
82 Indent = getIndent(Line.Level);
83 }
84 if (static_cast<int>(Indent) + Offset >= 0)
85 Indent += Offset;
86 if (Line.IsContinuation)
87 Indent = Line.Level * Style.IndentWidth + Style.ContinuationIndentWidth;
88 }
89
90 /// Update the level indent to adapt to the given \p Line.
91 ///
92 /// When a line is not formatted, we move the subsequent lines on the same
93 /// level to the same indent.
94 /// Note that \c nextLine must have been called before this method.
95 void adjustToUnmodifiedLine(const AnnotatedLine &Line) {
96 if (Line.InPPDirective || Line.IsContinuation)
97 return;
98 assert(Line.Level < IndentForLevel.size());
99 if (Line.First->is(tok::comment) && IndentForLevel[Line.Level] != -1)
100 return;
101 unsigned LevelIndent = Line.First->OriginalColumn;
102 if (static_cast<int>(LevelIndent) - Offset >= 0)
103 LevelIndent -= Offset;
104 IndentForLevel[Line.Level] = LevelIndent;
105 }
106
107private:
108 /// Get the offset of the line relatively to the level.
109 ///
110 /// For example, 'public:' labels in classes are offset by 1 or 2
111 /// characters to the left from their level.
112 int getIndentOffset(const FormatToken &RootToken) {
113 if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() ||
114 Style.isCSharp()) {
115 return 0;
116 }
117
118 auto IsAccessModifier = [this, &RootToken]() {
119 if (RootToken.isAccessSpecifier(Style.isCpp())) {
120 return true;
121 } else if (RootToken.isObjCAccessSpecifier()) {
122 return true;
123 }
124 // Handle Qt signals.
125 else if (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
126 RootToken.Next && RootToken.Next->is(tok::colon)) {
127 return true;
128 } else if (RootToken.Next &&
129 RootToken.Next->isOneOf(Keywords.kw_slots,
130 Keywords.kw_qslots) &&
131 RootToken.Next->Next && RootToken.Next->Next->is(tok::colon)) {
132 return true;
133 }
134 // Handle malformed access specifier e.g. 'private' without trailing ':'.
135 else if (!RootToken.Next && RootToken.isAccessSpecifier(false)) {
136 return true;
137 }
138 return false;
139 };
140
141 if (IsAccessModifier()) {
142 // The AccessModifierOffset may be overridden by IndentAccessModifiers,
143 // in which case we take a negative value of the IndentWidth to simulate
144 // the upper indent level.
145 return Style.IndentAccessModifiers ? -Style.IndentWidth
146 : Style.AccessModifierOffset;
147 }
148 return 0;
149 }
150
151 /// Get the indent of \p Level from \p IndentForLevel.
152 ///
153 /// \p IndentForLevel must contain the indent for the level \c l
154 /// at \p IndentForLevel[l], or a value < 0 if the indent for
155 /// that level is unknown.
156 unsigned getIndent(unsigned Level) const {
157 assert(Level < IndentForLevel.size());
158 if (IndentForLevel[Level] != -1)
159 return IndentForLevel[Level];
160 if (Level == 0)
161 return 0;
162 return getIndent(Level - 1) + Style.IndentWidth;
163 }
164
165 const FormatStyle &Style;
166 const AdditionalKeywords &Keywords;
167 const unsigned AdditionalIndent;
168
169 /// The indent in characters for each level. It remembers the indent of
170 /// previous lines (that are not PP directives) of equal or lower levels. This
171 /// is used to align formatted lines to the indent of previous non-formatted
172 /// lines. Think about the --lines parameter of clang-format.
173 SmallVector<int> IndentForLevel;
174
175 /// Offset of the current line relative to the indent level.
176 ///
177 /// For example, the 'public' keywords is often indented with a negative
178 /// offset.
179 int Offset = 0;
180
181 /// The current line's indent.
182 unsigned Indent = 0;
183};
184
185const FormatToken *getMatchingNamespaceToken(
186 const AnnotatedLine *Line,
187 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
188 if (!Line->startsWith(tok::r_brace))
189 return nullptr;
190 size_t StartLineIndex = Line->MatchingOpeningBlockLineIndex;
191 if (StartLineIndex == UnwrappedLine::kInvalidIndex)
192 return nullptr;
193 assert(StartLineIndex < AnnotatedLines.size());
194 return AnnotatedLines[StartLineIndex]->First->getNamespaceToken();
195}
196
197StringRef getNamespaceTokenText(const AnnotatedLine *Line) {
198 const FormatToken *NamespaceToken = Line->First->getNamespaceToken();
199 return NamespaceToken ? NamespaceToken->TokenText : StringRef();
200}
201
202StringRef getMatchingNamespaceTokenText(
203 const AnnotatedLine *Line,
204 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
205 const FormatToken *NamespaceToken =
206 getMatchingNamespaceToken(Line, AnnotatedLines);
207 return NamespaceToken ? NamespaceToken->TokenText : StringRef();
208}
209
210class LineJoiner {
211public:
212 LineJoiner(const FormatStyle &Style, const AdditionalKeywords &Keywords,
213 const SmallVectorImpl<AnnotatedLine *> &Lines)
214 : Style(Style), Keywords(Keywords), End(Lines.end()), Next(Lines.begin()),
215 AnnotatedLines(Lines) {}
216
217 /// Returns the next line, merging multiple lines into one if possible.
218 const AnnotatedLine *getNextMergedLine(bool DryRun,
219 LevelIndentTracker &IndentTracker) {
220 if (Next == End)
221 return nullptr;
222 const AnnotatedLine *Current = *Next;
223 IndentTracker.nextLine(*Current);
224 unsigned MergedLines = tryFitMultipleLinesInOne(IndentTracker, Next, End);
225 if (MergedLines > 0 && Style.ColumnLimit == 0) {
226 // Disallow line merging if there is a break at the start of one of the
227 // input lines.
228 for (unsigned i = 0; i < MergedLines; ++i)
229 if (Next[i + 1]->First->NewlinesBefore > 0)
230 MergedLines = 0;
231 }
232 if (!DryRun)
233 for (unsigned i = 0; i < MergedLines; ++i)
234 join(*Next[0], *Next[i + 1]);
235 Next = Next + MergedLines + 1;
236 return Current;
237 }
238
239private:
240 /// Calculates how many lines can be merged into 1 starting at \p I.
241 unsigned
242 tryFitMultipleLinesInOne(LevelIndentTracker &IndentTracker,
243 SmallVectorImpl<AnnotatedLine *>::const_iterator I,
244 SmallVectorImpl<AnnotatedLine *>::const_iterator E) {
245 const unsigned Indent = IndentTracker.getIndent();
246
247 // Can't join the last line with anything.
248 if (I + 1 == E)
249 return 0;
250 // We can never merge stuff if there are trailing line comments.
251 const AnnotatedLine *TheLine = *I;
252 if (TheLine->Last->is(TT_LineComment))
253 return 0;
254 const auto &NextLine = *I[1];
255 if (NextLine.Type == LT_Invalid || NextLine.First->MustBreakBefore)
256 return 0;
257 if (TheLine->InPPDirective &&
258 (!NextLine.InPPDirective || NextLine.First->HasUnescapedNewline)) {
259 return 0;
260 }
261
262 if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit)
263 return 0;
264
265 unsigned Limit =
266 Style.ColumnLimit == 0 ? UINT_MAX : Style.ColumnLimit - Indent;
267 // If we already exceed the column limit, we set 'Limit' to 0. The different
268 // tryMerge..() functions can then decide whether to still do merging.
269 Limit = TheLine->Last->TotalLength > Limit
270 ? 0
271 : Limit - TheLine->Last->TotalLength;
272
273 if (TheLine->Last->is(TT_FunctionLBrace) &&
274 TheLine->First == TheLine->Last &&
275 !Style.BraceWrapping.SplitEmptyFunction &&
276 NextLine.First->is(tok::r_brace)) {
277 return tryMergeSimpleBlock(I, E, Limit);
278 }
279
280 const auto *PreviousLine = I != AnnotatedLines.begin() ? I[-1] : nullptr;
281 // Handle empty record blocks where the brace has already been wrapped.
282 if (PreviousLine && TheLine->Last->is(tok::l_brace) &&
283 TheLine->First == TheLine->Last) {
284 bool EmptyBlock = NextLine.First->is(tok::r_brace);
285
286 const FormatToken *Tok = PreviousLine->First;
287 if (Tok && Tok->is(tok::comment))
288 Tok = Tok->getNextNonComment();
289
290 if (Tok && Tok->getNamespaceToken()) {
291 return !Style.BraceWrapping.SplitEmptyNamespace && EmptyBlock
292 ? tryMergeSimpleBlock(I, E, Limit)
293 : 0;
294 }
295
296 if (Tok && Tok->is(tok::kw_typedef))
297 Tok = Tok->getNextNonComment();
298 if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
299 tok::kw_extern, Keywords.kw_interface)) {
300 return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock
301 ? tryMergeSimpleBlock(I, E, Limit)
302 : 0;
303 }
304
305 if (Tok && Tok->is(tok::kw_template) &&
306 Style.BraceWrapping.SplitEmptyRecord && EmptyBlock) {
307 return 0;
308 }
309 }
310
311 auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
312 TheLine]() {
313 if (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
314 return true;
315 if (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty &&
316 NextLine.First->is(tok::r_brace)) {
317 return true;
318 }
319
320 if (Style.AllowShortFunctionsOnASingleLine &
322 // Just checking TheLine->Level != 0 is not enough, because it
323 // provokes treating functions inside indented namespaces as short.
324 if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
325 return true;
326
327 if (TheLine->Level != 0) {
328 if (!PreviousLine)
329 return false;
330
331 // TODO: Use IndentTracker to avoid loop?
332 // Find the last line with lower level.
333 const AnnotatedLine *Line = nullptr;
334 for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
335 assert(*J);
336 if (!(*J)->InPPDirective && !(*J)->isComment() &&
337 (*J)->Level < TheLine->Level) {
338 Line = *J;
339 break;
340 }
341 }
342
343 if (!Line)
344 return false;
345
346 // Check if the found line starts a record.
347 const auto *LastNonComment = Line->getLastNonComment();
348 // There must be another token (usually `{`), because we chose a
349 // non-PPDirective and non-comment line that has a smaller level.
350 assert(LastNonComment);
351 return isRecordLBrace(*LastNonComment);
352 }
353 }
354
355 return false;
356 };
357
358 bool MergeShortFunctions = ShouldMergeShortFunctions();
359
360 const auto *FirstNonComment = TheLine->getFirstNonComment();
361 if (!FirstNonComment)
362 return 0;
363 // FIXME: There are probably cases where we should use FirstNonComment
364 // instead of TheLine->First.
365
366 if (Style.CompactNamespaces) {
367 if (const auto *NSToken = TheLine->First->getNamespaceToken()) {
368 int J = 1;
369 assert(TheLine->MatchingClosingBlockLineIndex > 0);
370 for (auto ClosingLineIndex = TheLine->MatchingClosingBlockLineIndex - 1;
371 I + J != E && NSToken->TokenText == getNamespaceTokenText(I[J]) &&
372 ClosingLineIndex == I[J]->MatchingClosingBlockLineIndex &&
373 I[J]->Last->TotalLength < Limit;
374 ++J, --ClosingLineIndex) {
375 Limit -= I[J]->Last->TotalLength;
376
377 // Reduce indent level for bodies of namespaces which were compacted,
378 // but only if their content was indented in the first place.
379 auto *ClosingLine = AnnotatedLines.begin() + ClosingLineIndex + 1;
380 const int OutdentBy = I[J]->Level - TheLine->Level;
381 assert(OutdentBy >= 0);
382 for (auto *CompactedLine = I + J; CompactedLine <= ClosingLine;
383 ++CompactedLine) {
384 if (!(*CompactedLine)->InPPDirective) {
385 const int Level = (*CompactedLine)->Level;
386 (*CompactedLine)->Level = std::max(Level - OutdentBy, 0);
387 }
388 }
389 }
390 return J - 1;
391 }
392
393 if (auto nsToken = getMatchingNamespaceToken(TheLine, AnnotatedLines)) {
394 int i = 0;
395 unsigned openingLine = TheLine->MatchingOpeningBlockLineIndex - 1;
396 for (; I + 1 + i != E &&
397 nsToken->TokenText ==
398 getMatchingNamespaceTokenText(I[i + 1], AnnotatedLines) &&
399 openingLine == I[i + 1]->MatchingOpeningBlockLineIndex;
400 i++, --openingLine) {
401 // No space between consecutive braces.
402 I[i + 1]->First->SpacesRequiredBefore =
403 I[i]->Last->isNot(tok::r_brace);
404
405 // Indent like the outer-most namespace.
406 IndentTracker.nextLine(*I[i + 1]);
407 }
408 return i;
409 }
410 }
411
412 const auto *LastNonComment = TheLine->getLastNonComment();
413 assert(LastNonComment);
414 // FIXME: There are probably cases where we should use LastNonComment
415 // instead of TheLine->Last.
416
417 // Try to merge a function block with left brace unwrapped.
418 if (LastNonComment->is(TT_FunctionLBrace) &&
419 TheLine->First != LastNonComment) {
420 return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0;
421 }
422 // Try to merge a control statement block with left brace unwrapped.
423 if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last &&
424 FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for,
425 TT_ForEachMacro)) {
426 return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never
427 ? tryMergeSimpleBlock(I, E, Limit)
428 : 0;
429 }
430 // Try to merge a control statement block with left brace wrapped.
431 if (NextLine.First->is(tok::l_brace)) {
432 if ((TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
433 tok::kw_for, tok::kw_switch, tok::kw_try,
434 tok::kw_do, TT_ForEachMacro) ||
435 (TheLine->First->is(tok::r_brace) && TheLine->First->Next &&
436 TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch))) &&
437 Style.BraceWrapping.AfterControlStatement ==
439 // If possible, merge the next line's wrapped left brace with the
440 // current line. Otherwise, leave it on the next line, as this is a
441 // multi-line control statement.
442 return (Style.ColumnLimit == 0 || TheLine->Level * Style.IndentWidth +
443 TheLine->Last->TotalLength <=
444 Style.ColumnLimit)
445 ? 1
446 : 0;
447 }
448 if (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
449 tok::kw_for, TT_ForEachMacro)) {
450 return (Style.BraceWrapping.AfterControlStatement ==
452 ? tryMergeSimpleBlock(I, E, Limit)
453 : 0;
454 }
455 if (TheLine->First->isOneOf(tok::kw_else, tok::kw_catch) &&
456 Style.BraceWrapping.AfterControlStatement ==
458 // This case if different from the upper BWACS_MultiLine processing
459 // in that a preceding r_brace is not on the same line as else/catch
460 // most likely because of BeforeElse/BeforeCatch set to true.
461 // If the line length doesn't fit ColumnLimit, leave l_brace on the
462 // next line to respect the BWACS_MultiLine.
463 return (Style.ColumnLimit == 0 ||
464 TheLine->Last->TotalLength <= Style.ColumnLimit)
465 ? 1
466 : 0;
467 }
468 }
469 if (PreviousLine && TheLine->First->is(tok::l_brace)) {
470 switch (PreviousLine->First->Tok.getKind()) {
471 case tok::at:
472 // Don't merge block with left brace wrapped after ObjC special blocks.
473 if (PreviousLine->First->Next) {
475 PreviousLine->First->Next->Tok.getObjCKeywordID();
476 if (kwId == tok::objc_autoreleasepool ||
477 kwId == tok::objc_synchronized) {
478 return 0;
479 }
480 }
481 break;
482
483 case tok::kw_case:
484 case tok::kw_default:
485 // Don't merge block with left brace wrapped after case labels.
486 return 0;
487
488 default:
489 break;
490 }
491 }
492
493 // Don't merge an empty template class or struct if SplitEmptyRecords
494 // is defined.
495 if (PreviousLine && Style.BraceWrapping.SplitEmptyRecord &&
496 TheLine->Last->is(tok::l_brace) && PreviousLine->Last) {
497 const FormatToken *Previous = PreviousLine->Last;
498 if (Previous) {
499 if (Previous->is(tok::comment))
500 Previous = Previous->getPreviousNonComment();
501 if (Previous) {
502 if (Previous->is(tok::greater) && !PreviousLine->InPPDirective)
503 return 0;
504 if (Previous->is(tok::identifier)) {
505 const FormatToken *PreviousPrevious =
506 Previous->getPreviousNonComment();
507 if (PreviousPrevious &&
508 PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct)) {
509 return 0;
510 }
511 }
512 }
513 }
514 }
515
516 if (TheLine->Last->is(tok::l_brace)) {
517 bool ShouldMerge = false;
518 // Try to merge records.
519 if (TheLine->Last->is(TT_EnumLBrace)) {
520 ShouldMerge = Style.AllowShortEnumsOnASingleLine;
521 } else if (TheLine->Last->is(TT_RequiresExpressionLBrace)) {
522 ShouldMerge = Style.AllowShortCompoundRequirementOnASingleLine;
523 } else if (TheLine->Last->isOneOf(TT_ClassLBrace, TT_StructLBrace)) {
524 // NOTE: We use AfterClass (whereas AfterStruct exists) for both classes
525 // and structs, but it seems that wrapping is still handled correctly
526 // elsewhere.
527 ShouldMerge = !Style.BraceWrapping.AfterClass ||
528 (NextLine.First->is(tok::r_brace) &&
529 !Style.BraceWrapping.SplitEmptyRecord);
530 } else if (TheLine->InPPDirective ||
531 !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum,
532 tok::kw_struct)) {
533 // Try to merge a block with left brace unwrapped that wasn't yet
534 // covered.
535 ShouldMerge = !Style.BraceWrapping.AfterFunction ||
536 (NextLine.First->is(tok::r_brace) &&
537 !Style.BraceWrapping.SplitEmptyFunction);
538 }
539 return ShouldMerge ? tryMergeSimpleBlock(I, E, Limit) : 0;
540 }
541
542 // Try to merge a function block with left brace wrapped.
543 if (NextLine.First->is(TT_FunctionLBrace) &&
544 Style.BraceWrapping.AfterFunction) {
545 if (NextLine.Last->is(TT_LineComment))
546 return 0;
547
548 // Check for Limit <= 2 to account for the " {".
549 if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine)))
550 return 0;
551 Limit -= 2;
552
553 unsigned MergedLines = 0;
554 if (MergeShortFunctions ||
555 (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty &&
556 NextLine.First == NextLine.Last && I + 2 != E &&
557 I[2]->First->is(tok::r_brace))) {
558 MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
559 // If we managed to merge the block, count the function header, which is
560 // on a separate line.
561 if (MergedLines > 0)
562 ++MergedLines;
563 }
564 return MergedLines;
565 }
566 auto IsElseLine = [&TheLine]() -> bool {
567 const FormatToken *First = TheLine->First;
568 if (First->is(tok::kw_else))
569 return true;
570
571 return First->is(tok::r_brace) && First->Next &&
572 First->Next->is(tok::kw_else);
573 };
574 if (TheLine->First->is(tok::kw_if) ||
575 (IsElseLine() && (Style.AllowShortIfStatementsOnASingleLine ==
577 return Style.AllowShortIfStatementsOnASingleLine
578 ? tryMergeSimpleControlStatement(I, E, Limit)
579 : 0;
580 }
581 if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while, tok::kw_do,
582 TT_ForEachMacro)) {
583 return Style.AllowShortLoopsOnASingleLine
584 ? tryMergeSimpleControlStatement(I, E, Limit)
585 : 0;
586 }
587 if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) {
588 return Style.AllowShortCaseLabelsOnASingleLine
589 ? tryMergeShortCaseLabels(I, E, Limit)
590 : 0;
591 }
592 if (TheLine->InPPDirective &&
593 (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {
594 return tryMergeSimplePPDirective(I, E, Limit);
595 }
596 return 0;
597 }
598
599 unsigned
600 tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
601 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
602 unsigned Limit) {
603 if (Limit == 0)
604 return 0;
605 if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline)
606 return 0;
607 if (1 + I[1]->Last->TotalLength > Limit)
608 return 0;
609 return 1;
610 }
611
612 unsigned tryMergeSimpleControlStatement(
613 SmallVectorImpl<AnnotatedLine *>::const_iterator I,
614 SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {
615 if (Limit == 0)
616 return 0;
617 if (Style.BraceWrapping.AfterControlStatement ==
619 I[1]->First->is(tok::l_brace) &&
620 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) {
621 return 0;
622 }
623 if (I[1]->InPPDirective != (*I)->InPPDirective ||
624 (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline)) {
625 return 0;
626 }
627 Limit = limitConsideringMacros(I + 1, E, Limit);
628 AnnotatedLine &Line = **I;
629 if (Line.First->isNot(tok::kw_do) && Line.First->isNot(tok::kw_else) &&
630 Line.Last->isNot(tok::kw_else) && Line.Last->isNot(tok::r_paren)) {
631 return 0;
632 }
633 // Only merge `do while` if `do` is the only statement on the line.
634 if (Line.First->is(tok::kw_do) && Line.Last->isNot(tok::kw_do))
635 return 0;
636 if (1 + I[1]->Last->TotalLength > Limit)
637 return 0;
638 // Don't merge with loops, ifs, a single semicolon or a line comment.
639 if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, tok::kw_while,
640 TT_ForEachMacro, TT_LineComment)) {
641 return 0;
642 }
643 // Only inline simple if's (no nested if or else), unless specified
644 if (Style.AllowShortIfStatementsOnASingleLine ==
646 if (I + 2 != E && Line.startsWith(tok::kw_if) &&
647 I[2]->First->is(tok::kw_else)) {
648 return 0;
649 }
650 }
651 return 1;
652 }
653
654 unsigned
655 tryMergeShortCaseLabels(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
656 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
657 unsigned Limit) {
658 if (Limit == 0 || I + 1 == E ||
659 I[1]->First->isOneOf(tok::kw_case, tok::kw_default)) {
660 return 0;
661 }
662 if (I[0]->Last->is(tok::l_brace) || I[1]->First->is(tok::l_brace))
663 return 0;
664 unsigned NumStmts = 0;
665 unsigned Length = 0;
666 bool EndsWithComment = false;
667 bool InPPDirective = I[0]->InPPDirective;
668 bool InMacroBody = I[0]->InMacroBody;
669 const unsigned Level = I[0]->Level;
670 for (; NumStmts < 3; ++NumStmts) {
671 if (I + 1 + NumStmts == E)
672 break;
673 const AnnotatedLine *Line = I[1 + NumStmts];
674 if (Line->InPPDirective != InPPDirective)
675 break;
676 if (Line->InMacroBody != InMacroBody)
677 break;
678 if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
679 break;
680 if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,
681 tok::kw_while) ||
682 EndsWithComment) {
683 return 0;
684 }
685 if (Line->First->is(tok::comment)) {
686 if (Level != Line->Level)
687 return 0;
688 SmallVectorImpl<AnnotatedLine *>::const_iterator J = I + 2 + NumStmts;
689 for (; J != E; ++J) {
690 Line = *J;
691 if (Line->InPPDirective != InPPDirective)
692 break;
693 if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
694 break;
695 if (Line->First->isNot(tok::comment) || Level != Line->Level)
696 return 0;
697 }
698 break;
699 }
700 if (Line->Last->is(tok::comment))
701 EndsWithComment = true;
702 Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.
703 }
704 if (NumStmts == 0 || NumStmts == 3 || Length > Limit)
705 return 0;
706 return NumStmts;
707 }
708
709 unsigned
710 tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
711 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
712 unsigned Limit) {
713 // Don't merge with a preprocessor directive.
714 if (I[1]->Type == LT_PreprocessorDirective)
715 return 0;
716
717 AnnotatedLine &Line = **I;
718
719 // Don't merge ObjC @ keywords and methods.
720 // FIXME: If an option to allow short exception handling clauses on a single
721 // line is added, change this to not return for @try and friends.
722 if (Style.Language != FormatStyle::LK_Java &&
723 Line.First->isOneOf(tok::at, tok::minus, tok::plus)) {
724 return 0;
725 }
726
727 // Check that the current line allows merging. This depends on whether we
728 // are in a control flow statements as well as several style flags.
729 if (Line.First->is(tok::kw_case) ||
730 (Line.First->Next && Line.First->Next->is(tok::kw_else))) {
731 return 0;
732 }
733 // default: in switch statement
734 if (Line.First->is(tok::kw_default)) {
735 const FormatToken *Tok = Line.First->getNextNonComment();
736 if (Tok && Tok->is(tok::colon))
737 return 0;
738 }
739
740 auto IsCtrlStmt = [](const auto &Line) {
741 return Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
742 tok::kw_do, tok::kw_for, TT_ForEachMacro);
743 };
744
745 const bool IsSplitBlock =
746 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never ||
747 (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Empty &&
748 I[1]->First->isNot(tok::r_brace));
749
750 if (IsCtrlStmt(Line) ||
751 Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch,
752 tok::kw___finally, tok::r_brace,
753 Keywords.kw___except)) {
754 if (IsSplitBlock)
755 return 0;
756 // Don't merge when we can't except the case when
757 // the control statement block is empty
758 if (!Style.AllowShortIfStatementsOnASingleLine &&
759 Line.First->isOneOf(tok::kw_if, tok::kw_else) &&
760 !Style.BraceWrapping.AfterControlStatement &&
761 I[1]->First->isNot(tok::r_brace)) {
762 return 0;
763 }
764 if (!Style.AllowShortIfStatementsOnASingleLine &&
765 Line.First->isOneOf(tok::kw_if, tok::kw_else) &&
766 Style.BraceWrapping.AfterControlStatement ==
768 I + 2 != E && I[2]->First->isNot(tok::r_brace)) {
769 return 0;
770 }
771 if (!Style.AllowShortLoopsOnASingleLine &&
772 Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for,
773 TT_ForEachMacro) &&
774 !Style.BraceWrapping.AfterControlStatement &&
775 I[1]->First->isNot(tok::r_brace)) {
776 return 0;
777 }
778 if (!Style.AllowShortLoopsOnASingleLine &&
779 Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for,
780 TT_ForEachMacro) &&
781 Style.BraceWrapping.AfterControlStatement ==
783 I + 2 != E && I[2]->First->isNot(tok::r_brace)) {
784 return 0;
785 }
786 // FIXME: Consider an option to allow short exception handling clauses on
787 // a single line.
788 // FIXME: This isn't covered by tests.
789 // FIXME: For catch, __except, __finally the first token on the line
790 // is '}', so this isn't correct here.
791 if (Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch,
792 Keywords.kw___except, tok::kw___finally)) {
793 return 0;
794 }
795 }
796
797 if (const auto *LastNonComment = Line.getLastNonComment();
798 LastNonComment && LastNonComment->is(tok::l_brace)) {
799 if (IsSplitBlock && Line.First == Line.Last &&
800 I > AnnotatedLines.begin() &&
801 (I[-1]->endsWith(tok::kw_else) || IsCtrlStmt(*I[-1]))) {
802 return 0;
803 }
804 FormatToken *Tok = I[1]->First;
805 auto ShouldMerge = [Tok]() {
806 if (Tok->isNot(tok::r_brace) || Tok->MustBreakBefore)
807 return false;
808 const FormatToken *Next = Tok->getNextNonComment();
809 return !Next || Next->is(tok::semi);
810 };
811
812 if (ShouldMerge()) {
813 // We merge empty blocks even if the line exceeds the column limit.
814 Tok->SpacesRequiredBefore =
815 (Style.SpaceInEmptyBlock || Line.Last->is(tok::comment)) ? 1 : 0;
816 Tok->CanBreakBefore = true;
817 return 1;
818 } else if (Limit != 0 && !Line.startsWithNamespace() &&
819 !startsExternCBlock(Line)) {
820 // We don't merge short records.
821 if (isRecordLBrace(*Line.Last))
822 return 0;
823
824 // Check that we still have three lines and they fit into the limit.
825 if (I + 2 == E || I[2]->Type == LT_Invalid)
826 return 0;
827 Limit = limitConsideringMacros(I + 2, E, Limit);
828
829 if (!nextTwoLinesFitInto(I, Limit))
830 return 0;
831
832 // Second, check that the next line does not contain any braces - if it
833 // does, readability declines when putting it into a single line.
834 if (I[1]->Last->is(TT_LineComment))
835 return 0;
836 do {
837 if (Tok->is(tok::l_brace) && Tok->isNot(BK_BracedInit))
838 return 0;
839 Tok = Tok->Next;
840 } while (Tok);
841
842 // Last, check that the third line starts with a closing brace.
843 Tok = I[2]->First;
844 if (Tok->isNot(tok::r_brace))
845 return 0;
846
847 // Don't merge "if (a) { .. } else {".
848 if (Tok->Next && Tok->Next->is(tok::kw_else))
849 return 0;
850
851 // Don't merge a trailing multi-line control statement block like:
852 // } else if (foo &&
853 // bar)
854 // { <-- current Line
855 // baz();
856 // }
857 if (Line.First == Line.Last && Line.First->isNot(TT_FunctionLBrace) &&
858 Style.BraceWrapping.AfterControlStatement ==
860 return 0;
861 }
862
863 return 2;
864 }
865 } else if (I[1]->First->is(tok::l_brace)) {
866 if (I[1]->Last->is(TT_LineComment))
867 return 0;
868
869 // Check for Limit <= 2 to account for the " {".
870 if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(*I)))
871 return 0;
872 Limit -= 2;
873 unsigned MergedLines = 0;
874 if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never ||
875 (I[1]->First == I[1]->Last && I + 2 != E &&
876 I[2]->First->is(tok::r_brace))) {
877 MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
878 // If we managed to merge the block, count the statement header, which
879 // is on a separate line.
880 if (MergedLines > 0)
881 ++MergedLines;
882 }
883 return MergedLines;
884 }
885 return 0;
886 }
887
888 /// Returns the modified column limit for \p I if it is inside a macro and
889 /// needs a trailing '\'.
890 unsigned
891 limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
892 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
893 unsigned Limit) {
894 if (I[0]->InPPDirective && I + 1 != E &&
895 !I[1]->First->HasUnescapedNewline && I[1]->First->isNot(tok::eof)) {
896 return Limit < 2 ? 0 : Limit - 2;
897 }
898 return Limit;
899 }
900
901 bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
902 unsigned Limit) {
903 if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore)
904 return false;
905 return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit;
906 }
907
908 bool containsMustBreak(const AnnotatedLine *Line) {
909 assert(Line->First);
910 // Ignore the first token, because in this situation, it applies more to the
911 // last token of the previous line.
912 for (const FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next)
913 if (Tok->MustBreakBefore)
914 return true;
915 return false;
916 }
917
918 void join(AnnotatedLine &A, const AnnotatedLine &B) {
919 assert(!A.Last->Next);
920 assert(!B.First->Previous);
921 if (B.Affected)
922 A.Affected = true;
923 A.Last->Next = B.First;
924 B.First->Previous = A.Last;
925 B.First->CanBreakBefore = true;
926 unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore;
927 for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) {
928 Tok->TotalLength += LengthA;
929 A.Last = Tok;
930 }
931 }
932
933 const FormatStyle &Style;
934 const AdditionalKeywords &Keywords;
935 const SmallVectorImpl<AnnotatedLine *>::const_iterator End;
936
937 SmallVectorImpl<AnnotatedLine *>::const_iterator Next;
938 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines;
939};
940
941static void markFinalized(FormatToken *Tok) {
942 if (Tok->is(tok::hash) && !Tok->Previous && Tok->Next &&
943 Tok->Next->isOneOf(tok::pp_if, tok::pp_ifdef, tok::pp_ifndef,
944 tok::pp_elif, tok::pp_elifdef, tok::pp_elifndef,
945 tok::pp_else, tok::pp_endif)) {
946 Tok = Tok->Next;
947 }
948 for (; Tok; Tok = Tok->Next) {
949 if (Tok->MacroCtx && Tok->MacroCtx->Role == MR_ExpandedArg) {
950 // In the first pass we format all macro arguments in the expanded token
951 // stream. Instead of finalizing the macro arguments, we mark that they
952 // will be modified as unexpanded arguments (as part of the macro call
953 // formatting) in the next pass.
954 Tok->MacroCtx->Role = MR_UnexpandedArg;
955 // Reset whether spaces or a line break are required before this token, as
956 // that is context dependent, and that context may change when formatting
957 // the macro call. For example, given M(x) -> 2 * x, and the macro call
958 // M(var), the token 'var' will have SpacesRequiredBefore = 1 after being
959 // formatted as part of the expanded macro, but SpacesRequiredBefore = 0
960 // for its position within the macro call.
961 Tok->SpacesRequiredBefore = 0;
962 if (!Tok->MustBreakBeforeFinalized)
963 Tok->MustBreakBefore = 0;
964 } else {
965 Tok->Finalized = true;
966 }
967 }
968}
969
970#ifndef NDEBUG
971static void printLineState(const LineState &State) {
972 llvm::dbgs() << "State: ";
973 for (const ParenState &P : State.Stack) {
974 llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent << "|"
975 << P.LastSpace << "|" << P.NestedBlockIndent << " ";
976 }
977 llvm::dbgs() << State.NextToken->TokenText << "\n";
978}
979#endif
980
981/// Base class for classes that format one \c AnnotatedLine.
982class LineFormatter {
983public:
984 LineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces,
985 const FormatStyle &Style,
986 UnwrappedLineFormatter *BlockFormatter)
987 : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style),
988 BlockFormatter(BlockFormatter) {}
989 virtual ~LineFormatter() {}
990
991 /// Formats an \c AnnotatedLine and returns the penalty.
992 ///
993 /// If \p DryRun is \c false, directly applies the changes.
994 virtual unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
995 unsigned FirstStartColumn, bool DryRun) = 0;
996
997protected:
998 /// If the \p State's next token is an r_brace closing a nested block,
999 /// format the nested block before it.
1000 ///
1001 /// Returns \c true if all children could be placed successfully and adapts
1002 /// \p Penalty as well as \p State. If \p DryRun is false, also directly
1003 /// creates changes using \c Whitespaces.
1004 ///
1005 /// The crucial idea here is that children always get formatted upon
1006 /// encountering the closing brace right after the nested block. Now, if we
1007 /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is
1008 /// \c false), the entire block has to be kept on the same line (which is only
1009 /// possible if it fits on the line, only contains a single statement, etc.
1010 ///
1011 /// If \p NewLine is true, we format the nested block on separate lines, i.e.
1012 /// break after the "{", format all lines with correct indentation and the put
1013 /// the closing "}" on yet another new line.
1014 ///
1015 /// This enables us to keep the simple structure of the
1016 /// \c UnwrappedLineFormatter, where we only have two options for each token:
1017 /// break or don't break.
1018 bool formatChildren(LineState &State, bool NewLine, bool DryRun,
1019 unsigned &Penalty) {
1020 const FormatToken *LBrace = State.NextToken->getPreviousNonComment();
1021 bool HasLBrace = LBrace && LBrace->is(tok::l_brace) && LBrace->is(BK_Block);
1022 FormatToken &Previous = *State.NextToken->Previous;
1023 if (Previous.Children.size() == 0 || (!HasLBrace && !LBrace->MacroParent)) {
1024 // The previous token does not open a block. Nothing to do. We don't
1025 // assert so that we can simply call this function for all tokens.
1026 return true;
1027 }
1028
1029 if (NewLine || Previous.MacroParent) {
1030 const ParenState &P = State.Stack.back();
1031
1032 int AdditionalIndent =
1033 P.Indent - Previous.Children[0]->Level * Style.IndentWidth;
1034 Penalty +=
1035 BlockFormatter->format(Previous.Children, DryRun, AdditionalIndent,
1036 /*FixBadIndentation=*/true);
1037 return true;
1038 }
1039
1040 if (Previous.Children[0]->First->MustBreakBefore)
1041 return false;
1042
1043 // Cannot merge into one line if this line ends on a comment.
1044 if (Previous.is(tok::comment))
1045 return false;
1046
1047 // Cannot merge multiple statements into a single line.
1048 if (Previous.Children.size() > 1)
1049 return false;
1050
1051 const AnnotatedLine *Child = Previous.Children[0];
1052 // We can't put the closing "}" on a line with a trailing comment.
1053 if (Child->Last->isTrailingComment())
1054 return false;
1055
1056 // If the child line exceeds the column limit, we wouldn't want to merge it.
1057 // We add +2 for the trailing " }".
1058 if (Style.ColumnLimit > 0 &&
1059 Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit) {
1060 return false;
1061 }
1062
1063 if (!DryRun) {
1064 Whitespaces->replaceWhitespace(
1065 *Child->First, /*Newlines=*/0, /*Spaces=*/1,
1066 /*StartOfTokenColumn=*/State.Column, /*IsAligned=*/false,
1067 State.Line->InPPDirective);
1068 }
1069 Penalty +=
1070 formatLine(*Child, State.Column + 1, /*FirstStartColumn=*/0, DryRun);
1071 if (!DryRun)
1072 markFinalized(Child->First);
1073
1074 State.Column += 1 + Child->Last->TotalLength;
1075 return true;
1076 }
1077
1078 ContinuationIndenter *Indenter;
1079
1080private:
1081 WhitespaceManager *Whitespaces;
1082 const FormatStyle &Style;
1083 UnwrappedLineFormatter *BlockFormatter;
1084};
1085
1086/// Formatter that keeps the existing line breaks.
1087class NoColumnLimitLineFormatter : public LineFormatter {
1088public:
1089 NoColumnLimitLineFormatter(ContinuationIndenter *Indenter,
1090 WhitespaceManager *Whitespaces,
1091 const FormatStyle &Style,
1092 UnwrappedLineFormatter *BlockFormatter)
1093 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
1094
1095 /// Formats the line, simply keeping all of the input's line breaking
1096 /// decisions.
1097 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
1098 unsigned FirstStartColumn, bool DryRun) override {
1099 assert(!DryRun);
1100 LineState State = Indenter->getInitialState(FirstIndent, FirstStartColumn,
1101 &Line, /*DryRun=*/false);
1102 while (State.NextToken) {
1103 bool Newline =
1104 Indenter->mustBreak(State) ||
1105 (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
1106 unsigned Penalty = 0;
1107 formatChildren(State, Newline, /*DryRun=*/false, Penalty);
1108 Indenter->addTokenToState(State, Newline, /*DryRun=*/false);
1109 }
1110 return 0;
1111 }
1112};
1113
1114/// Formatter that puts all tokens into a single line without breaks.
1115class NoLineBreakFormatter : public LineFormatter {
1116public:
1117 NoLineBreakFormatter(ContinuationIndenter *Indenter,
1118 WhitespaceManager *Whitespaces, const FormatStyle &Style,
1119 UnwrappedLineFormatter *BlockFormatter)
1120 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
1121
1122 /// Puts all tokens into a single line.
1123 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
1124 unsigned FirstStartColumn, bool DryRun) override {
1125 unsigned Penalty = 0;
1126 LineState State =
1127 Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun);
1128 while (State.NextToken) {
1129 formatChildren(State, /*NewLine=*/false, DryRun, Penalty);
1130 Indenter->addTokenToState(
1131 State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun);
1132 }
1133 return Penalty;
1134 }
1135};
1136
1137/// Finds the best way to break lines.
1138class OptimizingLineFormatter : public LineFormatter {
1139public:
1140 OptimizingLineFormatter(ContinuationIndenter *Indenter,
1141 WhitespaceManager *Whitespaces,
1142 const FormatStyle &Style,
1143 UnwrappedLineFormatter *BlockFormatter)
1144 : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {}
1145
1146 /// Formats the line by finding the best line breaks with line lengths
1147 /// below the column limit.
1148 unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
1149 unsigned FirstStartColumn, bool DryRun) override {
1150 LineState State =
1151 Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun);
1152
1153 // If the ObjC method declaration does not fit on a line, we should format
1154 // it with one arg per line.
1155 if (State.Line->Type == LT_ObjCMethodDecl)
1156 State.Stack.back().BreakBeforeParameter = true;
1157
1158 // Find best solution in solution space.
1159 return analyzeSolutionSpace(State, DryRun);
1160 }
1161
1162private:
1163 struct CompareLineStatePointers {
1164 bool operator()(LineState *obj1, LineState *obj2) const {
1165 return *obj1 < *obj2;
1166 }
1167 };
1168
1169 /// A pair of <penalty, count> that is used to prioritize the BFS on.
1170 ///
1171 /// In case of equal penalties, we want to prefer states that were inserted
1172 /// first. During state generation we make sure that we insert states first
1173 /// that break the line as late as possible.
1174 typedef std::pair<unsigned, unsigned> OrderedPenalty;
1175
1176 /// An edge in the solution space from \c Previous->State to \c State,
1177 /// inserting a newline dependent on the \c NewLine.
1178 struct StateNode {
1179 StateNode(const LineState &State, bool NewLine, StateNode *Previous)
1180 : State(State), NewLine(NewLine), Previous(Previous) {}
1181 LineState State;
1183 StateNode *Previous;
1184 };
1185
1186 /// An item in the prioritized BFS search queue. The \c StateNode's
1187 /// \c State has the given \c OrderedPenalty.
1188 typedef std::pair<OrderedPenalty, StateNode *> QueueItem;
1189
1190 /// The BFS queue type.
1191 typedef std::priority_queue<QueueItem, SmallVector<QueueItem>,
1192 std::greater<QueueItem>>
1193 QueueType;
1194
1195 /// Analyze the entire solution space starting from \p InitialState.
1196 ///
1197 /// This implements a variant of Dijkstra's algorithm on the graph that spans
1198 /// the solution space (\c LineStates are the nodes). The algorithm tries to
1199 /// find the shortest path (the one with lowest penalty) from \p InitialState
1200 /// to a state where all tokens are placed. Returns the penalty.
1201 ///
1202 /// If \p DryRun is \c false, directly applies the changes.
1203 unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun) {
1204 std::set<LineState *, CompareLineStatePointers> Seen;
1205
1206 // Increasing count of \c StateNode items we have created. This is used to
1207 // create a deterministic order independent of the container.
1208 unsigned Count = 0;
1209 QueueType Queue;
1210
1211 // Insert start element into queue.
1212 StateNode *RootNode =
1213 new (Allocator.Allocate()) StateNode(InitialState, false, nullptr);
1214 Queue.push(QueueItem(OrderedPenalty(0, Count), RootNode));
1215 ++Count;
1216
1217 unsigned Penalty = 0;
1218
1219 // While not empty, take first element and follow edges.
1220 while (!Queue.empty()) {
1221 // Quit if we still haven't found a solution by now.
1222 if (Count > 25'000'000)
1223 return 0;
1224
1225 Penalty = Queue.top().first.first;
1226 StateNode *Node = Queue.top().second;
1227 if (!Node->State.NextToken) {
1228 LLVM_DEBUG(llvm::dbgs()
1229 << "\n---\nPenalty for line: " << Penalty << "\n");
1230 break;
1231 }
1232 Queue.pop();
1233
1234 // Cut off the analysis of certain solutions if the analysis gets too
1235 // complex. See description of IgnoreStackForComparison.
1236 if (Count > 50'000)
1237 Node->State.IgnoreStackForComparison = true;
1238
1239 if (!Seen.insert(&Node->State).second) {
1240 // State already examined with lower penalty.
1241 continue;
1242 }
1243
1244 FormatDecision LastFormat = Node->State.NextToken->getDecision();
1245 if (LastFormat == FD_Unformatted || LastFormat == FD_Continue)
1246 addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue);
1247 if (LastFormat == FD_Unformatted || LastFormat == FD_Break)
1248 addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue);
1249 }
1250
1251 if (Queue.empty()) {
1252 // We were unable to find a solution, do nothing.
1253 // FIXME: Add diagnostic?
1254 LLVM_DEBUG(llvm::dbgs() << "Could not find a solution.\n");
1255 return 0;
1256 }
1257
1258 // Reconstruct the solution.
1259 if (!DryRun)
1260 reconstructPath(InitialState, Queue.top().second);
1261
1262 LLVM_DEBUG(llvm::dbgs()
1263 << "Total number of analyzed states: " << Count << "\n");
1264 LLVM_DEBUG(llvm::dbgs() << "---\n");
1265
1266 return Penalty;
1267 }
1268
1269 /// Add the following state to the analysis queue \c Queue.
1270 ///
1271 /// Assume the current state is \p PreviousNode and has been reached with a
1272 /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true.
1273 void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode,
1274 bool NewLine, unsigned *Count, QueueType *Queue) {
1275 if (NewLine && !Indenter->canBreak(PreviousNode->State))
1276 return;
1277 if (!NewLine && Indenter->mustBreak(PreviousNode->State))
1278 return;
1279
1280 StateNode *Node = new (Allocator.Allocate())
1281 StateNode(PreviousNode->State, NewLine, PreviousNode);
1282 if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty))
1283 return;
1284
1285 Penalty += Indenter->addTokenToState(Node->State, NewLine, true);
1286
1287 Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node));
1288 ++(*Count);
1289 }
1290
1291 /// Applies the best formatting by reconstructing the path in the
1292 /// solution space that leads to \c Best.
1293 void reconstructPath(LineState &State, StateNode *Best) {
1295 // We do not need a break before the initial token.
1296 while (Best->Previous) {
1297 Path.push_back(Best);
1298 Best = Best->Previous;
1299 }
1300 for (const auto &Node : llvm::reverse(Path)) {
1301 unsigned Penalty = 0;
1302 formatChildren(State, Node->NewLine, /*DryRun=*/false, Penalty);
1303 Penalty += Indenter->addTokenToState(State, Node->NewLine, false);
1304
1305 LLVM_DEBUG({
1306 printLineState(Node->Previous->State);
1307 if (Node->NewLine) {
1308 llvm::dbgs() << "Penalty for placing "
1309 << Node->Previous->State.NextToken->Tok.getName()
1310 << " on a new line: " << Penalty << "\n";
1311 }
1312 });
1313 }
1314 }
1315
1316 llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
1317};
1318
1319} // anonymous namespace
1320
1322 const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
1323 int AdditionalIndent, bool FixBadIndentation, unsigned FirstStartColumn,
1324 unsigned NextStartColumn, unsigned LastStartColumn) {
1325 LineJoiner Joiner(Style, Keywords, Lines);
1326
1327 // Try to look up already computed penalty in DryRun-mode.
1328 std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey(
1329 &Lines, AdditionalIndent);
1330 auto CacheIt = PenaltyCache.find(CacheKey);
1331 if (DryRun && CacheIt != PenaltyCache.end())
1332 return CacheIt->second;
1333
1334 assert(!Lines.empty());
1335 unsigned Penalty = 0;
1336 LevelIndentTracker IndentTracker(Style, Keywords, Lines[0]->Level,
1337 AdditionalIndent);
1338 const AnnotatedLine *PrevPrevLine = nullptr;
1339 const AnnotatedLine *PreviousLine = nullptr;
1340 const AnnotatedLine *NextLine = nullptr;
1341
1342 // The minimum level of consecutive lines that have been formatted.
1343 unsigned RangeMinLevel = UINT_MAX;
1344
1345 bool FirstLine = true;
1346 for (const AnnotatedLine *Line =
1347 Joiner.getNextMergedLine(DryRun, IndentTracker);
1348 Line; PrevPrevLine = PreviousLine, PreviousLine = Line, Line = NextLine,
1349 FirstLine = false) {
1350 assert(Line->First);
1351 const AnnotatedLine &TheLine = *Line;
1352 unsigned Indent = IndentTracker.getIndent();
1353
1354 // We continue formatting unchanged lines to adjust their indent, e.g. if a
1355 // scope was added. However, we need to carefully stop doing this when we
1356 // exit the scope of affected lines to prevent indenting the entire
1357 // remaining file if it currently missing a closing brace.
1358 bool PreviousRBrace =
1359 PreviousLine && PreviousLine->startsWith(tok::r_brace);
1360 bool ContinueFormatting =
1361 TheLine.Level > RangeMinLevel ||
1362 (TheLine.Level == RangeMinLevel && !PreviousRBrace &&
1363 !TheLine.startsWith(tok::r_brace));
1364
1365 bool FixIndentation = (FixBadIndentation || ContinueFormatting) &&
1366 Indent != TheLine.First->OriginalColumn;
1367 bool ShouldFormat = TheLine.Affected || FixIndentation;
1368 // We cannot format this line; if the reason is that the line had a
1369 // parsing error, remember that.
1370 if (ShouldFormat && TheLine.Type == LT_Invalid && Status) {
1371 Status->FormatComplete = false;
1372 Status->Line =
1373 SourceMgr.getSpellingLineNumber(TheLine.First->Tok.getLocation());
1374 }
1375
1376 if (ShouldFormat && TheLine.Type != LT_Invalid) {
1377 if (!DryRun) {
1378 bool LastLine = TheLine.First->is(tok::eof);
1379 formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines, Indent,
1380 LastLine ? LastStartColumn : NextStartColumn + Indent);
1381 }
1382
1383 NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
1384 unsigned ColumnLimit = getColumnLimit(TheLine.InPPDirective, NextLine);
1385 bool FitsIntoOneLine =
1386 !TheLine.ContainsMacroCall &&
1387 (TheLine.Last->TotalLength + Indent <= ColumnLimit ||
1388 (TheLine.Type == LT_ImportStatement &&
1389 (!Style.isJavaScript() || !Style.JavaScriptWrapImports)) ||
1390 (Style.isCSharp() &&
1391 TheLine.InPPDirective)); // don't split #regions in C#
1392 if (Style.ColumnLimit == 0) {
1393 NoColumnLimitLineFormatter(Indenter, Whitespaces, Style, this)
1394 .formatLine(TheLine, NextStartColumn + Indent,
1395 FirstLine ? FirstStartColumn : 0, DryRun);
1396 } else if (FitsIntoOneLine) {
1397 Penalty += NoLineBreakFormatter(Indenter, Whitespaces, Style, this)
1398 .formatLine(TheLine, NextStartColumn + Indent,
1399 FirstLine ? FirstStartColumn : 0, DryRun);
1400 } else {
1401 Penalty += OptimizingLineFormatter(Indenter, Whitespaces, Style, this)
1402 .formatLine(TheLine, NextStartColumn + Indent,
1403 FirstLine ? FirstStartColumn : 0, DryRun);
1404 }
1405 RangeMinLevel = std::min(RangeMinLevel, TheLine.Level);
1406 } else {
1407 // If no token in the current line is affected, we still need to format
1408 // affected children.
1409 if (TheLine.ChildrenAffected) {
1410 for (const FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next)
1411 if (!Tok->Children.empty())
1412 format(Tok->Children, DryRun);
1413 }
1414
1415 // Adapt following lines on the current indent level to the same level
1416 // unless the current \c AnnotatedLine is not at the beginning of a line.
1417 bool StartsNewLine =
1418 TheLine.First->NewlinesBefore > 0 || TheLine.First->IsFirst;
1419 if (StartsNewLine)
1420 IndentTracker.adjustToUnmodifiedLine(TheLine);
1421 if (!DryRun) {
1422 bool ReformatLeadingWhitespace =
1423 StartsNewLine && ((PreviousLine && PreviousLine->Affected) ||
1425 // Format the first token.
1426 if (ReformatLeadingWhitespace) {
1427 formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines,
1428 TheLine.First->OriginalColumn,
1429 TheLine.First->OriginalColumn);
1430 } else {
1431 Whitespaces->addUntouchableToken(*TheLine.First,
1432 TheLine.InPPDirective);
1433 }
1434
1435 // Notify the WhitespaceManager about the unchanged whitespace.
1436 for (FormatToken *Tok = TheLine.First->Next; Tok; Tok = Tok->Next)
1437 Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
1438 }
1439 NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
1440 RangeMinLevel = UINT_MAX;
1441 }
1442 if (!DryRun)
1443 markFinalized(TheLine.First);
1444 }
1445 PenaltyCache[CacheKey] = Penalty;
1446 return Penalty;
1447}
1448
1450 const AnnotatedLine *PreviousLine,
1451 const AnnotatedLine *PrevPrevLine,
1453 const FormatStyle &Style) {
1454 const auto &RootToken = *Line.First;
1455 auto Newlines =
1456 std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
1457 // Remove empty lines before "}" where applicable.
1458 if (RootToken.is(tok::r_brace) &&
1459 (!RootToken.Next ||
1460 (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)) &&
1461 // Do not remove empty lines before namespace closing "}".
1462 !getNamespaceToken(&Line, Lines)) {
1463 Newlines = std::min(Newlines, 1u);
1464 }
1465 // Remove empty lines at the start of nested blocks (lambdas/arrow functions)
1466 if (!PreviousLine && Line.Level > 0)
1467 Newlines = std::min(Newlines, 1u);
1468 if (Newlines == 0 && !RootToken.IsFirst)
1469 Newlines = 1;
1470 if (RootToken.IsFirst && !RootToken.HasUnescapedNewline)
1471 Newlines = 0;
1472
1473 // Remove empty lines after "{".
1474 if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
1475 PreviousLine->Last->is(tok::l_brace) &&
1476 !PreviousLine->startsWithNamespace() &&
1477 !(PrevPrevLine && PrevPrevLine->startsWithNamespace() &&
1478 PreviousLine->startsWith(tok::l_brace)) &&
1479 !startsExternCBlock(*PreviousLine)) {
1480 Newlines = 1;
1481 }
1482
1483 // Insert or remove empty line before access specifiers.
1484 if (PreviousLine && RootToken.isAccessSpecifier()) {
1485 switch (Style.EmptyLineBeforeAccessModifier) {
1487 if (Newlines > 1)
1488 Newlines = 1;
1489 break;
1491 Newlines = std::max(RootToken.NewlinesBefore, 1u);
1492 break;
1494 if (PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && Newlines <= 1)
1495 Newlines = 2;
1496 if (PreviousLine->First->isAccessSpecifier())
1497 Newlines = 1; // Previous is an access modifier remove all new lines.
1498 break;
1500 const FormatToken *previousToken;
1501 if (PreviousLine->Last->is(tok::comment))
1502 previousToken = PreviousLine->Last->getPreviousNonComment();
1503 else
1504 previousToken = PreviousLine->Last;
1505 if ((!previousToken || previousToken->isNot(tok::l_brace)) &&
1506 Newlines <= 1) {
1507 Newlines = 2;
1508 }
1509 } break;
1510 }
1511 }
1512
1513 // Insert or remove empty line after access specifiers.
1514 if (PreviousLine && PreviousLine->First->isAccessSpecifier() &&
1515 (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline)) {
1516 // EmptyLineBeforeAccessModifier is handling the case when two access
1517 // modifiers follow each other.
1518 if (!RootToken.isAccessSpecifier()) {
1519 switch (Style.EmptyLineAfterAccessModifier) {
1521 Newlines = 1;
1522 break;
1524 Newlines = std::max(Newlines, 1u);
1525 break;
1527 if (RootToken.is(tok::r_brace)) // Do not add at end of class.
1528 Newlines = 1u;
1529 else
1530 Newlines = std::max(Newlines, 2u);
1531 break;
1532 }
1533 }
1534 }
1535
1536 return Newlines;
1537}
1538
1539void UnwrappedLineFormatter::formatFirstToken(
1540 const AnnotatedLine &Line, const AnnotatedLine *PreviousLine,
1541 const AnnotatedLine *PrevPrevLine,
1542 const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent,
1543 unsigned NewlineIndent) {
1544 FormatToken &RootToken = *Line.First;
1545 if (RootToken.is(tok::eof)) {
1546 unsigned Newlines =
1547 std::min(RootToken.NewlinesBefore,
1548 Style.KeepEmptyLinesAtEOF ? Style.MaxEmptyLinesToKeep + 1 : 1);
1549 unsigned TokenIndent = Newlines ? NewlineIndent : 0;
1550 Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent,
1551 TokenIndent);
1552 return;
1553 }
1554
1555 if (RootToken.Newlines < 0) {
1556 RootToken.Newlines =
1557 computeNewlines(Line, PreviousLine, PrevPrevLine, Lines, Style);
1558 assert(RootToken.Newlines >= 0);
1559 }
1560
1561 if (RootToken.Newlines > 0)
1562 Indent = NewlineIndent;
1563
1564 // Preprocessor directives get indented before the hash only if specified. In
1565 // Javascript import statements are indented like normal statements.
1566 if (!Style.isJavaScript() &&
1567 Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
1568 (Line.Type == LT_PreprocessorDirective ||
1569 Line.Type == LT_ImportStatement)) {
1570 Indent = 0;
1571 }
1572
1573 Whitespaces->replaceWhitespace(RootToken, RootToken.Newlines, Indent, Indent,
1574 /*IsAligned=*/false,
1575 Line.InPPDirective &&
1576 !RootToken.HasUnescapedNewline);
1577}
1578
1579unsigned
1580UnwrappedLineFormatter::getColumnLimit(bool InPPDirective,
1581 const AnnotatedLine *NextLine) const {
1582 // In preprocessor directives reserve two chars for trailing " \" if the
1583 // next line continues the preprocessor directive.
1584 bool ContinuesPPDirective =
1585 InPPDirective &&
1586 // If there is no next line, this is likely a child line and the parent
1587 // continues the preprocessor directive.
1588 (!NextLine ||
1589 (NextLine->InPPDirective &&
1590 // If there is an unescaped newline between this line and the next, the
1591 // next line starts a new preprocessor directive.
1592 !NextLine->First->HasUnescapedNewline));
1593 return Style.ColumnLimit - (ContinuesPPDirective ? 2 : 0);
1594}
1595
1596} // namespace format
1597} // namespace clang
MatchType Type
DynTypedNode Node
StringRef P
This file declares NamespaceEndCommentsFixer, a TokenAnalyzer that fixes namespace end comments.
StateNode * Previous
ContinuationIndenter * Indenter
Implements a combinatorial exploration of all the different linebreaks unwrapped lines can be formatt...
WhitespaceManager class manages whitespace around tokens and their replacements.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition: Token.h:132
bool LeadingEmptyLinesAffected
True if the leading empty lines of this line intersect with one of the input ranges.
bool Affected
True if this line should be formatted, i.e.
bool ContainsMacroCall
True if this line contains a macro call for which an expansion exists.
bool ChildrenAffected
True if one of this line's children intersects with an input range.
bool startsWithNamespace() const
true if this line starts a namespace definition.
bool startsWith(Ts... Tokens) const
true if this line starts with the given tokens in order, ignoring comments.
unsigned format(const SmallVectorImpl< AnnotatedLine * > &Lines, bool DryRun=false, int AdditionalIndent=0, bool FixBadIndentation=false, unsigned FirstStartColumn=0, unsigned NextStartColumn=0, unsigned LastStartColumn=0)
Format the current block and return the penalty.
#define UINT_MAX
Definition: limits.h:60
@ MR_UnexpandedArg
The token is part of a macro argument that was previously formatted as expansion when formatting the ...
Definition: FormatToken.h:223
@ MR_ExpandedArg
The token was expanded from a macro argument when formatting the expanded token sequence.
Definition: FormatToken.h:220
const FormatToken * getNamespaceToken(const AnnotatedLine *Line, const SmallVectorImpl< AnnotatedLine * > &AnnotatedLines)
static auto computeNewlines(const AnnotatedLine &Line, const AnnotatedLine *PreviousLine, const AnnotatedLine *PrevPrevLine, const SmallVectorImpl< AnnotatedLine * > &Lines, const FormatStyle &Style)
StringRef getNamespaceTokenText(const AnnotatedLine *Line, const SmallVectorImpl< AnnotatedLine * > &AnnotatedLines)
@ LT_CommentAbovePPDirective
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
Definition: TokenKinds.h:41
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
The FormatStyle is used to configure the formatting to follow specific guidelines.
Definition: Format.h:55
@ LK_Java
Should be used for Java.
Definition: Format.h:3093
@ ELBAMS_LogicalBlock
Add empty line only when access modifier starts a new logical block.
Definition: Format.h:2498
@ ELBAMS_Never
Remove all empty lines before access modifiers.
Definition: Format.h:2478
@ ELBAMS_Always
Always add empty line before access modifiers unless access modifier is at the start of struct or cla...
Definition: Format.h:2518
@ ELBAMS_Leave
Keep existing empty lines before access modifiers.
Definition: Format.h:2480
@ PPDIS_BeforeHash
Indents directives before the hash.
Definition: Format.h:2751
@ PPDIS_None
Does not indent any directives.
Definition: Format.h:2733
@ SBS_Empty
Only merge empty blocks.
Definition: Format.h:698
@ SBS_Never
Never merge blocks into a single line.
Definition: Format.h:690
@ SIS_WithoutElse
Put short ifs on the same line only if there is no else statement.
Definition: Format.h:846
@ SIS_AllIfsAndElse
Always put short ifs, else ifs and else statements on the same line.
Definition: Format.h:876
@ BWACS_Always
Always wrap braces after a control statement.
Definition: Format.h:1250
@ BWACS_MultiLine
Only wrap braces after a multi-line control statement.
Definition: Format.h:1240
@ SFS_All
Merge all functions fitting on a single line.
Definition: Format.h:804
@ SFS_Empty
Only merge empty functions.
Definition: Format.h:785
@ SFS_InlineOnly
Only merge functions defined inside a class.
Definition: Format.h:777
unsigned MaxEmptyLinesToKeep
The maximum number of consecutive empty lines to keep.
Definition: Format.h:3228
@ ELAAMS_Always
Always add empty line after access modifiers if there are none.
Definition: Format.h:2453
@ ELAAMS_Never
Remove all empty lines after access modifiers.
Definition: Format.h:2429
@ ELAAMS_Leave
Keep existing empty lines after access modifiers.
Definition: Format.h:2432
EmptyLineBeforeAccessModifierStyle EmptyLineBeforeAccessModifier
Defines in which cases to put empty line before access modifiers.
Definition: Format.h:2523
bool KeepEmptyLinesAtTheStartOfBlocks
If true, the empty line at the start of blocks is kept.
Definition: Format.h:3044
EmptyLineAfterAccessModifierStyle EmptyLineAfterAccessModifier
Defines when to put an empty line after access modifiers.
Definition: Format.h:2460
A wrapper around a Token storing information about the whitespace characters preceding it.
Definition: FormatToken.h:283
unsigned OriginalColumn
The original 0-based column of this token, including expanded tabs.
Definition: FormatToken.h:493
bool isNot(T Kind) const
Definition: FormatToken.h:611
FormatToken * getPreviousNonComment() const
Returns the previous token ignoring comments.
Definition: FormatToken.h:797
FormatToken * Next
The next token in the unwrapped line.
Definition: FormatToken.h:555
unsigned NewlinesBefore
The number of newlines immediately before the Token.
Definition: FormatToken.h:452
bool is(tok::TokenKind Kind) const
Definition: FormatToken.h:592
unsigned TotalLength
The total length of the unwrapped line up to and including this token.
Definition: FormatToken.h:489
bool isOneOf(A K1, B K2) const
Definition: FormatToken.h:604
unsigned IsFirst
Indicates that this is the first token of the file.
Definition: FormatToken.h:322
bool isAccessSpecifier(bool ColonRequired=true) const
Definition: FormatToken.h:654
bool FormatComplete
A value of false means that any of the affected ranges were not formatted due to a non-recoverable sy...
Definition: Format.h:5143
unsigned Line
If FormatComplete is false, Line records a one-based original line number at which a syntax error mig...
Definition: Format.h:5148
static const size_t kInvalidIndex