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));
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) {
104 if (End->Next->CanBreakBefore)
106 if (!End->Next->closesScope())
108 if (End->Next->MatchingParen &&
109 End->Next->MatchingParen->isOneOf(
110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {
111 const ParenState *State = FindParenState(End->Next->MatchingParen);
112 if (State && State->BreakBeforeClosingBrace)
134 bool HasTwoOperands =
Token.OperatorIndex == 0 && !
Token.NextOperator;
135 return Token.
is(TT_BinaryOperator) && !HasTwoOperands &&
159 if (LessTok.
isNot(tok::less))
171 if (TokenText.size() < 5
172 || !TokenText.starts_with(
"R\"") || !TokenText.ends_with(
"\"")) {
179 size_t LParenPos = TokenText.substr(0, 19).find_first_of(
'(');
180 if (LParenPos == StringRef::npos)
182 StringRef Delimiter = TokenText.substr(2, LParenPos - 2);
185 size_t RParenPos = TokenText.size() - Delimiter.size() - 2;
186 if (TokenText[RParenPos] !=
')')
188 if (!TokenText.substr(RParenPos + 1).starts_with(Delimiter))
200 return StringRef(Format.CanonicalDelimiter);
207 std::optional<FormatStyle> LanguageStyle =
209 if (!LanguageStyle) {
212 RawStringFormat.Language, &PredefinedStyle)) {
214 PredefinedStyle.
Language = RawStringFormat.Language;
216 LanguageStyle = PredefinedStyle;
219 for (StringRef Delimiter : RawStringFormat.Delimiters)
221 for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions)
226std::optional<FormatStyle>
234std::optional<FormatStyle>
236 StringRef EnclosingFunction)
const {
248 bool BinPackInconclusiveFunctions)
249 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
250 Whitespaces(Whitespaces), Encoding(Encoding),
251 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
252 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
255 unsigned FirstStartColumn,
259 State.FirstIndent = FirstIndent;
260 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
261 State.Column = FirstStartColumn;
263 State.Column = FirstIndent;
273 State.NextToken =
Line->First;
274 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
277 State.NoContinuation =
false;
278 State.StartOfStringLiteral = 0;
279 State.NoLineBreak =
false;
280 State.StartOfLineLevel = 0;
281 State.LowestLevelOnLine = 0;
282 State.IgnoreStackForComparison =
false;
287 auto &CurrentState = State.Stack.back();
288 CurrentState.AvoidBinPacking =
true;
289 CurrentState.BreakBeforeParameter =
true;
290 CurrentState.AlignColons =
false;
294 moveStateToNextToken(State, DryRun,
false);
301 const auto &CurrentState = State.Stack.back();
302 assert(&
Previous == Current.Previous);
303 if (!Current.CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
304 Current.closesBlockOrBlockTypeList(Style))) {
309 if (!Current.MustBreakBefore &&
Previous.is(tok::l_brace) &&
312 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
321 State.LowestLevelOnLine < State.StartOfLineLevel &&
322 State.LowestLevelOnLine < Current.NestingLevel) {
325 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
330 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
331 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
332 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {
333 return Style.
isCpp() &&
339 if (Current.is(TT_FunctionDeclarationName)) {
346 assert(State.Column >= State.FirstIndent);
347 if (State.Column - State.FirstIndent < 6)
354 if (Current.is(tok::r_brace) && Current.MatchingParen &&
355 Current.isBlockIndentedInitRBrace(Style)) {
356 return CurrentState.BreakBeforeClosingBrace;
362 Current.is(tok::r_paren)) {
363 return CurrentState.BreakBeforeClosingParen;
367 return CurrentState.BreakBeforeClosingAngle;
371 if (!Current.isOneOf(TT_BinaryOperator, tok::comma) &&
376 Current.isNot(TT_LambdaLBrace)) &&
377 CurrentState.NoLineBreakInOperand) {
384 if (Current.is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
386 Previous.MatchingParen->Previous->MatchingParen &&
387 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
389 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
393 return !State.NoLineBreak && !CurrentState.NoLineBreak;
399 const auto &CurrentState = State.Stack.back();
401 Current.is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
405 if (Current.MustBreakBefore ||
406 (Current.is(TT_InlineASMColon) &&
412 if (CurrentState.BreakBeforeClosingBrace &&
413 (Current.closesBlockOrBlockTypeList(Style) ||
414 (Current.is(tok::r_brace) &&
415 Current.isBlockIndentedInitRBrace(Style)))) {
418 if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
420 if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser))
424 Current.ObjCSelectorNameParts > 1 &&
425 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
430 if (CurrentState.IsCSharpGenericTypeConstraint &&
431 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
435 (
Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
436 State.Line->First->isNot(TT_AttributeSquare) && Style.
isCpp() &&
446 Previous.is(TT_ConditionalExpr))) &&
447 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
448 !Current.isOneOf(tok::r_paren, tok::r_brace)) {
451 if (CurrentState.IsChainedConditional &&
453 Current.is(tok::colon)) ||
459 (
Previous.is(TT_ArrayInitializerLSquare) &&
468 const FormatToken &BreakConstructorInitializersToken =
472 if (BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
473 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
475 CurrentState.BreakBeforeParameter) &&
476 ((!Current.isTrailingComment() && Style.
ColumnLimit > 0) ||
477 Current.NewlinesBefore > 0)) {
481 if (Current.is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
482 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
485 if (Current.is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
486 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
488 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
492 unsigned NewLineColumn = getNewLineColumn(State);
493 if (Current.isMemberAccess() && Style.
ColumnLimit != 0 &&
495 (State.Column > NewLineColumn ||
496 Current.NestingLevel < State.StartOfLineLevel)) {
501 (CurrentState.CallContinuation != 0 ||
502 CurrentState.BreakBeforeParameter) &&
508 !(State.Column <= NewLineColumn && Style.
isJavaScript()) &&
509 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
515 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
516 Current.CanBreakBefore) {
520 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
525 Previous.is(tok::comma) || Current.NestingLevel < 2) &&
526 !
Previous.isOneOf(tok::kw_return, tok::lessless, tok::at,
528 !
Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
529 nextIsMultilineString(State)) {
536 if (
Previous.is(TT_BinaryOperator) && Current.CanBreakBefore) {
537 const auto PreviousPrecedence =
Previous.getPrecedence();
539 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
540 const bool LHSIsBinaryExpr =
553 const bool IsComparison =
558 Previous.Previous->isNot(TT_BinaryOperator);
562 }
else if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore &&
564 CurrentState.BreakBeforeParameter) {
569 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
570 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
574 if (Current.NestingLevel == 0 && !Current.isTrailingComment()) {
579 if (
Previous.ClosesTemplateDeclaration) {
580 if (Current.is(tok::kw_concept)) {
590 if (Current.is(TT_RequiresClause)) {
601 Current.NewlinesBefore > 0);
603 if (
Previous.is(TT_FunctionAnnotationRParen) &&
607 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&
608 Current.isNot(TT_LeadingJavaAnnotation)) {
617 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
619 if (BreakBeforeDecoratedTokens.contains(Current.TokenText))
623 if (Current.is(TT_FunctionDeclarationName) &&
624 !State.Line->ReturnTypeWrapped &&
631 CurrentState.BreakBeforeParameter) {
632 for (
const auto *Tok = &
Previous; Tok; Tok = Tok->Previous) {
633 if (Tok->is(TT_LineComment))
635 if (Tok->is(TT_TemplateCloser)) {
636 Tok = Tok->MatchingParen;
639 if (Tok->FirstAfterPPLine)
651 !Current.isOneOf(tok::r_brace, tok::comment)) {
655 if (Current.is(tok::lessless) &&
658 Previous.TokenText ==
"\'\\n\'")))) {
665 if (State.NoContinuation)
673 unsigned ExtraSpaces) {
675 assert(State.NextToken->Previous);
678 assert(!State.Stack.empty());
679 State.NoContinuation =
false;
681 if (Current.is(TT_ImplicitStringLiteral) &&
682 (!
Previous.Tok.getIdentifierInfo() ||
683 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
684 tok::pp_not_keyword)) {
687 if (Current.LastNewlineOffset != 0) {
690 State.Column = EndColumn;
692 unsigned StartColumn =
694 assert(EndColumn >= StartColumn);
695 State.Column += EndColumn - StartColumn;
697 moveStateToNextToken(State, DryRun,
false);
701 unsigned Penalty = 0;
703 Penalty = addTokenOnNewLine(State, DryRun);
705 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
707 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
710void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
711 unsigned ExtraSpaces) {
713 assert(State.NextToken->Previous);
715 auto &CurrentState = State.Stack.back();
722 auto DisallowLineBreaks = [&] {
723 if (!Style.
isCpp() ||
729 if (
Previous.is(TT_BlockComment) && Current.SpacesRequiredBefore == 0)
732 if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
735 const auto *Prev = Current.getPreviousNonComment();
736 if (!Prev || Prev->isNot(tok::l_paren))
739 if (Prev->BlockParameterCount == 0)
743 if (Prev->BlockParameterCount > 1)
750 const auto *Comma = Prev->Role->lastComma();
754 const auto *Next = Comma->getNextNonComment();
755 return Next && !Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
758 if (DisallowLineBreaks())
759 State.NoLineBreak =
true;
761 if (Current.is(tok::equal) &&
762 (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&
763 CurrentState.VariablePos == 0 &&
765 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
766 CurrentState.VariablePos = State.Column;
769 while (Tok && CurrentState.VariablePos >= Tok->ColumnWidth) {
770 CurrentState.VariablePos -= Tok->ColumnWidth;
771 if (Tok->SpacesRequiredBefore != 0)
775 if (
Previous.PartOfMultiVariableDeclStmt)
776 CurrentState.LastSpace = CurrentState.VariablePos;
779 unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
782 int PPColumnCorrection = 0;
784 Previous.is(tok::hash) && State.FirstIndent > 0 &&
788 Spaces += State.FirstIndent;
795 PPColumnCorrection = -1;
800 State.Column + Spaces + PPColumnCorrection,
801 false, State.Line->InMacroBody);
807 Current.is(TT_InheritanceColon)) {
808 CurrentState.NoLineBreak =
true;
812 CurrentState.NoLineBreak =
true;
815 if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
816 unsigned MinIndent = std::max(
818 unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth;
819 if (Current.LongestObjCSelectorName == 0)
820 CurrentState.AlignColons =
false;
821 else if (MinIndent + Current.LongestObjCSelectorName > FirstColonPos)
822 CurrentState.ColonPos = MinIndent + Current.LongestObjCSelectorName;
824 CurrentState.ColonPos = FirstColonPos;
831 auto IsOpeningBracket = [&](
const FormatToken &Tok) {
832 auto IsStartOfBracedList = [&]() {
833 return Tok.is(tok::l_brace) && Tok.isNot(
BK_Block) &&
836 if (!Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
837 !IsStartOfBracedList()) {
842 if (Tok.Previous->isIf())
844 return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
848 auto IsFunctionCallParen = [](
const FormatToken &Tok) {
849 return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous &&
850 Tok.Previous->is(tok::identifier);
852 auto IsInTemplateString = [
this](
const FormatToken &Tok) {
855 for (
const auto *Prev = &Tok; Prev; Prev = Prev->Previous) {
856 if (Prev->is(TT_TemplateString) && Prev->opensScope())
858 if (Prev->opensScope() ||
859 (Prev->is(TT_TemplateString) && Prev->closesScope())) {
866 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
867 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
869 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
870 if (!Tok.FakeLParens.empty() && Tok.FakeLParens.back() >
prec::Unknown)
876 if (Tok.is(tok::kw_new) || Tok.startsSequence(tok::coloncolon, tok::kw_new))
878 if (Tok.is(TT_UnaryOperator) ||
880 Tok.isOneOf(tok::ellipsis, Keywords.
kw_await))) {
883 const auto *
Previous = Tok.Previous;
885 TT_LambdaDefinitionLParen) &&
889 if (IsOpeningBracket(Tok) || IsInTemplateString(Tok))
891 const auto *Next = Tok.Next;
892 return !Next || Next->isMemberAccess() ||
893 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next);
897 IsOpeningBracket(
Previous) && State.Column > getNewLineColumn(State) &&
908 !StartsSimpleOneArgList(Current)) {
909 CurrentState.NoLineBreak =
true;
913 CurrentState.NoLineBreak =
true;
920 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
922 Previous.isNot(TT_TableGenDAGArgOpener) &&
923 Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
924 !(Current.MacroParent &&
Previous.MacroParent) &&
925 (Current.isNot(TT_LineComment) ||
927 !IsInTemplateString(Current)) {
928 CurrentState.Indent = State.Column + Spaces;
929 CurrentState.IsAligned =
true;
932 CurrentState.NoLineBreak =
true;
934 CurrentState.NoLineBreak =
true;
937 State.Column > getNewLineColumn(State)) {
938 CurrentState.ContainsUnwrappedBuilder =
true;
941 if (Current.is(TT_LambdaArrow) && Style.
isJava())
942 CurrentState.NoLineBreak =
true;
943 if (Current.isMemberAccess() &&
Previous.is(tok::r_paren) &&
952 CurrentState.NoLineBreak =
true;
959 const FormatToken *
P = Current.getPreviousNonComment();
960 if (Current.isNot(tok::comment) &&
P &&
961 (
P->isOneOf(TT_BinaryOperator, tok::comma) ||
962 (
P->is(TT_ConditionalExpr) &&
P->is(tok::colon))) &&
963 !
P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
967 bool BreakBeforeOperator =
968 P->MustBreakBefore ||
P->is(tok::lessless) ||
969 (
P->is(TT_BinaryOperator) &&
975 bool HasTwoOperands =
P->OperatorIndex == 0 && !
P->NextOperator &&
976 P->isNot(TT_ConditionalExpr);
977 if ((!BreakBeforeOperator &&
980 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
981 CurrentState.NoLineBreakInOperand =
true;
985 State.Column += Spaces;
986 if (Current.isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
991 CurrentState.LastSpace = State.Column;
992 CurrentState.NestedBlockIndent = State.Column;
993 }
else if (!Current.isOneOf(tok::comment, tok::caret) &&
995 Previous.isNot(TT_OverloadedOperator)) ||
997 CurrentState.LastSpace = State.Column;
998 }
else if (
Previous.is(TT_CtorInitializerColon) &&
999 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
1002 CurrentState.Indent = State.Column;
1003 CurrentState.LastSpace = State.Column;
1004 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
1005 CurrentState.LastSpace = State.Column;
1006 }
else if (
Previous.is(TT_BinaryOperator) &&
1010 Current.StartsBinaryExpression)) {
1014 CurrentState.LastSpace = State.Column;
1015 }
else if (
Previous.is(TT_InheritanceColon)) {
1016 CurrentState.Indent = State.Column;
1017 CurrentState.LastSpace = State.Column;
1018 }
else if (Current.is(TT_CSharpGenericTypeConstraintColon)) {
1019 CurrentState.ColonPos = State.Column;
1020 }
else if (
Previous.opensScope()) {
1027 const FormatToken *Next =
Previous.MatchingParen->getNextNonComment();
1028 if (Next && Next->isMemberAccess() && State.Stack.size() > 1 &&
1029 State.Stack[State.Stack.size() - 2].CallContinuation == 0) {
1030 CurrentState.LastSpace = State.Column;
1036unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
1038 FormatToken &Current = *State.NextToken;
1039 assert(State.NextToken->Previous);
1040 const FormatToken &
Previous = *State.NextToken->Previous;
1041 auto &CurrentState = State.Stack.back();
1045 unsigned Penalty = 0;
1047 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1048 const FormatToken *NextNonComment =
Previous.getNextNonComment();
1049 if (!NextNonComment)
1050 NextNonComment = &Current;
1053 if (!CurrentState.ContainsLineBreak)
1055 CurrentState.ContainsLineBreak =
true;
1057 Penalty += State.NextToken->SplitPenalty;
1062 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1064 CurrentState.BreakBeforeParameter)) {
1068 State.Column = getNewLineColumn(State);
1082 if (State.Column > State.FirstIndent) {
1097 if (Current.isNot(TT_LambdaArrow) &&
1099 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1101 CurrentState.NestedBlockIndent = State.Column;
1104 if (NextNonComment->isMemberAccess()) {
1105 if (CurrentState.CallContinuation == 0)
1106 CurrentState.CallContinuation = State.Column;
1107 }
else if (NextNonComment->is(TT_SelectorName)) {
1108 if (!CurrentState.ObjCSelectorNameFound) {
1109 if (NextNonComment->LongestObjCSelectorName == 0) {
1110 CurrentState.AlignColons =
false;
1112 CurrentState.ColonPos =
1114 ? std::max(CurrentState.Indent,
1116 : CurrentState.Indent) +
1118 NextNonComment->ColumnWidth);
1120 }
else if (CurrentState.AlignColons &&
1121 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1122 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1124 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1125 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1135 if (State.Stack.size() > 1) {
1136 State.Stack[State.Stack.size() - 2].LastSpace =
1137 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1142 if ((PreviousNonComment &&
1143 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1144 !CurrentState.AvoidBinPacking) ||
1146 CurrentState.BreakBeforeParameter =
false;
1148 if (PreviousNonComment &&
1149 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1150 PreviousNonComment->ClosesRequiresClause) &&
1151 Current.NestingLevel == 0) {
1152 CurrentState.BreakBeforeParameter =
false;
1154 if (NextNonComment->is(tok::question) ||
1155 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1156 CurrentState.BreakBeforeParameter =
true;
1158 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1159 CurrentState.BreakBeforeParameter =
false;
1163 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1166 !Current.MatchingParen->Children.empty()) {
1170 MaxEmptyLinesToKeep = 1;
1173 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
1174 bool ContinuePPDirective =
1177 CurrentState.IsAligned, ContinuePPDirective);
1180 if (!Current.isTrailingComment())
1181 CurrentState.LastSpace = State.Column;
1182 if (Current.is(tok::lessless)) {
1186 CurrentState.LastSpace += 3;
1189 State.StartOfLineLevel = Current.NestingLevel;
1190 State.LowestLevelOnLine = Current.NestingLevel;
1194 bool NestedBlockSpecialCase =
1195 (!Style.
isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1196 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1200 NestedBlockSpecialCase =
1201 NestedBlockSpecialCase ||
1202 (Current.MatchingParen &&
1203 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1204 if (!NestedBlockSpecialCase) {
1205 auto ParentLevelIt = std::next(State.Stack.rbegin());
1207 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1222 auto FindCurrentLevel = [&](
const auto &It) {
1223 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1224 return PState.Tok != nullptr;
1227 auto MaybeIncrement = [&](
const auto &It) {
1228 return It != State.Stack.rend() ? std::next(It) : It;
1230 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1231 auto LevelContainingLambdaIt =
1232 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1233 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1235 for (
auto I = ParentLevelIt,
E = State.Stack.rend(); I !=
E; ++I)
1236 I->BreakBeforeParameter =
true;
1239 if (PreviousNonComment &&
1240 !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&
1241 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1242 !PreviousNonComment->ClosesRequiresClause) ||
1243 Current.NestingLevel != 0) &&
1244 !PreviousNonComment->isOneOf(
1245 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1246 TT_LeadingJavaAnnotation) &&
1247 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1251 Current.isNot(TT_LambdaLBrace))) {
1252 CurrentState.BreakBeforeParameter =
true;
1257 if (PreviousNonComment &&
1258 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1260 CurrentState.BreakBeforeClosingBrace =
true;
1263 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1264 CurrentState.BreakBeforeClosingParen =
1268 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))
1271 if (CurrentState.AvoidBinPacking) {
1276 bool PreviousIsBreakingCtorInitializerColon =
1277 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1279 bool AllowAllConstructorInitializersOnNextLine =
1282 if (!(
Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
1283 PreviousIsBreakingCtorInitializerColon) ||
1285 State.Line->MustBeDeclaration) ||
1287 !State.Line->MustBeDeclaration) ||
1288 (!AllowAllConstructorInitializersOnNextLine &&
1289 PreviousIsBreakingCtorInitializerColon) ||
1291 CurrentState.BreakBeforeParameter =
true;
1297 if (PreviousIsBreakingCtorInitializerColon &&
1298 AllowAllConstructorInitializersOnNextLine) {
1299 CurrentState.BreakBeforeParameter =
false;
1304 CurrentState.BreakBeforeParameter =
true;
1309unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1310 if (!State.NextToken || !State.NextToken->Previous)
1313 FormatToken &Current = *State.NextToken;
1314 const auto &CurrentState = State.Stack.back();
1316 if (CurrentState.IsCSharpGenericTypeConstraint &&
1317 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1318 return CurrentState.ColonPos + 2;
1321 const FormatToken &
Previous = *Current.Previous;
1323 unsigned ContinuationIndent =
1324 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1326 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1327 const FormatToken *NextNonComment =
Previous.getNextNonComment();
1328 if (!NextNonComment)
1329 NextNonComment = &Current;
1334 return std::max(CurrentState.LastSpace,
1340 if (Style.
isVerilog() && PreviousNonComment &&
1342 return State.FirstIndent;
1346 State.Line->First->is(tok::kw_enum)) {
1347 return (Style.
IndentWidth * State.Line->First->IndentLevel) +
1354 ? CurrentState.Indent
1355 : State.FirstIndent;
1359 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1361 if (Current.NestingLevel == 0 ||
1363 State.NextToken->is(TT_LambdaLBrace))) {
1364 return State.FirstIndent;
1366 return CurrentState.Indent;
1368 if (Current.is(TT_LambdaArrow) &&
1369 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1370 tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {
1371 return ContinuationIndent;
1373 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1375 State.Stack.size() > 1) {
1376 if (Current.closesBlockOrBlockTypeList(Style))
1377 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1378 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1379 return State.Stack[State.Stack.size() - 2].LastSpace;
1380 return State.FirstIndent;
1397 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1399 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1400 return State.Stack[State.Stack.size() - 2].LastSpace;
1404 if (Style.
isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1405 State.Stack.size() > 1) {
1406 return State.Stack[State.Stack.size() - 2].LastSpace;
1409 (Current.is(tok::r_paren) ||
1410 (Current.is(tok::r_brace) && Current.MatchingParen &&
1412 State.Stack.size() > 1) {
1413 return State.Stack[State.Stack.size() - 2].LastSpace;
1416 State.Stack.size() > 1) {
1417 return State.Stack[State.Stack.size() - 2].LastSpace;
1419 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1420 return State.Stack[State.Stack.size() - 2].LastSpace;
1428 if (Current.is(tok::identifier) && Current.Next &&
1429 (!Style.
isVerilog() || Current.Next->is(tok::colon)) &&
1430 (Current.Next->is(TT_DictLiteral) ||
1431 (Style.
isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1432 return CurrentState.Indent;
1434 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1435 State.StartOfStringLiteral != 0) {
1436 return State.StartOfStringLiteral - 1;
1438 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1439 return State.StartOfStringLiteral;
1440 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1441 return CurrentState.FirstLessLess;
1442 if (NextNonComment->isMemberAccess()) {
1443 if (CurrentState.CallContinuation == 0)
1444 return ContinuationIndent;
1445 return CurrentState.CallContinuation;
1447 if (CurrentState.QuestionColumn != 0 &&
1448 ((NextNonComment->is(tok::colon) &&
1449 NextNonComment->is(TT_ConditionalExpr)) ||
1450 Previous.is(TT_ConditionalExpr))) {
1451 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1452 !NextNonComment->Next->FakeLParens.empty() &&
1454 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1456 !CurrentState.IsWrappedConditional) {
1461 unsigned Indent = CurrentState.Indent;
1468 return CurrentState.QuestionColumn;
1470 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1471 return CurrentState.VariablePos;
1472 if (Current.is(TT_RequiresClause)) {
1479 return CurrentState.Indent;
1484 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1485 TT_InheritanceComma)) {
1488 if ((PreviousNonComment &&
1489 (PreviousNonComment->ClosesTemplateDeclaration ||
1490 PreviousNonComment->ClosesRequiresClause ||
1491 (PreviousNonComment->is(TT_AttributeMacro) &&
1492 Current.isNot(tok::l_paren) &&
1493 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
1494 TT_PointerOrReference)) ||
1495 PreviousNonComment->isOneOf(
1496 TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
1497 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
1499 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1500 return std::max(CurrentState.LastSpace, CurrentState.Indent);
1502 if (NextNonComment->is(TT_SelectorName)) {
1503 if (!CurrentState.ObjCSelectorNameFound) {
1504 unsigned MinIndent = CurrentState.Indent;
1506 MinIndent = std::max(MinIndent,
1519 std::max(NextNonComment->LongestObjCSelectorName,
1520 NextNonComment->ColumnWidth) -
1521 NextNonComment->ColumnWidth;
1523 if (!CurrentState.AlignColons)
1524 return CurrentState.Indent;
1525 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1526 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1527 return CurrentState.Indent;
1529 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1530 return CurrentState.ColonPos;
1531 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1532 if (CurrentState.StartOfArraySubscripts != 0) {
1533 return CurrentState.StartOfArraySubscripts;
1536 return CurrentState.Indent;
1538 return ContinuationIndent;
1543 if (State.Line->InPragmaDirective) {
1544 FormatToken *PragmaType = State.Line->First->Next->Next;
1545 if (PragmaType && PragmaType->TokenText ==
"omp")
1551 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1552 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1553 return CurrentState.Indent;
1556 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1557 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1558 return ContinuationIndent;
1560 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1561 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1562 return ContinuationIndent;
1564 if (NextNonComment->is(TT_CtorInitializerComma))
1565 return CurrentState.Indent;
1566 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1568 return CurrentState.Indent;
1570 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1572 return CurrentState.Indent;
1575 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1576 !Current.isBinaryOperator() &&
1577 !Current.isOneOf(tok::colon, tok::comment)) {
1578 return ContinuationIndent;
1580 if (Current.is(TT_ProtoExtensionLSquare))
1581 return CurrentState.Indent;
1582 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1583 return CurrentState.Indent - Current.Tok.getLength() -
1584 Current.SpacesRequiredBefore;
1586 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1587 CurrentState.UnindentOperator) {
1588 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1589 NextNonComment->SpacesRequiredBefore;
1591 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
1592 !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {
1597 return CurrentState.Indent;
1612unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1613 bool DryRun,
bool Newline) {
1614 assert(State.Stack.size());
1615 const FormatToken &Current = *State.NextToken;
1616 auto &CurrentState = State.Stack.back();
1618 if (Current.is(TT_CSharpGenericTypeConstraint))
1619 CurrentState.IsCSharpGenericTypeConstraint =
true;
1620 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1621 CurrentState.NoLineBreakInOperand =
false;
1622 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1623 CurrentState.AvoidBinPacking =
true;
1624 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1625 if (CurrentState.FirstLessLess == 0)
1626 CurrentState.FirstLessLess = State.Column;
1628 CurrentState.LastOperatorWrapped = Newline;
1630 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1631 CurrentState.LastOperatorWrapped = Newline;
1632 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1633 Current.Previous->isNot(TT_ConditionalExpr)) {
1634 CurrentState.LastOperatorWrapped = Newline;
1636 if (Current.is(TT_ArraySubscriptLSquare) &&
1637 CurrentState.StartOfArraySubscripts == 0) {
1638 CurrentState.StartOfArraySubscripts = State.Column;
1641 auto IsWrappedConditional = [](
const FormatToken &Tok) {
1642 if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question)))
1644 if (Tok.MustBreakBefore)
1647 const FormatToken *Next = Tok.getNextNonComment();
1648 return Next && Next->MustBreakBefore;
1650 if (IsWrappedConditional(Current))
1651 CurrentState.IsWrappedConditional =
true;
1653 CurrentState.QuestionColumn = State.Column;
1655 const FormatToken *
Previous = Current.Previous;
1659 CurrentState.QuestionColumn = State.Column;
1661 if (!Current.opensScope() && !Current.closesScope() &&
1662 Current.isNot(TT_PointerOrReference)) {
1663 State.LowestLevelOnLine =
1664 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1666 if (Current.isMemberAccess())
1667 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1668 if (Current.is(TT_SelectorName))
1669 CurrentState.ObjCSelectorNameFound =
true;
1670 if (Current.is(TT_CtorInitializerColon) &&
1681 CurrentState.NestedBlockIndent = CurrentState.Indent;
1683 CurrentState.AvoidBinPacking =
true;
1684 CurrentState.BreakBeforeParameter =
1689 CurrentState.BreakBeforeParameter =
false;
1692 if (Current.is(TT_CtorInitializerColon) &&
1694 CurrentState.Indent =
1696 CurrentState.NestedBlockIndent = CurrentState.Indent;
1698 CurrentState.AvoidBinPacking =
true;
1700 CurrentState.BreakBeforeParameter =
false;
1702 if (Current.is(TT_InheritanceColon)) {
1703 CurrentState.Indent =
1706 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1707 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1708 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1709 CurrentState.LastSpace = State.Column;
1710 if (Current.is(TT_RequiresExpression) &&
1712 CurrentState.NestedBlockIndent = State.Column;
1716 const FormatToken *
Previous = Current.getPreviousNonComment();
1724 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1726 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1727 !CurrentState.HasMultipleNestedBlocks) {
1728 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1729 for (ParenState &PState : llvm::drop_end(State.Stack))
1730 PState.NoLineBreak =
true;
1731 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1733 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1734 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1735 !
Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr,
1736 TT_CtorInitializerColon)))) {
1737 CurrentState.NestedBlockInlined =
1741 moveStatePastFakeLParens(State, Newline);
1742 moveStatePastScopeCloser(State);
1745 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1746 !State.Stack.back().NoLineBreakInOperand;
1747 moveStatePastScopeOpener(State, Newline);
1748 moveStatePastFakeRParens(State);
1750 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1751 State.StartOfStringLiteral = State.Column + 1;
1752 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1753 State.StartOfStringLiteral = State.Column + 1;
1754 }
else if (Current.is(TT_TableGenMultiLineString) &&
1755 State.StartOfStringLiteral == 0) {
1756 State.StartOfStringLiteral = State.Column + 1;
1757 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1758 State.StartOfStringLiteral = State.Column;
1759 }
else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
1760 !Current.isStringLiteral()) {
1761 State.StartOfStringLiteral = 0;
1764 State.Column += Current.ColumnWidth;
1765 State.NextToken = State.NextToken->Next;
1770 if (Style.
isVerilog() && State.NextToken &&
1771 State.NextToken->MustBreakBefore &&
1774 CurrentState.Indent = State.FirstIndent;
1778 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1781 Current.Role->formatFromToken(State,
this, DryRun);
1788 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1793void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
1795 const FormatToken &Current = *State.NextToken;
1796 if (Current.FakeLParens.empty())
1799 const FormatToken *
Previous = Current.getPreviousNonComment();
1804 bool SkipFirstExtraIndent =
1807 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1811 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1812 const auto &CurrentState = State.Stack.back();
1813 ParenState NewParenState = CurrentState;
1814 NewParenState.Tok =
nullptr;
1815 NewParenState.ContainsLineBreak =
false;
1816 NewParenState.LastOperatorWrapped =
true;
1817 NewParenState.IsChainedConditional =
false;
1818 NewParenState.IsWrappedConditional =
false;
1819 NewParenState.UnindentOperator =
false;
1820 NewParenState.NoLineBreak =
1821 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1825 NewParenState.AvoidBinPacking =
false;
1830 if (!Current.isTrailingComment() &&
1834 (!Style.
isJava() && PrecedenceLevel > 0)) &&
1836 PrecedenceLevel >
prec::Comma || Current.NestingLevel == 0) &&
1839 TT_TableGenDAGArgListCommaToBreak)))) {
1840 NewParenState.Indent = std::max(
1841 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
1848 State.Stack.size() > 1) {
1849 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1861 NewParenState.UnindentOperator =
true;
1864 NewParenState.IsAligned =
true;
1874 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1876 Current.isNot(TT_UnaryOperator) &&
1878 NewParenState.StartOfFunctionCall = State.Column;
1888 &PrecedenceLevel == &Current.FakeLParens.back() &&
1889 !CurrentState.IsWrappedConditional) {
1890 NewParenState.IsChainedConditional =
true;
1891 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1894 !Current.isTrailingComment())) {
1898 NewParenState.BreakBeforeParameter =
false;
1899 State.Stack.push_back(NewParenState);
1900 SkipFirstExtraIndent =
false;
1904void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
1905 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1906 unsigned VariablePos = State.Stack.back().VariablePos;
1907 if (State.Stack.size() == 1) {
1911 State.Stack.pop_back();
1912 State.Stack.back().VariablePos = VariablePos;
1918 State.Stack.back().LastSpace -= Style.
IndentWidth;
1922void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
1924 const FormatToken &Current = *State.NextToken;
1925 if (!Current.opensScope())
1928 const auto &CurrentState = State.Stack.back();
1931 if (Current.isOneOf(tok::less, tok::l_paren) &&
1932 CurrentState.IsCSharpGenericTypeConstraint) {
1936 if (Current.MatchingParen && Current.is(
BK_Block)) {
1937 moveStateToNewBlock(State, Newline);
1941 const bool EndsInComma = [](
const FormatToken *Tok) {
1944 const auto *Prev = Tok->getPreviousNonComment();
1947 return Prev->is(tok::comma);
1948 }(Current.MatchingParen);
1951 unsigned LastSpace = CurrentState.LastSpace;
1952 bool AvoidBinPacking;
1953 bool BreakBeforeParameter =
false;
1954 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
1955 CurrentState.NestedBlockIndent);
1956 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1958 if (Current.opensBlockOrBlockTypeList(Style)) {
1960 std::min(State.Column, CurrentState.NestedBlockIndent);
1961 }
else if (Current.is(tok::l_brace)) {
1963 NewIndent = CurrentState.LastSpace +
1968 const FormatToken *NextNonComment = Current.getNextNonComment();
1969 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
1971 (NextNonComment && NextNonComment->isOneOf(
1972 TT_DesignatedInitializerPeriod,
1973 TT_DesignatedInitializerLSquare));
1974 BreakBeforeParameter = EndsInComma;
1975 if (Current.ParameterCount > 1)
1976 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
1980 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
1982 if (Style.
isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
1988 const FormatToken *Next = Current.Next;
1989 if (Next && Next->is(TT_TableGenDAGArgOperatorID))
1990 NewIndent = State.Column + Next->TokenText.size() + 2;
1997 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
1998 NewIndent = std::max(NewIndent, CurrentState.Indent);
1999 LastSpace = std::max(LastSpace, CurrentState.Indent);
2004 bool ObjCBinPackProtocolList =
2009 bool BinPackDeclaration =
2012 (State.Line->Type ==
LT_ObjCDecl && ObjCBinPackProtocolList);
2014 bool GenericSelection =
2015 Current.getPreviousNonComment() &&
2016 Current.getPreviousNonComment()->is(tok::kw__Generic);
2019 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
2021 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
2027 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
2034 BreakBeforeParameter =
true;
2039 for (
const FormatToken *Tok = &Current;
2040 Tok && Tok != Current.MatchingParen; Tok = Tok->Next) {
2041 if (Tok->MustBreakBefore ||
2042 (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) {
2043 BreakBeforeParameter =
true;
2051 BreakBeforeParameter =
true;
2057 Current.Children.empty() &&
2058 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2059 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2060 (Current.is(TT_TemplateOpener) &&
2061 CurrentState.ContainsUnwrappedBuilder));
2062 State.Stack.push_back(
2063 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2064 auto &NewState = State.Stack.back();
2065 NewState.NestedBlockIndent = NestedBlockIndent;
2066 NewState.BreakBeforeParameter = BreakBeforeParameter;
2067 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2070 Current.is(tok::l_paren)) {
2072 FormatToken
const *next = Current.Next;
2074 if (next->is(TT_LambdaLSquare)) {
2075 NewState.HasMultipleNestedBlocks =
true;
2082 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2084 Current.Previous->is(tok::at);
2087void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
2088 const FormatToken &Current = *State.NextToken;
2089 if (!Current.closesScope())
2094 if (State.Stack.size() > 1 &&
2095 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2096 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2097 State.NextToken->is(TT_TemplateCloser) ||
2098 State.NextToken->is(TT_TableGenListCloser) ||
2099 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2100 State.Stack.pop_back();
2103 auto &CurrentState = State.Stack.back();
2115 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2116 Current.MatchingParen->Previous) {
2117 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2118 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2119 CurrentScopeOpener.MatchingParen) {
2120 int NecessarySpaceInLine =
2122 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2123 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2125 CurrentState.BreakBeforeParameter =
false;
2130 if (Current.is(tok::r_square)) {
2132 const FormatToken *NextNonComment = Current.getNextNonComment();
2133 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2134 CurrentState.StartOfArraySubscripts = 0;
2138void ContinuationIndenter::moveStateToNewBlock(LineState &State,
bool NewLine) {
2140 State.NextToken->is(TT_LambdaLBrace) &&
2141 !State.Line->MightBeFunctionDecl) {
2143 State.Stack.back().NestedBlockIndent = State.FirstIndent + Indent;
2145 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2147 unsigned NewIndent =
2148 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2158 State.NextToken->is(TT_LambdaLBrace);
2160 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2161 State.Stack.back().LastSpace,
2162 true, NoLineBreak));
2163 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2164 State.Stack.back().BreakBeforeParameter =
true;
2170 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2171 if (LastNewlinePos == StringRef::npos) {
2172 return StartColumn +
2176 0, TabWidth, Encoding);
2180unsigned ContinuationIndenter::reformatRawStringLiteral(
2181 const FormatToken &Current, LineState &State,
2182 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2183 unsigned StartColumn = State.Column - Current.ColumnWidth;
2185 StringRef NewDelimiter =
2187 if (NewDelimiter.empty())
2188 NewDelimiter = OldDelimiter;
2191 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2192 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2195 std::string RawText = std::string(
2196 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2197 if (NewDelimiter != OldDelimiter) {
2200 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2201 if (StringRef(RawText).contains(CanonicalDelimiterSuffix))
2202 NewDelimiter = OldDelimiter;
2205 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2206 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2209 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2220 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2242 unsigned CurrentIndent =
2243 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2244 ? State.Stack.back().NestedBlockIndent
2245 : State.Stack.back().Indent;
2246 unsigned NextStartColumn = ContentStartsOnNewline
2258 unsigned LastStartColumn =
2259 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2262 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2263 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2268 return addMultilineToken(Current, State);
2270 if (NewDelimiter != OldDelimiter) {
2273 SourceLocation PrefixDelimiterStart =
2274 Current.Tok.getLocation().getLocWithOffset(2);
2275 auto PrefixErr = Whitespaces.
addReplacement(tooling::Replacement(
2276 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2279 <<
"Failed to update the prefix delimiter of a raw string: "
2280 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2284 SourceLocation SuffixDelimiterStart =
2285 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2286 1 - OldDelimiter.size());
2287 auto SuffixErr = Whitespaces.
addReplacement(tooling::Replacement(
2288 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2291 <<
"Failed to update the suffix delimiter of a raw string: "
2292 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2295 SourceLocation OriginLoc =
2296 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2297 for (
const tooling::Replacement &Fix : Fixes.first) {
2299 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2300 Fix.getLength(), Fix.getReplacementText()));
2302 llvm::errs() <<
"Failed to reformat raw string: "
2303 << llvm::toString(std::move(Err)) <<
"\n";
2308 *NewCode, FirstStartColumn, Style.
TabWidth, Encoding);
2309 State.Column = RawLastLineEndColumn + NewSuffixSize;
2313 unsigned PrefixExcessCharacters =
2318 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2321 for (ParenState &
Paren : State.Stack)
2322 Paren.BreakBeforeParameter =
true;
2327unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2330 for (ParenState &
Paren : State.Stack)
2331 Paren.BreakBeforeParameter =
true;
2333 unsigned ColumnsUsed = State.Column;
2336 State.Column = Current.LastLineColumnWidth;
2343unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2344 LineState &State,
bool DryRun,
2345 bool AllowBreak,
bool Newline) {
2346 unsigned Penalty = 0;
2349 auto RawStringStyle = getRawStringStyle(Current, State);
2350 if (RawStringStyle && !Current.Finalized) {
2351 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2353 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2356 Penalty = addMultilineToken(Current, State);
2359 LineState OriginalState = State;
2363 bool Strict =
false;
2366 bool Exceeded =
false;
2367 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2368 Current, State, AllowBreak,
true, Strict);
2372 LineState StrictState = OriginalState;
2373 unsigned StrictPenalty =
2374 breakProtrudingToken(Current, StrictState, AllowBreak,
2377 Strict = StrictPenalty <= Penalty;
2379 Penalty = StrictPenalty;
2380 State = StrictState;
2386 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2391 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2402 if (!Tok || Tok->isNot(tok::l_paren))
2407 if (Tok->is(TT_TemplateCloser)) {
2412 if (!Tok || Tok->isNot(tok::identifier))
2417std::optional<FormatStyle>
2418ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2419 const LineState &State) {
2420 if (!Current.isStringLiteral())
2421 return std::nullopt;
2424 return std::nullopt;
2426 if (!RawStringStyle && Delimiter->empty()) {
2430 if (!RawStringStyle)
2431 return std::nullopt;
2433 return RawStringStyle;
2436std::unique_ptr<BreakableToken>
2437ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2438 LineState &State,
bool AllowBreak) {
2439 unsigned StartColumn = State.Column - Current.ColumnWidth;
2440 if (Current.isStringLiteral()) {
2457 if (Current.IsUnterminatedLiteral)
2461 if (State.Stack.back().IsInsideObjCArrayLiteral)
2468 if (Style.
isVerilog() && Current.Previous &&
2469 Current.Previous->isOneOf(tok::kw_export, Keywords.
kw_import)) {
2472 StringRef
Text = Current.TokenText;
2478 unsigned UnbreakableTailLength = (State.NextToken &&
canBreak(State))
2480 : Current.UnbreakableTailLength;
2486 Text.ends_with(
"'")) {
2488 }
else if (Style.
isCSharp() &&
Text.starts_with(
"@\"") &&
2489 Text.ends_with(
"\"")) {
2491 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2496 return std::make_unique<BreakableStringLiteralUsingOperators>(
2497 Current, QuoteStyle,
2499 UnbreakableTailLength, State.Line->InPPDirective, Encoding, Style);
2508 if ((
Text.ends_with(Postfix =
"\"") &&
2509 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2510 Text.starts_with(Prefix =
"u\"") ||
2511 Text.starts_with(Prefix =
"U\"") ||
2512 Text.starts_with(Prefix =
"u8\"") ||
2513 Text.starts_with(Prefix =
"L\""))) ||
2514 (
Text.starts_with(Prefix =
"_T(\"") &&
2515 Text.ends_with(Postfix =
"\")"))) {
2516 return std::make_unique<BreakableStringLiteral>(
2517 Current, StartColumn, Prefix, Postfix, UnbreakableTailLength,
2518 State.Line->InPPDirective, Encoding, Style);
2520 }
else if (Current.is(TT_BlockComment)) {
2528 return std::make_unique<BreakableBlockComment>(
2529 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2530 State.Line->InPPDirective, Encoding, Style, Whitespaces.
useCRLF());
2531 }
else if (Current.is(TT_LineComment) &&
2532 (!Current.Previous ||
2533 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2534 bool RegularComments = [&]() {
2535 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2537 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2543 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2547 return std::make_unique<BreakableLineCommentSection>(
2548 Current, StartColumn,
false, Encoding, Style);
2553std::pair<unsigned, bool>
2554ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2555 LineState &State,
bool AllowBreak,
2556 bool DryRun,
bool Strict) {
2557 std::unique_ptr<const BreakableToken> Token =
2558 createBreakableToken(Current, State, AllowBreak);
2561 assert(Token->getLineCount() > 0);
2563 if (Current.is(TT_LineComment)) {
2567 if (ColumnLimit == 0) {
2570 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2572 if (Current.UnbreakableTailLength >= ColumnLimit)
2576 unsigned StartColumn = State.Column - Current.ColumnWidth;
2577 unsigned NewBreakPenalty = Current.isStringLiteral()
2582 bool Exceeded =
false;
2584 bool BreakInserted = Token->introducesBreakBeforeToken();
2587 bool NewBreakBefore =
false;
2591 bool Reflow =
false;
2594 unsigned TailOffset = 0;
2596 unsigned ContentStartColumn =
2597 Token->getContentStartColumn(0,
false);
2599 unsigned RemainingTokenColumns =
2600 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2603 Token->adaptStartOfLine(0, Whitespaces);
2605 unsigned ContentIndent = 0;
2606 unsigned Penalty = 0;
2607 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2608 << StartColumn <<
".\n");
2609 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2610 LineIndex != EndIndex; ++LineIndex) {
2611 LLVM_DEBUG(llvm::dbgs()
2612 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2613 NewBreakBefore =
false;
2617 bool TryReflow = Reflow;
2619 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2620 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2621 << (ContentStartColumn + RemainingTokenColumns)
2622 <<
", space: " << ColumnLimit
2623 <<
", reflown prefix: " << ContentStartColumn
2624 <<
", offset in line: " << TailOffset <<
"\n");
2630 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2631 ContentStartColumn, CommentPragmasRegex);
2632 if (
Split.first == StringRef::npos) {
2635 if (LineIndex < EndIndex - 1) {
2639 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2641 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2644 assert(
Split.first != 0);
2646 if (Token->supportsReflow()) {
2666 unsigned ToSplitColumns = Token->getRangeLength(
2667 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2668 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2671 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2672 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2675 unsigned ToNextSplitColumns = 0;
2676 if (NextSplit.first == StringRef::npos) {
2677 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2678 ContentStartColumn);
2680 ToNextSplitColumns = Token->getRangeLength(
2681 LineIndex, TailOffset,
2682 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2686 ToNextSplitColumns =
2687 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2688 LLVM_DEBUG(llvm::dbgs()
2689 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2690 LLVM_DEBUG(llvm::dbgs()
2691 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2694 bool ContinueOnLine =
2695 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2696 unsigned ExcessCharactersPenalty = 0;
2697 if (!ContinueOnLine && !Strict) {
2700 ExcessCharactersPenalty =
2701 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2703 LLVM_DEBUG(llvm::dbgs()
2704 <<
" Penalty excess: " << ExcessCharactersPenalty
2705 <<
"\n break : " << NewBreakPenalty <<
"\n");
2706 if (ExcessCharactersPenalty < NewBreakPenalty) {
2708 ContinueOnLine =
true;
2711 if (ContinueOnLine) {
2712 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2717 Token->compressWhitespace(LineIndex, TailOffset, Split,
2721 ContentStartColumn += ToSplitColumns + 1;
2722 Penalty += ExcessCharactersPenalty;
2724 RemainingTokenColumns = Token->getRemainingLength(
2725 LineIndex, TailOffset, ContentStartColumn);
2729 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2734 ContentIndent = Token->getContentIndent(LineIndex);
2735 LLVM_DEBUG(llvm::dbgs()
2736 <<
" ContentIndent: " << ContentIndent <<
"\n");
2737 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2740 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2741 LineIndex, TailOffset +
Split.first +
Split.second,
2742 ContentStartColumn);
2743 if (NewRemainingTokenColumns == 0) {
2746 ContentStartColumn =
2747 Token->getContentStartColumn(LineIndex,
true);
2748 NewRemainingTokenColumns = Token->getRemainingLength(
2749 LineIndex, TailOffset +
Split.first +
Split.second,
2750 ContentStartColumn);
2756 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2761 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2762 <<
", " <<
Split.second <<
"\n");
2764 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2768 Penalty += NewBreakPenalty;
2770 RemainingTokenColumns = NewRemainingTokenColumns;
2771 BreakInserted =
true;
2772 NewBreakBefore =
true;
2776 if (LineIndex + 1 != EndIndex) {
2777 unsigned NextLineIndex = LineIndex + 1;
2778 if (NewBreakBefore) {
2797 ContentStartColumn += RemainingTokenColumns + 1;
2802 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2803 LLVM_DEBUG(llvm::dbgs()
2804 <<
" Size of reflown text: " << ContentStartColumn
2805 <<
"\n Potential reflow split: ");
2806 if (SplitBeforeNext.first != StringRef::npos) {
2807 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2808 << SplitBeforeNext.second <<
"\n");
2809 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2812 RemainingTokenColumns = Token->getRemainingLength(
2813 NextLineIndex, TailOffset, ContentStartColumn);
2815 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2816 LLVM_DEBUG(llvm::dbgs()
2817 <<
" Over limit after reflow, need: "
2818 << (ContentStartColumn + RemainingTokenColumns)
2819 <<
", space: " << ColumnLimit
2820 <<
", reflown prefix: " << ContentStartColumn
2821 <<
", offset in line: " << TailOffset <<
"\n");
2827 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2828 ContentStartColumn, CommentPragmasRegex);
2829 if (
Split.first == StringRef::npos) {
2830 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2836 unsigned ToSplitColumns = Token->getRangeLength(
2837 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2838 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2839 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2840 << (ContentStartColumn + ToSplitColumns)
2841 <<
", space: " << ColumnLimit);
2842 unsigned ExcessCharactersPenalty =
2843 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2845 if (NewBreakPenalty < ExcessCharactersPenalty)
2851 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2859 ContentStartColumn =
2860 Token->getContentStartColumn(NextLineIndex,
false);
2861 RemainingTokenColumns = Token->getRemainingLength(
2862 NextLineIndex, TailOffset, ContentStartColumn);
2865 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2880 if (NewBreakBefore) {
2881 assert(Penalty >= NewBreakPenalty);
2882 Penalty -= NewBreakPenalty;
2885 Token->reflow(NextLineIndex, Whitespaces);
2891 Token->getSplitAfterLastLine(TailOffset);
2892 if (SplitAfterLastLine.first != StringRef::npos) {
2893 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2898 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2901 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2904 ContentStartColumn =
2905 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2906 RemainingTokenColumns = Token->getRemainingLength(
2907 Token->getLineCount() - 1,
2908 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2909 ContentStartColumn);
2912 State.Column = ContentStartColumn + RemainingTokenColumns -
2913 Current.UnbreakableTailLength;
2915 if (BreakInserted) {
2917 Token->updateAfterBroken(Whitespaces);
2922 if (Current.isNot(TT_LineComment))
2923 for (ParenState &
Paren : State.Stack)
2924 Paren.BreakBeforeParameter =
true;
2926 if (Current.is(TT_BlockComment))
2927 State.NoContinuation =
true;
2929 State.Stack.back().LastSpace = StartColumn;
2932 Token->updateNextToken(State);
2934 return {Penalty, Exceeded};
2939 return Style.
ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
2942bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
2944 if (!Current.isStringLiteral() || Current.is(TT_ImplicitStringLiteral))
2949 if (Current.TokenText.starts_with(
"R\""))
2951 if (Current.IsMultiline)
2953 if (Current.getNextNonComment() &&
2954 Current.getNextNonComment()->isStringLiteral()) {
2958 State.Column + Current.ColumnWidth + Current.UnbreakableTailLength >
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.
Defines the SourceManager interface.
unsigned LongestObjCSelectorName
Defines the clang::TokenKind enum and support functions.
WhitespaceManager class manages whitespace around tokens and their replacements.
__DEVICE__ int max(int __a, int __b)
This class handles loading and caching of source files into memory.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Token - This structure provides full information about a lexed token.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
Language
The language for the input, used to select and validate the language standard and possible actions.
const FunctionProtoType * T