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.BeforeLambdaBody && Current.
CanBreakBefore &&
479 Current.
is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
483 if (Style.BraceWrapping.AfterRequiresExpression && Current.
CanBreakBefore &&
484 Current.
is(TT_RequiresExpressionLBrace) &&
489 (Current.
is(TT_InlineASMColon) &&
492 Style.ColumnLimit > 0)))) {
495 if (CurrentState.BreakBeforeClosingBrace &&
496 (Current.closesBlockOrBlockTypeList(Style) ||
498 Current.isBlockIndentedInitRBrace(Style)))) {
501 if (CurrentState.BreakBeforeClosingParen && Current.
is(tok::r_paren))
503 if (CurrentState.BreakBeforeClosingAngle && Current.
is(TT_TemplateCloser))
506 Style.ObjCBreakBeforeNestedBlockParam &&
508 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
513 if (CurrentState.IsCSharpGenericTypeConstraint &&
514 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
518 (
Previous.is(TT_TemplateCloser) && Current.
is(TT_StartOfName) &&
519 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
527 (Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
529 (!Style.BreakBeforeTernaryOperators &&
530 Previous.is(TT_ConditionalExpr))) &&
531 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
532 Current.
isNoneOf(tok::r_paren, tok::r_brace)) {
535 if (CurrentState.IsChainedConditional &&
536 ((Style.BreakBeforeTernaryOperators && Current.
is(TT_ConditionalExpr) &&
537 Current.
is(tok::colon)) ||
538 (!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr) &&
543 (
Previous.is(TT_ArrayInitializerLSquare) &&
546 Style.ColumnLimit > 0 &&
552 const FormatToken &BreakConstructorInitializersToken =
557 BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
558 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
560 CurrentState.BreakBeforeParameter) &&
561 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||
566 if (Current.
is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
567 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
570 if (Current.
is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
571 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
572 (Style.ObjCBreakBeforeNestedBlockParam ||
573 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
577 unsigned NewLineColumn = getNewLineColumn(State).Total;
578 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
580 (State.Column > NewLineColumn ||
586 (CurrentState.CallContinuation != 0 ||
587 CurrentState.BreakBeforeParameter) &&
593 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&
594 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
600 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
605 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
608 if (Style.AlwaysBreakBeforeMultilineStrings &&
609 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
611 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
612 Keywords.kw_dollar) &&
613 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
614 nextIsMultilineString(State)) {
622 const auto PreviousPrecedence =
Previous.getPrecedence();
624 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
625 const bool LHSIsBinaryExpr =
638 const bool IsComparison =
643 Previous.Previous->isNot(TT_BinaryOperator);
649 CurrentState.BreakBeforeParameter) {
654 if (Current.
is(tok::lessless) && Current.
isNot(TT_OverloadedOperator) &&
655 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
659 if (Current.
NestingLevel == 0 && !Current.isTrailingComment()) {
664 if (
Previous.ClosesTemplateDeclaration) {
665 if (Current.
is(tok::kw_concept)) {
666 switch (Style.BreakBeforeConceptDeclarations) {
675 if (Current.
is(TT_RequiresClause)) {
676 switch (Style.RequiresClausePosition) {
688 if (
Previous.is(TT_FunctionAnnotationRParen) &&
692 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.
isNot(tok::l_paren) &&
693 Current.
isNot(TT_LeadingJavaAnnotation)) {
698 if (Style.isJavaScript() &&
Previous.is(tok::r_paren) &&
702 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
704 if (BreakBeforeDecoratedTokens.contains(Current.
TokenText))
708 if (Current.
is(TT_FunctionDeclarationName) &&
709 !State.Line->ReturnTypeWrapped &&
711 (!Style.isCSharp() ||
715 !Style.isJavaScript() &&
Previous.isNot(tok::kw_template) &&
716 CurrentState.BreakBeforeParameter) {
718 if (
Tok->is(TT_LineComment))
720 if (
Tok->is(TT_TemplateCloser)) {
725 if (
Tok->FirstAfterPPLine)
737 Current.
isNoneOf(tok::r_brace, tok::comment)) {
741 if (Current.
is(tok::lessless) &&
744 Previous.TokenText ==
"\'\\n\'")))) {
751 if (State.NoContinuation)
759 unsigned ExtraSpaces) {
761 assert(State.NextToken->Previous);
764 assert(!State.Stack.empty());
765 State.NoContinuation =
false;
767 if (Current.
is(TT_ImplicitStringLiteral) &&
768 (!
Previous.Tok.getIdentifierInfo() ||
769 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
770 tok::pp_not_keyword)) {
776 State.Column = EndColumn;
778 unsigned StartColumn =
780 assert(EndColumn >= StartColumn);
781 State.Column += EndColumn - StartColumn;
783 moveStateToNextToken(State, DryRun,
false);
787 unsigned Penalty = 0;
789 Penalty = addTokenOnNewLine(State, DryRun);
791 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
793 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
796void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
797 unsigned ExtraSpaces) {
799 assert(State.NextToken->Previous);
801 auto &CurrentState = State.Stack.back();
808 auto DisallowLineBreaks = [&] {
809 if (!Style.isCpp() ||
818 if (Current.
isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
821 const auto *Prev = Current.getPreviousNonComment();
822 if (!Prev || Prev->isNot(tok::l_paren))
825 if (Prev->BlockParameterCount == 0)
829 if (Prev->BlockParameterCount > 1)
836 const auto *Comma = Prev->
Role->lastComma();
840 const auto *
Next = Comma->getNextNonComment();
841 return Next &&
Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
844 if (DisallowLineBreaks())
845 State.NoLineBreak =
true;
847 if (Current.
is(tok::equal) &&
848 (State.Line->First->is(tok::kw_for) || Current.
NestingLevel == 0) &&
849 CurrentState.VariablePos == 0 &&
851 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
852 CurrentState.VariablePos = State.Column;
855 while (
Tok && CurrentState.VariablePos >=
Tok->ColumnWidth) {
856 CurrentState.VariablePos -=
Tok->ColumnWidth;
857 if (
Tok->SpacesRequiredBefore != 0)
861 if (
Previous.PartOfMultiVariableDeclStmt)
862 CurrentState.LastSpace = CurrentState.VariablePos;
868 int PPColumnCorrection = 0;
880 PPColumnCorrection = -1;
887 const bool ContinuePPDirective =
889 Whitespaces.replaceWhitespace(Current, 0, Spaces,
890 State.
Column + Spaces + PPColumnCorrection,
891 nullptr, ContinuePPDirective);
897 Current.
is(TT_InheritanceColon)) {
898 CurrentState.NoLineBreak =
true;
902 CurrentState.NoLineBreak =
true;
905 if (Current.
is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
907 std::max(State.
FirstIndent + Style.ContinuationIndentWidth,
908 CurrentState.Indent.Total);
911 CurrentState.AlignColons =
false;
915 CurrentState.ColonPos = FirstColonPos;
923 auto IsStartOfBracedList = [&]() {
927 if (IsStartOfBracedList())
928 return Style.BreakAfterOpenBracketBracedList;
929 if (
Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))
933 if (
Tok.Previous->isIf())
934 return Style.BreakAfterOpenBracketIf;
935 if (
Tok.Previous->isLoop(Style))
936 return Style.BreakAfterOpenBracketLoop;
937 if (
Tok.Previous->is(tok::kw_switch))
938 return Style.BreakAfterOpenBracketSwitch;
939 if (Style.BreakAfterOpenBracketFunction) {
940 return !
Tok.Previous->is(TT_CastRParen) &&
941 !(Style.isJavaScript() &&
Tok.is(Keywords.kw_await));
946 return Tok.is(tok::l_paren) &&
Tok.ParameterCount > 0 &&
Tok.Previous &&
947 Tok.Previous->is(tok::identifier);
949 auto IsInTemplateString = [
this](
const FormatToken &
Tok,
bool NestBlocks) {
950 if (!Style.isJavaScript())
952 for (
const auto *Prev = &
Tok; Prev; Prev = Prev->Previous) {
953 if (Prev->is(TT_TemplateString) && Prev->opensScope())
955 if (Prev->opensScope() && !NestBlocks)
957 if (Prev->is(TT_TemplateString) && Prev->closesScope())
963 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
964 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
966 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
973 if (
Tok.is(tok::kw_new) ||
Tok.startsSequence(tok::coloncolon, tok::kw_new))
975 if (
Tok.is(TT_UnaryOperator) ||
976 (Style.isJavaScript() &&
977 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
980 const auto *
Previous = TokAfterLParen.Previous;
984 Previous->Previous->is(tok::kw_switch))) {
987 if (
Previous->isNoneOf(TT_FunctionDeclarationLParen,
988 TT_LambdaDefinitionLParen) &&
992 if (IsOpeningBracket(
Tok) || IsInTemplateString(
Tok,
true))
995 return !
Next ||
Next->isMemberAccess() ||
996 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*
Next);
999 State.
Column > getNewLineColumn(State).Total &&
1010 !StartsSimpleOneArgList(Current)) {
1011 CurrentState.NoLineBreak =
true;
1015 CurrentState.NoLineBreak =
true;
1021 if (Style.AlignAfterOpenBracket &&
1022 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
1023 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
1024 TT_TableGenDAGArgOpener,
1025 TT_TableGenDAGArgOpenerToBreak) &&
1027 (Current.
isNot(TT_LineComment) ||
1030 Previous.is(TT_VerilogMultiLineListLParen)) &&
1031 !IsInTemplateString(Current,
false)) {
1032 CurrentState.Indent = State.
Column + Spaces;
1033 CurrentState.AlignedTo = &
Previous;
1036 CurrentState.NoLineBreak =
true;
1038 CurrentState.NoLineBreak =
true;
1041 State.
Column > getNewLineColumn(State).Total) {
1042 CurrentState.ContainsUnwrappedBuilder =
true;
1045 if (Current.
is(TT_LambdaArrow) && Style.isJava())
1046 CurrentState.NoLineBreak =
true;
1047 if (Current.isMemberAccess() &&
Previous.
is(tok::r_paren) &&
1056 CurrentState.NoLineBreak =
true;
1063 const FormatToken *P = Current.getPreviousNonComment();
1064 if (Current.
isNot(tok::comment) && P &&
1065 (P->isOneOf(TT_BinaryOperator, tok::comma) ||
1066 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
1067 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
1071 bool BreakBeforeOperator =
1072 P->MustBreakBefore || P->is(tok::lessless) ||
1073 (P->is(TT_BinaryOperator) &&
1075 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
1079 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&
1080 P->isNot(TT_ConditionalExpr);
1081 if ((!BreakBeforeOperator &&
1084 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
1085 CurrentState.NoLineBreakInOperand =
true;
1090 if (Current.
isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
1095 CurrentState.LastSpace = State.
Column;
1096 CurrentState.NestedBlockIndent = State.
Column;
1097 }
else if (Current.
isNoneOf(tok::comment, tok::caret) &&
1099 Previous.isNot(TT_OverloadedOperator)) ||
1101 CurrentState.LastSpace = State.
Column;
1102 }
else if (
Previous.is(TT_CtorInitializerColon) &&
1104 Style.BreakConstructorInitializers ==
1106 CurrentState.Indent = State.
Column;
1107 CurrentState.LastSpace = State.
Column;
1108 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1109 CurrentState.LastSpace = State.
Column;
1110 }
else if (
Previous.is(TT_BinaryOperator) &&
1118 CurrentState.LastSpace = State.
Column;
1119 }
else if (
Previous.is(TT_InheritanceColon)) {
1120 CurrentState.Indent = State.
Column;
1121 CurrentState.LastSpace = State.
Column;
1122 }
else if (Current.
is(TT_CSharpGenericTypeConstraintColon)) {
1123 CurrentState.ColonPos = State.
Column;
1124 }
else if (
Previous.opensScope()) {
1132 if (
Next &&
Next->isMemberAccess() && State.
Stack.size() > 1 &&
1133 State.
Stack[State.
Stack.size() - 2].CallContinuation == 0) {
1134 CurrentState.LastSpace = State.
Column;
1140unsigned ContinuationIndenter::addTokenOnNewLine(
LineState &State,
1143 assert(State.NextToken->Previous);
1145 auto &CurrentState = State.Stack.back();
1149 unsigned Penalty = 0;
1151 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1153 if (!NextNonComment)
1154 NextNonComment = &Current;
1157 if (!CurrentState.ContainsLineBreak)
1159 CurrentState.ContainsLineBreak =
true;
1161 Penalty += State.NextToken->SplitPenalty;
1166 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1167 (State.Column <= Style.ColumnLimit / 3 ||
1168 CurrentState.BreakBeforeParameter)) {
1169 Penalty += Style.PenaltyBreakFirstLessLess;
1172 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
1173 State.Column = TotalColumn;
1187 if (State.Column > State.FirstIndent) {
1189 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);
1202 if (Current.isNot(TT_LambdaArrow) &&
1203 (!Style.isJavaScript() || Current.NestingLevel != 0 ||
1204 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1205 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
1206 CurrentState.NestedBlockIndent = State.Column;
1209 if (NextNonComment->isMemberAccess()) {
1210 if (CurrentState.CallContinuation == 0)
1211 CurrentState.CallContinuation = State.Column;
1212 }
else if (NextNonComment->is(TT_SelectorName)) {
1213 if (!CurrentState.ObjCSelectorNameFound) {
1214 if (NextNonComment->LongestObjCSelectorName == 0) {
1215 CurrentState.AlignColons =
false;
1217 CurrentState.ColonPos =
1219 ? std::max(CurrentState.Indent.Total,
1220 State.FirstIndent + Style.ContinuationIndentWidth)
1221 : CurrentState.
Indent.Total) +
1225 }
else if (CurrentState.AlignColons &&
1226 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1227 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1229 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1230 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1240 if (State.Stack.size() > 1) {
1241 State.Stack[State.Stack.size() - 2].LastSpace =
1242 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
1243 Style.ContinuationIndentWidth;
1247 switch (Style.BreakInheritanceList) {
1250 if (Current.is(TT_InheritanceColon) ||
Previous.is(TT_InheritanceComma)) {
1251 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1252 tok::kw_class, tok::kw_struct, tok::kw_union);
1256 if (Current.isOneOf(TT_InheritanceColon, TT_InheritanceComma)) {
1257 CurrentState.AlignedTo =
Previous.getPreviousOneOf(
1258 tok::kw_class, tok::kw_struct, tok::kw_union);
1262 if (
Previous.isOneOf(TT_InheritanceColon, TT_InheritanceComma))
1263 CurrentState.AlignedTo = &
Previous;
1267 if ((PreviousNonComment &&
1268 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1269 !CurrentState.AvoidBinPacking) ||
1271 CurrentState.BreakBeforeParameter =
false;
1273 if (PreviousNonComment &&
1274 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1275 PreviousNonComment->ClosesRequiresClause) &&
1276 Current.NestingLevel == 0) {
1277 CurrentState.BreakBeforeParameter =
false;
1279 if (NextNonComment->is(tok::question) ||
1280 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1281 CurrentState.BreakBeforeParameter =
true;
1283 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore) {
1284 CurrentState.BreakBeforeParameter =
false;
1285 CurrentState.AlignedTo = &Current;
1288 Current.is(TT_ConditionalExpr)) {
1289 switch (Style.AlignOperands) {
1291 CurrentState.AlignedTo = Current.is(tok::question)
1292 ? Current.getPrevious(tok::equal)
1293 : Current.getPrevious(tok::question);
1296 if (Current.is(tok::colon))
1297 CurrentState.AlignedTo = Current.getPrevious(tok::question);
1305 unsigned MaxEmptyLinesToKeep = Style.MaxEmptyLinesToKeep + 1;
1306 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1309 !Current.MatchingParen->Children.empty()) {
1314 if (!Style.KeepEmptyLines.AtEndOfBlock)
1315 MaxEmptyLinesToKeep = 1;
1318 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
1319 const bool ContinuePPDirective = State.Line->InPPDirective &&
1321 Current.isNot(TT_LineComment);
1322 Whitespaces.replaceWhitespace(Current,
Newlines, State.Column, State.Column,
1323 CurrentState.AlignedTo, ContinuePPDirective,
1324 IndentedFromColumn);
1327 if (!Current.isTrailingComment())
1328 CurrentState.LastSpace = State.Column;
1329 if (Current.is(tok::lessless)) {
1333 CurrentState.LastSpace += 3;
1336 State.StartOfLineLevel = Current.NestingLevel;
1337 State.LowestLevelOnLine = Current.NestingLevel;
1341 bool NestedBlockSpecialCase =
1342 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1343 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1345 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);
1347 NestedBlockSpecialCase =
1348 NestedBlockSpecialCase ||
1349 (Current.MatchingParen &&
1350 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1351 if (!NestedBlockSpecialCase) {
1352 auto ParentLevelIt = std::next(State.Stack.rbegin());
1354 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1369 auto FindCurrentLevel = [&](
const auto &It) {
1370 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1371 return PState.Tok != nullptr;
1374 auto MaybeIncrement = [&](
const auto &It) {
1375 return It != State.Stack.rend() ? std::next(It) : It;
1377 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1378 auto LevelContainingLambdaIt =
1379 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1380 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1382 for (
auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)
1383 I->BreakBeforeParameter =
true;
1386 if (PreviousNonComment &&
1387 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
1388 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1389 !PreviousNonComment->ClosesRequiresClause) ||
1390 Current.NestingLevel != 0) &&
1391 PreviousNonComment->isNoneOf(
1392 TT_BinaryOperator, TT_EnumEqual, TT_FunctionAnnotationRParen,
1393 TT_JavaAnnotation, TT_LeadingJavaAnnotation) &&
1394 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1397 (!Style.BraceWrapping.BeforeLambdaBody ||
1398 Current.isNot(TT_LambdaLBrace))) {
1399 CurrentState.BreakBeforeParameter =
true;
1404 if (PreviousNonComment &&
1405 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1407 CurrentState.BreakBeforeClosingBrace =
true;
1410 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1411 if (
auto Previous = PreviousNonComment->Previous) {
1413 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;
1414 }
else if (
Previous->isLoop(Style)) {
1415 CurrentState.BreakBeforeClosingParen =
1416 Style.BreakBeforeCloseBracketLoop;
1417 }
else if (
Previous->is(tok::kw_switch)) {
1418 CurrentState.BreakBeforeClosingParen =
1419 Style.BreakBeforeCloseBracketSwitch;
1421 CurrentState.BreakBeforeClosingParen =
1422 Style.BreakBeforeCloseBracketFunction;
1427 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1428 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;
1430 if (CurrentState.AvoidBinPacking) {
1435 bool PreviousIsBreakingCtorInitializerColon =
1436 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1438 bool AllowAllConstructorInitializersOnNextLine =
1441 if ((
Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
1442 !PreviousIsBreakingCtorInitializerColon) ||
1443 (!Style.AllowAllParametersOfDeclarationOnNextLine &&
1444 State.Line->MustBeDeclaration) ||
1445 (!Style.AllowAllArgumentsOnNextLine &&
1446 !State.Line->MustBeDeclaration) ||
1447 (!AllowAllConstructorInitializersOnNextLine &&
1448 PreviousIsBreakingCtorInitializerColon) ||
1450 CurrentState.BreakBeforeParameter =
true;
1456 if (PreviousIsBreakingCtorInitializerColon &&
1457 AllowAllConstructorInitializersOnNextLine) {
1458 CurrentState.BreakBeforeParameter =
false;
1463 CurrentState.BreakBeforeParameter =
true;
1469ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1470 if (!State.NextToken || !State.NextToken->Previous)
1474 const auto &CurrentState = State.Stack.back();
1476 if (CurrentState.IsCSharpGenericTypeConstraint &&
1477 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1478 return CurrentState.ColonPos + 2;
1483 const auto ContinuationIndent =
1484 std::max(IndentationAndAlignment(CurrentState.LastSpace),
1485 CurrentState.Indent) +
1486 Style.ContinuationIndentWidth;
1487 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1489 if (!NextNonComment)
1490 NextNonComment = &Current;
1493 if (Style.isJava() &&
1494 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
1495 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1496 CurrentState.Indent + Style.ContinuationIndentWidth);
1501 if (Style.isVerilog() && PreviousNonComment &&
1502 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {
1503 return State.FirstIndent;
1507 State.Line->First->is(tok::kw_enum)) {
1508 return IndentationAndAlignment(Style.IndentWidth *
1509 State.Line->First->IndentLevel) +
1513 if (Style.BraceWrapping.BeforeLambdaBody &&
1514 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {
1516 ? CurrentState.Indent
1517 : State.FirstIndent;
1518 return From + Style.IndentWidth;
1523 if (Style.BraceWrapping.AfterRequiresExpression &&
1524 Current.is(TT_RequiresExpressionLBrace)) {
1525 return CurrentState.NestedBlockIndent;
1528 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1529 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
1530 if (Current.NestingLevel == 0 ||
1532 State.NextToken->is(TT_LambdaLBrace))) {
1533 return State.FirstIndent;
1535 return CurrentState.Indent;
1537 if (Current.is(TT_LambdaArrow) &&
1538 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1539 tok::kw_consteval, tok::kw_static,
1540 TT_AttributeRSquare)) {
1541 return ContinuationIndent;
1543 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1544 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
1545 State.Stack.size() > 1) {
1546 if (Current.closesBlockOrBlockTypeList(Style))
1547 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1548 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit)) {
1558 if ((State.Stack.size() == 2 &&
1559 Current.MatchingParen->getPreviousNonComment() &&
1560 Current.MatchingParen->getPreviousNonComment()->is(
1562 (State.Stack.size() == 3 &&
1564 return State.FirstIndent;
1566 return State.Stack[State.Stack.size() - 2].LastSpace;
1568 return State.FirstIndent;
1585 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1587 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1588 return State.Stack[State.Stack.size() - 2].LastSpace;
1592 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1593 State.Stack.size() > 1) {
1594 return State.Stack[State.Stack.size() - 2].LastSpace;
1596 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&
1597 Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit) &&
1598 State.Stack.size() > 1) {
1599 return State.Stack[State.Stack.size() - 2].LastSpace;
1601 if ((Style.BreakBeforeCloseBracketFunction ||
1602 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||
1603 Style.BreakBeforeCloseBracketSwitch) &&
1604 Current.is(tok::r_paren) && State.Stack.size() > 1) {
1605 return State.Stack[State.Stack.size() - 2].LastSpace;
1607 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&
1608 State.Stack.size() > 1) {
1609 return State.Stack[State.Stack.size() - 2].LastSpace;
1611 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1612 return State.Stack[State.Stack.size() - 2].LastSpace;
1620 if (Current.is(tok::identifier) && Current.Next &&
1621 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
1622 (Current.Next->is(TT_DictLiteral) ||
1623 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1624 return CurrentState.Indent;
1626 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1627 State.StartOfStringLiteral != 0) {
1628 return State.StartOfStringLiteral - 1;
1630 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1631 return State.StartOfStringLiteral;
1632 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1633 return CurrentState.FirstLessLess;
1634 if (NextNonComment->isMemberAccess()) {
1635 if (CurrentState.CallContinuation == 0)
1636 return ContinuationIndent;
1637 return CurrentState.CallContinuation;
1639 if (CurrentState.QuestionColumn != 0 &&
1640 ((NextNonComment->is(tok::colon) &&
1641 NextNonComment->is(TT_ConditionalExpr)) ||
1642 Previous.is(TT_ConditionalExpr))) {
1643 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1644 !NextNonComment->Next->FakeLParens.empty() &&
1646 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1648 !CurrentState.IsWrappedConditional) {
1653 unsigned Indent = CurrentState.Indent.Total;
1655 Indent -= Style.ContinuationIndentWidth;
1656 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
1660 return CurrentState.QuestionColumn;
1662 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1663 return CurrentState.VariablePos;
1664 if (Current.is(TT_RequiresClause)) {
1665 if (Style.IndentRequiresClause)
1666 return CurrentState.Indent + Style.IndentWidth;
1667 switch (Style.RequiresClausePosition) {
1671 return CurrentState.Indent;
1676 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1677 TT_InheritanceComma)) {
1678 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1680 if ((PreviousNonComment &&
1681 (PreviousNonComment->ClosesTemplateDeclaration ||
1682 PreviousNonComment->ClosesRequiresClause ||
1683 (PreviousNonComment->is(TT_AttributeMacro) &&
1684 Current.isNot(tok::l_paren) &&
1685 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1686 TT_PointerOrReference)) ||
1687 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
1688 TT_FunctionAnnotationRParen,
1690 TT_LeadingJavaAnnotation))) ||
1691 (!Style.IndentWrappedFunctionNames &&
1692 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName)) ||
1693 (State.Line->ReturnTypeWrapped && PreviousNonComment &&
1695 return std::max(IndentationAndAlignment(CurrentState.LastSpace),
1696 CurrentState.Indent);
1698 if (NextNonComment->is(TT_SelectorName)) {
1699 if (!CurrentState.ObjCSelectorNameFound) {
1700 auto MinIndent = CurrentState.Indent;
1703 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
1704 Style.ContinuationIndentWidth);
1715 return MinIndent.addPadding(
1716 std::max(NextNonComment->LongestObjCSelectorName,
1717 NextNonComment->ColumnWidth) -
1718 NextNonComment->ColumnWidth);
1720 if (!CurrentState.AlignColons)
1721 return CurrentState.Indent;
1722 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1723 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1724 return CurrentState.Indent;
1726 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1727 return CurrentState.ColonPos;
1728 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1729 if (CurrentState.StartOfArraySubscripts != 0) {
1730 return CurrentState.StartOfArraySubscripts;
1731 }
else if (Style.isCSharp()) {
1733 return CurrentState.Indent;
1735 return ContinuationIndent;
1740 if (State.Line->InPragmaDirective) {
1741 FormatToken *PragmaType = State.Line->First->Next->Next;
1742 if (PragmaType && PragmaType->TokenText ==
"omp")
1743 return CurrentState.Indent + Style.ContinuationIndentWidth;
1748 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1749 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1750 return CurrentState.Indent;
1753 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1754 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1755 return ContinuationIndent;
1757 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1758 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1759 return ContinuationIndent;
1761 if (NextNonComment->is(TT_CtorInitializerComma))
1762 return CurrentState.Indent;
1763 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1765 return CurrentState.Indent;
1767 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1769 return CurrentState.Indent;
1772 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1773 !Current.isBinaryOperator() &&
1774 Current.isNoneOf(tok::colon, tok::comment)) {
1775 return ContinuationIndent;
1777 if (Current.is(TT_ProtoExtensionLSquare))
1778 return CurrentState.Indent;
1779 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1780 return CurrentState.Indent - Current.Tok.getLength() -
1781 Current.SpacesRequiredBefore;
1783 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1784 CurrentState.UnindentOperator) {
1785 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1786 NextNonComment->SpacesRequiredBefore;
1788 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
1789 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
1792 return CurrentState.Indent + Style.ContinuationIndentWidth;
1794 return CurrentState.Indent;
1806 return Style.BraceWrapping.BeforeLambdaBody && Current.
is(TT_LambdaLSquare);
1809unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1810 bool DryRun,
bool Newline) {
1811 assert(State.Stack.size());
1813 auto &CurrentState = State.Stack.back();
1815 if (Current.is(TT_CSharpGenericTypeConstraint))
1816 CurrentState.IsCSharpGenericTypeConstraint =
true;
1817 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1818 CurrentState.NoLineBreakInOperand =
false;
1819 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1820 CurrentState.AvoidBinPacking =
true;
1821 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1822 if (CurrentState.FirstLessLess == 0)
1823 CurrentState.FirstLessLess = State.Column;
1825 CurrentState.LastOperatorWrapped = Newline;
1827 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1828 CurrentState.LastOperatorWrapped = Newline;
1829 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1830 Current.Previous->isNot(TT_ConditionalExpr)) {
1831 CurrentState.LastOperatorWrapped = Newline;
1833 if (Current.is(TT_ArraySubscriptLSquare) &&
1834 CurrentState.StartOfArraySubscripts == 0) {
1835 CurrentState.StartOfArraySubscripts = State.Column;
1839 if (!(
Tok.is(TT_ConditionalExpr) &&
Tok.is(tok::question)))
1841 if (
Tok.MustBreakBefore)
1845 return Next &&
Next->MustBreakBefore;
1847 if (IsWrappedConditional(Current))
1848 CurrentState.IsWrappedConditional =
true;
1849 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))
1850 CurrentState.QuestionColumn = State.Column;
1851 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {
1856 CurrentState.QuestionColumn = State.Column;
1858 if (!Current.opensScope() && !Current.closesScope() &&
1859 Current.isNot(TT_PointerOrReference)) {
1860 State.LowestLevelOnLine =
1861 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1863 if (Current.isMemberAccess())
1864 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1865 if (Current.is(TT_SelectorName))
1866 CurrentState.ObjCSelectorNameFound =
true;
1867 if (Current.is(TT_CtorInitializerColon) &&
1874 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==
1878 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1880 CurrentState.AvoidBinPacking =
true;
1881 CurrentState.BreakBeforeParameter =
1882 Style.ColumnLimit > 0 &&
1886 CurrentState.BreakBeforeParameter =
false;
1889 if (Current.is(TT_CtorInitializerColon) &&
1891 CurrentState.Indent =
1892 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1893 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
1895 CurrentState.AvoidBinPacking =
true;
1897 CurrentState.BreakBeforeParameter =
false;
1899 if (Current.is(TT_InheritanceColon)) {
1900 CurrentState.Indent =
1901 State.FirstIndent + Style.ConstructorInitializerIndentWidth;
1903 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1904 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1905 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1906 CurrentState.LastSpace = State.Column;
1907 if (Current.is(TT_RequiresExpression) &&
1909 CurrentState.NestedBlockIndent = State.Column;
1921 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1923 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1924 !CurrentState.HasMultipleNestedBlocks) {
1925 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1926 for (ParenState &PState : llvm::drop_end(State.Stack))
1927 PState.NoLineBreak =
true;
1928 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1930 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1931 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1932 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1933 TT_CtorInitializerColon)))) {
1934 CurrentState.NestedBlockInlined =
1938 moveStatePastFakeLParens(State, Newline);
1939 moveStatePastScopeCloser(State);
1942 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1943 !State.Stack.back().NoLineBreakInOperand;
1944 moveStatePastScopeOpener(State, Newline);
1945 moveStatePastFakeRParens(State);
1947 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1948 State.StartOfStringLiteral = State.Column + 1;
1949 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1950 State.StartOfStringLiteral = State.Column + 1;
1951 }
else if (Current.is(TT_TableGenMultiLineString) &&
1952 State.StartOfStringLiteral == 0) {
1953 State.StartOfStringLiteral = State.Column + 1;
1954 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1955 State.StartOfStringLiteral = State.Column;
1956 }
else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
1957 !Current.isStringLiteral()) {
1958 State.StartOfStringLiteral = 0;
1961 State.Column += Current.ColumnWidth;
1962 State.NextToken = State.NextToken->Next;
1967 if (Style.isVerilog() && State.NextToken &&
1968 State.NextToken->MustBreakBefore &&
1969 Keywords.isVerilogEndOfLabel(Current)) {
1970 State.FirstIndent += Style.IndentWidth;
1971 CurrentState.Indent = State.FirstIndent;
1975 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1978 Current.Role->formatFromToken(State,
this, DryRun);
1985 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1990void ContinuationIndenter::moveStatePastFakeLParens(
LineState &State,
1993 if (Current.FakeLParens.empty())
2001 bool SkipFirstExtraIndent =
2004 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
2008 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
2009 const auto &CurrentState = State.Stack.back();
2010 ParenState NewParenState = CurrentState;
2011 NewParenState.Tok =
nullptr;
2012 NewParenState.ContainsLineBreak =
false;
2013 NewParenState.LastOperatorWrapped =
true;
2014 NewParenState.IsChainedConditional =
false;
2015 NewParenState.IsWrappedConditional =
false;
2016 NewParenState.UnindentOperator =
false;
2017 NewParenState.NoLineBreak =
2018 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
2019 NewParenState.Precedence = PrecedenceLevel;
2023 NewParenState.AvoidBinPacking =
false;
2028 if (!Current.isTrailingComment() &&
2032 (!Style.isJava() && PrecedenceLevel > 0)) &&
2033 (Style.AlignAfterOpenBracket || PrecedenceLevel >
prec::Comma ||
2034 Current.NestingLevel == 0) &&
2035 (!Style.isTableGen() ||
2037 TT_TableGenDAGArgListCommaToBreak)))) {
2038 NewParenState.Indent =
2039 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,
2040 IndentationAndAlignment(CurrentState.LastSpace)});
2047 State.Stack.size() > 1) {
2048 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
2049 Style.ContinuationIndentWidth;
2060 NewParenState.UnindentOperator =
true;
2063 NewParenState.AlignedTo =
Previous;
2073 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
2075 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {
2076 NewParenState.StartOfFunctionCall = State.Column;
2086 &PrecedenceLevel == &Current.FakeLParens.back() &&
2087 !CurrentState.IsWrappedConditional) {
2088 NewParenState.IsChainedConditional =
true;
2089 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
2092 !Current.isTrailingComment())) {
2093 NewParenState.Indent += Style.ContinuationIndentWidth;
2096 NewParenState.BreakBeforeParameter =
false;
2097 State.Stack.push_back(NewParenState);
2098 SkipFirstExtraIndent =
false;
2102void ContinuationIndenter::moveStatePastFakeRParens(
LineState &State) {
2103 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
2104 unsigned VariablePos = State.Stack.back().VariablePos;
2105 if (State.Stack.size() == 1) {
2109 State.Stack.pop_back();
2110 State.Stack.back().VariablePos = VariablePos;
2113 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {
2116 State.Stack.back().LastSpace -= Style.IndentWidth;
2120void ContinuationIndenter::moveStatePastScopeOpener(
LineState &State,
2123 if (!Current.opensScope())
2126 const auto &CurrentState = State.Stack.back();
2129 if (Current.isOneOf(tok::less, tok::l_paren) &&
2130 CurrentState.IsCSharpGenericTypeConstraint) {
2134 if (Current.MatchingParen && Current.is(
BK_Block)) {
2135 moveStateToNewBlock(State, Newline);
2142 const auto *Prev =
Tok->getPreviousNonComment();
2145 return Prev->is(tok::comma);
2146 }(Current.MatchingParen);
2148 IndentationAndAlignment NewIndent = 0;
2149 unsigned LastSpace = CurrentState.LastSpace;
2150 bool AvoidBinPacking;
2151 bool BreakBeforeParameter =
false;
2152 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
2153 CurrentState.NestedBlockIndent);
2154 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2156 if (Current.opensBlockOrBlockTypeList(Style)) {
2157 NewIndent = Style.IndentWidth +
2158 std::min(State.Column, CurrentState.NestedBlockIndent);
2159 }
else if (Current.is(tok::l_brace)) {
2160 const auto Width = Style.BracedInitializerIndentWidth;
2161 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
2162 (Width < 0 ? Style.ContinuationIndentWidth : Width);
2164 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
2166 const FormatToken *NextNonComment = Current.getNextNonComment();
2168 EndsInComma || Current.is(TT_DictLiteral) || Style.isProto() ||
2171 NextNonComment->isOneOf(TT_DesignatedInitializerPeriod,
2172 TT_DesignatedInitializerLSquare));
2173 BreakBeforeParameter = EndsInComma;
2174 if (Current.ParameterCount > 1)
2175 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
2177 NewIndent = IndentationAndAlignment(std::max(
2178 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
2179 Style.ContinuationIndentWidth;
2181 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
2188 if (
Next &&
Next->is(TT_TableGenDAGArgOperatorID))
2189 NewIndent = State.Column +
Next->TokenText.size() + 2;
2196 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
2197 NewIndent = std::max(NewIndent, CurrentState.Indent);
2198 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
2203 bool ObjCBinPackProtocolList =
2209 bool BinPackDeclaration =
2213 (State.Line->Type ==
LT_ObjCDecl && ObjCBinPackProtocolList);
2215 bool GenericSelection =
2216 Current.getPreviousNonComment() &&
2217 Current.getPreviousNonComment()->is(tok::kw__Generic);
2220 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2221 (Style.isJavaScript() && EndsInComma) ||
2222 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2223 (!State.Line->MustBeDeclaration &&
2225 (Style.ExperimentalAutoDetectBinPacking &&
2229 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2230 Style.ObjCBreakBeforeNestedBlockParam) {
2231 if (Style.ColumnLimit) {
2236 BreakBeforeParameter =
true;
2242 Tok &&
Tok != Current.MatchingParen;
Tok =
Tok->Next) {
2243 if (
Tok->MustBreakBefore ||
2244 (
Tok->CanBreakBefore &&
Tok->NewlinesBefore > 0)) {
2245 BreakBeforeParameter =
true;
2252 if (Style.isJavaScript() && EndsInComma)
2253 BreakBeforeParameter =
true;
2259 Current.Children.empty() &&
2260 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2261 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2262 (Current.is(TT_TemplateOpener) &&
2263 CurrentState.ContainsUnwrappedBuilder));
2264 State.Stack.push_back(
2265 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2266 auto &NewState = State.Stack.back();
2267 NewState.NestedBlockIndent = NestedBlockIndent;
2268 NewState.BreakBeforeParameter = BreakBeforeParameter;
2269 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2271 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
2272 Current.is(tok::l_paren)) {
2276 if (next->is(TT_LambdaLSquare)) {
2277 NewState.HasMultipleNestedBlocks =
true;
2284 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2286 Current.Previous->is(tok::at);
2289void ContinuationIndenter::moveStatePastScopeCloser(
LineState &State) {
2291 if (!Current.closesScope())
2296 if (State.Stack.size() > 1 &&
2297 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2298 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2299 State.NextToken->is(TT_TemplateCloser) ||
2300 State.NextToken->is(TT_TableGenListCloser) ||
2301 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2302 State.Stack.pop_back();
2305 auto &CurrentState = State.Stack.back();
2317 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2318 Current.MatchingParen->Previous) {
2319 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2320 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2321 CurrentScopeOpener.MatchingParen) {
2322 int NecessarySpaceInLine =
2324 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2325 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2326 Style.ColumnLimit) {
2327 CurrentState.BreakBeforeParameter =
false;
2332 if (Current.is(tok::r_square)) {
2334 const FormatToken *NextNonComment = Current.getNextNonComment();
2335 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2336 CurrentState.StartOfArraySubscripts = 0;
2340void ContinuationIndenter::moveStateToNewBlock(
LineState &State,
bool NewLine) {
2342 State.NextToken->is(TT_LambdaLBrace) &&
2343 !State.Line->MightBeFunctionDecl) {
2344 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;
2345 State.Stack.back().NestedBlockIndent = State.FirstIndent +
Indent;
2347 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2349 unsigned NewIndent =
2350 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2351 ? Style.ObjCBlockIndentWidth
2352 : Style.IndentWidth);
2359 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&
2360 State.NextToken->is(TT_LambdaLBrace);
2362 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2363 State.Stack.back().LastSpace,
2364 true, NoLineBreak));
2365 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2366 State.Stack.back().BreakBeforeParameter =
true;
2372 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2373 if (LastNewlinePos == StringRef::npos) {
2374 return StartColumn +
2378 0, TabWidth, Encoding);
2382unsigned ContinuationIndenter::reformatRawStringLiteral(
2384 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2385 unsigned StartColumn = State.Column - Current.ColumnWidth;
2387 StringRef NewDelimiter =
2389 if (NewDelimiter.empty())
2390 NewDelimiter = OldDelimiter;
2393 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2394 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2397 std::string RawText = std::string(
2398 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2399 if (NewDelimiter != OldDelimiter) {
2402 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2403 if (StringRef(RawText).
contains(CanonicalDelimiterSuffix))
2404 NewDelimiter = OldDelimiter;
2407 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2408 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2411 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2422 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2444 unsigned CurrentIndent =
2445 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2446 ? State.Stack.back().NestedBlockIndent
2447 : State.Stack.back().Indent.Total;
2448 unsigned NextStartColumn = ContentStartsOnNewline
2449 ? CurrentIndent + Style.IndentWidth
2460 unsigned LastStartColumn =
2461 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2464 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2465 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2470 return addMultilineToken(Current, State);
2472 if (NewDelimiter != OldDelimiter) {
2475 SourceLocation PrefixDelimiterStart =
2476 Current.Tok.getLocation().getLocWithOffset(2);
2477 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
2478 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2481 <<
"Failed to update the prefix delimiter of a raw string: "
2482 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2486 SourceLocation SuffixDelimiterStart =
2487 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2488 1 - OldDelimiter.size());
2489 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
2490 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2493 <<
"Failed to update the suffix delimiter of a raw string: "
2494 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2497 SourceLocation OriginLoc =
2498 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2499 for (
const tooling::Replacement &Fix : Fixes.first) {
2500 auto Err = Whitespaces.addReplacement(tooling::Replacement(
2501 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2502 Fix.getLength(), Fix.getReplacementText()));
2504 llvm::errs() <<
"Failed to reformat raw string: "
2505 << llvm::toString(std::move(Err)) <<
"\n";
2510 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
2511 State.Column = RawLastLineEndColumn + NewSuffixSize;
2515 unsigned PrefixExcessCharacters =
2516 StartColumn + NewPrefixSize > Style.ColumnLimit
2517 ? StartColumn + NewPrefixSize - Style.ColumnLimit
2520 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2523 for (ParenState &
Paren : State.Stack)
2524 Paren.BreakBeforeParameter =
true;
2526 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
2529unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2532 for (ParenState &
Paren : State.Stack)
2533 Paren.BreakBeforeParameter =
true;
2535 unsigned ColumnsUsed = State.Column;
2538 State.Column = Current.LastLineColumnWidth;
2541 return Style.PenaltyExcessCharacter * (ColumnsUsed -
getColumnLimit(State));
2545unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2547 bool AllowBreak,
bool Newline) {
2548 unsigned Penalty = 0;
2551 auto RawStringStyle = getRawStringStyle(Current, State);
2552 if (RawStringStyle && !Current.Finalized) {
2553 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2555 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2558 Penalty = addMultilineToken(Current, State);
2561 LineState OriginalState = State;
2565 bool Strict =
false;
2568 bool Exceeded =
false;
2569 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2570 Current, State, AllowBreak,
true, Strict);
2574 LineState StrictState = OriginalState;
2575 unsigned StrictPenalty =
2576 breakProtrudingToken(Current, StrictState, AllowBreak,
2579 Strict = StrictPenalty <= Penalty;
2581 Penalty = StrictPenalty;
2582 State = std::move(StrictState);
2588 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2593 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2594 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
2603 auto Tok = Current.getPreviousNonComment();
2604 if (!
Tok ||
Tok->isNot(tok::l_paren))
2606 Tok =
Tok->getPreviousNonComment();
2609 if (
Tok->is(TT_TemplateCloser)) {
2610 Tok =
Tok->MatchingParen;
2612 Tok =
Tok->getPreviousNonComment();
2614 if (!
Tok ||
Tok->isNot(tok::identifier))
2616 return Tok->TokenText;
2619std::optional<FormatStyle>
2620ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2621 const LineState &State) {
2622 if (!Current.isStringLiteral())
2623 return std::nullopt;
2626 return std::nullopt;
2628 if (!RawStringStyle && Delimiter->empty()) {
2632 if (!RawStringStyle)
2633 return std::nullopt;
2635 return RawStringStyle;
2638std::unique_ptr<BreakableToken>
2639ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2641 unsigned StartColumn = State.Column - Current.ColumnWidth;
2642 if (Current.isStringLiteral()) {
2645 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||
2659 if (Current.IsUnterminatedLiteral)
2663 if (State.Stack.back().IsInsideObjCArrayLiteral)
2670 if (Style.isVerilog() && Current.Previous &&
2671 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {
2674 StringRef
Text = Current.TokenText;
2684 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||
2687 if (Style.isJavaScript() &&
Text.starts_with(
"'") &&
2688 Text.ends_with(
"'")) {
2690 }
else if (Style.isCSharp() &&
Text.starts_with(
"@\"") &&
2691 Text.ends_with(
"\"")) {
2693 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2698 return std::make_unique<BreakableStringLiteralUsingOperators>(
2699 Current, QuoteStyle,
2710 if ((
Text.ends_with(Postfix =
"\"") &&
2711 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2712 Text.starts_with(Prefix =
"u\"") ||
2713 Text.starts_with(Prefix =
"U\"") ||
2714 Text.starts_with(Prefix =
"u8\"") ||
2715 Text.starts_with(Prefix =
"L\""))) ||
2716 (
Text.starts_with(Prefix =
"_T(\"") &&
2717 Text.ends_with(Postfix =
"\")"))) {
2718 return std::make_unique<BreakableStringLiteral>(
2720 State.Line->InPPDirective, Encoding, Style);
2722 }
else if (Current.is(TT_BlockComment)) {
2730 return std::make_unique<BreakableBlockComment>(
2731 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2732 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
2733 }
else if (Current.is(TT_LineComment) &&
2734 (!Current.Previous ||
2735 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2736 bool RegularComments = [&]() {
2737 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2739 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2745 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2749 return std::make_unique<BreakableLineCommentSection>(
2750 Current, StartColumn,
false, Encoding, Style);
2755std::pair<unsigned, bool>
2756ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2758 bool DryRun,
bool Strict) {
2759 std::unique_ptr<const BreakableToken> Token =
2760 createBreakableToken(Current, State, AllowBreak);
2763 assert(Token->getLineCount() > 0);
2765 if (Current.is(TT_LineComment)) {
2767 ColumnLimit = Style.ColumnLimit;
2769 if (ColumnLimit == 0) {
2772 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2774 if (Current.UnbreakableTailLength >= ColumnLimit)
2778 unsigned StartColumn = State.Column - Current.ColumnWidth;
2779 unsigned NewBreakPenalty = Current.isStringLiteral()
2780 ? Style.PenaltyBreakString
2781 : Style.PenaltyBreakComment;
2784 bool Exceeded =
false;
2786 bool BreakInserted = Token->introducesBreakBeforeToken();
2789 bool NewBreakBefore =
false;
2793 bool Reflow =
false;
2796 unsigned TailOffset = 0;
2798 unsigned ContentStartColumn =
2799 Token->getContentStartColumn(0,
false);
2801 unsigned RemainingTokenColumns =
2802 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2805 Token->adaptStartOfLine(0, Whitespaces);
2807 unsigned ContentIndent = 0;
2808 unsigned Penalty = 0;
2809 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2810 << StartColumn <<
".\n");
2811 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2812 LineIndex != EndIndex; ++LineIndex) {
2813 LLVM_DEBUG(llvm::dbgs()
2814 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2815 NewBreakBefore =
false;
2819 bool TryReflow = Reflow;
2821 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2822 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2823 << (ContentStartColumn + RemainingTokenColumns)
2824 <<
", space: " << ColumnLimit
2825 <<
", reflown prefix: " << ContentStartColumn
2826 <<
", offset in line: " << TailOffset <<
"\n");
2832 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2833 ContentStartColumn, CommentPragmasRegex);
2834 if (
Split.first == StringRef::npos) {
2837 if (LineIndex < EndIndex - 1) {
2840 Penalty += Style.PenaltyExcessCharacter *
2841 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2843 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2846 assert(
Split.first != 0);
2848 if (Token->supportsReflow()) {
2868 unsigned ToSplitColumns = Token->getRangeLength(
2869 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2870 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2873 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2874 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2877 unsigned ToNextSplitColumns = 0;
2878 if (NextSplit.first == StringRef::npos) {
2879 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2880 ContentStartColumn);
2882 ToNextSplitColumns = Token->getRangeLength(
2883 LineIndex, TailOffset,
2884 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2888 ToNextSplitColumns =
2889 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2890 LLVM_DEBUG(llvm::dbgs()
2891 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2892 LLVM_DEBUG(llvm::dbgs()
2893 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2896 bool ContinueOnLine =
2897 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2898 unsigned ExcessCharactersPenalty = 0;
2899 if (!ContinueOnLine && !Strict) {
2902 ExcessCharactersPenalty =
2903 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2904 Style.PenaltyExcessCharacter;
2905 LLVM_DEBUG(llvm::dbgs()
2906 <<
" Penalty excess: " << ExcessCharactersPenalty
2907 <<
"\n break : " << NewBreakPenalty <<
"\n");
2908 if (ExcessCharactersPenalty < NewBreakPenalty) {
2910 ContinueOnLine =
true;
2913 if (ContinueOnLine) {
2914 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2919 Token->compressWhitespace(LineIndex, TailOffset, Split,
2923 ContentStartColumn += ToSplitColumns + 1;
2924 Penalty += ExcessCharactersPenalty;
2926 RemainingTokenColumns = Token->getRemainingLength(
2927 LineIndex, TailOffset, ContentStartColumn);
2931 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2936 ContentIndent = Token->getContentIndent(LineIndex);
2937 LLVM_DEBUG(llvm::dbgs()
2938 <<
" ContentIndent: " << ContentIndent <<
"\n");
2939 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2942 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2943 LineIndex, TailOffset +
Split.first +
Split.second,
2944 ContentStartColumn);
2945 if (NewRemainingTokenColumns == 0) {
2948 ContentStartColumn =
2949 Token->getContentStartColumn(LineIndex,
true);
2950 NewRemainingTokenColumns = Token->getRemainingLength(
2951 LineIndex, TailOffset +
Split.first +
Split.second,
2952 ContentStartColumn);
2958 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2963 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2964 <<
", " <<
Split.second <<
"\n");
2966 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2970 Penalty += NewBreakPenalty;
2972 RemainingTokenColumns = NewRemainingTokenColumns;
2973 BreakInserted =
true;
2974 NewBreakBefore =
true;
2978 if (LineIndex + 1 != EndIndex) {
2979 unsigned NextLineIndex = LineIndex + 1;
2980 if (NewBreakBefore) {
2999 ContentStartColumn += RemainingTokenColumns + 1;
3004 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
3005 LLVM_DEBUG(llvm::dbgs()
3006 <<
" Size of reflown text: " << ContentStartColumn
3007 <<
"\n Potential reflow split: ");
3008 if (SplitBeforeNext.first != StringRef::npos) {
3009 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
3010 << SplitBeforeNext.second <<
"\n");
3011 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
3014 RemainingTokenColumns = Token->getRemainingLength(
3015 NextLineIndex, TailOffset, ContentStartColumn);
3017 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
3018 LLVM_DEBUG(llvm::dbgs()
3019 <<
" Over limit after reflow, need: "
3020 << (ContentStartColumn + RemainingTokenColumns)
3021 <<
", space: " << ColumnLimit
3022 <<
", reflown prefix: " << ContentStartColumn
3023 <<
", offset in line: " << TailOffset <<
"\n");
3029 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
3030 ContentStartColumn, CommentPragmasRegex);
3031 if (
Split.first == StringRef::npos) {
3032 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
3038 unsigned ToSplitColumns = Token->getRangeLength(
3039 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
3040 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
3041 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
3042 << (ContentStartColumn + ToSplitColumns)
3043 <<
", space: " << ColumnLimit);
3044 unsigned ExcessCharactersPenalty =
3045 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
3046 Style.PenaltyExcessCharacter;
3047 if (NewBreakPenalty < ExcessCharactersPenalty)
3053 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
3061 ContentStartColumn =
3062 Token->getContentStartColumn(NextLineIndex,
false);
3063 RemainingTokenColumns = Token->getRemainingLength(
3064 NextLineIndex, TailOffset, ContentStartColumn);
3067 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
3082 if (NewBreakBefore) {
3083 assert(Penalty >= NewBreakPenalty);
3084 Penalty -= NewBreakPenalty;
3087 Token->reflow(NextLineIndex, Whitespaces);
3093 Token->getSplitAfterLastLine(TailOffset);
3094 if (SplitAfterLastLine.first != StringRef::npos) {
3095 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
3099 Penalty += Style.PenaltyExcessCharacter *
3100 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
3103 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
3106 ContentStartColumn =
3107 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
3108 RemainingTokenColumns = Token->getRemainingLength(
3109 Token->getLineCount() - 1,
3110 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
3111 ContentStartColumn);
3114 State.Column = ContentStartColumn + RemainingTokenColumns -
3115 Current.UnbreakableTailLength;
3117 if (BreakInserted) {
3119 Token->updateAfterBroken(Whitespaces);
3124 if (Current.isNot(TT_LineComment))
3125 for (ParenState &
Paren : State.Stack)
3126 Paren.BreakBeforeParameter =
true;
3128 if (Current.is(TT_BlockComment))
3129 State.NoContinuation =
true;
3131 State.Stack.back().LastSpace = StartColumn;
3134 Token->updateNextToken(State);
3136 return {Penalty, Exceeded};
3141 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
3144bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
3146 if (!Current.isStringLiteral() || Current.
is(TT_ImplicitStringLiteral))
3151 if (Current.
TokenText.starts_with(
"R\""))
3155 if (Current.getNextNonComment() &&
3156 Current.getNextNonComment()->isStringLiteral()) {
3159 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&
3161 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...