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 &&
158 if (LessTok.
isNot(tok::less))
170 if (TokenText.size() < 5
171 || !TokenText.starts_with(
"R\"") || !TokenText.ends_with(
"\"")) {
178 size_t LParenPos = TokenText.substr(0, 19).find_first_of(
'(');
179 if (LParenPos == StringRef::npos)
181 StringRef Delimiter = TokenText.substr(2, LParenPos - 2);
184 size_t RParenPos = TokenText.size() - Delimiter.size() - 2;
185 if (TokenText[RParenPos] !=
')')
187 if (!TokenText.substr(RParenPos + 1).starts_with(Delimiter))
199 return StringRef(Format.CanonicalDelimiter);
206 std::optional<FormatStyle> LanguageStyle =
208 if (!LanguageStyle) {
211 RawStringFormat.Language, &PredefinedStyle)) {
213 PredefinedStyle.
Language = RawStringFormat.Language;
215 LanguageStyle = PredefinedStyle;
218 for (StringRef Delimiter : RawStringFormat.Delimiters)
220 for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions)
225std::optional<FormatStyle>
233std::optional<FormatStyle>
235 StringRef EnclosingFunction)
const {
247 bool BinPackInconclusiveFunctions)
248 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),
249 Whitespaces(Whitespaces), Encoding(Encoding),
250 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
251 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}
254 unsigned FirstStartColumn,
258 State.FirstIndent = FirstIndent;
259 if (FirstStartColumn &&
Line->First->NewlinesBefore == 0)
260 State.Column = FirstStartColumn;
262 State.Column = FirstIndent;
272 State.NextToken =
Line->First;
273 State.Stack.push_back(
ParenState(
nullptr, FirstIndent, FirstIndent,
276 State.NoContinuation =
false;
277 State.StartOfStringLiteral = 0;
278 State.NoLineBreak =
false;
279 State.StartOfLineLevel = 0;
280 State.LowestLevelOnLine = 0;
281 State.IgnoreStackForComparison =
false;
286 auto &CurrentState = State.Stack.back();
287 CurrentState.AvoidBinPacking =
true;
288 CurrentState.BreakBeforeParameter =
true;
289 CurrentState.AlignColons =
false;
293 moveStateToNextToken(State, DryRun,
false);
300 const auto &CurrentState = State.Stack.back();
301 assert(&
Previous == Current.Previous);
302 if (!Current.CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&
303 Current.closesBlockOrBlockTypeList(Style))) {
308 if (!Current.MustBreakBefore &&
Previous.is(tok::l_brace) &&
311 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {
320 State.LowestLevelOnLine < State.StartOfLineLevel &&
321 State.LowestLevelOnLine < Current.NestingLevel) {
324 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)
329 if (
Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
330 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&
331 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks &&
338 if (Current.is(TT_FunctionDeclarationName)) {
345 assert(State.Column >= State.FirstIndent);
346 if (State.Column - State.FirstIndent < 6)
353 if (Current.is(tok::r_brace) && Current.MatchingParen &&
354 Current.isBlockIndentedInitRBrace(Style)) {
355 return CurrentState.BreakBeforeClosingBrace;
360 if (!Current.isOneOf(TT_BinaryOperator, tok::comma) &&
365 Current.isNot(TT_LambdaLBrace)) &&
366 CurrentState.NoLineBreakInOperand) {
373 if (Current.is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
375 Previous.MatchingParen->Previous->MatchingParen &&
376 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
378 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
382 return !State.NoLineBreak && !CurrentState.NoLineBreak;
388 const auto &CurrentState = State.Stack.back();
390 Current.is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
394 if (Current.MustBreakBefore ||
395 (Current.is(TT_InlineASMColon) &&
401 if (CurrentState.BreakBeforeClosingBrace &&
402 (Current.closesBlockOrBlockTypeList(Style) ||
403 (Current.is(tok::r_brace) &&
404 Current.isBlockIndentedInitRBrace(Style)))) {
407 if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
411 Current.ObjCSelectorNameParts > 1 &&
412 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
417 if (CurrentState.IsCSharpGenericTypeConstraint &&
418 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
422 (
Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
423 State.Line->First->isNot(TT_AttributeSquare) && Style.
isCpp() &&
433 Previous.is(TT_ConditionalExpr))) &&
434 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
435 !Current.isOneOf(tok::r_paren, tok::r_brace)) {
438 if (CurrentState.IsChainedConditional &&
440 Current.is(tok::colon)) ||
446 (
Previous.is(TT_ArrayInitializerLSquare) &&
455 const FormatToken &BreakConstructorInitializersToken =
459 if (BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
460 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
462 CurrentState.BreakBeforeParameter) &&
463 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
465 Style.
ColumnLimit > 0 || Current.NewlinesBefore > 0)) {
469 if (Current.is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
470 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
473 if (Current.is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
474 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
476 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
480 unsigned NewLineColumn = getNewLineColumn(State);
481 if (Current.isMemberAccess() && Style.
ColumnLimit != 0 &&
483 (State.Column > NewLineColumn ||
484 Current.NestingLevel < State.StartOfLineLevel)) {
489 (CurrentState.CallContinuation != 0 ||
490 CurrentState.BreakBeforeParameter) &&
496 !(State.Column <= NewLineColumn && Style.
isJavaScript()) &&
497 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
503 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
504 Current.CanBreakBefore) {
508 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
513 Previous.is(tok::comma) || Current.NestingLevel < 2) &&
514 !
Previous.isOneOf(tok::kw_return, tok::lessless, tok::at,
516 !
Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
517 nextIsMultilineString(State)) {
524 if (
Previous.is(TT_BinaryOperator) && Current.CanBreakBefore) {
525 const auto PreviousPrecedence =
Previous.getPrecedence();
527 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
528 const bool LHSIsBinaryExpr =
541 const bool IsComparison =
546 Previous.Previous->isNot(TT_BinaryOperator);
550 }
else if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore &&
551 CurrentState.BreakBeforeParameter) {
556 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
557 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
561 if (Current.NestingLevel == 0 && !Current.isTrailingComment()) {
566 if (
Previous.ClosesTemplateDeclaration) {
567 if (Current.is(tok::kw_concept)) {
577 if (Current.is(TT_RequiresClause)) {
588 Current.NewlinesBefore > 0);
590 if (
Previous.is(TT_FunctionAnnotationRParen) &&
594 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&
595 Current.isNot(TT_LeadingJavaAnnotation)) {
604 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
606 if (BreakBeforeDecoratedTokens.contains(Current.TokenText))
610 if (Current.is(TT_FunctionDeclarationName) &&
611 !State.Line->ReturnTypeWrapped &&
618 CurrentState.BreakBeforeParameter) {
627 !Current.isOneOf(tok::r_brace, tok::comment)) {
631 if (Current.is(tok::lessless) &&
634 Previous.TokenText ==
"\'\\n\'")))) {
641 if (State.NoContinuation)
649 unsigned ExtraSpaces) {
651 assert(State.NextToken->Previous);
654 assert(!State.Stack.empty());
655 State.NoContinuation =
false;
657 if (Current.is(TT_ImplicitStringLiteral) &&
658 (!
Previous.Tok.getIdentifierInfo() ||
659 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
660 tok::pp_not_keyword)) {
663 if (Current.LastNewlineOffset != 0) {
666 State.Column = EndColumn;
668 unsigned StartColumn =
670 assert(EndColumn >= StartColumn);
671 State.Column += EndColumn - StartColumn;
673 moveStateToNextToken(State, DryRun,
false);
677 unsigned Penalty = 0;
679 Penalty = addTokenOnNewLine(State, DryRun);
681 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
683 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
686void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
687 unsigned ExtraSpaces) {
689 assert(State.NextToken->Previous);
691 auto &CurrentState = State.Stack.back();
693 bool DisallowLineBreaksOnThisLine =
700 Style.
isCpp() && [&] {
702 if (
Previous.is(TT_BlockComment) && Current.SpacesRequiredBefore == 0)
704 const auto *PrevNonComment = Current.getPreviousNonComment();
705 if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren))
707 if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
709 auto BlockParameterCount = PrevNonComment->BlockParameterCount;
710 if (BlockParameterCount == 0)
714 if (BlockParameterCount > 1)
718 if (!PrevNonComment->Role)
720 auto Comma = PrevNonComment->Role->lastComma();
723 auto Next = Comma->getNextNonComment();
725 !Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
728 if (DisallowLineBreaksOnThisLine)
729 State.NoLineBreak =
true;
731 if (Current.is(tok::equal) &&
732 (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&
733 CurrentState.VariablePos == 0 &&
735 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
736 CurrentState.VariablePos = State.Column;
739 while (Tok && CurrentState.VariablePos >= Tok->ColumnWidth) {
740 CurrentState.VariablePos -= Tok->ColumnWidth;
741 if (Tok->SpacesRequiredBefore != 0)
745 if (
Previous.PartOfMultiVariableDeclStmt)
746 CurrentState.LastSpace = CurrentState.VariablePos;
749 unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
752 int PPColumnCorrection = 0;
754 Previous.is(tok::hash) && State.FirstIndent > 0 &&
758 Spaces += State.FirstIndent;
765 PPColumnCorrection = -1;
770 State.Column + Spaces + PPColumnCorrection,
771 false, State.Line->InMacroBody);
777 Current.is(TT_InheritanceColon)) {
778 CurrentState.NoLineBreak =
true;
782 CurrentState.NoLineBreak =
true;
785 if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
786 unsigned MinIndent = std::max(
788 unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth;
789 if (Current.LongestObjCSelectorName == 0)
790 CurrentState.AlignColons =
false;
791 else if (MinIndent + Current.LongestObjCSelectorName > FirstColonPos)
792 CurrentState.ColonPos = MinIndent + Current.LongestObjCSelectorName;
794 CurrentState.ColonPos = FirstColonPos;
801 auto IsOpeningBracket = [&](
const FormatToken &Tok) {
802 auto IsStartOfBracedList = [&]() {
803 return Tok.is(tok::l_brace) && Tok.isNot(
BK_Block) &&
806 if (!Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
807 !IsStartOfBracedList()) {
812 if (Tok.Previous->isIf())
814 return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
818 auto IsFunctionCallParen = [](
const FormatToken &Tok) {
819 return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous &&
820 Tok.Previous->is(tok::identifier);
822 auto IsInTemplateString = [
this](
const FormatToken &Tok) {
825 for (
const auto *Prev = &Tok; Prev; Prev = Prev->Previous) {
826 if (Prev->is(TT_TemplateString) && Prev->opensScope())
828 if (Prev->opensScope() ||
829 (Prev->is(TT_TemplateString) && Prev->closesScope())) {
836 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
837 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
839 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
840 if (!Tok.FakeLParens.empty() && Tok.FakeLParens.back() >
prec::Unknown)
846 if (Tok.is(tok::kw_new) || Tok.startsSequence(tok::coloncolon, tok::kw_new))
848 if (Tok.is(TT_UnaryOperator) ||
850 Tok.isOneOf(tok::ellipsis, Keywords.
kw_await))) {
853 const auto *
Previous = Tok.Previous;
855 TT_LambdaDefinitionLParen) &&
859 if (IsOpeningBracket(Tok) || IsInTemplateString(Tok))
861 const auto *Next = Tok.Next;
862 return !Next || Next->isMemberAccess() ||
863 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next);
867 IsOpeningBracket(
Previous) && State.Column > getNewLineColumn(State) &&
878 !StartsSimpleOneArgList(Current)) {
879 CurrentState.NoLineBreak =
true;
883 CurrentState.NoLineBreak =
true;
890 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
892 Previous.isNot(TT_TableGenDAGArgOpener) &&
893 Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
894 !(Current.MacroParent &&
Previous.MacroParent) &&
895 (Current.isNot(TT_LineComment) ||
897 !IsInTemplateString(Current)) {
898 CurrentState.Indent = State.Column + Spaces;
899 CurrentState.IsAligned =
true;
902 CurrentState.NoLineBreak =
true;
904 CurrentState.NoLineBreak =
true;
907 State.Column > getNewLineColumn(State)) {
908 CurrentState.ContainsUnwrappedBuilder =
true;
912 CurrentState.NoLineBreak =
true;
913 if (Current.isMemberAccess() &&
Previous.is(tok::r_paren) &&
922 CurrentState.NoLineBreak =
true;
929 const FormatToken *
P = Current.getPreviousNonComment();
930 if (Current.isNot(tok::comment) &&
P &&
931 (
P->isOneOf(TT_BinaryOperator, tok::comma) ||
932 (
P->is(TT_ConditionalExpr) &&
P->is(tok::colon))) &&
933 !
P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
937 bool BreakBeforeOperator =
938 P->MustBreakBefore ||
P->is(tok::lessless) ||
939 (
P->is(TT_BinaryOperator) &&
945 bool HasTwoOperands =
P->OperatorIndex == 0 && !
P->NextOperator &&
946 P->isNot(TT_ConditionalExpr);
947 if ((!BreakBeforeOperator &&
950 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
951 CurrentState.NoLineBreakInOperand =
true;
955 State.Column += Spaces;
956 if (Current.isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
961 CurrentState.LastSpace = State.Column;
962 CurrentState.NestedBlockIndent = State.Column;
963 }
else if (!Current.isOneOf(tok::comment, tok::caret) &&
965 Previous.isNot(TT_OverloadedOperator)) ||
967 CurrentState.LastSpace = State.Column;
968 }
else if (
Previous.is(TT_CtorInitializerColon) &&
969 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
972 CurrentState.Indent = State.Column;
973 CurrentState.LastSpace = State.Column;
974 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
975 CurrentState.LastSpace = State.Column;
976 }
else if (
Previous.is(TT_BinaryOperator) &&
980 Current.StartsBinaryExpression)) {
984 CurrentState.LastSpace = State.Column;
985 }
else if (
Previous.is(TT_InheritanceColon)) {
986 CurrentState.Indent = State.Column;
987 CurrentState.LastSpace = State.Column;
988 }
else if (Current.is(TT_CSharpGenericTypeConstraintColon)) {
989 CurrentState.ColonPos = State.Column;
997 const FormatToken *Next =
Previous.MatchingParen->getNextNonComment();
998 if (Next && Next->isMemberAccess() && State.Stack.size() > 1 &&
999 State.Stack[State.Stack.size() - 2].CallContinuation == 0) {
1000 CurrentState.LastSpace = State.Column;
1006unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
1008 FormatToken &Current = *State.NextToken;
1009 assert(State.NextToken->Previous);
1010 const FormatToken &
Previous = *State.NextToken->Previous;
1011 auto &CurrentState = State.Stack.back();
1015 unsigned Penalty = 0;
1017 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1018 const FormatToken *NextNonComment =
Previous.getNextNonComment();
1019 if (!NextNonComment)
1020 NextNonComment = &Current;
1023 if (!CurrentState.ContainsLineBreak)
1025 CurrentState.ContainsLineBreak =
true;
1027 Penalty += State.NextToken->SplitPenalty;
1032 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1034 CurrentState.BreakBeforeParameter)) {
1038 State.Column = getNewLineColumn(State);
1052 if (State.Column > State.FirstIndent) {
1067 if (Current.isNot(TT_LambdaArrow) &&
1069 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1071 CurrentState.NestedBlockIndent = State.Column;
1074 if (NextNonComment->isMemberAccess()) {
1075 if (CurrentState.CallContinuation == 0)
1076 CurrentState.CallContinuation = State.Column;
1077 }
else if (NextNonComment->is(TT_SelectorName)) {
1078 if (!CurrentState.ObjCSelectorNameFound) {
1079 if (NextNonComment->LongestObjCSelectorName == 0) {
1080 CurrentState.AlignColons =
false;
1082 CurrentState.ColonPos =
1084 ? std::max(CurrentState.Indent,
1086 : CurrentState.Indent) +
1088 NextNonComment->ColumnWidth);
1090 }
else if (CurrentState.AlignColons &&
1091 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1092 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1094 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1095 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1105 if (State.Stack.size() > 1) {
1106 State.Stack[State.Stack.size() - 2].LastSpace =
1107 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1112 if ((PreviousNonComment &&
1113 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1114 !CurrentState.AvoidBinPacking) ||
1116 CurrentState.BreakBeforeParameter =
false;
1118 if (PreviousNonComment &&
1119 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1120 PreviousNonComment->ClosesRequiresClause) &&
1121 Current.NestingLevel == 0) {
1122 CurrentState.BreakBeforeParameter =
false;
1124 if (NextNonComment->is(tok::question) ||
1125 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1126 CurrentState.BreakBeforeParameter =
true;
1128 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1129 CurrentState.BreakBeforeParameter =
false;
1133 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1136 !Current.MatchingParen->Children.empty()) {
1140 MaxEmptyLinesToKeep = 1;
1143 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
1144 bool ContinuePPDirective =
1147 CurrentState.IsAligned, ContinuePPDirective);
1150 if (!Current.isTrailingComment())
1151 CurrentState.LastSpace = State.Column;
1152 if (Current.is(tok::lessless)) {
1156 CurrentState.LastSpace += 3;
1159 State.StartOfLineLevel = Current.NestingLevel;
1160 State.LowestLevelOnLine = Current.NestingLevel;
1164 bool NestedBlockSpecialCase =
1165 (!Style.
isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1166 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1170 NestedBlockSpecialCase =
1171 NestedBlockSpecialCase ||
1172 (Current.MatchingParen &&
1173 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1174 if (!NestedBlockSpecialCase) {
1175 auto ParentLevelIt = std::next(State.Stack.rbegin());
1177 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1192 auto FindCurrentLevel = [&](
const auto &It) {
1193 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1194 return PState.Tok != nullptr;
1197 auto MaybeIncrement = [&](
const auto &It) {
1198 return It != State.Stack.rend() ? std::next(It) : It;
1200 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1201 auto LevelContainingLambdaIt =
1202 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1203 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1205 for (
auto I = ParentLevelIt,
E = State.Stack.rend(); I !=
E; ++I)
1206 I->BreakBeforeParameter =
true;
1209 if (PreviousNonComment &&
1210 !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&
1211 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1212 !PreviousNonComment->ClosesRequiresClause) ||
1213 Current.NestingLevel != 0) &&
1214 !PreviousNonComment->isOneOf(
1215 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1216 TT_LeadingJavaAnnotation) &&
1217 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1221 Current.isNot(TT_LambdaLBrace))) {
1222 CurrentState.BreakBeforeParameter =
true;
1227 if (PreviousNonComment &&
1228 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1230 CurrentState.BreakBeforeClosingBrace =
true;
1233 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1234 CurrentState.BreakBeforeClosingParen =
1238 if (CurrentState.AvoidBinPacking) {
1243 bool PreviousIsBreakingCtorInitializerColon =
1244 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1246 bool AllowAllConstructorInitializersOnNextLine =
1249 if (!(
Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
1250 PreviousIsBreakingCtorInitializerColon) ||
1252 State.Line->MustBeDeclaration) ||
1254 !State.Line->MustBeDeclaration) ||
1255 (!AllowAllConstructorInitializersOnNextLine &&
1256 PreviousIsBreakingCtorInitializerColon) ||
1258 CurrentState.BreakBeforeParameter =
true;
1264 if (PreviousIsBreakingCtorInitializerColon &&
1265 AllowAllConstructorInitializersOnNextLine) {
1266 CurrentState.BreakBeforeParameter =
false;
1271 CurrentState.BreakBeforeParameter =
true;
1276unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1277 if (!State.NextToken || !State.NextToken->Previous)
1280 FormatToken &Current = *State.NextToken;
1281 const auto &CurrentState = State.Stack.back();
1283 if (CurrentState.IsCSharpGenericTypeConstraint &&
1284 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1285 return CurrentState.ColonPos + 2;
1288 const FormatToken &
Previous = *Current.Previous;
1290 unsigned ContinuationIndent =
1291 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1293 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1294 const FormatToken *NextNonComment =
Previous.getNextNonComment();
1295 if (!NextNonComment)
1296 NextNonComment = &Current;
1301 return std::max(CurrentState.LastSpace,
1307 if (Style.
isVerilog() && PreviousNonComment &&
1309 return State.FirstIndent;
1313 State.Line->First->is(tok::kw_enum)) {
1314 return (Style.
IndentWidth * State.Line->First->IndentLevel) +
1318 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1320 if (Current.NestingLevel == 0 ||
1322 State.NextToken->is(TT_LambdaLBrace))) {
1323 return State.FirstIndent;
1325 return CurrentState.Indent;
1327 if (Current.is(TT_LambdaArrow) &&
1328 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1329 tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {
1330 return ContinuationIndent;
1332 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1334 State.Stack.size() > 1) {
1335 if (Current.closesBlockOrBlockTypeList(Style))
1336 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1337 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1338 return State.Stack[State.Stack.size() - 2].LastSpace;
1339 return State.FirstIndent;
1356 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1358 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1359 return State.Stack[State.Stack.size() - 2].LastSpace;
1363 if (Style.
isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1364 State.Stack.size() > 1) {
1365 return State.Stack[State.Stack.size() - 2].LastSpace;
1368 (Current.is(tok::r_paren) ||
1369 (Current.is(tok::r_brace) && Current.MatchingParen &&
1371 State.Stack.size() > 1) {
1372 return State.Stack[State.Stack.size() - 2].LastSpace;
1374 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1375 return State.Stack[State.Stack.size() - 2].LastSpace;
1383 if (Current.is(tok::identifier) && Current.Next &&
1384 (!Style.
isVerilog() || Current.Next->is(tok::colon)) &&
1385 (Current.Next->is(TT_DictLiteral) ||
1386 (Style.
isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1387 return CurrentState.Indent;
1389 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1390 State.StartOfStringLiteral != 0) {
1391 return State.StartOfStringLiteral - 1;
1393 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1394 return State.StartOfStringLiteral;
1395 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1396 return CurrentState.FirstLessLess;
1397 if (NextNonComment->isMemberAccess()) {
1398 if (CurrentState.CallContinuation == 0)
1399 return ContinuationIndent;
1400 return CurrentState.CallContinuation;
1402 if (CurrentState.QuestionColumn != 0 &&
1403 ((NextNonComment->is(tok::colon) &&
1404 NextNonComment->is(TT_ConditionalExpr)) ||
1405 Previous.is(TT_ConditionalExpr))) {
1406 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1407 !NextNonComment->Next->FakeLParens.empty() &&
1409 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1411 !CurrentState.IsWrappedConditional) {
1416 unsigned Indent = CurrentState.Indent;
1423 return CurrentState.QuestionColumn;
1425 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1426 return CurrentState.VariablePos;
1427 if (Current.is(TT_RequiresClause)) {
1434 return CurrentState.Indent;
1439 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1440 TT_InheritanceComma)) {
1443 if ((PreviousNonComment &&
1444 (PreviousNonComment->ClosesTemplateDeclaration ||
1445 PreviousNonComment->ClosesRequiresClause ||
1446 (PreviousNonComment->is(TT_AttributeMacro) &&
1447 Current.isNot(tok::l_paren)) ||
1448 PreviousNonComment->isOneOf(
1449 TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
1450 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
1452 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1453 return std::max(CurrentState.LastSpace, CurrentState.Indent);
1455 if (NextNonComment->is(TT_SelectorName)) {
1456 if (!CurrentState.ObjCSelectorNameFound) {
1457 unsigned MinIndent = CurrentState.Indent;
1459 MinIndent = std::max(MinIndent,
1472 std::max(NextNonComment->LongestObjCSelectorName,
1473 NextNonComment->ColumnWidth) -
1474 NextNonComment->ColumnWidth;
1476 if (!CurrentState.AlignColons)
1477 return CurrentState.Indent;
1478 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1479 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1480 return CurrentState.Indent;
1482 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1483 return CurrentState.ColonPos;
1484 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1485 if (CurrentState.StartOfArraySubscripts != 0) {
1486 return CurrentState.StartOfArraySubscripts;
1489 return CurrentState.Indent;
1491 return ContinuationIndent;
1496 if (State.Line->InPragmaDirective) {
1497 FormatToken *PragmaType = State.Line->First->Next->Next;
1498 if (PragmaType && PragmaType->TokenText ==
"omp")
1504 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1505 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1506 return CurrentState.Indent;
1509 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1510 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1511 return ContinuationIndent;
1513 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1514 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1515 return ContinuationIndent;
1517 if (NextNonComment->is(TT_CtorInitializerComma))
1518 return CurrentState.Indent;
1519 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1521 return CurrentState.Indent;
1523 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1525 return CurrentState.Indent;
1528 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1529 !Current.isBinaryOperator() &&
1530 !Current.isOneOf(tok::colon, tok::comment)) {
1531 return ContinuationIndent;
1533 if (Current.is(TT_ProtoExtensionLSquare))
1534 return CurrentState.Indent;
1535 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1536 return CurrentState.Indent - Current.Tok.getLength() -
1537 Current.SpacesRequiredBefore;
1539 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1540 CurrentState.UnindentOperator) {
1541 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1542 NextNonComment->SpacesRequiredBefore;
1544 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
1545 !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {
1550 return CurrentState.Indent;
1565unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1566 bool DryRun,
bool Newline) {
1567 assert(State.Stack.size());
1568 const FormatToken &Current = *State.NextToken;
1569 auto &CurrentState = State.Stack.back();
1571 if (Current.is(TT_CSharpGenericTypeConstraint))
1572 CurrentState.IsCSharpGenericTypeConstraint =
true;
1573 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1574 CurrentState.NoLineBreakInOperand =
false;
1575 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1576 CurrentState.AvoidBinPacking =
true;
1577 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1578 if (CurrentState.FirstLessLess == 0)
1579 CurrentState.FirstLessLess = State.Column;
1581 CurrentState.LastOperatorWrapped = Newline;
1583 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1584 CurrentState.LastOperatorWrapped = Newline;
1585 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1586 Current.Previous->isNot(TT_ConditionalExpr)) {
1587 CurrentState.LastOperatorWrapped = Newline;
1589 if (Current.is(TT_ArraySubscriptLSquare) &&
1590 CurrentState.StartOfArraySubscripts == 0) {
1591 CurrentState.StartOfArraySubscripts = State.Column;
1594 auto IsWrappedConditional = [](
const FormatToken &Tok) {
1595 if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question)))
1597 if (Tok.MustBreakBefore)
1600 const FormatToken *Next = Tok.getNextNonComment();
1601 return Next && Next->MustBreakBefore;
1603 if (IsWrappedConditional(Current))
1604 CurrentState.IsWrappedConditional =
true;
1606 CurrentState.QuestionColumn = State.Column;
1608 const FormatToken *
Previous = Current.Previous;
1612 CurrentState.QuestionColumn = State.Column;
1614 if (!Current.opensScope() && !Current.closesScope() &&
1615 Current.isNot(TT_PointerOrReference)) {
1616 State.LowestLevelOnLine =
1617 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1619 if (Current.isMemberAccess())
1620 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1621 if (Current.is(TT_SelectorName))
1622 CurrentState.ObjCSelectorNameFound =
true;
1623 if (Current.is(TT_CtorInitializerColon) &&
1634 CurrentState.NestedBlockIndent = CurrentState.Indent;
1636 CurrentState.AvoidBinPacking =
true;
1637 CurrentState.BreakBeforeParameter =
1642 CurrentState.BreakBeforeParameter =
false;
1645 if (Current.is(TT_CtorInitializerColon) &&
1647 CurrentState.Indent =
1649 CurrentState.NestedBlockIndent = CurrentState.Indent;
1651 CurrentState.AvoidBinPacking =
true;
1653 CurrentState.BreakBeforeParameter =
false;
1655 if (Current.is(TT_InheritanceColon)) {
1656 CurrentState.Indent =
1659 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1660 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1661 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1662 CurrentState.LastSpace = State.Column;
1663 if (Current.is(TT_RequiresExpression) &&
1665 CurrentState.NestedBlockIndent = State.Column;
1669 const FormatToken *
Previous = Current.getPreviousNonComment();
1677 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1679 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1680 !CurrentState.HasMultipleNestedBlocks) {
1681 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1682 for (ParenState &PState : llvm::drop_end(State.Stack))
1683 PState.NoLineBreak =
true;
1684 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1686 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1687 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1688 !
Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))) {
1689 CurrentState.NestedBlockInlined =
1693 moveStatePastFakeLParens(State, Newline);
1694 moveStatePastScopeCloser(State);
1697 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1698 !State.Stack.back().NoLineBreakInOperand;
1699 moveStatePastScopeOpener(State, Newline);
1700 moveStatePastFakeRParens(State);
1702 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1703 State.StartOfStringLiteral = State.Column + 1;
1704 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1705 State.StartOfStringLiteral = State.Column + 1;
1706 }
else if (Current.is(TT_TableGenMultiLineString) &&
1707 State.StartOfStringLiteral == 0) {
1708 State.StartOfStringLiteral = State.Column + 1;
1709 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1710 State.StartOfStringLiteral = State.Column;
1711 }
else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
1712 !Current.isStringLiteral()) {
1713 State.StartOfStringLiteral = 0;
1716 State.Column += Current.ColumnWidth;
1717 State.NextToken = State.NextToken->Next;
1722 if (Style.
isVerilog() && State.NextToken &&
1723 State.NextToken->MustBreakBefore &&
1726 CurrentState.Indent = State.FirstIndent;
1730 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1733 Current.Role->formatFromToken(State,
this, DryRun);
1740 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1745void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
1747 const FormatToken &Current = *State.NextToken;
1748 if (Current.FakeLParens.empty())
1751 const FormatToken *
Previous = Current.getPreviousNonComment();
1756 bool SkipFirstExtraIndent =
1759 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1763 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1764 const auto &CurrentState = State.Stack.back();
1765 ParenState NewParenState = CurrentState;
1766 NewParenState.Tok =
nullptr;
1767 NewParenState.ContainsLineBreak =
false;
1768 NewParenState.LastOperatorWrapped =
true;
1769 NewParenState.IsChainedConditional =
false;
1770 NewParenState.IsWrappedConditional =
false;
1771 NewParenState.UnindentOperator =
false;
1772 NewParenState.NoLineBreak =
1773 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1777 NewParenState.AvoidBinPacking =
false;
1782 if (!Current.isTrailingComment() &&
1788 PrecedenceLevel >
prec::Comma || Current.NestingLevel == 0) &&
1791 TT_TableGenDAGArgListCommaToBreak)))) {
1792 NewParenState.Indent = std::max(
1793 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
1800 State.Stack.size() > 1) {
1801 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1813 NewParenState.UnindentOperator =
true;
1816 NewParenState.IsAligned =
true;
1826 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1828 Current.isNot(TT_UnaryOperator) &&
1830 NewParenState.StartOfFunctionCall = State.Column;
1840 &PrecedenceLevel == &Current.FakeLParens.back() &&
1841 !CurrentState.IsWrappedConditional) {
1842 NewParenState.IsChainedConditional =
true;
1843 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1846 !Current.isTrailingComment())) {
1850 NewParenState.BreakBeforeParameter =
false;
1851 State.Stack.push_back(NewParenState);
1852 SkipFirstExtraIndent =
false;
1856void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
1857 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1858 unsigned VariablePos = State.Stack.back().VariablePos;
1859 if (State.Stack.size() == 1) {
1863 State.Stack.pop_back();
1864 State.Stack.back().VariablePos = VariablePos;
1870 State.Stack.back().LastSpace -= Style.
IndentWidth;
1874void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
1876 const FormatToken &Current = *State.NextToken;
1877 if (!Current.opensScope())
1880 const auto &CurrentState = State.Stack.back();
1883 if (Current.isOneOf(tok::less, tok::l_paren) &&
1884 CurrentState.IsCSharpGenericTypeConstraint) {
1888 if (Current.MatchingParen && Current.is(
BK_Block)) {
1889 moveStateToNewBlock(State, Newline);
1894 unsigned LastSpace = CurrentState.LastSpace;
1895 bool AvoidBinPacking;
1896 bool BreakBeforeParameter =
false;
1897 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
1898 CurrentState.NestedBlockIndent);
1899 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1901 if (Current.opensBlockOrBlockTypeList(Style)) {
1903 std::min(State.Column, CurrentState.NestedBlockIndent);
1904 }
else if (Current.is(tok::l_brace)) {
1911 const FormatToken *NextNonComment = Current.getNextNonComment();
1912 bool EndsInComma = Current.MatchingParen &&
1913 Current.MatchingParen->Previous &&
1914 Current.MatchingParen->Previous->is(tok::comma);
1915 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
1917 (NextNonComment && NextNonComment->isOneOf(
1918 TT_DesignatedInitializerPeriod,
1919 TT_DesignatedInitializerLSquare));
1920 BreakBeforeParameter = EndsInComma;
1921 if (Current.ParameterCount > 1)
1922 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
1926 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
1928 if (Style.
isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
1934 const FormatToken *Next = Current.Next;
1935 if (Next && Next->is(TT_TableGenDAGArgOperatorID))
1936 NewIndent = State.Column + Next->TokenText.size() + 2;
1943 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
1944 NewIndent = std::max(NewIndent, CurrentState.Indent);
1945 LastSpace = std::max(LastSpace, CurrentState.Indent);
1949 Current.MatchingParen &&
1950 Current.MatchingParen->getPreviousNonComment() &&
1951 Current.MatchingParen->getPreviousNonComment()->is(tok::comma);
1955 bool ObjCBinPackProtocolList =
1960 bool BinPackDeclaration =
1963 (State.Line->Type ==
LT_ObjCDecl && ObjCBinPackProtocolList);
1965 bool GenericSelection =
1966 Current.getPreviousNonComment() &&
1967 Current.getPreviousNonComment()->is(tok::kw__Generic);
1970 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
1972 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
1978 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
1985 BreakBeforeParameter =
true;
1990 for (
const FormatToken *Tok = &Current;
1991 Tok && Tok != Current.MatchingParen; Tok = Tok->Next) {
1992 if (Tok->MustBreakBefore ||
1993 (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) {
1994 BreakBeforeParameter =
true;
2002 BreakBeforeParameter =
true;
2008 Current.Children.empty() &&
2009 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2010 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2011 (Current.is(TT_TemplateOpener) &&
2012 CurrentState.ContainsUnwrappedBuilder));
2013 State.Stack.push_back(
2014 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2015 auto &NewState = State.Stack.back();
2016 NewState.NestedBlockIndent = NestedBlockIndent;
2017 NewState.BreakBeforeParameter = BreakBeforeParameter;
2018 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2021 Current.is(tok::l_paren)) {
2023 FormatToken
const *next = Current.Next;
2025 if (next->is(TT_LambdaLSquare)) {
2026 NewState.HasMultipleNestedBlocks =
true;
2033 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2035 Current.Previous->is(tok::at);
2038void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
2039 const FormatToken &Current = *State.NextToken;
2040 if (!Current.closesScope())
2045 if (State.Stack.size() > 1 &&
2046 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2047 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2048 State.NextToken->is(TT_TemplateCloser) ||
2049 State.NextToken->is(TT_TableGenListCloser) ||
2050 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2051 State.Stack.pop_back();
2054 auto &CurrentState = State.Stack.back();
2066 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2067 Current.MatchingParen->Previous) {
2068 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2069 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2070 CurrentScopeOpener.MatchingParen) {
2071 int NecessarySpaceInLine =
2073 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2074 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2076 CurrentState.BreakBeforeParameter =
false;
2081 if (Current.is(tok::r_square)) {
2083 const FormatToken *NextNonComment = Current.getNextNonComment();
2084 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2085 CurrentState.StartOfArraySubscripts = 0;
2089void ContinuationIndenter::moveStateToNewBlock(LineState &State,
bool NewLine) {
2091 State.NextToken->is(TT_LambdaLBrace) &&
2092 !State.Line->MightBeFunctionDecl) {
2093 State.Stack.back().NestedBlockIndent = State.FirstIndent;
2095 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2097 unsigned NewIndent =
2098 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2108 State.NextToken->is(TT_LambdaLBrace);
2110 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2111 State.Stack.back().LastSpace,
2112 true, NoLineBreak));
2113 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2114 State.Stack.back().BreakBeforeParameter =
true;
2120 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2121 if (LastNewlinePos == StringRef::npos) {
2122 return StartColumn +
2126 0, TabWidth, Encoding);
2130unsigned ContinuationIndenter::reformatRawStringLiteral(
2131 const FormatToken &Current, LineState &State,
2132 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2133 unsigned StartColumn = State.Column - Current.ColumnWidth;
2135 StringRef NewDelimiter =
2137 if (NewDelimiter.empty())
2138 NewDelimiter = OldDelimiter;
2141 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2142 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2145 std::string RawText = std::string(
2146 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2147 if (NewDelimiter != OldDelimiter) {
2150 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2151 if (StringRef(RawText).contains(CanonicalDelimiterSuffix))
2152 NewDelimiter = OldDelimiter;
2155 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2156 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2159 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2170 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2192 unsigned CurrentIndent =
2193 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2194 ? State.Stack.back().NestedBlockIndent
2195 : State.Stack.back().Indent;
2196 unsigned NextStartColumn = ContentStartsOnNewline
2208 unsigned LastStartColumn =
2209 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2212 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2213 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2217 tooling::Replacements NoFixes;
2219 return addMultilineToken(Current, State);
2221 if (NewDelimiter != OldDelimiter) {
2224 SourceLocation PrefixDelimiterStart =
2225 Current.Tok.getLocation().getLocWithOffset(2);
2226 auto PrefixErr = Whitespaces.
addReplacement(tooling::Replacement(
2227 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2230 <<
"Failed to update the prefix delimiter of a raw string: "
2231 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2235 SourceLocation SuffixDelimiterStart =
2236 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2237 1 - OldDelimiter.size());
2238 auto SuffixErr = Whitespaces.
addReplacement(tooling::Replacement(
2239 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2242 <<
"Failed to update the suffix delimiter of a raw string: "
2243 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2246 SourceLocation OriginLoc =
2247 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2248 for (
const tooling::Replacement &Fix : Fixes.first) {
2250 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2251 Fix.getLength(), Fix.getReplacementText()));
2253 llvm::errs() <<
"Failed to reformat raw string: "
2254 << llvm::toString(std::move(Err)) <<
"\n";
2259 *NewCode, FirstStartColumn, Style.
TabWidth, Encoding);
2260 State.Column = RawLastLineEndColumn + NewSuffixSize;
2264 unsigned PrefixExcessCharacters =
2269 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2272 for (ParenState &
Paren : State.Stack)
2273 Paren.BreakBeforeParameter =
true;
2278unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2281 for (ParenState &
Paren : State.Stack)
2282 Paren.BreakBeforeParameter =
true;
2284 unsigned ColumnsUsed = State.Column;
2287 State.Column = Current.LastLineColumnWidth;
2294unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2295 LineState &State,
bool DryRun,
2296 bool AllowBreak,
bool Newline) {
2297 unsigned Penalty = 0;
2300 auto RawStringStyle = getRawStringStyle(Current, State);
2301 if (RawStringStyle && !Current.Finalized) {
2302 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2304 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2307 Penalty = addMultilineToken(Current, State);
2310 LineState OriginalState = State;
2314 bool Strict =
false;
2317 bool Exceeded =
false;
2318 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2319 Current, State, AllowBreak,
true, Strict);
2323 LineState StrictState = OriginalState;
2324 unsigned StrictPenalty =
2325 breakProtrudingToken(Current, StrictState, AllowBreak,
2328 Strict = StrictPenalty <= Penalty;
2330 Penalty = StrictPenalty;
2331 State = StrictState;
2337 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2342 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2353 if (!Tok || Tok->isNot(tok::l_paren))
2358 if (Tok->is(TT_TemplateCloser)) {
2363 if (!Tok || Tok->isNot(tok::identifier))
2368std::optional<FormatStyle>
2369ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2370 const LineState &State) {
2371 if (!Current.isStringLiteral())
2372 return std::nullopt;
2375 return std::nullopt;
2377 if (!RawStringStyle && Delimiter->empty()) {
2381 if (!RawStringStyle)
2382 return std::nullopt;
2384 return RawStringStyle;
2387std::unique_ptr<BreakableToken>
2388ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2389 LineState &State,
bool AllowBreak) {
2390 unsigned StartColumn = State.Column - Current.ColumnWidth;
2391 if (Current.isStringLiteral()) {
2408 if (Current.IsUnterminatedLiteral)
2412 if (State.Stack.back().IsInsideObjCArrayLiteral)
2419 if (Style.
isVerilog() && Current.Previous &&
2420 Current.Previous->isOneOf(tok::kw_export, Keywords.
kw_import)) {
2423 StringRef
Text = Current.TokenText;
2429 unsigned UnbreakableTailLength = (State.NextToken &&
canBreak(State))
2431 : Current.UnbreakableTailLength;
2437 Text.ends_with(
"'")) {
2439 }
else if (Style.
isCSharp() &&
Text.starts_with(
"@\"") &&
2440 Text.ends_with(
"\"")) {
2442 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2447 return std::make_unique<BreakableStringLiteralUsingOperators>(
2448 Current, QuoteStyle,
2450 UnbreakableTailLength, State.Line->InPPDirective, Encoding, Style);
2459 if ((
Text.ends_with(Postfix =
"\"") &&
2460 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2461 Text.starts_with(Prefix =
"u\"") ||
2462 Text.starts_with(Prefix =
"U\"") ||
2463 Text.starts_with(Prefix =
"u8\"") ||
2464 Text.starts_with(Prefix =
"L\""))) ||
2465 (
Text.starts_with(Prefix =
"_T(\"") &&
2466 Text.ends_with(Postfix =
"\")"))) {
2467 return std::make_unique<BreakableStringLiteral>(
2468 Current, StartColumn, Prefix, Postfix, UnbreakableTailLength,
2469 State.Line->InPPDirective, Encoding, Style);
2471 }
else if (Current.is(TT_BlockComment)) {
2479 return std::make_unique<BreakableBlockComment>(
2480 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2481 State.Line->InPPDirective, Encoding, Style, Whitespaces.
useCRLF());
2482 }
else if (Current.is(TT_LineComment) &&
2483 (!Current.Previous ||
2484 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2485 bool RegularComments = [&]() {
2486 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2488 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2494 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2498 return std::make_unique<BreakableLineCommentSection>(
2499 Current, StartColumn,
false, Encoding, Style);
2504std::pair<unsigned, bool>
2505ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2506 LineState &State,
bool AllowBreak,
2507 bool DryRun,
bool Strict) {
2508 std::unique_ptr<const BreakableToken> Token =
2509 createBreakableToken(Current, State, AllowBreak);
2512 assert(Token->getLineCount() > 0);
2514 if (Current.is(TT_LineComment)) {
2518 if (ColumnLimit == 0) {
2521 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2523 if (Current.UnbreakableTailLength >= ColumnLimit)
2527 unsigned StartColumn = State.Column - Current.ColumnWidth;
2528 unsigned NewBreakPenalty = Current.isStringLiteral()
2533 bool Exceeded =
false;
2535 bool BreakInserted = Token->introducesBreakBeforeToken();
2538 bool NewBreakBefore =
false;
2542 bool Reflow =
false;
2545 unsigned TailOffset = 0;
2547 unsigned ContentStartColumn =
2548 Token->getContentStartColumn(0,
false);
2550 unsigned RemainingTokenColumns =
2551 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2554 Token->adaptStartOfLine(0, Whitespaces);
2556 unsigned ContentIndent = 0;
2557 unsigned Penalty = 0;
2558 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2559 << StartColumn <<
".\n");
2560 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2561 LineIndex != EndIndex; ++LineIndex) {
2562 LLVM_DEBUG(llvm::dbgs()
2563 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2564 NewBreakBefore =
false;
2568 bool TryReflow = Reflow;
2570 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2571 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2572 << (ContentStartColumn + RemainingTokenColumns)
2573 <<
", space: " << ColumnLimit
2574 <<
", reflown prefix: " << ContentStartColumn
2575 <<
", offset in line: " << TailOffset <<
"\n");
2581 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2582 ContentStartColumn, CommentPragmasRegex);
2583 if (
Split.first == StringRef::npos) {
2586 if (LineIndex < EndIndex - 1) {
2590 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2592 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2595 assert(
Split.first != 0);
2597 if (Token->supportsReflow()) {
2617 unsigned ToSplitColumns = Token->getRangeLength(
2618 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2619 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2622 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2623 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2626 unsigned ToNextSplitColumns = 0;
2627 if (NextSplit.first == StringRef::npos) {
2628 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2629 ContentStartColumn);
2631 ToNextSplitColumns = Token->getRangeLength(
2632 LineIndex, TailOffset,
2633 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2637 ToNextSplitColumns =
2638 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2639 LLVM_DEBUG(llvm::dbgs()
2640 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2641 LLVM_DEBUG(llvm::dbgs()
2642 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2645 bool ContinueOnLine =
2646 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2647 unsigned ExcessCharactersPenalty = 0;
2648 if (!ContinueOnLine && !Strict) {
2651 ExcessCharactersPenalty =
2652 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2654 LLVM_DEBUG(llvm::dbgs()
2655 <<
" Penalty excess: " << ExcessCharactersPenalty
2656 <<
"\n break : " << NewBreakPenalty <<
"\n");
2657 if (ExcessCharactersPenalty < NewBreakPenalty) {
2659 ContinueOnLine =
true;
2662 if (ContinueOnLine) {
2663 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2668 Token->compressWhitespace(LineIndex, TailOffset, Split,
2672 ContentStartColumn += ToSplitColumns + 1;
2673 Penalty += ExcessCharactersPenalty;
2675 RemainingTokenColumns = Token->getRemainingLength(
2676 LineIndex, TailOffset, ContentStartColumn);
2680 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2685 ContentIndent = Token->getContentIndent(LineIndex);
2686 LLVM_DEBUG(llvm::dbgs()
2687 <<
" ContentIndent: " << ContentIndent <<
"\n");
2688 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2691 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2692 LineIndex, TailOffset +
Split.first +
Split.second,
2693 ContentStartColumn);
2694 if (NewRemainingTokenColumns == 0) {
2697 ContentStartColumn =
2698 Token->getContentStartColumn(LineIndex,
true);
2699 NewRemainingTokenColumns = Token->getRemainingLength(
2700 LineIndex, TailOffset +
Split.first +
Split.second,
2701 ContentStartColumn);
2707 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2712 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2713 <<
", " <<
Split.second <<
"\n");
2715 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2719 Penalty += NewBreakPenalty;
2721 RemainingTokenColumns = NewRemainingTokenColumns;
2722 BreakInserted =
true;
2723 NewBreakBefore =
true;
2727 if (LineIndex + 1 != EndIndex) {
2728 unsigned NextLineIndex = LineIndex + 1;
2729 if (NewBreakBefore) {
2748 ContentStartColumn += RemainingTokenColumns + 1;
2753 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2754 LLVM_DEBUG(llvm::dbgs()
2755 <<
" Size of reflown text: " << ContentStartColumn
2756 <<
"\n Potential reflow split: ");
2757 if (SplitBeforeNext.first != StringRef::npos) {
2758 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2759 << SplitBeforeNext.second <<
"\n");
2760 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2763 RemainingTokenColumns = Token->getRemainingLength(
2764 NextLineIndex, TailOffset, ContentStartColumn);
2766 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2767 LLVM_DEBUG(llvm::dbgs()
2768 <<
" Over limit after reflow, need: "
2769 << (ContentStartColumn + RemainingTokenColumns)
2770 <<
", space: " << ColumnLimit
2771 <<
", reflown prefix: " << ContentStartColumn
2772 <<
", offset in line: " << TailOffset <<
"\n");
2778 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2779 ContentStartColumn, CommentPragmasRegex);
2780 if (
Split.first == StringRef::npos) {
2781 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2787 unsigned ToSplitColumns = Token->getRangeLength(
2788 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2789 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2790 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2791 << (ContentStartColumn + ToSplitColumns)
2792 <<
", space: " << ColumnLimit);
2793 unsigned ExcessCharactersPenalty =
2794 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2796 if (NewBreakPenalty < ExcessCharactersPenalty)
2802 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2810 ContentStartColumn =
2811 Token->getContentStartColumn(NextLineIndex,
false);
2812 RemainingTokenColumns = Token->getRemainingLength(
2813 NextLineIndex, TailOffset, ContentStartColumn);
2816 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2831 if (NewBreakBefore) {
2832 assert(Penalty >= NewBreakPenalty);
2833 Penalty -= NewBreakPenalty;
2836 Token->reflow(NextLineIndex, Whitespaces);
2842 Token->getSplitAfterLastLine(TailOffset);
2843 if (SplitAfterLastLine.first != StringRef::npos) {
2844 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2849 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2852 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2855 ContentStartColumn =
2856 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2857 RemainingTokenColumns = Token->getRemainingLength(
2858 Token->getLineCount() - 1,
2859 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2860 ContentStartColumn);
2863 State.Column = ContentStartColumn + RemainingTokenColumns -
2864 Current.UnbreakableTailLength;
2866 if (BreakInserted) {
2868 Token->updateAfterBroken(Whitespaces);
2873 if (Current.isNot(TT_LineComment))
2874 for (ParenState &
Paren : State.Stack)
2875 Paren.BreakBeforeParameter =
true;
2877 if (Current.is(TT_BlockComment))
2878 State.NoContinuation =
true;
2880 State.Stack.back().LastSpace = StartColumn;
2883 Token->updateNextToken(State);
2885 return {Penalty, Exceeded};
2890 return Style.
ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
2893bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
2895 if (!Current.isStringLiteral() || Current.is(TT_ImplicitStringLiteral))
2900 if (Current.TokenText.starts_with(
"R\""))
2902 if (Current.IsMultiline)
2904 if (Current.getNextNonComment() &&
2905 Current.getNextNonComment()->isStringLiteral()) {
2909 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