clang: lib/Format/ContinuationIndenter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/Debug.h"
25#include
26
27#define DEBUG_TYPE "format-indenter"
28
30namespace format {
31
32
33
37}
38
39
40
44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
45}
46
47
48
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
90 return 0;
92
93 int MatchingStackIndex = Stack.size() - 1;
94
95
96
97
99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].Tok != LBrace)
100 --MatchingStackIndex;
101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] : nullptr;
102 };
103 for (; End->Next; End = End->Next) {
104 if (End->Next->CanBreakBefore)
105 break;
106 if (!End->Next->closesScope())
107 continue;
108 if (End->Next->MatchingParen &&
109 End->Next->MatchingParen->isOneOf(
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
111 const ParenState *State = FindParenState(End->Next->MatchingParen);
112 if (State && State->BreakBeforeClosingBrace)
113 break;
114 }
115 }
116 return End->TotalLength - Tok.TotalLength + 1;
117}
118
121 return 0;
123}
124
125
126
129}
130
131
133
134 bool HasTwoOperands = Token.OperatorIndex == 0 && .NextOperator;
135 return Token.is(TT_BinaryOperator) && !HasTwoOperands &&
138}
139
140
145}
146
147
154}
155
158 if (LessTok.isNot(tok::less))
159 return false;
164}
165
166
167
168
170 if (TokenText.size() < 5
171 || !TokenText.starts_with("R\"") || !TokenText.ends_with("\"")) {
172 return std::nullopt;
173 }
174
175
176
177
178 size_t LParenPos = TokenText.substr(0, 19).find_first_of('(');
179 if (LParenPos == StringRef::npos)
180 return std::nullopt;
181 StringRef Delimiter = TokenText.substr(2, LParenPos - 2);
182
183
184 size_t RParenPos = TokenText.size() - Delimiter.size() - 2;
185 if (TokenText[RParenPos] != ')')
186 return std::nullopt;
187 if (!TokenText.substr(RParenPos + 1).starts_with(Delimiter))
188 return std::nullopt;
189 return Delimiter;
190}
191
192
193
194static StringRef
198 if (Format.Language == Language)
199 return StringRef(Format.CanonicalDelimiter);
200 return "";
201}
202
205 for (const auto &RawStringFormat : CodeStyle.RawStringFormats) {
206 std::optional LanguageStyle =
208 if (!LanguageStyle) {
211 RawStringFormat.Language, &PredefinedStyle)) {
213 PredefinedStyle.Language = RawStringFormat.Language;
214 }
215 LanguageStyle = PredefinedStyle;
216 }
218 for (StringRef Delimiter : RawStringFormat.Delimiters)
220 for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions)
222 }
223}
224
225std::optional
229 return std::nullopt;
230 return It->second;
231}
232
233std::optional
235 StringRef EnclosingFunction) const {
238 return std::nullopt;
239 return It->second;
240}
241
247 bool BinPackInconclusiveFunctions)
248 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
249 Whitespaces(Whitespaces), Encoding(Encoding),
250 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
251 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
252
254 unsigned FirstStartColumn,
256 bool DryRun) {
258 State.FirstIndent = FirstIndent;
259 if (FirstStartColumn && Line->First->NewlinesBefore == 0)
260 State.Column = FirstStartColumn;
261 else
262 State.Column = FirstIndent;
263
264
265
269 State.Column = 0;
270 }
271 State.Line = Line;
272 State.NextToken = Line->First;
273 State.Stack.push_back(ParenState(nullptr, FirstIndent, FirstIndent,
274 false,
275 false));
276 State.NoContinuation = false;
277 State.StartOfStringLiteral = 0;
278 State.NoLineBreak = false;
279 State.StartOfLineLevel = 0;
280 State.LowestLevelOnLine = 0;
281 State.IgnoreStackForComparison = false;
282
284
285
286 auto &CurrentState = State.Stack.back();
287 CurrentState.AvoidBinPacking = true;
288 CurrentState.BreakBeforeParameter = true;
289 CurrentState.AlignColons = false;
290 }
291
292
293 moveStateToNextToken(State, DryRun, false);
294 return State;
295}
296
298 const FormatToken &Current = *State.NextToken;
300 const auto &CurrentState = State.Stack.back();
301 assert(&Previous == Current.Previous);
302 if (!Current.CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
303 Current.closesBlockOrBlockTypeList(Style))) {
304 return false;
305 }
306
307
308 if (!Current.MustBreakBefore && Previous.is(tok::l_brace) &&
311 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
312 return false;
313 }
314
315
316
317
318
320 State.LowestLevelOnLine < State.StartOfLineLevel &&
321 State.LowestLevelOnLine < Current.NestingLevel) {
322 return false;
323 }
324 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
325 return false;
326
327
328
329 if (Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
330 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
331 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks &&
333 return false;
334 }
335
336
337
338 if (Current.is(TT_FunctionDeclarationName)) {
340 State.Column < 6) {
341 return false;
342 }
343
345 assert(State.Column >= State.FirstIndent);
346 if (State.Column - State.FirstIndent < 6)
347 return false;
348 }
349 }
350
351
352
353 if (Current.is(tok::r_brace) && Current.MatchingParen &&
354 Current.isBlockIndentedInitRBrace(Style)) {
355 return CurrentState.BreakBeforeClosingBrace;
356 }
357
358
359
360 if (!Current.isOneOf(TT_BinaryOperator, tok::comma) &&
361
362
363
365 Current.isNot(TT_LambdaLBrace)) &&
366 CurrentState.NoLineBreakInOperand) {
367 return false;
368 }
369
370 if (Previous.is(tok::l_square) && Previous.is(TT_ObjCMethodExpr))
371 return false;
372
373 if (Current.is(TT_ConditionalExpr) && Previous.is(tok::r_paren) &&
374 Previous.MatchingParen && Previous.MatchingParen->Previous &&
375 Previous.MatchingParen->Previous->MatchingParen &&
376 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
377
378 assert(Previous.MatchingParen->Previous->is(tok::r_brace));
379 return true;
380 }
381
382 return !State.NoLineBreak && !CurrentState.NoLineBreak;
383}
384
386 const FormatToken &Current = *State.NextToken;
388 const auto &CurrentState = State.Stack.back();
390 Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) {
393 }
394 if (Current.MustBreakBefore ||
395 (Current.is(TT_InlineASMColon) &&
399 return true;
400 }
401 if (CurrentState.BreakBeforeClosingBrace &&
402 (Current.closesBlockOrBlockTypeList(Style) ||
403 (Current.is(tok::r_brace) &&
404 Current.isBlockIndentedInitRBrace(Style)))) {
405 return true;
406 }
407 if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
408 return true;
411 Current.ObjCSelectorNameParts > 1 &&
412 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
413 return true;
414 }
415
416
417 if (CurrentState.IsCSharpGenericTypeConstraint &&
418 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
419 return false;
420 }
422 (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
423 State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() &&
424
425
426
427
428 (Previous.NestingLevel == 1 ||
431 Previous.isNot(tok::question)) ||
433 Previous.is(TT_ConditionalExpr))) &&
434 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
435 !Current.isOneOf(tok::r_paren, tok::r_brace)) {
436 return true;
437 }
438 if (CurrentState.IsChainedConditional &&
440 Current.is(tok::colon)) ||
443 return true;
444 }
445 if (((Previous.is(TT_DictLiteral) && Previous.is(tok::l_brace)) ||
446 (Previous.is(TT_ArrayInitializerLSquare) &&
447 Previous.ParameterCount > 1) ||
452 return true;
453 }
454
455 const FormatToken &BreakConstructorInitializersToken =
458 : Current;
459 if (BreakConstructorInitializersToken.is(TT_CtorInitializerColon) &&
460 (State.Column + State.Line->Last->TotalLength - Previous.TotalLength >
462 CurrentState.BreakBeforeParameter) &&
463 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
465 Style.ColumnLimit > 0 || Current.NewlinesBefore > 0)) {
466 return true;
467 }
468
469 if (Current.is(TT_ObjCMethodExpr) && Previous.isNot(TT_SelectorName) &&
470 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
471 return true;
472 }
473 if (Current.is(TT_SelectorName) && Previous.isNot(tok::at) &&
474 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
476 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
477 return true;
478 }
479
480 unsigned NewLineColumn = getNewLineColumn(State);
481 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
483 (State.Column > NewLineColumn ||
484 Current.NestingLevel < State.StartOfLineLevel)) {
485 return true;
486 }
487
489 (CurrentState.CallContinuation != 0 ||
490 CurrentState.BreakBeforeParameter) &&
491
492
493
494
495
496 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
497 !(Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
498 return true;
499 }
500
501
502
503 if (Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
504 Current.CanBreakBefore) {
505 return true;
506 }
507
508 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
509 return false;
510
513 Previous.is(tok::comma) || Current.NestingLevel < 2) &&
514 .isOneOf(tok::kw_return, tok::lessless, tok::at,
516 .isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
517 nextIsMultilineString(State)) {
518 return true;
519 }
520
521
522
523
524 if (Previous.is(TT_BinaryOperator) && Current.CanBreakBefore) {
525 const auto PreviousPrecedence = Previous.getPrecedence();
527 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
528 const bool LHSIsBinaryExpr =
529 Previous.Previous && Previous.Previous->EndsBinaryExpression;
530 if (LHSIsBinaryExpr)
531 return true;
532
533
534
535
536
537
538
539
540
541 const bool IsComparison =
546 Previous.Previous->isNot(TT_BinaryOperator);
547 if (!IsComparison)
548 return true;
549 }
550 } else if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore &&
551 CurrentState.BreakBeforeParameter) {
552 return true;
553 }
554
555
556 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
557 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
558 return true;
559 }
560
561 if (Current.NestingLevel == 0 && !Current.isTrailingComment()) {
562
563
564
565
566 if (Previous.ClosesTemplateDeclaration) {
567 if (Current.is(tok::kw_concept)) {
570 break;
572 return true;
574 return false;
575 }
576 }
577 if (Current.is(TT_RequiresClause)) {
581 return false;
582 default:
583 return true;
584 }
585 }
588 Current.NewlinesBefore > 0);
589 }
590 if (Previous.is(TT_FunctionAnnotationRParen) &&
592 return true;
593 }
594 if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&
595 Current.isNot(TT_LeadingJavaAnnotation)) {
596 return true;
597 }
598 }
599
601 Previous.is(TT_JavaAnnotation)) {
602
603
604 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {"get", "set",
605 "function"};
606 if (BreakBeforeDecoratedTokens.contains(Current.TokenText))
607 return true;
608 }
609
610 if (Current.is(TT_FunctionDeclarationName) &&
611 !State.Line->ReturnTypeWrapped &&
612
615
616
618 CurrentState.BreakBeforeParameter) {
619 return true;
620 }
621
622
623
624
627 !Current.isOneOf(tok::r_brace, tok::comment)) {
628 return true;
629 }
630
631 if (Current.is(tok::lessless) &&
632 ((Previous.is(tok::identifier) && Previous.TokenText == "endl") ||
633 (Previous.Tok.isLiteral() && (Previous.TokenText.ends_with("\\n\"") ||
634 Previous.TokenText == "\'\\n\'")))) {
635 return true;
636 }
637
639 return true;
640
641 if (State.NoContinuation)
642 return true;
643
644 return false;
645}
646
648 bool DryRun,
649 unsigned ExtraSpaces) {
650 const FormatToken &Current = *State.NextToken;
651 assert(State.NextToken->Previous);
653
654 assert(!State.Stack.empty());
655 State.NoContinuation = false;
656
657 if (Current.is(TT_ImplicitStringLiteral) &&
658 (.Tok.getIdentifierInfo() ||
659 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
660 tok::pp_not_keyword)) {
661 unsigned EndColumn =
663 if (Current.LastNewlineOffset != 0) {
664
665
666 State.Column = EndColumn;
667 } else {
668 unsigned StartColumn =
670 assert(EndColumn >= StartColumn);
671 State.Column += EndColumn - StartColumn;
672 }
673 moveStateToNextToken(State, DryRun, false);
674 return 0;
675 }
676
677 unsigned Penalty = 0;
678 if (Newline)
679 Penalty = addTokenOnNewLine(State, DryRun);
680 else
681 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
682
683 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
684}
685
686void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
687 unsigned ExtraSpaces) {
689 assert(State.NextToken->Previous);
691 auto &CurrentState = State.Stack.back();
692
693 bool DisallowLineBreaksOnThisLine =
695
696
697
698
699
700 Style.isCpp() && [&] {
701
702 if (Previous.is(TT_BlockComment) && Current.SpacesRequiredBefore == 0)
703 return false;
704 const auto *PrevNonComment = Current.getPreviousNonComment();
705 if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren))
706 return false;
707 if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
708 return false;
709 auto BlockParameterCount = PrevNonComment->BlockParameterCount;
710 if (BlockParameterCount == 0)
711 return false;
712
713
714 if (BlockParameterCount > 1)
715 return true;
716
717
718 if (!PrevNonComment->Role)
719 return false;
720 auto Comma = PrevNonComment->Role->lastComma();
721 if (!Comma)
722 return false;
723 auto Next = Comma->getNextNonComment();
724 return Next &&
725 !Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
726 }();
727
728 if (DisallowLineBreaksOnThisLine)
729 State.NoLineBreak = true;
730
731 if (Current.is(tok::equal) &&
732 (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&
733 CurrentState.VariablePos == 0 &&
735 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
736 CurrentState.VariablePos = State.Column;
737
738 const FormatToken *Tok = &Previous;
739 while (Tok && CurrentState.VariablePos >= Tok->ColumnWidth) {
740 CurrentState.VariablePos -= Tok->ColumnWidth;
741 if (Tok->SpacesRequiredBefore != 0)
742 break;
743 Tok = Tok->Previous;
744 }
745 if (Previous.PartOfMultiVariableDeclStmt)
746 CurrentState.LastSpace = CurrentState.VariablePos;
747 }
748
749 unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
750
751
752 int PPColumnCorrection = 0;
754 Previous.is(tok::hash) && State.FirstIndent > 0 &&
755 &Previous == State.Line->First &&
758 Spaces += State.FirstIndent;
759
760
761
762
763
765 PPColumnCorrection = -1;
766 }
767
768 if (!DryRun) {
770 State.Column + Spaces + PPColumnCorrection,
771 false, State.Line->InMacroBody);
772 }
773
774
775
777 Current.is(TT_InheritanceColon)) {
778 CurrentState.NoLineBreak = true;
779 }
781 Previous.is(TT_InheritanceColon)) {
782 CurrentState.NoLineBreak = true;
783 }
784
785 if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
786 unsigned MinIndent = std::max(
788 unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth;
789 if (Current.LongestObjCSelectorName == 0)
790 CurrentState.AlignColons = false;
791 else if (MinIndent + Current.LongestObjCSelectorName > FirstColonPos)
792 CurrentState.ColonPos = MinIndent + Current.LongestObjCSelectorName;
793 else
794 CurrentState.ColonPos = FirstColonPos;
795 }
796
797
798
799
800
801 auto IsOpeningBracket = [&](const FormatToken &Tok) {
802 auto IsStartOfBracedList = [&]() {
803 return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) &&
805 };
806 if (!Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
807 !IsStartOfBracedList()) {
808 return false;
809 }
810 if (!Tok.Previous)
811 return true;
812 if (Tok.Previous->isIf())
814 return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
815 tok::kw_switch) &&
817 };
818 auto IsFunctionCallParen = [](const FormatToken &Tok) {
819 return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous &&
820 Tok.Previous->is(tok::identifier);
821 };
822 auto IsInTemplateString = [this](const FormatToken &Tok) {
824 return false;
825 for (const auto *Prev = &Tok; Prev; Prev = Prev->Previous) {
826 if (Prev->is(TT_TemplateString) && Prev->opensScope())
827 return true;
828 if (Prev->opensScope() ||
829 (Prev->is(TT_TemplateString) && Prev->closesScope())) {
830 break;
831 }
832 }
833 return false;
834 };
835
836 auto StartsSimpleOneArgList = [&](const FormatToken &TokAfterLParen) {
837 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
838 const auto &Tok =
839 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
840 if (!Tok.FakeLParens.empty() && Tok.FakeLParens.back() > prec::Unknown)
841 return false;
842
843
844
845
846 if (Tok.is(tok::kw_new) || Tok.startsSequence(tok::coloncolon, tok::kw_new))
847 return true;
848 if (Tok.is(TT_UnaryOperator) ||
850 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
851 return true;
852 }
853 const auto *Previous = Tok.Previous;
854 if ( || (
->isOneOf(TT_FunctionDeclarationLParen,
855 TT_LambdaDefinitionLParen) &&
856 !IsFunctionCallParen(*Previous))) {
857 return true;
858 }
859 if (IsOpeningBracket(Tok) || IsInTemplateString(Tok))
860 return true;
861 const auto *Next = Tok.Next;
862 return !Next || Next->isMemberAccess() ||
863 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next);
864 };
867 IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) &&
868
869
870
871
872
873
874
875
876
877
878 !StartsSimpleOneArgList(Current)) {
879 CurrentState.NoLineBreak = true;
880 }
881
883 CurrentState.NoLineBreak = true;
884
885
886
887
888
890 !CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() &&
891 Previous.isNot(TT_ObjCMethodExpr) && Previous.isNot(TT_RequiresClause) &&
892 Previous.isNot(TT_TableGenDAGArgOpener) &&
893 Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
894 !(Current.MacroParent && Previous.MacroParent) &&
895 (Current.isNot(TT_LineComment) ||
897 !IsInTemplateString(Current)) {
898 CurrentState.Indent = State.Column + Spaces;
899 CurrentState.IsAligned = true;
900 }
902 CurrentState.NoLineBreak = true;
904 CurrentState.NoLineBreak = true;
905
907 State.Column > getNewLineColumn(State)) {
908 CurrentState.ContainsUnwrappedBuilder = true;
909 }
910
912 CurrentState.NoLineBreak = true;
913 if (Current.isMemberAccess() && Previous.is(tok::r_paren) &&
915 (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) {
916
917
918
919
920
921
922 CurrentState.NoLineBreak = true;
923 }
924
925
926
927
928
929 const FormatToken *P = Current.getPreviousNonComment();
930 if (Current.isNot(tok::comment) && P &&
931 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
932 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
933 ->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
937 bool BreakBeforeOperator =
938 P->MustBreakBefore || P->is(tok::lessless) ||
939 (P->is(TT_BinaryOperator) &&
942
943
944
945 bool HasTwoOperands = P->OperatorIndex == 0 && ->NextOperator &&
946 P->isNot(TT_ConditionalExpr);
947 if ((!BreakBeforeOperator &&
948 !(HasTwoOperands &&
950 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
951 CurrentState.NoLineBreakInOperand = true;
952 }
953 }
954
955 State.Column += Spaces;
956 if (Current.isNot(tok::comment) && Previous.is(tok::l_paren) &&
958 (Previous.Previous->is(tok::kw_for) || Previous.Previous->isIf())) {
959
960
961 CurrentState.LastSpace = State.Column;
962 CurrentState.NestedBlockIndent = State.Column;
963 } else if (!Current.isOneOf(tok::comment, tok::caret) &&
965 Previous.isNot(TT_OverloadedOperator)) ||
966 (Previous.is(tok::colon) && Previous.is(TT_ObjCMethodExpr)))) {
967 CurrentState.LastSpace = State.Column;
968 } else if (Previous.is(TT_CtorInitializerColon) &&
969 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
972 CurrentState.Indent = State.Column;
973 CurrentState.LastSpace = State.Column;
974 } else if (Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
975 CurrentState.LastSpace = State.Column;
976 } else if (Previous.is(TT_BinaryOperator) &&
978 (Previous.isNot(tok::lessless) || Previous.OperatorIndex != 0 ||
980 Current.StartsBinaryExpression)) {
981
982
984 CurrentState.LastSpace = State.Column;
985 } else if (Previous.is(TT_InheritanceColon)) {
986 CurrentState.Indent = State.Column;
987 CurrentState.LastSpace = State.Column;
988 } else if (Current.is(TT_CSharpGenericTypeConstraintColon)) {
989 CurrentState.ColonPos = State.Column;
990 } else if (Previous.opensScope()) {
991
992
993
994
995
996 if (Previous.MatchingParen) {
997 const FormatToken *Next = Previous.MatchingParen->getNextNonComment();
998 if (Next && Next->isMemberAccess() && State.Stack.size() > 1 &&
999 State.Stack[State.Stack.size() - 2].CallContinuation == 0) {
1000 CurrentState.LastSpace = State.Column;
1001 }
1002 }
1003 }
1004}
1005
1006unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
1007 bool DryRun) {
1008 FormatToken &Current = *State.NextToken;
1009 assert(State.NextToken->Previous);
1010 const FormatToken &Previous = *State.NextToken->Previous;
1011 auto &CurrentState = State.Stack.back();
1012
1013
1014
1015 unsigned Penalty = 0;
1016
1017 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1018 const FormatToken *NextNonComment = Previous.getNextNonComment();
1019 if (!NextNonComment)
1020 NextNonComment = &Current;
1021
1022
1023 if (!CurrentState.ContainsLineBreak)
1024 Penalty += 15;
1025 CurrentState.ContainsLineBreak = true;
1026
1027 Penalty += State.NextToken->SplitPenalty;
1028
1029
1030
1031
1032 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1033 (State.Column <= Style.ColumnLimit / 3 ||
1034 CurrentState.BreakBeforeParameter)) {
1036 }
1037
1038 State.Column = getNewLineColumn(State);
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052 if (State.Column > State.FirstIndent) {
1053 Penalty +=
1055 }
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 if (Current.isNot(TT_LambdaArrow) &&
1068 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1069 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1071 CurrentState.NestedBlockIndent = State.Column;
1072 }
1073
1074 if (NextNonComment->isMemberAccess()) {
1075 if (CurrentState.CallContinuation == 0)
1076 CurrentState.CallContinuation = State.Column;
1077 } else if (NextNonComment->is(TT_SelectorName)) {
1078 if (!CurrentState.ObjCSelectorNameFound) {
1079 if (NextNonComment->LongestObjCSelectorName == 0) {
1080 CurrentState.AlignColons = false;
1081 } else {
1082 CurrentState.ColonPos =
1084 ? std::max(CurrentState.Indent,
1086 : CurrentState.Indent) +
1088 NextNonComment->ColumnWidth);
1089 }
1090 } else if (CurrentState.AlignColons &&
1091 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1092 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1093 }
1094 } else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1095 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105 if (State.Stack.size() > 1) {
1106 State.Stack[State.Stack.size() - 2].LastSpace =
1107 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1109 }
1110 }
1111
1112 if ((PreviousNonComment &&
1113 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1114 !CurrentState.AvoidBinPacking) ||
1115 Previous.is(TT_BinaryOperator)) {
1116 CurrentState.BreakBeforeParameter = false;
1117 }
1118 if (PreviousNonComment &&
1119 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1120 PreviousNonComment->ClosesRequiresClause) &&
1121 Current.NestingLevel == 0) {
1122 CurrentState.BreakBeforeParameter = false;
1123 }
1124 if (NextNonComment->is(tok::question) ||
1125 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1126 CurrentState.BreakBeforeParameter = true;
1127 }
1128 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1129 CurrentState.BreakBeforeParameter = false;
1130
1131 if (!DryRun) {
1133 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1134
1135
1136 !Current.MatchingParen->Children.empty()) {
1137
1138
1139
1140 MaxEmptyLinesToKeep = 1;
1141 }
1142 unsigned Newlines =
1143 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
1144 bool ContinuePPDirective =
1145 State.Line->InPPDirective && State.Line->Type != LT_ImportStatement;
1146 Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
1147 CurrentState.IsAligned, ContinuePPDirective);
1148 }
1149
1150 if (!Current.isTrailingComment())
1151 CurrentState.LastSpace = State.Column;
1152 if (Current.is(tok::lessless)) {
1153
1154
1155
1156 CurrentState.LastSpace += 3;
1157 }
1158
1159 State.StartOfLineLevel = Current.NestingLevel;
1160 State.LowestLevelOnLine = Current.NestingLevel;
1161
1162
1163
1164 bool NestedBlockSpecialCase =
1165 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1166 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1169
1170 NestedBlockSpecialCase =
1171 NestedBlockSpecialCase ||
1172 (Current.MatchingParen &&
1173 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1174 if (!NestedBlockSpecialCase) {
1175 auto ParentLevelIt = std::next(State.Stack.rbegin());
1177 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192 auto FindCurrentLevel = [&](const auto &It) {
1193 return std::find_if(It, State.Stack.rend(), [](const auto &PState) {
1194 return PState.Tok != nullptr;
1195 });
1196 };
1197 auto MaybeIncrement = [&](const auto &It) {
1198 return It != State.Stack.rend() ? std::next(It) : It;
1199 };
1200 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1201 auto LevelContainingLambdaIt =
1202 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1203 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1204 }
1205 for (auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1206 I->BreakBeforeParameter = true;
1207 }
1208
1209 if (PreviousNonComment &&
1210 !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&
1211 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1212 !PreviousNonComment->ClosesRequiresClause) ||
1213 Current.NestingLevel != 0) &&
1214 !PreviousNonComment->isOneOf(
1215 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1216 TT_LeadingJavaAnnotation) &&
1217 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1218
1219
1221 Current.isNot(TT_LambdaLBrace))) {
1222 CurrentState.BreakBeforeParameter = true;
1223 }
1224
1225
1226
1227 if (PreviousNonComment &&
1228 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1230 CurrentState.BreakBeforeClosingBrace = true;
1231 }
1232
1233 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1234 CurrentState.BreakBeforeClosingParen =
1236 }
1237
1238 if (CurrentState.AvoidBinPacking) {
1239
1240
1241
1242
1243 bool PreviousIsBreakingCtorInitializerColon =
1244 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1246 bool AllowAllConstructorInitializersOnNextLine =
1249 if (!(Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
1250 PreviousIsBreakingCtorInitializerColon) ||
1252 State.Line->MustBeDeclaration) ||
1254 !State.Line->MustBeDeclaration) ||
1255 (!AllowAllConstructorInitializersOnNextLine &&
1256 PreviousIsBreakingCtorInitializerColon) ||
1257 Previous.is(TT_DictLiteral)) {
1258 CurrentState.BreakBeforeParameter = true;
1259 }
1260
1261
1262
1263
1264 if (PreviousIsBreakingCtorInitializerColon &&
1265 AllowAllConstructorInitializersOnNextLine) {
1266 CurrentState.BreakBeforeParameter = false;
1267 }
1268 }
1269
1271 CurrentState.BreakBeforeParameter = true;
1272
1273 return Penalty;
1274}
1275
1276unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
1277 if (!State.NextToken || !State.NextToken->Previous)
1278 return 0;
1279
1280 FormatToken &Current = *State.NextToken;
1281 const auto &CurrentState = State.Stack.back();
1282
1283 if (CurrentState.IsCSharpGenericTypeConstraint &&
1284 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1285 return CurrentState.ColonPos + 2;
1286 }
1287
1288 const FormatToken &Previous = *Current.Previous;
1289
1290 unsigned ContinuationIndent =
1291 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1293 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1294 const FormatToken *NextNonComment = Previous.getNextNonComment();
1295 if (!NextNonComment)
1296 NextNonComment = &Current;
1297
1298
1301 return std::max(CurrentState.LastSpace,
1303 }
1304
1305
1306
1307 if (Style.isVerilog() && PreviousNonComment &&
1309 return State.FirstIndent;
1310 }
1311
1313 State.Line->First->is(tok::kw_enum)) {
1314 return (Style.IndentWidth * State.Line->First->IndentLevel) +
1316 }
1317
1318 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) ||
1320 if (Current.NestingLevel == 0 ||
1322 State.NextToken->is(TT_LambdaLBrace))) {
1323 return State.FirstIndent;
1324 }
1325 return CurrentState.Indent;
1326 }
1327 if (Current.is(TT_LambdaArrow) &&
1328 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1329 tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {
1330 return ContinuationIndent;
1331 }
1332 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1333 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1334 State.Stack.size() > 1) {
1335 if (Current.closesBlockOrBlockTypeList(Style))
1336 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1337 if (Current.MatchingParen && Current.MatchingParen->is(BK_BracedInit))
1338 return State.Stack[State.Stack.size() - 2].LastSpace;
1339 return State.FirstIndent;
1340 }
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1357 (!Current.Next ||
1358 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1359 return State.Stack[State.Stack.size() - 2].LastSpace;
1360 }
1361
1362
1363 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1364 State.Stack.size() > 1) {
1365 return State.Stack[State.Stack.size() - 2].LastSpace;
1366 }
1368 (Current.is(tok::r_paren) ||
1369 (Current.is(tok::r_brace) && Current.MatchingParen &&
1371 State.Stack.size() > 1) {
1372 return State.Stack[State.Stack.size() - 2].LastSpace;
1373 }
1374 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1375 return State.Stack[State.Stack.size() - 2].LastSpace;
1376
1377
1378
1379
1380
1381
1382
1383 if (Current.is(tok::identifier) && Current.Next &&
1384 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1385 (Current.Next->is(TT_DictLiteral) ||
1386 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1387 return CurrentState.Indent;
1388 }
1389 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1390 State.StartOfStringLiteral != 0) {
1391 return State.StartOfStringLiteral - 1;
1392 }
1393 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1394 return State.StartOfStringLiteral;
1395 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1396 return CurrentState.FirstLessLess;
1397 if (NextNonComment->isMemberAccess()) {
1398 if (CurrentState.CallContinuation == 0)
1399 return ContinuationIndent;
1400 return CurrentState.CallContinuation;
1401 }
1402 if (CurrentState.QuestionColumn != 0 &&
1403 ((NextNonComment->is(tok::colon) &&
1404 NextNonComment->is(TT_ConditionalExpr)) ||
1405 Previous.is(TT_ConditionalExpr))) {
1406 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1407 !NextNonComment->Next->FakeLParens.empty() &&
1408 NextNonComment->Next->FakeLParens.back() == prec::Conditional) ||
1409 (Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1411 !CurrentState.IsWrappedConditional) {
1412
1413
1414
1415
1416 unsigned Indent = CurrentState.Indent;
1420 Indent -= 2;
1421 return Indent;
1422 }
1423 return CurrentState.QuestionColumn;
1424 }
1425 if (Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1426 return CurrentState.VariablePos;
1427 if (Current.is(TT_RequiresClause)) {
1429 return CurrentState.Indent + Style.IndentWidth;
1434 return CurrentState.Indent;
1435 default:
1436 break;
1437 }
1438 }
1439 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1440 TT_InheritanceComma)) {
1442 }
1443 if ((PreviousNonComment &&
1444 (PreviousNonComment->ClosesTemplateDeclaration ||
1445 PreviousNonComment->ClosesRequiresClause ||
1446 (PreviousNonComment->is(TT_AttributeMacro) &&
1447 Current.isNot(tok::l_paren)) ||
1448 PreviousNonComment->isOneOf(
1449 TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
1450 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
1452 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1453 return std::max(CurrentState.LastSpace, CurrentState.Indent);
1454 }
1455 if (NextNonComment->is(TT_SelectorName)) {
1456 if (!CurrentState.ObjCSelectorNameFound) {
1457 unsigned MinIndent = CurrentState.Indent;
1459 MinIndent = std::max(MinIndent,
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471 return MinIndent +
1472 std::max(NextNonComment->LongestObjCSelectorName,
1473 NextNonComment->ColumnWidth) -
1474 NextNonComment->ColumnWidth;
1475 }
1476 if (!CurrentState.AlignColons)
1477 return CurrentState.Indent;
1478 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1479 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1480 return CurrentState.Indent;
1481 }
1482 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1483 return CurrentState.ColonPos;
1484 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1485 if (CurrentState.StartOfArraySubscripts != 0) {
1486 return CurrentState.StartOfArraySubscripts;
1487 } else if (Style.isCSharp()) {
1488
1489 return CurrentState.Indent;
1490 }
1491 return ContinuationIndent;
1492 }
1493
1494
1495
1496 if (State.Line->InPragmaDirective) {
1497 FormatToken *PragmaType = State.Line->First->Next->Next;
1498 if (PragmaType && PragmaType->TokenText == "omp")
1500 }
1501
1502
1503
1504 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1505 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1506 return CurrentState.Indent;
1507 }
1508
1509 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1510 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1511 return ContinuationIndent;
1512 }
1513 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1514 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1515 return ContinuationIndent;
1516 }
1517 if (NextNonComment->is(TT_CtorInitializerComma))
1518 return CurrentState.Indent;
1519 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1521 return CurrentState.Indent;
1522 }
1523 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1525 return CurrentState.Indent;
1526 }
1527 if (Previous.is(tok::r_paren) &&
1528 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1529 !Current.isBinaryOperator() &&
1530 !Current.isOneOf(tok::colon, tok::comment)) {
1531 return ContinuationIndent;
1532 }
1533 if (Current.is(TT_ProtoExtensionLSquare))
1534 return CurrentState.Indent;
1535 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1536 return CurrentState.Indent - Current.Tok.getLength() -
1537 Current.SpacesRequiredBefore;
1538 }
1539 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1540 CurrentState.UnindentOperator) {
1541 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1542 NextNonComment->SpacesRequiredBefore;
1543 }
1544 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
1545 !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {
1546
1547
1549 }
1550 return CurrentState.Indent;
1551}
1552
1556 if (Previous->isNot(tok::l_paren))
1557 return true;
1558 if (Previous->ParameterCount > 1)
1559 return true;
1560
1561
1563}
1564
1565unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1566 bool DryRun, bool Newline) {
1567 assert(State.Stack.size());
1568 const FormatToken &Current = *State.NextToken;
1569 auto &CurrentState = State.Stack.back();
1570
1571 if (Current.is(TT_CSharpGenericTypeConstraint))
1572 CurrentState.IsCSharpGenericTypeConstraint = true;
1573 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1574 CurrentState.NoLineBreakInOperand = false;
1575 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1576 CurrentState.AvoidBinPacking = true;
1577 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1578 if (CurrentState.FirstLessLess == 0)
1579 CurrentState.FirstLessLess = State.Column;
1580 else
1581 CurrentState.LastOperatorWrapped = Newline;
1582 }
1583 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1584 CurrentState.LastOperatorWrapped = Newline;
1585 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1586 Current.Previous->isNot(TT_ConditionalExpr)) {
1587 CurrentState.LastOperatorWrapped = Newline;
1588 }
1589 if (Current.is(TT_ArraySubscriptLSquare) &&
1590 CurrentState.StartOfArraySubscripts == 0) {
1591 CurrentState.StartOfArraySubscripts = State.Column;
1592 }
1593
1594 auto IsWrappedConditional = [](const FormatToken &Tok) {
1595 if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question)))
1596 return false;
1597 if (Tok.MustBreakBefore)
1598 return true;
1599
1600 const FormatToken *Next = Tok.getNextNonComment();
1601 return Next && Next->MustBreakBefore;
1602 };
1603 if (IsWrappedConditional(Current))
1604 CurrentState.IsWrappedConditional = true;
1606 CurrentState.QuestionColumn = State.Column;
1608 const FormatToken *Previous = Current.Previous;
1612 CurrentState.QuestionColumn = State.Column;
1613 }
1614 if (!Current.opensScope() && !Current.closesScope() &&
1615 Current.isNot(TT_PointerOrReference)) {
1616 State.LowestLevelOnLine =
1617 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1618 }
1619 if (Current.isMemberAccess())
1620 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1621 if (Current.is(TT_SelectorName))
1622 CurrentState.ObjCSelectorNameFound = true;
1623 if (Current.is(TT_CtorInitializerColon) &&
1625
1626
1627
1628
1629
1632 ? 0
1633 : 2);
1634 CurrentState.NestedBlockIndent = CurrentState.Indent;
1636 CurrentState.AvoidBinPacking = true;
1637 CurrentState.BreakBeforeParameter =
1641 } else {
1642 CurrentState.BreakBeforeParameter = false;
1643 }
1644 }
1645 if (Current.is(TT_CtorInitializerColon) &&
1647 CurrentState.Indent =
1649 CurrentState.NestedBlockIndent = CurrentState.Indent;
1651 CurrentState.AvoidBinPacking = true;
1652 else
1653 CurrentState.BreakBeforeParameter = false;
1654 }
1655 if (Current.is(TT_InheritanceColon)) {
1656 CurrentState.Indent =
1658 }
1659 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1660 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1661 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1662 CurrentState.LastSpace = State.Column;
1663 if (Current.is(TT_RequiresExpression) &&
1665 CurrentState.NestedBlockIndent = State.Column;
1666 }
1667
1668
1669 const FormatToken *Previous = Current.getPreviousNonComment();
1670
1671
1672
1673
1674
1675
1676
1677 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1678 Previous && Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
1679 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1680 !CurrentState.HasMultipleNestedBlocks) {
1681 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1682 for (ParenState &PState : llvm::drop_end(State.Stack))
1683 PState.NoLineBreak = true;
1684 State.Stack[State.Stack.size() - 2].NestedBlockInlined = false;
1685 }
1686 if (Previous && (Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1687 (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1688 ->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))) {
1689 CurrentState.NestedBlockInlined =
1691 }
1692
1693 moveStatePastFakeLParens(State, Newline);
1694 moveStatePastScopeCloser(State);
1695
1696
1697 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1698 !State.Stack.back().NoLineBreakInOperand;
1699 moveStatePastScopeOpener(State, Newline);
1700 moveStatePastFakeRParens(State);
1701
1702 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1703 State.StartOfStringLiteral = State.Column + 1;
1704 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1705 State.StartOfStringLiteral = State.Column + 1;
1706 } else if (Current.is(TT_TableGenMultiLineString) &&
1707 State.StartOfStringLiteral == 0) {
1708 State.StartOfStringLiteral = State.Column + 1;
1709 } else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1710 State.StartOfStringLiteral = State.Column;
1711 } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
1712 !Current.isStringLiteral()) {
1713 State.StartOfStringLiteral = 0;
1714 }
1715
1716 State.Column += Current.ColumnWidth;
1717 State.NextToken = State.NextToken->Next;
1718
1719
1720
1721
1722 if (Style.isVerilog() && State.NextToken &&
1723 State.NextToken->MustBreakBefore &&
1726 CurrentState.Indent = State.FirstIndent;
1727 }
1728
1729 unsigned Penalty =
1730 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1731
1732 if (Current.Role)
1733 Current.Role->formatFromToken(State, this, DryRun);
1734
1735
1736
1737
1738
1740 Penalty += Previous->Role->formatAfterToken(State, this, DryRun);
1741
1742 return Penalty;
1743}
1744
1745void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
1746 bool Newline) {
1747 const FormatToken &Current = *State.NextToken;
1748 if (Current.FakeLParens.empty())
1749 return;
1750
1751 const FormatToken *Previous = Current.getPreviousNonComment();
1752
1753
1754
1755
1756 bool SkipFirstExtraIndent =
1759 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1762 Previous->is(TT_ObjCMethodExpr));
1763 for (const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1764 const auto &CurrentState = State.Stack.back();
1765 ParenState NewParenState = CurrentState;
1766 NewParenState.Tok = nullptr;
1767 NewParenState.ContainsLineBreak = false;
1768 NewParenState.LastOperatorWrapped = true;
1769 NewParenState.IsChainedConditional = false;
1770 NewParenState.IsWrappedConditional = false;
1771 NewParenState.UnindentOperator = false;
1772 NewParenState.NoLineBreak =
1773 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1774
1775
1777 NewParenState.AvoidBinPacking = false;
1778
1779
1780
1781
1782 if (!Current.isTrailingComment() &&
1788 PrecedenceLevel > prec::Comma || Current.NestingLevel == 0) &&
1791 TT_TableGenDAGArgListCommaToBreak)))) {
1792 NewParenState.Indent = std::max(
1793 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
1794 }
1795
1796
1797
1798
1799 if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic) &&
1800 State.Stack.size() > 1) {
1801 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1803 }
1804
1808 Previous->is(tok::question) && Previous->is(TT_ConditionalExpr)))) &&
1809 !Newline) {
1810
1811
1813 NewParenState.UnindentOperator = true;
1814
1816 NewParenState.IsAligned = true;
1817 }
1818
1819
1820
1821
1822
1823
1824
1826 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1828 Current.isNot(TT_UnaryOperator) &&
1830 NewParenState.StartOfFunctionCall = State.Column;
1831 }
1832
1833
1834
1835
1836
1837
1839 Previous->is(tok::colon) && Previous->is(TT_ConditionalExpr) &&
1840 &PrecedenceLevel == &Current.FakeLParens.back() &&
1841 !CurrentState.IsWrappedConditional) {
1842 NewParenState.IsChainedConditional = true;
1843 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1845 (!SkipFirstExtraIndent && PrecedenceLevel > prec::Assignment &&
1846 !Current.isTrailingComment())) {
1848 }
1850 NewParenState.BreakBeforeParameter = false;
1851 State.Stack.push_back(NewParenState);
1852 SkipFirstExtraIndent = false;
1853 }
1854}
1855
1856void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
1857 for (unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1858 unsigned VariablePos = State.Stack.back().VariablePos;
1859 if (State.Stack.size() == 1) {
1860
1861 break;
1862 }
1863 State.Stack.pop_back();
1864 State.Stack.back().VariablePos = VariablePos;
1865 }
1866
1868
1869
1870 State.Stack.back().LastSpace -= Style.IndentWidth;
1871 }
1872}
1873
1874void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
1875 bool Newline) {
1876 const FormatToken &Current = *State.NextToken;
1877 if (!Current.opensScope())
1878 return;
1879
1880 const auto &CurrentState = State.Stack.back();
1881
1882
1883 if (Current.isOneOf(tok::less, tok::l_paren) &&
1884 CurrentState.IsCSharpGenericTypeConstraint) {
1885 return;
1886 }
1887
1888 if (Current.MatchingParen && Current.is(BK_Block)) {
1889 moveStateToNewBlock(State, Newline);
1890 return;
1891 }
1892
1893 unsigned NewIndent;
1894 unsigned LastSpace = CurrentState.LastSpace;
1895 bool AvoidBinPacking;
1896 bool BreakBeforeParameter = false;
1897 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
1898 CurrentState.NestedBlockIndent);
1899 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1901 if (Current.opensBlockOrBlockTypeList(Style)) {
1903 std::min(State.Column, CurrentState.NestedBlockIndent);
1904 } else if (Current.is(tok::l_brace)) {
1905 NewIndent =
1908 } else {
1910 }
1911 const FormatToken *NextNonComment = Current.getNextNonComment();
1912 bool EndsInComma = Current.MatchingParen &&
1913 Current.MatchingParen->Previous &&
1914 Current.MatchingParen->Previous->is(tok::comma);
1915 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
1917 (NextNonComment && NextNonComment->isOneOf(
1918 TT_DesignatedInitializerPeriod,
1919 TT_DesignatedInitializerLSquare));
1920 BreakBeforeParameter = EndsInComma;
1921 if (Current.ParameterCount > 1)
1922 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
1923 } else {
1924 NewIndent =
1926 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
1927
1928 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
1930
1931
1932
1933
1934 const FormatToken *Next = Current.Next;
1935 if (Next && Next->is(TT_TableGenDAGArgOperatorID))
1936 NewIndent = State.Column + Next->TokenText.size() + 2;
1937 }
1938
1939
1940
1941
1942
1943 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
1944 NewIndent = std::max(NewIndent, CurrentState.Indent);
1945 LastSpace = std::max(LastSpace, CurrentState.Indent);
1946 }
1947
1948 bool EndsInComma =
1949 Current.MatchingParen &&
1950 Current.MatchingParen->getPreviousNonComment() &&
1951 Current.MatchingParen->getPreviousNonComment()->is(tok::comma);
1952
1953
1954
1955 bool ObjCBinPackProtocolList =
1959
1960 bool BinPackDeclaration =
1963 (State.Line->Type == LT_ObjCDecl && ObjCBinPackProtocolList);
1964
1965 bool GenericSelection =
1966 Current.getPreviousNonComment() &&
1967 Current.getPreviousNonComment()->is(tok::kw__Generic);
1968
1969 AvoidBinPacking =
1970 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
1972 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
1973 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
1976 (!BinPackInconclusiveFunctions && Current.is(PPK_Inconclusive))));
1977
1978 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
1981
1982
1985 BreakBeforeParameter = true;
1986 }
1987 } else {
1988
1989
1990 for (const FormatToken *Tok = &Current;
1991 Tok && Tok != Current.MatchingParen; Tok = Tok->Next) {
1992 if (Tok->MustBreakBefore ||
1993 (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) {
1994 BreakBeforeParameter = true;
1995 break;
1996 }
1997 }
1998 }
1999 }
2000
2002 BreakBeforeParameter = true;
2003 }
2004
2005
2006
2007 bool NoLineBreak =
2008 Current.Children.empty() &&
2009 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2010 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2011 (Current.is(TT_TemplateOpener) &&
2012 CurrentState.ContainsUnwrappedBuilder));
2013 State.Stack.push_back(
2014 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2015 auto &NewState = State.Stack.back();
2016 NewState.NestedBlockIndent = NestedBlockIndent;
2017 NewState.BreakBeforeParameter = BreakBeforeParameter;
2018 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2019
2021 Current.is(tok::l_paren)) {
2022
2023 FormatToken const *next = Current.Next;
2024 while (next) {
2025 if (next->is(TT_LambdaLSquare)) {
2026 NewState.HasMultipleNestedBlocks = true;
2027 break;
2028 }
2029 next = next->Next;
2030 }
2031 }
2032
2033 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2034 Current.Previous &&
2035 Current.Previous->is(tok::at);
2036}
2037
2038void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
2039 const FormatToken &Current = *State.NextToken;
2040 if (!Current.closesScope())
2041 return;
2042
2043
2044
2045 if (State.Stack.size() > 1 &&
2046 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2047 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2048 State.NextToken->is(TT_TemplateCloser) ||
2049 State.NextToken->is(TT_TableGenListCloser) ||
2050 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2051 State.Stack.pop_back();
2052 }
2053
2054 auto &CurrentState = State.Stack.back();
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2067 Current.MatchingParen->Previous) {
2068 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2069 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2070 CurrentScopeOpener.MatchingParen) {
2071 int NecessarySpaceInLine =
2073 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2074 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2076 CurrentState.BreakBeforeParameter = false;
2077 }
2078 }
2079 }
2080
2081 if (Current.is(tok::r_square)) {
2082
2083 const FormatToken *NextNonComment = Current.getNextNonComment();
2084 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2085 CurrentState.StartOfArraySubscripts = 0;
2086 }
2087}
2088
2089void ContinuationIndenter::moveStateToNewBlock(LineState &State, bool NewLine) {
2091 State.NextToken->is(TT_LambdaLBrace) &&
2092 !State.Line->MightBeFunctionDecl) {
2093 State.Stack.back().NestedBlockIndent = State.FirstIndent;
2094 }
2095 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2096
2097 unsigned NewIndent =
2098 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2101
2102
2103
2104
2105
2106
2108 State.NextToken->is(TT_LambdaLBrace);
2109
2110 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2111 State.Stack.back().LastSpace,
2112 true, NoLineBreak));
2113 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2114 State.Stack.back().BreakBeforeParameter = true;
2115}
2116
2118 unsigned TabWidth,
2120 size_t LastNewlinePos = Text.find_last_of("\n");
2121 if (LastNewlinePos == StringRef::npos) {
2122 return StartColumn +
2124 } else {
2126 0, TabWidth, Encoding);
2127 }
2128}
2129
2130unsigned ContinuationIndenter::reformatRawStringLiteral(
2131 const FormatToken &Current, LineState &State,
2132 const FormatStyle &RawStringStyle, bool DryRun, bool Newline) {
2133 unsigned StartColumn = State.Column - Current.ColumnWidth;
2135 StringRef NewDelimiter =
2137 if (NewDelimiter.empty())
2138 NewDelimiter = OldDelimiter;
2139
2140
2141 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2142 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2143
2144
2145 std::string RawText = std::string(
2146 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2147 if (NewDelimiter != OldDelimiter) {
2148
2149
2150 std::string CanonicalDelimiterSuffix = (")" + NewDelimiter + "\"").str();
2151 if (StringRef(RawText).contains(CanonicalDelimiterSuffix))
2152 NewDelimiter = OldDelimiter;
2153 }
2154
2155 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2156 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2157
2158
2159 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] == '\n';
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192 unsigned CurrentIndent =
2193 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2194 ? State.Stack.back().NestedBlockIndent
2195 : State.Stack.back().Indent;
2196 unsigned NextStartColumn = ContentStartsOnNewline
2198 : FirstStartColumn;
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208 unsigned LastStartColumn =
2209 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2210
2211 std::pair<tooling::Replacements, unsigned> Fixes = internal::reformat(
2212 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2213 FirstStartColumn, NextStartColumn, LastStartColumn, "",
2214 nullptr);
2215
2217 tooling::Replacements NoFixes;
2218 if (!NewCode)
2219 return addMultilineToken(Current, State);
2220 if (!DryRun) {
2221 if (NewDelimiter != OldDelimiter) {
2222
2223
2224 SourceLocation PrefixDelimiterStart =
2225 Current.Tok.getLocation().getLocWithOffset(2);
2226 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2227 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2228 if (PrefixErr) {
2229 llvm::errs()
2230 << "Failed to update the prefix delimiter of a raw string: "
2231 << llvm::toString(std::move(PrefixErr)) << "\n";
2232 }
2233
2234
2235 SourceLocation SuffixDelimiterStart =
2236 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2237 1 - OldDelimiter.size());
2238 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2239 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2240 if (SuffixErr) {
2241 llvm::errs()
2242 << "Failed to update the suffix delimiter of a raw string: "
2243 << llvm::toString(std::move(SuffixErr)) << "\n";
2244 }
2245 }
2246 SourceLocation OriginLoc =
2247 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2248 for (const tooling::Replacement &Fix : Fixes.first) {
2249 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2250 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2251 Fix.getLength(), Fix.getReplacementText()));
2252 if (Err) {
2253 llvm::errs() << "Failed to reformat raw string: "
2254 << llvm::toString(std::move(Err)) << "\n";
2255 }
2256 }
2257 }
2259 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2260 State.Column = RawLastLineEndColumn + NewSuffixSize;
2261
2262
2263
2264 unsigned PrefixExcessCharacters =
2265 StartColumn + NewPrefixSize > Style.ColumnLimit
2266 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2267 : 0;
2268 bool IsMultiline =
2269 ContentStartsOnNewline || (NewCode->find('\n') != std:🧵:npos);
2270 if (IsMultiline) {
2271
2272 for (ParenState &Paren : State.Stack)
2273 Paren.BreakBeforeParameter = true;
2274 }
2276}
2277
2278unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current,
2279 LineState &State) {
2280
2281 for (ParenState &Paren : State.Stack)
2282 Paren.BreakBeforeParameter = true;
2283
2284 unsigned ColumnsUsed = State.Column;
2285
2286
2287 State.Column = Current.LastLineColumnWidth;
2288
2291 return 0;
2292}
2293
2294unsigned ContinuationIndenter::handleEndOfLine(const FormatToken &Current,
2295 LineState &State, bool DryRun,
2296 bool AllowBreak, bool Newline) {
2297 unsigned Penalty = 0;
2298
2299
2300 auto RawStringStyle = getRawStringStyle(Current, State);
2301 if (RawStringStyle && !Current.Finalized) {
2302 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2303 Newline);
2304 } else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2305
2306
2307 Penalty = addMultilineToken(Current, State);
2309
2310 LineState OriginalState = State;
2311
2312
2313
2314 bool Strict = false;
2315
2316
2317 bool Exceeded = false;
2318 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2319 Current, State, AllowBreak, true, Strict);
2320 if (Exceeded) {
2321
2322
2323 LineState StrictState = OriginalState;
2324 unsigned StrictPenalty =
2325 breakProtrudingToken(Current, StrictState, AllowBreak,
2326 true, true)
2327 .first;
2328 Strict = StrictPenalty <= Penalty;
2329 if (Strict) {
2330 Penalty = StrictPenalty;
2331 State = StrictState;
2332 }
2333 }
2334 if (!DryRun) {
2335
2336
2337 breakProtrudingToken(Current, OriginalState, AllowBreak, false,
2338 Strict);
2339 }
2340 }
2342 unsigned ExcessCharacters = State.Column - getColumnLimit(State);
2344 }
2345 return Penalty;
2346}
2347
2348
2349
2351
2353 if (!Tok || Tok->isNot(tok::l_paren))
2354 return "";
2356 if (!Tok)
2357 return "";
2358 if (Tok->is(TT_TemplateCloser)) {
2360 if (Tok)
2362 }
2363 if (!Tok || Tok->isNot(tok::identifier))
2364 return "";
2366}
2367
2368std::optional
2369ContinuationIndenter::getRawStringStyle(const FormatToken &Current,
2370 const LineState &State) {
2371 if (!Current.isStringLiteral())
2372 return std::nullopt;
2374 if (!Delimiter)
2375 return std::nullopt;
2376 auto RawStringStyle = RawStringFormats.getDelimiterStyle(*Delimiter);
2377 if (!RawStringStyle && Delimiter->empty()) {
2380 }
2381 if (!RawStringStyle)
2382 return std::nullopt;
2383 RawStringStyle->ColumnLimit = getColumnLimit(State);
2384 return RawStringStyle;
2385}
2386
2387std::unique_ptr
2388ContinuationIndenter::createBreakableToken(const FormatToken &Current,
2389 LineState &State, bool AllowBreak) {
2390 unsigned StartColumn = State.Column - Current.ColumnWidth;
2391 if (Current.isStringLiteral()) {
2392
2393
2395 !AllowBreak) {
2396 return nullptr;
2397 }
2398
2399
2400
2401
2402
2403
2405 return nullptr;
2406
2407
2408 if (Current.IsUnterminatedLiteral)
2409 return nullptr;
2410
2411
2412 if (State.Stack.back().IsInsideObjCArrayLiteral)
2413 return nullptr;
2414
2415
2416
2417
2418
2419 if (Style.isVerilog() && Current.Previous &&
2420 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2421 return nullptr;
2422 }
2423 StringRef Text = Current.TokenText;
2424
2425
2426
2427
2428
2429 unsigned UnbreakableTailLength = (State.NextToken && canBreak(State))
2430 ? 0
2431 : Current.UnbreakableTailLength;
2432
2437 Text.ends_with("'")) {
2439 } else if (Style.isCSharp() && Text.starts_with("@\"") &&
2440 Text.ends_with("\"")) {
2442 } else if (Text.starts_with("\"") && Text.ends_with("\"")) {
2444 } else {
2445 return nullptr;
2446 }
2447 return std::make_unique(
2448 Current, QuoteStyle,
2450 UnbreakableTailLength, State.Line->InPPDirective, Encoding, Style);
2451 }
2452
2453 StringRef Prefix;
2454 StringRef Postfix;
2455
2456
2457
2458
2459 if ((Text.ends_with(Postfix = "\"") &&
2460 (Text.starts_with(Prefix = "@\"") || Text.starts_with(Prefix = "\"") ||
2461 Text.starts_with(Prefix = "u\"") ||
2462 Text.starts_with(Prefix = "U\"") ||
2463 Text.starts_with(Prefix = "u8\"") ||
2464 Text.starts_with(Prefix = "L\""))) ||
2465 (Text.starts_with(Prefix = "_T(\"") &&
2466 Text.ends_with(Postfix = "\")"))) {
2467 return std::make_unique(
2468 Current, StartColumn, Prefix, Postfix, UnbreakableTailLength,
2469 State.Line->InPPDirective, Encoding, Style);
2470 }
2471 } else if (Current.is(TT_BlockComment)) {
2473
2474
2475
2477 return nullptr;
2478 }
2479 return std::make_unique(
2480 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2481 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2482 } else if (Current.is(TT_LineComment) &&
2483 (!Current.Previous ||
2484 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2485 bool RegularComments = [&]() {
2486 for (const FormatToken *T = &Current; T && T->is(TT_LineComment);
2488 if (!(T->TokenText.starts_with("//") || T->TokenText.starts_with("#")))
2489 return false;
2490 }
2491 return true;
2492 }();
2494 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2496 return nullptr;
2497 }
2498 return std::make_unique(
2499 Current, StartColumn, false, Encoding, Style);
2500 }
2501 return nullptr;
2502}
2503
2504std::pair<unsigned, bool>
2505ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
2506 LineState &State, bool AllowBreak,
2507 bool DryRun, bool Strict) {
2508 std::unique_ptr Token =
2509 createBreakableToken(Current, State, AllowBreak);
2510 if (!Token)
2511 return {0, false};
2512 assert(Token->getLineCount() > 0);
2514 if (Current.is(TT_LineComment)) {
2515
2517 }
2518 if (ColumnLimit == 0) {
2519
2520
2521 ColumnLimit = std::numeric_limits<decltype(ColumnLimit)>::max();
2522 }
2523 if (Current.UnbreakableTailLength >= ColumnLimit)
2524 return {0, false};
2525
2526
2527 unsigned StartColumn = State.Column - Current.ColumnWidth;
2528 unsigned NewBreakPenalty = Current.isStringLiteral()
2531
2532
2533 bool Exceeded = false;
2534
2535 bool BreakInserted = Token->introducesBreakBeforeToken();
2536
2537
2538 bool NewBreakBefore = false;
2539
2540
2541
2542 bool Reflow = false;
2543
2544
2545 unsigned TailOffset = 0;
2546
2547 unsigned ContentStartColumn =
2548 Token->getContentStartColumn(0, false);
2549
2550 unsigned RemainingTokenColumns =
2551 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2552
2553 if (!DryRun)
2554 Token->adaptStartOfLine(0, Whitespaces);
2555
2556 unsigned ContentIndent = 0;
2557 unsigned Penalty = 0;
2558 LLVM_DEBUG(llvm::dbgs() << "Breaking protruding token at column "
2559 << StartColumn << ".\n");
2560 for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2561 LineIndex != EndIndex; ++LineIndex) {
2562 LLVM_DEBUG(llvm::dbgs()
2563 << " Line: " << LineIndex << " (Reflow: " << Reflow << ")\n");
2564 NewBreakBefore = false;
2565
2566
2567
2568 bool TryReflow = Reflow;
2569
2570 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2571 LLVM_DEBUG(llvm::dbgs() << " Over limit, need: "
2572 << (ContentStartColumn + RemainingTokenColumns)
2573 << ", space: " << ColumnLimit
2574 << ", reflown prefix: " << ContentStartColumn
2575 << ", offset in line: " << TailOffset << "\n");
2576
2577
2578
2579
2581 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2582 ContentStartColumn, CommentPragmasRegex);
2583 if (Split.first == StringRef::npos) {
2584
2585
2586 if (LineIndex < EndIndex - 1) {
2587
2588
2590 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2591 }
2592 LLVM_DEBUG(llvm::dbgs() << " No break opportunity.\n");
2593 break;
2594 }
2595 assert(Split.first != 0);
2596
2597 if (Token->supportsReflow()) {
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617 unsigned ToSplitColumns = Token->getRangeLength(
2618 LineIndex, TailOffset, Split.first, ContentStartColumn);
2619 LLVM_DEBUG(llvm::dbgs() << " ToSplit: " << ToSplitColumns << "\n");
2620
2622 LineIndex, TailOffset + Split.first + Split.second, ColumnLimit,
2623 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2624
2625
2626 unsigned ToNextSplitColumns = 0;
2627 if (NextSplit.first == StringRef::npos) {
2628 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2629 ContentStartColumn);
2630 } else {
2631 ToNextSplitColumns = Token->getRangeLength(
2632 LineIndex, TailOffset,
2633 Split.first + Split.second + NextSplit.first, ContentStartColumn);
2634 }
2635
2636
2637 ToNextSplitColumns =
2638 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2639 LLVM_DEBUG(llvm::dbgs()
2640 << " ContentStartColumn: " << ContentStartColumn << "\n");
2641 LLVM_DEBUG(llvm::dbgs()
2642 << " ToNextSplit: " << ToNextSplitColumns << "\n");
2643
2644
2645 bool ContinueOnLine =
2646 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2647 unsigned ExcessCharactersPenalty = 0;
2648 if (!ContinueOnLine && !Strict) {
2649
2650
2651 ExcessCharactersPenalty =
2652 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2654 LLVM_DEBUG(llvm::dbgs()
2655 << " Penalty excess: " << ExcessCharactersPenalty
2656 << "\n break : " << NewBreakPenalty << "\n");
2657 if (ExcessCharactersPenalty < NewBreakPenalty) {
2658 Exceeded = true;
2659 ContinueOnLine = true;
2660 }
2661 }
2662 if (ContinueOnLine) {
2663 LLVM_DEBUG(llvm::dbgs() << " Continuing on line...\n");
2664
2665
2666 TryReflow = true;
2667 if (!DryRun) {
2668 Token->compressWhitespace(LineIndex, TailOffset, Split,
2669 Whitespaces);
2670 }
2671
2672 ContentStartColumn += ToSplitColumns + 1;
2673 Penalty += ExcessCharactersPenalty;
2674 TailOffset += Split.first + Split.second;
2675 RemainingTokenColumns = Token->getRemainingLength(
2676 LineIndex, TailOffset, ContentStartColumn);
2677 continue;
2678 }
2679 }
2680 LLVM_DEBUG(llvm::dbgs() << " Breaking...\n");
2681
2682
2683
2684 if (!Reflow)
2685 ContentIndent = Token->getContentIndent(LineIndex);
2686 LLVM_DEBUG(llvm::dbgs()
2687 << " ContentIndent: " << ContentIndent << "\n");
2688 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2689 LineIndex, true);
2690
2691 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2692 LineIndex, TailOffset + Split.first + Split.second,
2693 ContentStartColumn);
2694 if (NewRemainingTokenColumns == 0) {
2695
2696 ContentIndent = 0;
2697 ContentStartColumn =
2698 Token->getContentStartColumn(LineIndex, true);
2699 NewRemainingTokenColumns = Token->getRemainingLength(
2700 LineIndex, TailOffset + Split.first + Split.second,
2701 ContentStartColumn);
2702 }
2703
2704
2705
2706
2707 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2708
2709 break;
2710 }
2711
2712 LLVM_DEBUG(llvm::dbgs() << " Breaking at: " << TailOffset + Split.first
2713 << ", " << Split.second << "\n");
2714 if (!DryRun) {
2715 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2716 Whitespaces);
2717 }
2718
2719 Penalty += NewBreakPenalty;
2720 TailOffset += Split.first + Split.second;
2721 RemainingTokenColumns = NewRemainingTokenColumns;
2722 BreakInserted = true;
2723 NewBreakBefore = true;
2724 }
2725
2726
2727 if (LineIndex + 1 != EndIndex) {
2728 unsigned NextLineIndex = LineIndex + 1;
2729 if (NewBreakBefore) {
2730
2731
2732 TryReflow = true;
2733 }
2734 if (TryReflow) {
2735
2736
2737
2738
2739
2740
2741 Reflow = false;
2742
2743
2744
2745
2746
2747
2748 ContentStartColumn += RemainingTokenColumns + 1;
2749
2750
2751
2753 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2754 LLVM_DEBUG(llvm::dbgs()
2755 << " Size of reflown text: " << ContentStartColumn
2756 << "\n Potential reflow split: ");
2757 if (SplitBeforeNext.first != StringRef::npos) {
2758 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first << ", "
2759 << SplitBeforeNext.second << "\n");
2760 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2761
2762
2763 RemainingTokenColumns = Token->getRemainingLength(
2764 NextLineIndex, TailOffset, ContentStartColumn);
2765 Reflow = true;
2766 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2767 LLVM_DEBUG(llvm::dbgs()
2768 << " Over limit after reflow, need: "
2769 << (ContentStartColumn + RemainingTokenColumns)
2770 << ", space: " << ColumnLimit
2771 << ", reflown prefix: " << ContentStartColumn
2772 << ", offset in line: " << TailOffset << "\n");
2773
2774
2775
2776
2778 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2779 ContentStartColumn, CommentPragmasRegex);
2780 if (Split.first == StringRef::npos) {
2781 LLVM_DEBUG(llvm::dbgs() << " Did not find later break\n");
2782 Reflow = false;
2783 } else {
2784
2785
2786
2787 unsigned ToSplitColumns = Token->getRangeLength(
2788 NextLineIndex, TailOffset, Split.first, ContentStartColumn);
2789 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2790 LLVM_DEBUG(llvm::dbgs() << " Next split protrudes, need: "
2791 << (ContentStartColumn + ToSplitColumns)
2792 << ", space: " << ColumnLimit);
2793 unsigned ExcessCharactersPenalty =
2794 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2796 if (NewBreakPenalty < ExcessCharactersPenalty)
2797 Reflow = false;
2798 }
2799 }
2800 }
2801 } else {
2802 LLVM_DEBUG(llvm::dbgs() << "not found.\n");
2803 }
2804 }
2805 if (!Reflow) {
2806
2807
2808
2809 TailOffset = 0;
2810 ContentStartColumn =
2811 Token->getContentStartColumn(NextLineIndex, false);
2812 RemainingTokenColumns = Token->getRemainingLength(
2813 NextLineIndex, TailOffset, ContentStartColumn);
2814
2815 if (!DryRun)
2816 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2817 } else {
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831 if (NewBreakBefore) {
2832 assert(Penalty >= NewBreakPenalty);
2833 Penalty -= NewBreakPenalty;
2834 }
2835 if (!DryRun)
2836 Token->reflow(NextLineIndex, Whitespaces);
2837 }
2838 }
2839 }
2840
2842 Token->getSplitAfterLastLine(TailOffset);
2843 if (SplitAfterLastLine.first != StringRef::npos) {
2844 LLVM_DEBUG(llvm::dbgs() << "Replacing whitespace after last line.\n");
2845
2846
2847
2849 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2850
2851 if (!DryRun) {
2852 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2853 Whitespaces);
2854 }
2855 ContentStartColumn =
2856 Token->getContentStartColumn(Token->getLineCount() - 1, true);
2857 RemainingTokenColumns = Token->getRemainingLength(
2858 Token->getLineCount() - 1,
2859 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2860 ContentStartColumn);
2861 }
2862
2863 State.Column = ContentStartColumn + RemainingTokenColumns -
2864 Current.UnbreakableTailLength;
2865
2866 if (BreakInserted) {
2867 if (!DryRun)
2868 Token->updateAfterBroken(Whitespaces);
2869
2870
2871
2872
2873 if (Current.isNot(TT_LineComment))
2874 for (ParenState &Paren : State.Stack)
2875 Paren.BreakBeforeParameter = true;
2876
2877 if (Current.is(TT_BlockComment))
2878 State.NoContinuation = true;
2879
2880 State.Stack.back().LastSpace = StartColumn;
2881 }
2882
2883 Token->updateNextToken(State);
2884
2885 return {Penalty, Exceeded};
2886}
2887
2889
2890 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
2891}
2892
2893bool ContinuationIndenter::nextIsMultilineString(const LineState &State) {
2894 const FormatToken &Current = *State.NextToken;
2895 if (!Current.isStringLiteral() || Current.is(TT_ImplicitStringLiteral))
2896 return false;
2897
2898
2899
2900 if (Current.TokenText.starts_with("R\""))
2901 return false;
2902 if (Current.IsMultiline)
2903 return true;
2904 if (Current.getNextNonComment() &&
2905 Current.getNextNonComment()->isStringLiteral()) {
2906 return true;
2907 }
2909 State.Column + Current.ColumnWidth + Current.UnbreakableTailLength >
2911 return true;
2912 }
2913 return false;
2914}
2915
2916}
2917}
Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...
This file implements an indenter that manages the indentation of continuations.
This file declares Format APIs to be used internally by the formatting library implementation.
This file contains the declaration of the FormatToken, a wrapper around Token with additional informa...
Various functions to configurably format source code.
Defines and computes precedence levels for binary/ternary operators.
Defines the SourceManager interface.
unsigned LongestObjCSelectorName
Defines the clang::TokenKind enum and support functions.
WhitespaceManager class manages whitespace around tokens and their replacements.
__DEVICE__ int max(int __a, int __b)
This class handles loading and caching of source files into memory.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Token - This structure provides full information about a lexed token.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
std::pair< StringRef::size_type, unsigned > Split
Contains starting character index and length of split.
bool canBreak(const LineState &State)
Returns true, if a line break after State is allowed.
unsigned addTokenToState(LineState &State, bool Newline, bool DryRun, unsigned ExtraSpaces=0)
Appends the next token to State and updates information necessary for indentation.
unsigned getColumnLimit(const LineState &State) const
Get the column limit for this line.
LineState getInitialState(unsigned FirstIndent, unsigned FirstStartColumn, const AnnotatedLine *Line, bool DryRun)
Get the initial state, i.e.
ContinuationIndenter(const FormatStyle &Style, const AdditionalKeywords &Keywords, const SourceManager &SourceMgr, WhitespaceManager &Whitespaces, encoding::Encoding Encoding, bool BinPackInconclusiveFunctions)
Constructs a ContinuationIndenter to format Line starting in column FirstIndent.
bool mustBreak(const LineState &State)
Returns true, if a line break after State is mandatory.
Manages the whitespaces around tokens and their replacements.
llvm::Error addReplacement(const tooling::Replacement &Replacement)
void replaceWhitespace(FormatToken &Tok, unsigned Newlines, unsigned Spaces, unsigned StartOfTokenColumn, bool IsAligned=false, bool InPPDirective=false)
Replaces the whitespace in front of Tok.
unsigned columnWidthWithTabs(StringRef Text, unsigned StartColumn, unsigned TabWidth, Encoding Encoding)
Returns the number of columns required to display the Text, starting from the StartColumn on a termin...
std::pair< tooling::Replacements, unsigned > reformat(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, unsigned FirstStartColumn, unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, FormattingAttemptStatus *Status)
Reformats the given Ranges in the code fragment Code.
static bool mustBreakBinaryOperation(const FormatToken &Current, const FormatStyle &Style)
static unsigned getLastLineEndColumn(StringRef Text, unsigned StartColumn, unsigned TabWidth, encoding::Encoding Encoding)
static bool shouldUnindentNextOperator(const FormatToken &Tok)
FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language=FormatStyle::LanguageKind::LK_Cpp)
Returns a format style complying with the LLVM coding standards: http://llvm.org/docs/CodingStandards...
bool switchesFormatting(const FormatToken &Token)
Checks if Token switches formatting, like /* clang-format off */.
static bool hasNestedBlockInlined(const FormatToken *Previous, const FormatToken &Current, const FormatStyle &Style)
static bool startsSegmentOfBuilderTypeCall(const FormatToken &Tok)
static unsigned getLengthToNextOperator(const FormatToken &Tok)
static bool isAlignableBinaryOperator(const FormatToken &Token)
static unsigned getLengthToMatchingParen(const FormatToken &Tok, ArrayRef< ParenState > Stack)
static bool shouldIndentWrappedSelectorName(const FormatStyle &Style, LineType LineType)
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style)
Gets a predefined style for the specified language by name.
static std::optional< StringRef > getRawStringDelimiter(StringRef TokenText)
static StringRef getCanonicalRawStringDelimiter(const FormatStyle &Style, FormatStyle::LanguageKind Language)
static bool startsNextOperand(const FormatToken &Current)
static bool opensProtoMessageField(const FormatToken &LessTok, const FormatStyle &Style)
static StringRef getEnclosingFunctionName(const FormatToken &Current)
@ LT_PreprocessorDirective
bool startsNextParameter(const FormatToken &Current, const FormatStyle &Style)
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
Language
The language for the input, used to select and validate the language standard and possible actions.
const FunctionProtoType * T
Encapsulates keywords that are context sensitive or for languages not properly supported by Clang's l...
bool isVerilogBegin(const FormatToken &Tok) const
Returns whether Tok is a Verilog keyword that opens a block.
bool isVerilogEndOfLabel(const FormatToken &Tok) const
IdentifierInfo * kw_import
IdentifierInfo * kw_dollar
IdentifierInfo * kw_async
IdentifierInfo * kw_await
IdentifierInfo * kw_implements
IdentifierInfo * kw_function
IdentifierInfo * kw_extends
bool BeforeLambdaBody
Wrap lambda block.
The FormatStyle is used to configure the formatting to follow specific guidelines.
unsigned ContinuationIndentWidth
Indent width for line continuations.
bool AlwaysBreakBeforeMultilineStrings
This option is renamed to BreakAfterReturnType.
ReturnTypeBreakingStyle BreakAfterReturnType
The function declaration return type breaking style to use.
LanguageKind
Supported languages.
@ LK_Java
Should be used for Java.
@ LK_ObjC
Should be used for Objective-C, Objective-C++.
@ LK_Proto
Should be used for Protocol Buffers (https://developers.google.com/protocol-buffers/).
@ LK_TextProto
Should be used for Protocol Buffer messages in text format (https://developers.google....
bool Cpp11BracedListStyle
If true, format braced lists as best suited for C++11 braced lists.
BreakInheritanceListStyle BreakInheritanceList
The inheritance list style to use.
unsigned IndentWidth
The number of columns to use for indentation.
bool IndentRequiresClause
Indent the requires clause in a template.
std::vector< RawStringFormat > RawStringFormats
Defines hints for detecting supported languages code blocks in raw strings.
PPDirectiveIndentStyle IndentPPDirectives
The preprocessor directive indenting style to use.
@ BPPS_BinPack
Bin-pack parameters.
BinaryOperatorStyle BreakBeforeBinaryOperators
The way to wrap binary operators.
@ BPS_Auto
Automatically determine parameter bin-packing behavior.
@ BPS_Always
Always bin-pack parameters.
@ RCS_Never
Leave comments untouched.
@ BCIS_AfterColon
Break constructor initializers after the colon and commas.
@ BCIS_BeforeColon
Break constructor initializers before the colon and after the commas.
@ BCIS_BeforeComma
Break constructor initializers before the colon and commas, and align the commas with the colon.
BreakBeforeConceptDeclarationsStyle BreakBeforeConceptDeclarations
The concept declaration style to use.
BreakTemplateDeclarationsStyle BreakTemplateDeclarations
The template declaration breaking style to use.
@ BOS_None
Break after operators.
bool IndentWrappedFunctionNames
Indent if a function definition or declaration is wrapped after the type.
LanguageKind Language
Language, this format style is targeted at.
@ BAS_DontAlign
Don't align, instead use ContinuationIndentWidth, e.g.:
@ BAS_AlwaysBreak
Always break after an open bracket, if the parameters don't fit on a single line, e....
@ BAS_BlockIndent
Always break after an open bracket, if the parameters don't fit on a single line.
@ BBIAS_Always
Always break before inline ASM colon.
@ BBIAS_OnlyMultiline
Break before inline ASM colon if the line length is longer than column limit.
unsigned TabWidth
The number of columns used for tab stops.
@ PPDIS_AfterHash
Indents directives after the hash.
@ LBI_OuterScope
For statements within block scope, align lambda body relative to the indentation level of the outer s...
@ LBI_Signature
Align lambda body relative to the lambda signature.
unsigned PenaltyBreakFirstLessLess
The penalty for breaking before the first <<.
unsigned ObjCBlockIndentWidth
The number of characters to use for indentation of ObjC blocks.
std::optional< FormatStyle > GetLanguageStyle(LanguageKind Language) const
std::optional< unsigned > BracedInitializerIndentWidth
The number of columns to use to indent the contents of braced init lists.
bool ExperimentalAutoDetectBinPacking
If true, clang-format detects whether function calls and definitions are formatted with one parameter...
bool ObjCBreakBeforeNestedBlockParam
Break parameters list into lines when there is nested block parameters in a function call.
OperandAlignmentStyle AlignOperands
If true, horizontally align operands of binary and ternary expressions.
@ BTDS_No
Do not force break before declaration.
@ BTDS_Leave
Do not change the line breaking before the declaration.
BreakBinaryOperationsStyle BreakBinaryOperations
The break binary operations style to use.
BreakConstructorInitializersStyle BreakConstructorInitializers
The break constructor initializers style to use.
bool BreakStringLiterals
Allow breaking string literals when formatting.
@ PCIS_NextLineOnly
Put all constructor initializers on the next line if they fit.
@ PCIS_BinPack
Bin-pack constructor initializers.
@ PCIS_NextLine
Same as PCIS_CurrentLine except that if all constructor initializers do not fit on the current line,...
BraceBreakingStyle BreakBeforeBraces
The brace breaking style to use.
@ BILS_AfterColon
Break inheritance list after the colon and commas.
@ BILS_BeforeComma
Break inheritance list before the colon and commas, and align the commas with the colon.
unsigned PenaltyExcessCharacter
The penalty for each character outside of the column limit.
@ DAS_BreakElements
Break inside DAGArg after each list element but for the last.
unsigned ConstructorInitializerIndentWidth
This option is deprecated.
@ RCPS_OwnLineWithBrace
As with OwnLine, except, unless otherwise prohibited, place a following open brace (of a function def...
@ RCPS_OwnLine
Always put the requires clause on its own line (possibly followed by a semicolon).
@ RCPS_WithPreceding
Try to put the clause together with the preceding part of a declaration.
@ RCPS_SingleLine
Try to put everything in the same line if possible.
@ RCPS_WithFollowing
Try to put the requires clause together with the class or function declaration.
RequiresClausePositionStyle RequiresClausePosition
The position of the requires clause.
BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon
The inline ASM colon style to use.
@ BS_Whitesmiths
Like Allman but always indent braces and line up code with braces.
bool BinPackArguments
If false, a function call's arguments will either be all on the same line or will have one line each.
@ REI_Keyword
Align requires expression body relative to the requires keyword.
PackConstructorInitializersStyle PackConstructorInitializers
The pack constructor initializers style to use.
@ BBCDS_Allowed
Breaking between template declaration and concept is allowed.
@ BBCDS_Never
Keep the template declaration line together with concept.
@ BBCDS_Always
Always break before concept, putting it in the line after the template declaration.
ReflowCommentsStyle ReflowComments
Comment reformatting style.
bool AllowAllParametersOfDeclarationOnNextLine
This option is deprecated.
BracketAlignmentStyle AlignAfterOpenBracket
If true, horizontally aligns arguments after an open bracket.
BinPackParametersStyle BinPackParameters
The bin pack parameters style to use.
unsigned MaxEmptyLinesToKeep
The maximum number of consecutive empty lines to keep.
BinPackStyle ObjCBinPackProtocolList
Controls bin-packing Objective-C protocol conformance list items into as few lines as possible when t...
bool isJavaScript() const
DAGArgStyle TableGenBreakInsideDAGArg
The styles of the line break inside the DAGArg in TableGen.
LambdaBodyIndentationKind LambdaBodyIndentation
The indentation style of lambda bodies.
@ BBO_Never
Don't break binary operations.
BraceWrappingFlags BraceWrapping
Control of individual brace wrapping cases.
unsigned PenaltyBreakString
The penalty for each line break introduced inside a string literal.
RequiresExpressionIndentationKind RequiresExpressionIndentation
The indentation used for requires expression bodies.
unsigned PenaltyIndentedWhitespace
Penalty for each character of whitespace indentation (counted relative to leading non-whitespace colu...
bool AllowAllArgumentsOnNextLine
If a function call or braced initializer list doesn't fit on a line, allow putting all arguments onto...
unsigned PenaltyBreakComment
The penalty for each line break introduced inside a comment.
@ RTBS_ExceptShortType
Same as Automatic above, except that there is no break after short return types.
@ RTBS_None
This is deprecated. See Automatic below.
UseTabStyle UseTab
The way to use tab characters in the resulting file.
@ OAS_AlignAfterOperator
Horizontally align operands of binary and ternary expressions.
@ OAS_DontAlign
Do not align operands of binary and ternary expressions.
bool BreakBeforeTernaryOperators
If true, ternary operators will be placed after line breaks.
unsigned ColumnLimit
The column limit.
A wrapper around a Token storing information about the whitespace characters preceding it.
unsigned NestingLevel
The nesting level of this token, i.e.
bool isMemberAccess() const
Returns true if this is a "." or "->" accessing a member.
StringRef TokenText
The raw text of the token.
FormatToken * getPreviousNonComment() const
Returns the previous token ignoring comments.
bool closesScope() const
Returns whether Tok is )]} or a closing > of a template or in protos.
bool is(tok::TokenKind Kind) const
unsigned TotalLength
The total length of the unwrapped line up to and including this token.
bool isTrailingComment() const
FormatToken * NextOperator
If this is an operator (or "."/"->") in a sequence of operators with the same precedence,...
FormatToken * MatchingParen
If this is a bracket, this points to the matching one.
FormatToken * Previous
The previous token in the unwrapped line.
The current state when indenting a unwrapped line.
llvm::StringMap< FormatStyle > EnclosingFunctionStyle
std::optional< FormatStyle > getDelimiterStyle(StringRef Delimiter) const
std::optional< FormatStyle > getEnclosingFunctionStyle(StringRef EnclosingFunction) const
RawStringFormatStyleManager(const FormatStyle &CodeStyle)
llvm::StringMap< FormatStyle > DelimiterStyle