23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/Debug.h"
27#define DEBUG_TYPE "format-indenter"
44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));
89 if (!
Tok.MatchingParen)
93 int MatchingStackIndex = Stack.size() - 1;
99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].
Tok != LBrace)
100 --MatchingStackIndex;
101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] :
nullptr;
103 for (; End->
Next; End = End->
Next) {
106 if (!End->
Next->closesScope())
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
112 if (State && State->BreakBeforeClosingBrace)
120 if (!
Tok.NextOperator)
122 return Tok.NextOperator->TotalLength -
Tok.TotalLength;
128 return Tok.isMemberAccess() &&
Tok.Previous &&
Tok.Previous->closesScope();
134 bool HasTwoOperands =
Token.OperatorIndex == 0 && !
Token.NextOperator;
135 return Token.
is(TT_BinaryOperator) && !HasTwoOperands &&
151 while (
Last->NextOperator)
153 return Last->OperatorIndex + 2;
179 const auto OperatorBreakStyle =
180 Style.BreakBinaryOperations.getStyleForOperator(OpToken->
Tok.
getKind());
185 const unsigned MinChain =
186 Style.BreakBinaryOperations.getMinChainLengthForOperator(
193 if (LessTok.
isNot(tok::less))
195 return Style.isTextProto() ||
213 size_t LParenPos =
TokenText.substr(0, 19).find_first_of(
'(');
214 if (LParenPos == StringRef::npos)
216 StringRef Delimiter =
TokenText.substr(2, LParenPos - 2);
219 size_t RParenPos =
TokenText.size() - Delimiter.size() - 2;
222 if (!
TokenText.substr(RParenPos + 1).starts_with(Delimiter))
232 for (
const auto &Format : Style.RawStringFormats)
234 return StringRef(Format.CanonicalDelimiter);
241 std::optional<FormatStyle> LanguageStyle =
243 if (!LanguageStyle) {
246 RawStringFormat.Language, &PredefinedStyle)) {
248 PredefinedStyle.
Language = RawStringFormat.Language;
250 LanguageStyle = PredefinedStyle;
252 LanguageStyle->ColumnLimit = CodeStyle.
ColumnLimit;
253 for (StringRef Delimiter : RawStringFormat.Delimiters)
255 for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions)
260std::optional<FormatStyle>
268std::optional<FormatStyle>
270 StringRef EnclosingFunction)
const {
293 *
this = *
this + Spaces;
321 bool BinPackInconclusiveFunctions)
322 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
323 Whitespaces(Whitespaces), Encoding(Encoding),
324 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
325 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
328 unsigned FirstStartColumn,
333 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
334 State.Column = FirstStartColumn;
336 State.Column = FirstIndent;
346 State.NextToken =
Line->First;
347 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
350 State.NoContinuation =
false;
351 State.StartOfStringLiteral = 0;
352 State.NoLineBreak =
false;
353 State.StartOfLineLevel = 0;
354 State.LowestLevelOnLine = 0;
355 State.IgnoreStackForComparison =
false;
357 if (Style.isTextProto()) {
360 auto &CurrentState = State.Stack.back();
361 CurrentState.AvoidBinPacking =
true;
362 CurrentState.BreakBeforeParameter =
true;
363 CurrentState.AlignColons =
false;
367 moveStateToNextToken(State, DryRun,
false);
374 const auto &CurrentState = State.Stack.back();
376 if (!Current.
CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
377 Current.closesBlockOrBlockTypeList(Style))) {
385 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
394 State.LowestLevelOnLine < State.StartOfLineLevel &&
398 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
403 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
404 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
405 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
406 return Style.isCpp() &&
412 if (Current.
is(TT_FunctionDeclarationName)) {
419 assert(State.Column >= State.FirstIndent);
420 if (State.Column - State.FirstIndent < 6)
428 Current.isBlockIndentedInitRBrace(Style)) {
429 return CurrentState.BreakBeforeClosingBrace;
434 if ((Style.BreakBeforeCloseBracketFunction ||
435 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
436 Style.BreakBeforeCloseBracketSwitch) &&
437 Current.
is(tok::r_paren)) {
438 return CurrentState.BreakBeforeClosingParen;
441 if (Style.BreakBeforeTemplateCloser && Current.
is(TT_TemplateCloser))
442 return CurrentState.BreakBeforeClosingAngle;
446 if (Current.
isNoneOf(TT_BinaryOperator, tok::comma) &&
450 (!Style.BraceWrapping.BeforeLambdaBody ||
451 Current.
isNot(TT_LambdaLBrace)) &&
453 (!Style.BraceWrapping.AfterRequiresExpression ||
454 Current.
isNot(TT_RequiresExpressionLBrace)) &&
455 CurrentState.NoLineBreakInOperand) {
462 if (Current.
is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
464 Previous.MatchingParen->Previous->MatchingParen &&
465 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
467 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
471 return !State.NoLineBreak && !CurrentState.NoLineBreak;
477 const auto &CurrentState = State.Stack.back();
478 if (Style.BraceWrapping.AfterRequiresExpression && Current.
CanBreakBefore &&
479 Current.
is(TT_RequiresExpressionLBrace) &&
484 (Current.
is(TT_InlineASMColon) &&
487 Style.ColumnLimit > 0)))) {
490 if (Style.BraceWrapping.BeforeLambdaBody && Current.
CanBreakBefore &&
491 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
492 const auto LambdaBodyLength =
496 if (CurrentState.BreakBeforeClosingBrace &&
497 (Current.closesBlockOrBlockTypeList(Style) ||
499 Current.isBlockIndentedInitRBrace(Style)))) {
502 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
504 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
507 Style.ObjCBreakBeforeNestedBlockParam &&
509 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
514 if (CurrentState.IsCSharpGenericTypeConstraint &&
515 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
519 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
520 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
528 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
530 (!Style.BreakBeforeTernaryOperators &&
531 Previous.is(TT_ConditionalExpr))) &&
532 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
533 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
536 if (CurrentState.IsChainedConditional &&
537 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
538 Current.
is(tok::colon)) ||
539 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
544 (
Previous.is(TT_ArrayInitializerLSquare) &&
547 Style.ColumnLimit > 0 &&
553 const FormatToken &BreakConstructorInitializersToken =
558 BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
559 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
561 CurrentState.BreakBeforeParameter) &&
562 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
567 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
568 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
571 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
572 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
573 (Style.ObjCBreakBeforeNestedBlockParam ||
574 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
578 unsigned NewLineColumn = getNewLineColumn(State).Total;
579 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
581 (State.Column > NewLineColumn ||
587 (CurrentState.CallContinuation != 0 ||
588 CurrentState.BreakBeforeParameter) &&
594 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
595 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
601 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
606 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
609 if (Style.AlwaysBreakBeforeMultilineStrings &&
610 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
612 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
613 Keywords.kw_dollar) &&
614 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
615 nextIsMultilineString(State)) {
623 const auto PreviousPrecedence =
Previous.getPrecedence();
625 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
626 const bool LHSIsBinaryExpr =
639 const bool IsComparison =
644 Previous.Previous->isNot(TT_BinaryOperator);
650 CurrentState.BreakBeforeParameter) {
655 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
656 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
660 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
665 if (
Previous.ClosesTemplateDeclaration) {
666 if (Current.
is(tok::kw_concept)) {
667 switch (Style.BreakBeforeConceptDeclarations) {
676 if (Current.
is(TT_RequiresClause)) {
677 switch (Style.RequiresClausePosition) {
689 if (
Previous.is(TT_FunctionAnnotationRParen) &&
693 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
694 Current.
isNot(TT_LeadingJavaAnnotation)) {
699 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
703 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
705 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
709 if (Current.
is(TT_FunctionDeclarationName) &&
710 !State.Line->ReturnTypeWrapped &&
712 (!Style.isCSharp() ||
716 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
717 CurrentState.BreakBeforeParameter) {
719 if (
Tok->is(TT_LineComment))
721 if (
Tok->is(TT_TemplateCloser)) {
726 if (
Tok->FirstAfterPPLine)
738 Current.
isNoneOf(tok::r_brace, tok::comment)) {
742 if (Current.
is(tok::lessless) &&
745 Previous.TokenText ==
"\'\\n\'")))) {
752 if (State.NoContinuation)
760 unsigned ExtraSpaces) {
762 assert(State.NextToken->Previous);
765 assert(!State.Stack.empty());
766 State.NoContinuation =
false;
768 if (Current.
is(TT_ImplicitStringLiteral) &&
769 (!
Previous.Tok.getIdentifierInfo() ||
770 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
771 tok::pp_not_keyword)) {
777 State.Column = EndColumn;
779 unsigned StartColumn =
781 assert(EndColumn >= StartColumn);
782 State.Column += EndColumn - StartColumn;
784 moveStateToNextToken(State, DryRun,
false);
788 unsigned Penalty = 0;
790 Penalty = addTokenOnNewLine(State, DryRun);
792 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
794 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
797void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
798 unsigned ExtraSpaces) {
800 assert(State.NextToken->Previous);
802 auto &CurrentState = State.Stack.back();
809 auto DisallowLineBreaks = [&] {
810 if (!Style.isCpp() ||
819 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
822 const auto *Prev = Current.getPreviousNonComment();
823 if (!Prev || Prev->isNot(tok::l_paren))
826 if (Prev->BlockParameterCount == 0)
830 for (
const auto *
Tok = &Current;
Tok &&
Tok != Prev->MatchingParen;
832 if (
Tok->is(TT_LambdaLBrace) &&
Tok->MustBreakBefore)
837 if (Prev->BlockParameterCount > 1)
844 const auto *Comma = Prev->
Role->lastComma();
848 const auto *
Next = Comma->getNextNonComment();
849 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
852 if (DisallowLineBreaks())
855 if (Current.
is(tok::equal) &&
857 CurrentState.VariablePos == 0 &&
859 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
860 CurrentState.VariablePos = State.
Column;
863 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
864 CurrentState.VariablePos -=
Tok->ColumnWidth;
865 if (
Tok->SpacesRequiredBefore != 0)
869 if (
Previous.PartOfMultiVariableDeclStmt)
870 CurrentState.LastSpace = CurrentState.VariablePos;
876 int PPColumnCorrection = 0;
888 PPColumnCorrection = -1;
895 const bool ContinuePPDirective =
897 Whitespaces.replaceWhitespace(Current, 0, Spaces,
898 State.
Column + Spaces + PPColumnCorrection,
899 nullptr, ContinuePPDirective);
905 Current.
is(TT_InheritanceColon)) {
906 CurrentState.NoLineBreak =
true;
910 CurrentState.NoLineBreak =
true;
913 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
915 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
916 CurrentState.Indent.Total);
919 CurrentState.AlignColons =
false;
923 CurrentState.ColonPos = FirstColonPos;
931 auto IsStartOfBracedList = [&]() {
935 if (IsStartOfBracedList())
936 return Style.BreakAfterOpenBracketBracedList;
937 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
941 if (
Tok.Previous->isIf())
942 return Style.BreakAfterOpenBracketIf;
943 if (
Tok.Previous->isLoop(Style))
944 return Style.BreakAfterOpenBracketLoop;
945 if (
Tok.Previous->is(tok::kw_switch))
946 return Style.BreakAfterOpenBracketSwitch;
947 if (Style.BreakAfterOpenBracketFunction) {
948 return !
Tok.Previous->is(TT_CastRParen) &&
949 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
954 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
955 Tok.Previous->is(tok::identifier);
957 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
958 if (!Style.isJavaScript())
960 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
961 if (Prev->is(TT_TemplateString) && Prev->opensScope())
963 if (Prev->opensScope() && !NestBlocks)
965 if (Prev->is(TT_TemplateString) && Prev->closesScope())
971 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
972 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
974 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
981 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
983 if (
Tok.is(TT_UnaryOperator) ||
984 (Style.isJavaScript() &&
985 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
988 const auto *
Previous = TokAfterLParen.Previous;
992 Previous->Previous->is(tok::kw_switch))) {
995 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
996 TT_LambdaDefinitionLParen) &&
1000 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
1003 return !
Next ||
Next->isMemberAccess() ||
1004 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
1007 State.
Column > getNewLineColumn(State).Total &&
1018 !StartsSimpleOneArgList(Current)) {
1019 CurrentState.NoLineBreak =
true;
1023 CurrentState.NoLineBreak =
true;
1029 if (Style.AlignAfterOpenBracket &&
1030 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
1031 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
1032 TT_TableGenDAGArgOpener,
1033 TT_TableGenDAGArgOpenerToBreak) &&
1035 (Current.
isNot(TT_LineComment) ||
1038 Previous.is(TT_VerilogMultiLineListLParen)) &&
1039 !IsInTemplateString(Current,
false)) {
1040 CurrentState.Indent = State.
Column + Spaces;
1041 CurrentState.AlignedTo = &
Previous;
1044 CurrentState.NoLineBreak =
true;
1046 CurrentState.NoLineBreak =
true;
1049 State.
Column > getNewLineColumn(State).Total) {
1050 CurrentState.ContainsUnwrappedBuilder =
true;
1053 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1054 CurrentState.NoLineBreak =
true;
1055 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1064 CurrentState.NoLineBreak =
true;
1071 const FormatToken *P = Current.getPreviousNonComment();
1072 if (Current.
isNot(tok::comment) && P &&
1073 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1074 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1075 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1079 bool BreakBeforeOperator =
1080 P->MustBreakBefore || P->is(tok::lessless) ||
1081 (P->is(TT_BinaryOperator) &&
1083 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1087 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1088 P->isNot(TT_ConditionalExpr);
1089 if ((!BreakBeforeOperator &&
1092 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1093 CurrentState.NoLineBreakInOperand =
true;
1098 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1103 CurrentState.LastSpace = State.
Column;
1104 CurrentState.NestedBlockIndent = State.
Column;
1105 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1107 Previous.isNot(TT_OverloadedOperator)) ||
1109 CurrentState.LastSpace = State.
Column;
1110 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1112 Style.BreakConstructorInitializers ==
1114 CurrentState.Indent = State.
Column;
1115 CurrentState.LastSpace = State.
Column;
1116 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1117 CurrentState.LastSpace = State.
Column;
1118 }
else if (
Previous.isOneOf(TT_BinaryOperator, TT_EnumEqual) &&
1126 CurrentState.LastSpace = State.
Column;
1127 }
else if (
Previous.is(TT_InheritanceColon)) {
1128 CurrentState.Indent = State.
Column;
1129 CurrentState.LastSpace = State.
Column;
1130 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1131 CurrentState.ColonPos = State.
Column;
1132 }
else if (
Previous.opensScope()) {
1140 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1141 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1142 CurrentState.LastSpace = State.
Column;
1148unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1151 assert(State.NextToken->Previous);
1153 auto &CurrentState = State.Stack.back();
1157 unsigned Penalty = 0;
1159 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1161 if (!NextNonComment)
1162 NextNonComment = &Current;
1165 if (!CurrentState.ContainsLineBreak)
1167 CurrentState.ContainsLineBreak =
true;
1169 Penalty += State.NextToken->SplitPenalty;
1174 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1175 (State.Column <= Style.ColumnLimit / 3 ||
1176 CurrentState.BreakBeforeParameter)) {
1177 Penalty += Style.PenaltyBreakFirstLessLess;
1180 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1181 State.Column = TotalColumn;
1195 if (State.Column > State.FirstIndent) {
1197 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1210 if (Current.isNot(TT_LambdaArrow) &&
1211 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1212 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1213 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1214 CurrentState.NestedBlockIndent = State.Column;
1217 if (NextNonComment->isMemberAccess()) {
1218 if (CurrentState.CallContinuation == 0)
1219 CurrentState.CallContinuation = State.Column;
1220 }
else if (NextNonComment->is(TT_SelectorName)) {
1221 if (!CurrentState.ObjCSelectorNameFound) {
1222 if (NextNonComment->LongestObjCSelectorName == 0) {
1223 CurrentState.AlignColons =
false;
1225 CurrentState.ColonPos =
1227 ? std::max(CurrentState.Indent.Total,
1228 State.FirstIndent + Style.ContinuationIndentWidth)
1229 : CurrentState.
Indent.Total) +
1233 }
else if (CurrentState.AlignColons &&
1234 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1235 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1237 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1238 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1248 if (State.Stack.size() > 1) {
1249 State.Stack[State.Stack.size() - 2].LastSpace =
1250 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1251 Style.ContinuationIndentWidth;
1255 switch (Style.BreakInheritanceList) {
1258 if (Current.is(TT_InheritanceColon) ||
Previous.is(TT_InheritanceComma)) {
1259 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1260 tok::kw_class, tok::kw_struct, tok::kw_union);
1264 if (Current.isOneOf(TT_InheritanceColon, TT_InheritanceComma)) {
1265 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1266 tok::kw_class, tok::kw_struct, tok::kw_union);
1270 if (
Previous.isOneOf(TT_InheritanceColon, TT_InheritanceComma))
1271 CurrentState.AlignedTo = &
Previous;
1275 if ((PreviousNonComment &&
1276 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1277 !CurrentState.AvoidBinPacking) ||
1279 CurrentState.BreakBeforeParameter =
false;
1281 if (PreviousNonComment &&
1282 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1283 PreviousNonComment->ClosesRequiresClause) &&
1284 Current.NestingLevel == 0) {
1285 CurrentState.BreakBeforeParameter =
false;
1287 if (NextNonComment->is(tok::question) ||
1288 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1289 CurrentState.BreakBeforeParameter =
true;
1291 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore) {
1292 CurrentState.BreakBeforeParameter =
false;
1293 CurrentState.AlignedTo = &Current;
1296 Current.is(TT_ConditionalExpr)) {
1297 switch (Style.AlignOperands) {
1299 CurrentState.AlignedTo = Current.is(tok::question)
1300 ? Current.getPrevious(tok::equal)
1301 : Current.getPrevious(tok::question);
1304 if (Current.is(tok::colon))
1305 CurrentState.AlignedTo = Current.getPrevious(tok::question);
1313 unsigned MaxEmptyLinesToKeep = Style.MaxEmptyLinesToKeep + 1;
1314 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1317 !Current.MatchingParen->Children.empty()) {
1322 if (!Style.KeepEmptyLines.AtEndOfBlock)
1323 MaxEmptyLinesToKeep = 1;
1326 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
1327 const bool ContinuePPDirective = State.Line->InPPDirective &&
1329 Current.isNot(TT_LineComment);
1330 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1331 CurrentState.AlignedTo, ContinuePPDirective,
1332 IndentedFromColumn);
1335 if (!Current.isTrailingComment())
1336 CurrentState.LastSpace = State.Column;
1337 if (Current.is(tok::lessless)) {
1341 CurrentState.LastSpace += 3;
1344 State.StartOfLineLevel = Current.NestingLevel;
1345 State.LowestLevelOnLine = Current.NestingLevel;
1349 bool NestedBlockSpecialCase =
1350 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1351 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1353 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1355 NestedBlockSpecialCase =
1356 NestedBlockSpecialCase ||
1357 (Current.MatchingParen &&
1358 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1359 if (!NestedBlockSpecialCase) {
1360 auto ParentLevelIt = std::next(State.Stack.rbegin());
1362 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1377 auto FindCurrentLevel = [&](
const auto &It) {
1378 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1379 return PState.Tok != nullptr;
1382 auto MaybeIncrement = [&](
const auto &It) {
1383 return It != State.Stack.rend() ? std::next(It) : It;
1385 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1386 auto LevelContainingLambdaIt =
1387 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1388 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1390 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1391 I->BreakBeforeParameter =
true;
1394 if (PreviousNonComment &&
1395 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1396 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1397 !PreviousNonComment->ClosesRequiresClause) ||
1398 Current.NestingLevel != 0) &&
1399 PreviousNonComment->isNoneOf(
1400 TT_BinaryOperator, TT_EnumEqual, TT_FunctionAnnotationRParen,
1401 TT_JavaAnnotation, TT_LeadingJavaAnnotation) &&
1402 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1405 (!Style.BraceWrapping.BeforeLambdaBody ||
1406 Current.isNot(TT_LambdaLBrace))) {
1407 CurrentState.BreakBeforeParameter =
true;
1412 if (PreviousNonComment &&
1413 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1415 CurrentState.BreakBeforeClosingBrace =
true;
1418 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1419 if (
auto Previous = PreviousNonComment->Previous) {
1421 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1422 }
else if (
Previous->isLoop(Style)) {
1423 CurrentState.BreakBeforeClosingParen =
1424 Style.BreakBeforeCloseBracketLoop;
1425 }
else if (
Previous->is(tok::kw_switch)) {
1426 CurrentState.BreakBeforeClosingParen =
1427 Style.BreakBeforeCloseBracketSwitch;
1429 CurrentState.BreakBeforeClosingParen =
1430 Style.BreakBeforeCloseBracketFunction;
1435 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1436 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1438 if (CurrentState.AvoidBinPacking) {
1443 bool PreviousIsBreakingCtorInitializerColon =
1444 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1446 bool AllowAllConstructorInitializersOnNextLine =
1449 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1450 !PreviousIsBreakingCtorInitializerColon) ||
1451 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1452 State.Line->MustBeDeclaration) ||
1453 (!Style.AllowAllArgumentsOnNextLine &&
1454 !State.Line->MustBeDeclaration) ||
1455 (!AllowAllConstructorInitializersOnNextLine &&
1456 PreviousIsBreakingCtorInitializerColon) ||
1458 CurrentState.BreakBeforeParameter =
true;
1464 if (PreviousIsBreakingCtorInitializerColon &&
1465 AllowAllConstructorInitializersOnNextLine) {
1466 CurrentState.BreakBeforeParameter =
false;
1471 CurrentState.BreakBeforeParameter =
true;
1477ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1478 if (!State.NextToken || !State.NextToken->Previous)
1482 const auto &CurrentState = State.Stack.back();
1484 if (CurrentState.IsCSharpGenericTypeConstraint &&
1485 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1486 return CurrentState.ColonPos + 2;
1491 const auto ContinuationIndent =
1492 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1493 CurrentState.Indent) +
1494 Style.ContinuationIndentWidth;
1495 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1497 if (!NextNonComment)
1498 NextNonComment = &Current;
1501 if (Style.isJava() &&
1502 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1503 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1504 CurrentState.Indent + Style.ContinuationIndentWidth);
1509 if (Style.isVerilog() && PreviousNonComment &&
1510 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1511 return State.FirstIndent;
1515 State.Line->First->is(tok::kw_enum)) {
1516 return IndentationAndAlignment(Style.IndentWidth *
1517 State.Line->First->IndentLevel) +
1521 if (Style.BraceWrapping.BeforeLambdaBody &&
1522 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1524 ? CurrentState.Indent
1525 : State.FirstIndent;
1526 return From + Style.IndentWidth;
1531 if (Style.BraceWrapping.AfterRequiresExpression &&
1532 Current.is(TT_RequiresExpressionLBrace)) {
1533 return CurrentState.NestedBlockIndent;
1536 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1537 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1538 if (Current.NestingLevel == 0 ||
1540 State.NextToken->is(TT_LambdaLBrace))) {
1541 return State.FirstIndent;
1543 return CurrentState.Indent;
1545 if (Current.is(TT_LambdaArrow) &&
1546 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1547 tok::kw_consteval, tok::kw_static,
1548 TT_AttributeRSquare)) {
1549 return ContinuationIndent;
1551 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1552 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1553 State.Stack.size() > 1) {
1554 if (Current.closesBlockOrBlockTypeList(Style))
1555 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1556 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit)) {
1566 if ((State.Stack.size() == 2 &&
1567 Current.MatchingParen->getPreviousNonComment() &&
1568 Current.MatchingParen->getPreviousNonComment()->is(
1570 (State.Stack.size() == 3 &&
1572 return State.FirstIndent;
1574 return State.Stack[State.Stack.size() - 2].LastSpace;
1576 return State.FirstIndent;
1593 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1595 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1596 return State.Stack[State.Stack.size() - 2].LastSpace;
1600 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1601 State.Stack.size() > 1) {
1602 return State.Stack[State.Stack.size() - 2].LastSpace;
1604 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1605 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1606 State.Stack.size() > 1) {
1607 return State.Stack[State.Stack.size() - 2].LastSpace;
1609 if ((Style.BreakBeforeCloseBracketFunction ||
1610 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1611 Style.BreakBeforeCloseBracketSwitch) &&
1612 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1613 return State.Stack[State.Stack.size() - 2].LastSpace;
1615 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1616 State.Stack.size() > 1) {
1617 return State.Stack[State.Stack.size() - 2].LastSpace;
1619 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1620 return State.Stack[State.Stack.size() - 2].LastSpace;
1628 if (Current.is(tok::identifier) && Current.Next &&
1629 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1630 (Current.Next->is(TT_DictLiteral) ||
1631 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1632 return CurrentState.Indent;
1634 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1635 State.StartOfStringLiteral != 0) {
1636 return State.StartOfStringLiteral - 1;
1638 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1639 return State.StartOfStringLiteral;
1640 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1641 return CurrentState.FirstLessLess;
1642 if (NextNonComment->isMemberAccess()) {
1643 if (CurrentState.CallContinuation == 0)
1644 return ContinuationIndent;
1645 return CurrentState.CallContinuation;
1647 if (CurrentState.QuestionColumn != 0 &&
1648 ((NextNonComment->is(tok::colon) &&
1649 NextNonComment->is(TT_ConditionalExpr)) ||
1650 Previous.is(TT_ConditionalExpr))) {
1651 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1652 !NextNonComment->Next->FakeLParens.empty() &&
1654 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1656 !CurrentState.IsWrappedConditional) {
1661 unsigned Indent = CurrentState.Indent.Total;
1663 Indent -= Style.ContinuationIndentWidth;
1664 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1668 return CurrentState.QuestionColumn;
1670 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1671 return CurrentState.VariablePos;
1672 if (Current.is(TT_RequiresClause)) {
1673 if (Style.IndentRequiresClause)
1674 return CurrentState.Indent + Style.IndentWidth;
1675 switch (Style.RequiresClausePosition) {
1679 return CurrentState.Indent;
1684 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1685 TT_InheritanceComma)) {
1686 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1688 if ((PreviousNonComment &&
1689 (PreviousNonComment->ClosesTemplateDeclaration ||
1690 PreviousNonComment->ClosesRequiresClause ||
1691 (PreviousNonComment->is(TT_AttributeMacro) &&
1692 Current.isNot(tok::l_paren) &&
1693 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1694 TT_PointerOrReference)) ||
1695 (PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1696 TT_FunctionAnnotationRParen,
1698 TT_LeadingJavaAnnotation) &&
1699 !Current.isBinaryOperator()))) ||
1700 (!Style.IndentWrappedFunctionNames &&
1701 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName)) ||
1702 (State.Line->ReturnTypeWrapped && PreviousNonComment &&
1704 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1705 CurrentState.Indent);
1707 if (NextNonComment->is(TT_SelectorName)) {
1708 if (!CurrentState.ObjCSelectorNameFound) {
1709 auto MinIndent = CurrentState.Indent;
1712 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1713 Style.ContinuationIndentWidth);
1724 return MinIndent.addPadding(
1725 std::max(NextNonComment->LongestObjCSelectorName,
1726 NextNonComment->ColumnWidth) -
1727 NextNonComment->ColumnWidth);
1729 if (!CurrentState.AlignColons)
1730 return CurrentState.Indent;
1731 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1732 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1733 return CurrentState.Indent;
1735 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1736 return CurrentState.ColonPos;
1737 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1738 if (CurrentState.StartOfArraySubscripts != 0) {
1739 return CurrentState.StartOfArraySubscripts;
1740 }
else if (Style.isCSharp()) {
1742 return CurrentState.Indent;
1744 return ContinuationIndent;
1749 if (State.Line->InPragmaDirective) {
1750 FormatToken *PragmaType = State.Line->First->Next->Next;
1751 if (PragmaType && PragmaType->TokenText ==
"omp")
1752 return CurrentState.Indent + Style.ContinuationIndentWidth;
1757 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1758 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1759 return CurrentState.Indent;
1762 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1763 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1764 return ContinuationIndent;
1766 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1767 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1768 return ContinuationIndent;
1770 if (NextNonComment->is(TT_CtorInitializerComma))
1771 return CurrentState.Indent;
1772 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1774 return CurrentState.Indent;
1776 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1778 return CurrentState.Indent;
1781 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1782 !Current.isBinaryOperator() &&
1783 Current.isNoneOf(tok::colon, tok::comment)) {
1784 return ContinuationIndent;
1786 if (Current.is(TT_ProtoExtensionLSquare))
1787 return CurrentState.Indent;
1788 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1789 return CurrentState.Indent - Current.Tok.getLength() -
1790 Current.SpacesRequiredBefore;
1792 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1793 CurrentState.UnindentOperator) {
1794 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1795 NextNonComment->SpacesRequiredBefore;
1797 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1798 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1801 return CurrentState.Indent + Style.ContinuationIndentWidth;
1803 return CurrentState.Indent;
1815 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1818unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1819 bool DryRun,
bool Newline) {
1820 assert(State.Stack.size());
1822 auto &CurrentState = State.Stack.back();
1824 if (Current.is(TT_CSharpGenericTypeConstraint))
1825 CurrentState.IsCSharpGenericTypeConstraint =
true;
1826 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1827 CurrentState.NoLineBreakInOperand =
false;
1828 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1829 CurrentState.AvoidBinPacking =
true;
1830 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1831 if (CurrentState.FirstLessLess == 0)
1832 CurrentState.FirstLessLess = State.Column;
1834 CurrentState.LastOperatorWrapped = Newline;
1836 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1837 CurrentState.LastOperatorWrapped = Newline;
1838 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1839 Current.Previous->isNot(TT_ConditionalExpr)) {
1840 CurrentState.LastOperatorWrapped = Newline;
1842 if (Current.is(TT_ArraySubscriptLSquare) &&
1843 CurrentState.StartOfArraySubscripts == 0) {
1844 CurrentState.StartOfArraySubscripts = State.Column;
1848 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1850 if (
Tok.MustBreakBefore)
1854 return Next &&
Next->MustBreakBefore;
1856 if (IsWrappedConditional(Current))
1857 CurrentState.IsWrappedConditional =
true;
1858 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1859 CurrentState.QuestionColumn = State.Column;
1860 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1865 CurrentState.QuestionColumn = State.Column;
1867 if (!Current.opensScope() && !Current.closesScope() &&
1868 Current.isNot(TT_PointerOrReference)) {
1869 State.LowestLevelOnLine =
1870 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1872 if (Current.isMemberAccess())
1873 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1874 if (Current.is(TT_SelectorName))
1875 CurrentState.ObjCSelectorNameFound =
true;
1876 if (Current.is(TT_CtorInitializerColon) &&
1883 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1887 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1889 CurrentState.AvoidBinPacking =
true;
1890 CurrentState.BreakBeforeParameter =
1891 Style.ColumnLimit > 0 &&
1895 CurrentState.BreakBeforeParameter =
false;
1898 if (Current.is(TT_CtorInitializerColon) &&
1900 CurrentState.Indent =
1901 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1902 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1904 CurrentState.AvoidBinPacking =
true;
1906 CurrentState.BreakBeforeParameter =
false;
1908 if (Current.is(TT_InheritanceColon)) {
1909 CurrentState.Indent =
1910 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1912 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1913 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1914 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1915 CurrentState.LastSpace = State.Column;
1916 if (Current.is(TT_RequiresExpression) &&
1918 CurrentState.NestedBlockIndent = State.Column;
1930 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1932 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1933 !CurrentState.HasMultipleNestedBlocks) {
1934 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1935 for (ParenState &PState : llvm::drop_end(State.Stack))
1936 PState.NoLineBreak =
true;
1937 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1939 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1940 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1941 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1942 TT_CtorInitializerColon)))) {
1943 CurrentState.NestedBlockInlined =
1947 moveStatePastFakeLParens(State, Newline);
1948 moveStatePastScopeCloser(State);
1951 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1952 !State.Stack.back().NoLineBreakInOperand;
1953 moveStatePastScopeOpener(State, Newline);
1954 moveStatePastFakeRParens(State);
1956 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1957 State.StartOfStringLiteral = State.Column + 1;
1958 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1959 State.StartOfStringLiteral = State.Column + 1;
1960 }
else if (Current.is(TT_TableGenMultiLineString) &&
1961 State.StartOfStringLiteral == 0) {
1962 State.StartOfStringLiteral = State.Column + 1;
1963 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1964 State.StartOfStringLiteral = State.Column;
1965 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1966 !Current.isStringLiteral()) {
1967 State.StartOfStringLiteral = 0;
1970 State.Column += Current.ColumnWidth;
1971 State.NextToken = State.NextToken->Next;
1976 if (Style.isVerilog() && State.NextToken &&
1977 State.NextToken->MustBreakBefore &&
1978 Keywords.isVerilogEndOfLabel(Current)) {
1979 State.FirstIndent += Style.IndentWidth;
1980 CurrentState.Indent = State.FirstIndent;
1984 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1987 Current.Role->formatFromToken(State,
this, DryRun);
1994 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1999void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
2002 if (Current.FakeLParens.empty())
2010 bool SkipFirstExtraIndent =
2013 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
2017 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
2018 const auto &CurrentState = State.Stack.back();
2019 ParenState NewParenState = CurrentState;
2020 NewParenState.Tok =
nullptr;
2021 NewParenState.ContainsLineBreak =
false;
2022 NewParenState.LastOperatorWrapped =
true;
2023 NewParenState.IsChainedConditional =
false;
2024 NewParenState.IsWrappedConditional =
false;
2025 NewParenState.UnindentOperator =
false;
2026 NewParenState.NoLineBreak =
2027 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
2028 NewParenState.Precedence = PrecedenceLevel;
2032 NewParenState.AvoidBinPacking =
false;
2037 if (!Current.isTrailingComment() &&
2041 (!Style.isJava() && PrecedenceLevel > 0)) &&
2042 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
2043 Current.NestingLevel == 0) &&
2044 (!Style.isTableGen() ||
2046 TT_TableGenDAGArgListCommaToBreak)))) {
2047 NewParenState.Indent =
2048 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
2049 IndentationAndAlignment(CurrentState.LastSpace)});
2056 State.Stack.size() > 1) {
2057 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
2058 Style.ContinuationIndentWidth;
2069 NewParenState.UnindentOperator =
true;
2072 NewParenState.AlignedTo =
Previous;
2082 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2084 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2085 NewParenState.StartOfFunctionCall = State.Column;
2095 &PrecedenceLevel == &Current.FakeLParens.back() &&
2096 !CurrentState.IsWrappedConditional) {
2097 NewParenState.IsChainedConditional =
true;
2098 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2101 !Current.isTrailingComment())) {
2102 NewParenState.Indent += Style.ContinuationIndentWidth;
2105 NewParenState.BreakBeforeParameter =
false;
2106 State.Stack.push_back(NewParenState);
2107 SkipFirstExtraIndent =
false;
2111void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2112 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2113 unsigned VariablePos = State.Stack.back().VariablePos;
2114 if (State.Stack.size() == 1) {
2118 State.Stack.pop_back();
2119 State.Stack.back().VariablePos = VariablePos;
2122 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2125 State.Stack.back().LastSpace -= Style.IndentWidth;
2129void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2132 if (!Current.opensScope())
2135 const auto &CurrentState = State.Stack.back();
2138 if (Current.isOneOf(tok::less, tok::l_paren) &&
2139 CurrentState.IsCSharpGenericTypeConstraint) {
2143 if (Current.MatchingParen && Current.is(
BK_Block)) {
2144 moveStateToNewBlock(State, Newline);
2151 const auto *Prev =
Tok->getPreviousNonComment();
2154 return Prev->is(tok::comma);
2155 }(Current.MatchingParen);
2157 IndentationAndAlignment NewIndent = 0;
2158 unsigned LastSpace = CurrentState.LastSpace;
2159 bool AvoidBinPacking;
2160 bool BreakBeforeParameter =
false;
2161 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2162 CurrentState.NestedBlockIndent);
2163 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2165 if (Current.opensBlockOrBlockTypeList(Style)) {
2166 NewIndent = Style.IndentWidth +
2167 std::min(State.Column, CurrentState.NestedBlockIndent);
2168 }
else if (Current.is(tok::l_brace)) {
2169 const auto Width = Style.BracedInitializerIndentWidth;
2170 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2171 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2173 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2175 const FormatToken *NextNonComment = Current.getNextNonComment();
2177 EndsInComma || Current.is(TT_DictLiteral) || Style.isProto() ||
2180 NextNonComment->isOneOf(TT_DesignatedInitializerPeriod,
2181 TT_DesignatedInitializerLSquare));
2182 BreakBeforeParameter = EndsInComma;
2183 if (Current.ParameterCount > 1)
2184 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2186 NewIndent = IndentationAndAlignment(std::max(
2187 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2188 Style.ContinuationIndentWidth;
2190 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2197 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2198 NewIndent = State.Column +
Next->TokenText.size() + 2;
2205 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2206 NewIndent = std::max(NewIndent, CurrentState.Indent);
2207 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2212 bool ObjCBinPackProtocolList =
2218 bool BinPackDeclaration =
2222 (State.Line->Type ==
LT_ObjCDecl && ObjCBinPackProtocolList);
2224 bool GenericSelection =
2225 Current.getPreviousNonComment() &&
2226 Current.getPreviousNonComment()->is(tok::kw__Generic);
2229 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2230 (Style.isJavaScript() && EndsInComma) ||
2231 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2232 (!State.Line->MustBeDeclaration &&
2234 (Style.ExperimentalAutoDetectBinPacking &&
2238 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2239 Style.ObjCBreakBeforeNestedBlockParam) {
2240 if (Style.ColumnLimit) {
2245 BreakBeforeParameter =
true;
2251 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2252 if (
Tok->MustBreakBefore ||
2253 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2254 BreakBeforeParameter =
true;
2261 if (Style.isJavaScript() && EndsInComma)
2262 BreakBeforeParameter =
true;
2268 Current.Children.empty() &&
2269 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2270 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2271 (Current.is(TT_TemplateOpener) &&
2272 CurrentState.ContainsUnwrappedBuilder));
2273 State.Stack.push_back(
2274 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2275 auto &NewState = State.Stack.back();
2276 NewState.NestedBlockIndent = NestedBlockIndent;
2277 NewState.BreakBeforeParameter = BreakBeforeParameter;
2278 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2280 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2281 Current.is(tok::l_paren)) {
2285 if (next->is(TT_LambdaLSquare)) {
2286 NewState.HasMultipleNestedBlocks =
true;
2293 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2295 Current.Previous->is(tok::at);
2298void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2300 if (!Current.closesScope())
2305 if (State.Stack.size() > 1 &&
2306 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2307 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2308 State.NextToken->is(TT_TemplateCloser) ||
2309 State.NextToken->is(TT_TableGenListCloser) ||
2310 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2311 State.Stack.pop_back();
2314 auto &CurrentState = State.Stack.back();
2326 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2327 Current.MatchingParen->Previous) {
2328 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2329 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2330 CurrentScopeOpener.MatchingParen) {
2331 int NecessarySpaceInLine =
2333 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2334 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2335 Style.ColumnLimit) {
2336 CurrentState.BreakBeforeParameter =
false;
2341 if (Current.is(tok::r_square)) {
2343 const FormatToken *NextNonComment = Current.getNextNonComment();
2344 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2345 CurrentState.StartOfArraySubscripts = 0;
2349void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2351 State.NextToken->is(TT_LambdaLBrace) &&
2352 !State.Line->MightBeFunctionDecl) {
2353 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2354 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2356 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2358 unsigned NewIndent =
2359 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2360 ? Style.ObjCBlockIndentWidth
2361 : Style.IndentWidth);
2368 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2369 State.NextToken->is(TT_LambdaLBrace);
2371 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2372 State.Stack.back().LastSpace,
2373 true, NoLineBreak));
2374 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2375 State.Stack.back().BreakBeforeParameter =
true;
2381 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2382 if (LastNewlinePos == StringRef::npos) {
2383 return StartColumn +
2387 0, TabWidth, Encoding);
2391unsigned ContinuationIndenter::reformatRawStringLiteral(
2393 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2394 unsigned StartColumn = State.Column - Current.ColumnWidth;
2396 StringRef NewDelimiter =
2398 if (NewDelimiter.empty())
2399 NewDelimiter = OldDelimiter;
2402 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2403 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2406 std::string RawText = std::string(
2407 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2408 if (NewDelimiter != OldDelimiter) {
2411 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2412 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2413 NewDelimiter = OldDelimiter;
2416 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2417 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2420 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2431 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2453 unsigned CurrentIndent =
2454 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2455 ? State.Stack.back().NestedBlockIndent
2456 : State.Stack.back().Indent.Total;
2457 unsigned NextStartColumn = ContentStartsOnNewline
2458 ? CurrentIndent + Style.IndentWidth
2469 unsigned LastStartColumn =
2470 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2473 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2474 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2479 return addMultilineToken(Current, State);
2481 if (NewDelimiter != OldDelimiter) {
2484 SourceLocation PrefixDelimiterStart =
2485 Current.Tok.getLocation().getLocWithOffset(2);
2486 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2487 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2490 <<
"Failed to update the prefix delimiter of a raw string: "
2491 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2495 SourceLocation SuffixDelimiterStart =
2496 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2497 1 - OldDelimiter.size());
2498 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2499 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2502 <<
"Failed to update the suffix delimiter of a raw string: "
2503 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2506 SourceLocation OriginLoc =
2507 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2508 for (
const tooling::Replacement &Fix : Fixes.first) {
2509 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2510 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2511 Fix.getLength(), Fix.getReplacementText()));
2513 llvm::errs() <<
"Failed to reformat raw string: "
2514 << llvm::toString(std::move(Err)) <<
"\n";
2519 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2520 State.Column = RawLastLineEndColumn + NewSuffixSize;
2524 unsigned PrefixExcessCharacters =
2525 StartColumn + NewPrefixSize > Style.ColumnLimit
2526 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2529 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2532 for (ParenState &
Paren : State.Stack)
2533 Paren.BreakBeforeParameter =
true;
2535 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2538unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2541 for (ParenState &
Paren : State.Stack)
2542 Paren.BreakBeforeParameter =
true;
2544 unsigned ColumnsUsed = State.Column;
2547 State.Column = Current.LastLineColumnWidth;
2550 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2554unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2556 bool AllowBreak,
bool Newline) {
2557 unsigned Penalty = 0;
2560 auto RawStringStyle = getRawStringStyle(Current, State);
2561 if (RawStringStyle && !Current.Finalized &&
2562 (!Current.MacroCtx || Current.MacroCtx->Role !=
MR_ExpandedArg)) {
2563 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2565 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2568 Penalty = addMultilineToken(Current, State);
2571 LineState OriginalState = State;
2575 bool Strict =
false;
2578 bool Exceeded =
false;
2579 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2580 Current, State, AllowBreak,
true, Strict);
2584 LineState StrictState = OriginalState;
2585 unsigned StrictPenalty =
2586 breakProtrudingToken(Current, StrictState, AllowBreak,
2589 Strict = StrictPenalty <= Penalty;
2591 Penalty = StrictPenalty;
2592 State = std::move(StrictState);
2598 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2603 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2604 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2613 auto Tok = Current.getPreviousNonComment();
2614 if (!
Tok ||
Tok->isNot(tok::l_paren))
2616 Tok =
Tok->getPreviousNonComment();
2619 if (
Tok->is(TT_TemplateCloser)) {
2620 Tok =
Tok->MatchingParen;
2622 Tok =
Tok->getPreviousNonComment();
2624 if (!
Tok ||
Tok->isNot(tok::identifier))
2626 return Tok->TokenText;
2629std::optional<FormatStyle>
2630ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2631 const LineState &State) {
2632 if (!Current.isStringLiteral())
2633 return std::nullopt;
2636 return std::nullopt;
2638 if (!RawStringStyle && Delimiter->empty()) {
2642 if (!RawStringStyle)
2643 return std::nullopt;
2645 return RawStringStyle;
2648std::unique_ptr<BreakableToken>
2649ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2651 unsigned StartColumn = State.Column - Current.ColumnWidth;
2652 if (Current.isStringLiteral()) {
2655 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2669 if (Current.IsUnterminatedLiteral)
2673 if (State.Stack.back().IsInsideObjCArrayLiteral)
2680 if (Style.isVerilog() && Current.Previous &&
2681 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2684 StringRef
Text = Current.TokenText;
2694 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2697 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2698 Text.ends_with(
"'")) {
2700 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2701 Text.ends_with(
"\"")) {
2703 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2708 return std::make_unique<BreakableStringLiteralUsingOperators>(
2709 Current, QuoteStyle,
2720 if ((
Text.ends_with(Postfix =
"\"") &&
2721 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2722 Text.starts_with(Prefix =
"u\"") ||
2723 Text.starts_with(Prefix =
"U\"") ||
2724 Text.starts_with(Prefix =
"u8\"") ||
2725 Text.starts_with(Prefix =
"L\""))) ||
2726 (
Text.starts_with(Prefix =
"_T(\"") &&
2727 Text.ends_with(Postfix =
"\")"))) {
2728 return std::make_unique<BreakableStringLiteral>(
2730 State.Line->InPPDirective, Encoding, Style);
2732 }
else if (Current.is(TT_BlockComment)) {
2740 return std::make_unique<BreakableBlockComment>(
2741 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2742 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2743 }
else if (Current.is(TT_LineComment) &&
2744 (!Current.Previous ||
2745 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2746 bool RegularComments = [&]() {
2747 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2749 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2755 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2759 return std::make_unique<BreakableLineCommentSection>(
2760 Current, StartColumn,
false, Encoding, Style);
2765std::pair<unsigned, bool>
2766ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2768 bool DryRun,
bool Strict) {
2769 std::unique_ptr<const BreakableToken> Token =
2770 createBreakableToken(Current, State, AllowBreak);
2773 assert(Token->getLineCount() > 0);
2775 if (Current.is(TT_LineComment)) {
2777 ColumnLimit = Style.ColumnLimit;
2779 if (ColumnLimit == 0) {
2782 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2784 if (Current.UnbreakableTailLength >= ColumnLimit)
2788 unsigned StartColumn = State.Column - Current.ColumnWidth;
2789 unsigned NewBreakPenalty = Current.isStringLiteral()
2790 ? Style.PenaltyBreakString
2791 : Style.PenaltyBreakComment;
2794 bool Exceeded =
false;
2796 bool BreakInserted = Token->introducesBreakBeforeToken();
2799 bool NewBreakBefore =
false;
2803 bool Reflow =
false;
2806 unsigned TailOffset = 0;
2808 unsigned ContentStartColumn =
2809 Token->getContentStartColumn(0,
false);
2811 unsigned RemainingTokenColumns =
2812 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2815 Token->adaptStartOfLine(0, Whitespaces);
2817 unsigned ContentIndent = 0;
2818 unsigned Penalty = 0;
2819 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2820 << StartColumn <<
".\n");
2821 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2822 LineIndex != EndIndex; ++LineIndex) {
2823 LLVM_DEBUG(llvm::dbgs()
2824 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2825 NewBreakBefore =
false;
2829 bool TryReflow = Reflow;
2831 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2832 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2833 << (ContentStartColumn + RemainingTokenColumns)
2834 <<
", space: " << ColumnLimit
2835 <<
", reflown prefix: " << ContentStartColumn
2836 <<
", offset in line: " << TailOffset <<
"\n");
2842 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2843 ContentStartColumn, CommentPragmasRegex);
2844 if (
Split.first == StringRef::npos) {
2847 if (LineIndex < EndIndex - 1) {
2850 Penalty += Style.PenaltyExcessCharacter *
2851 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2853 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2856 assert(
Split.first != 0);
2858 if (Token->supportsReflow()) {
2878 unsigned ToSplitColumns = Token->getRangeLength(
2879 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2880 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2883 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2884 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2887 unsigned ToNextSplitColumns = 0;
2888 if (NextSplit.first == StringRef::npos) {
2889 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2890 ContentStartColumn);
2892 ToNextSplitColumns = Token->getRangeLength(
2893 LineIndex, TailOffset,
2894 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2898 ToNextSplitColumns =
2899 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2900 LLVM_DEBUG(llvm::dbgs()
2901 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2902 LLVM_DEBUG(llvm::dbgs()
2903 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2906 bool ContinueOnLine =
2907 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2908 unsigned ExcessCharactersPenalty = 0;
2909 if (!ContinueOnLine && !Strict) {
2912 ExcessCharactersPenalty =
2913 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2914 Style.PenaltyExcessCharacter;
2915 LLVM_DEBUG(llvm::dbgs()
2916 <<
" Penalty excess: " << ExcessCharactersPenalty
2917 <<
"\n break : " << NewBreakPenalty <<
"\n");
2918 if (ExcessCharactersPenalty < NewBreakPenalty) {
2920 ContinueOnLine =
true;
2923 if (ContinueOnLine) {
2924 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2929 Token->compressWhitespace(LineIndex, TailOffset, Split,
2933 ContentStartColumn += ToSplitColumns + 1;
2934 Penalty += ExcessCharactersPenalty;
2936 RemainingTokenColumns = Token->getRemainingLength(
2937 LineIndex, TailOffset, ContentStartColumn);
2941 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2946 ContentIndent = Token->getContentIndent(LineIndex);
2947 LLVM_DEBUG(llvm::dbgs()
2948 <<
" ContentIndent: " << ContentIndent <<
"\n");
2949 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2952 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2953 LineIndex, TailOffset +
Split.first +
Split.second,
2954 ContentStartColumn);
2955 if (NewRemainingTokenColumns == 0) {
2958 ContentStartColumn =
2959 Token->getContentStartColumn(LineIndex,
true);
2960 NewRemainingTokenColumns = Token->getRemainingLength(
2961 LineIndex, TailOffset +
Split.first +
Split.second,
2962 ContentStartColumn);
2968 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2973 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2974 <<
", " <<
Split.second <<
"\n");
2976 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2980 Penalty += NewBreakPenalty;
2982 RemainingTokenColumns = NewRemainingTokenColumns;
2983 BreakInserted =
true;
2984 NewBreakBefore =
true;
2988 if (LineIndex + 1 != EndIndex) {
2989 unsigned NextLineIndex = LineIndex + 1;
2990 if (NewBreakBefore) {
3009 ContentStartColumn += RemainingTokenColumns + 1;
3014 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
3015 LLVM_DEBUG(llvm::dbgs()
3016 <<
" Size of reflown text: " << ContentStartColumn
3017 <<
"\n Potential reflow split: ");
3018 if (SplitBeforeNext.first != StringRef::npos) {
3019 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
3020 << SplitBeforeNext.second <<
"\n");
3021 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
3024 RemainingTokenColumns = Token->getRemainingLength(
3025 NextLineIndex, TailOffset, ContentStartColumn);
3027 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
3028 LLVM_DEBUG(llvm::dbgs()
3029 <<
" Over limit after reflow, need: "
3030 << (ContentStartColumn + RemainingTokenColumns)
3031 <<
", space: " << ColumnLimit
3032 <<
", reflown prefix: " << ContentStartColumn
3033 <<
", offset in line: " << TailOffset <<
"\n");
3039 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
3040 ContentStartColumn, CommentPragmasRegex);
3041 if (
Split.first == StringRef::npos) {
3042 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
3048 unsigned ToSplitColumns = Token->getRangeLength(
3049 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
3050 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
3051 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
3052 << (ContentStartColumn + ToSplitColumns)
3053 <<
", space: " << ColumnLimit);
3054 unsigned ExcessCharactersPenalty =
3055 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
3056 Style.PenaltyExcessCharacter;
3057 if (NewBreakPenalty < ExcessCharactersPenalty)
3063 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
3071 ContentStartColumn =
3072 Token->getContentStartColumn(NextLineIndex,
false);
3073 RemainingTokenColumns = Token->getRemainingLength(
3074 NextLineIndex, TailOffset, ContentStartColumn);
3077 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3092 if (NewBreakBefore) {
3093 assert(Penalty >= NewBreakPenalty);
3094 Penalty -= NewBreakPenalty;
3097 Token->reflow(NextLineIndex, Whitespaces);
3103 Token->getSplitAfterLastLine(TailOffset);
3104 if (SplitAfterLastLine.first != StringRef::npos) {
3105 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3109 Penalty += Style.PenaltyExcessCharacter *
3110 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3113 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3116 ContentStartColumn =
3117 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3118 RemainingTokenColumns = Token->getRemainingLength(
3119 Token->getLineCount() - 1,
3120 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3121 ContentStartColumn);
3124 State.Column = ContentStartColumn + RemainingTokenColumns -
3125 Current.UnbreakableTailLength;
3127 if (BreakInserted) {
3129 Token->updateAfterBroken(Whitespaces);
3134 if (Current.isNot(TT_LineComment))
3135 for (ParenState &
Paren : State.Stack)
3136 Paren.BreakBeforeParameter =
true;
3138 if (Current.is(TT_BlockComment))
3139 State.NoContinuation =
true;
3141 State.Stack.back().LastSpace = StartColumn;
3144 Token->updateNextToken(State);
3146 return {Penalty, Exceeded};
3151 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3154bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3156 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3161 if (Current.
TokenText.starts_with(
"R\""))
3165 if (Current.getNextNonComment() &&
3166 Current.getNextNonComment()->isStringLiteral()) {
3169 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3171 Style.ColumnLimit) {
Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...
This file implements an indenter that manages the indentation of continuations.
Defines and computes precedence levels for binary/ternary operators.
static bool contains(const std::set< tok::TokenKind > &Terminators, const Token &Tok)
Defines the SourceManager interface.
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.
SourceLocation getEnd() const
SourceLocation getBegin() 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)) {....
tok::TokenKind getKind() const
Top level wrappers for InstallAPI frontend operations.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Language
The language for the input, used to select and validate the language standard and possible actions.
const FunctionProtoType * T
bool isReturnTypePrefixSpecifier(const FormatToken &Tok)
Encapsulates keywords that are context sensitive or for languages not properly supported by Clang's l...