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 &&
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;
361 if (!Current.isOneOf(TT_BinaryOperator, tok::comma) &&
366 Current.isNot(TT_LambdaLBrace)) &&
367 CurrentState.NoLineBreakInOperand) {
374 if (Current.is(TT_ConditionalExpr) &&
Previous.is(tok::r_paren) &&
376 Previous.MatchingParen->Previous->MatchingParen &&
377 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {
379 assert(
Previous.MatchingParen->Previous->is(tok::r_brace));
383 return !State.NoLineBreak && !CurrentState.NoLineBreak;
389 const auto &CurrentState = State.Stack.back();
391 Current.is(TT_LambdaLBrace) &&
Previous.isNot(TT_LineComment)) {
395 if (Current.MustBreakBefore ||
396 (Current.is(TT_InlineASMColon) &&
402 if (CurrentState.BreakBeforeClosingBrace &&
403 (Current.closesBlockOrBlockTypeList(Style) ||
404 (Current.is(tok::r_brace) &&
405 Current.isBlockIndentedInitRBrace(Style)))) {
408 if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))
412 Current.ObjCSelectorNameParts > 1 &&
413 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {
418 if (CurrentState.IsCSharpGenericTypeConstraint &&
419 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {
423 (
Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
424 State.Line->First->isNot(TT_AttributeSquare) && Style.
isCpp() &&
434 Previous.is(TT_ConditionalExpr))) &&
435 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
436 !Current.isOneOf(tok::r_paren, tok::r_brace)) {
439 if (CurrentState.IsChainedConditional &&
441 Current.is(tok::colon)) ||
447 (
Previous.is(TT_ArrayInitializerLSquare) &&
456 const FormatToken &BreakConstructorInitializersToken =
460 if (BreakConstructorInitializersToken.
is(TT_CtorInitializerColon) &&
461 (State.Column + State.Line->Last->TotalLength -
Previous.TotalLength >
463 CurrentState.BreakBeforeParameter) &&
464 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
466 Style.
ColumnLimit > 0 || Current.NewlinesBefore > 0)) {
470 if (Current.is(TT_ObjCMethodExpr) &&
Previous.isNot(TT_SelectorName) &&
471 State.Line->startsWith(TT_ObjCMethodSpecifier)) {
474 if (Current.is(TT_SelectorName) &&
Previous.isNot(tok::at) &&
475 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&
477 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {
481 unsigned NewLineColumn = getNewLineColumn(State);
482 if (Current.isMemberAccess() && Style.
ColumnLimit != 0 &&
484 (State.Column > NewLineColumn ||
485 Current.NestingLevel < State.StartOfLineLevel)) {
490 (CurrentState.CallContinuation != 0 ||
491 CurrentState.BreakBeforeParameter) &&
497 !(State.Column <= NewLineColumn && Style.
isJavaScript()) &&
498 !(
Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {
504 if (
Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&
505 Current.CanBreakBefore) {
509 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)
514 Previous.is(tok::comma) || Current.NestingLevel < 2) &&
515 !
Previous.isOneOf(tok::kw_return, tok::lessless, tok::at,
517 !
Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
518 nextIsMultilineString(State)) {
525 if (
Previous.is(TT_BinaryOperator) && Current.CanBreakBefore) {
526 const auto PreviousPrecedence =
Previous.getPrecedence();
528 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {
529 const bool LHSIsBinaryExpr =
542 const bool IsComparison =
547 Previous.Previous->isNot(TT_BinaryOperator);
551 }
else if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore &&
552 CurrentState.BreakBeforeParameter) {
557 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
558 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {
562 if (Current.NestingLevel == 0 && !Current.isTrailingComment()) {
567 if (
Previous.ClosesTemplateDeclaration) {
568 if (Current.is(tok::kw_concept)) {
578 if (Current.is(TT_RequiresClause)) {
589 Current.NewlinesBefore > 0);
591 if (
Previous.is(TT_FunctionAnnotationRParen) &&
595 if (
Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&
596 Current.isNot(TT_LeadingJavaAnnotation)) {
605 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {
"get",
"set",
607 if (BreakBeforeDecoratedTokens.contains(Current.TokenText))
611 if (Current.is(TT_FunctionDeclarationName) &&
612 !State.Line->ReturnTypeWrapped &&
619 CurrentState.BreakBeforeParameter) {
628 !Current.isOneOf(tok::r_brace, tok::comment)) {
632 if (Current.is(tok::lessless) &&
635 Previous.TokenText ==
"\'\\n\'")))) {
642 if (State.NoContinuation)
650 unsigned ExtraSpaces) {
652 assert(State.NextToken->Previous);
655 assert(!State.Stack.empty());
656 State.NoContinuation =
false;
658 if (Current.is(TT_ImplicitStringLiteral) &&
659 (!
Previous.Tok.getIdentifierInfo() ||
660 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==
661 tok::pp_not_keyword)) {
664 if (Current.LastNewlineOffset != 0) {
667 State.Column = EndColumn;
669 unsigned StartColumn =
671 assert(EndColumn >= StartColumn);
672 State.Column += EndColumn - StartColumn;
674 moveStateToNextToken(State, DryRun,
false);
678 unsigned Penalty = 0;
680 Penalty = addTokenOnNewLine(State, DryRun);
682 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
684 return moveStateToNextToken(State, DryRun, Newline) + Penalty;
687void ContinuationIndenter::addTokenOnCurrentLine(
LineState &State,
bool DryRun,
688 unsigned ExtraSpaces) {
690 assert(State.NextToken->Previous);
692 auto &CurrentState = State.Stack.back();
694 bool DisallowLineBreaksOnThisLine =
701 Style.
isCpp() && [&] {
703 if (
Previous.is(TT_BlockComment) && Current.SpacesRequiredBefore == 0)
705 const auto *PrevNonComment = Current.getPreviousNonComment();
706 if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren))
708 if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
710 auto BlockParameterCount = PrevNonComment->BlockParameterCount;
711 if (BlockParameterCount == 0)
715 if (BlockParameterCount > 1)
719 if (!PrevNonComment->Role)
721 auto Comma = PrevNonComment->Role->lastComma();
724 auto Next = Comma->getNextNonComment();
726 !Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
729 if (DisallowLineBreaksOnThisLine)
730 State.NoLineBreak =
true;
732 if (Current.is(tok::equal) &&
733 (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&
734 CurrentState.VariablePos == 0 &&
736 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {
737 CurrentState.VariablePos = State.Column;
740 while (Tok && CurrentState.VariablePos >= Tok->ColumnWidth) {
741 CurrentState.VariablePos -= Tok->ColumnWidth;
742 if (Tok->SpacesRequiredBefore != 0)
746 if (
Previous.PartOfMultiVariableDeclStmt)
747 CurrentState.LastSpace = CurrentState.VariablePos;
750 unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
753 int PPColumnCorrection = 0;
755 Previous.is(tok::hash) && State.FirstIndent > 0 &&
759 Spaces += State.FirstIndent;
766 PPColumnCorrection = -1;
771 State.Column + Spaces + PPColumnCorrection,
772 false, State.Line->InMacroBody);
778 Current.is(TT_InheritanceColon)) {
779 CurrentState.NoLineBreak =
true;
783 CurrentState.NoLineBreak =
true;
786 if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
787 unsigned MinIndent = std::max(
789 unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth;
790 if (Current.LongestObjCSelectorName == 0)
791 CurrentState.AlignColons =
false;
792 else if (MinIndent + Current.LongestObjCSelectorName > FirstColonPos)
793 CurrentState.ColonPos = MinIndent + Current.LongestObjCSelectorName;
795 CurrentState.ColonPos = FirstColonPos;
802 auto IsOpeningBracket = [&](
const FormatToken &Tok) {
803 auto IsStartOfBracedList = [&]() {
804 return Tok.is(tok::l_brace) && Tok.isNot(
BK_Block) &&
807 if (!Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
808 !IsStartOfBracedList()) {
813 if (Tok.Previous->isIf())
815 return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
819 auto IsFunctionCallParen = [](
const FormatToken &Tok) {
820 return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous &&
821 Tok.Previous->is(tok::identifier);
823 auto IsInTemplateString = [
this](
const FormatToken &Tok) {
826 for (
const auto *Prev = &Tok; Prev; Prev = Prev->Previous) {
827 if (Prev->is(TT_TemplateString) && Prev->opensScope())
829 if (Prev->opensScope() ||
830 (Prev->is(TT_TemplateString) && Prev->closesScope())) {
837 auto StartsSimpleOneArgList = [&](
const FormatToken &TokAfterLParen) {
838 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);
840 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;
841 if (!Tok.FakeLParens.empty() && Tok.FakeLParens.back() >
prec::Unknown)
847 if (Tok.is(tok::kw_new) || Tok.startsSequence(tok::coloncolon, tok::kw_new))
849 if (Tok.is(TT_UnaryOperator) ||
851 Tok.isOneOf(tok::ellipsis, Keywords.
kw_await))) {
854 const auto *
Previous = Tok.Previous;
856 TT_LambdaDefinitionLParen) &&
860 if (IsOpeningBracket(Tok) || IsInTemplateString(Tok))
862 const auto *Next = Tok.Next;
863 return !Next || Next->isMemberAccess() ||
864 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next);
868 IsOpeningBracket(
Previous) && State.Column > getNewLineColumn(State) &&
879 !StartsSimpleOneArgList(Current)) {
880 CurrentState.NoLineBreak =
true;
884 CurrentState.NoLineBreak =
true;
891 !CurrentState.IsCSharpGenericTypeConstraint &&
Previous.opensScope() &&
893 Previous.isNot(TT_TableGenDAGArgOpener) &&
894 Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
895 !(Current.MacroParent &&
Previous.MacroParent) &&
896 (Current.isNot(TT_LineComment) ||
898 !IsInTemplateString(Current)) {
899 CurrentState.Indent = State.Column + Spaces;
900 CurrentState.IsAligned =
true;
903 CurrentState.NoLineBreak =
true;
905 CurrentState.NoLineBreak =
true;
908 State.Column > getNewLineColumn(State)) {
909 CurrentState.ContainsUnwrappedBuilder =
true;
913 CurrentState.NoLineBreak =
true;
914 if (Current.isMemberAccess() &&
Previous.is(tok::r_paren) &&
923 CurrentState.NoLineBreak =
true;
930 const FormatToken *
P = Current.getPreviousNonComment();
931 if (Current.isNot(tok::comment) &&
P &&
932 (
P->isOneOf(TT_BinaryOperator, tok::comma) ||
933 (
P->is(TT_ConditionalExpr) &&
P->is(tok::colon))) &&
934 !
P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
938 bool BreakBeforeOperator =
939 P->MustBreakBefore ||
P->is(tok::lessless) ||
940 (
P->is(TT_BinaryOperator) &&
946 bool HasTwoOperands =
P->OperatorIndex == 0 && !
P->NextOperator &&
947 P->isNot(TT_ConditionalExpr);
948 if ((!BreakBeforeOperator &&
951 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {
952 CurrentState.NoLineBreakInOperand =
true;
956 State.Column += Spaces;
957 if (Current.isNot(tok::comment) &&
Previous.is(tok::l_paren) &&
962 CurrentState.LastSpace = State.Column;
963 CurrentState.NestedBlockIndent = State.Column;
964 }
else if (!Current.isOneOf(tok::comment, tok::caret) &&
966 Previous.isNot(TT_OverloadedOperator)) ||
968 CurrentState.LastSpace = State.Column;
969 }
else if (
Previous.is(TT_CtorInitializerColon) &&
970 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&
973 CurrentState.Indent = State.Column;
974 CurrentState.LastSpace = State.Column;
975 }
else if (
Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {
976 CurrentState.LastSpace = State.Column;
977 }
else if (
Previous.is(TT_BinaryOperator) &&
981 Current.StartsBinaryExpression)) {
985 CurrentState.LastSpace = State.Column;
986 }
else if (
Previous.is(TT_InheritanceColon)) {
987 CurrentState.Indent = State.Column;
988 CurrentState.LastSpace = State.Column;
989 }
else if (Current.is(TT_CSharpGenericTypeConstraintColon)) {
990 CurrentState.ColonPos = State.Column;
998 const FormatToken *Next =
Previous.MatchingParen->getNextNonComment();
999 if (Next && Next->isMemberAccess() && State.Stack.size() > 1 &&
1000 State.Stack[State.Stack.size() - 2].CallContinuation == 0) {
1001 CurrentState.LastSpace = State.Column;
1007unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
1009 FormatToken &Current = *State.NextToken;
1010 assert(State.NextToken->Previous);
1011 const FormatToken &
Previous = *State.NextToken->Previous;
1012 auto &CurrentState = State.Stack.back();
1016 unsigned Penalty = 0;
1018 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1019 const FormatToken *NextNonComment =
Previous.getNextNonComment();
1020 if (!NextNonComment)
1021 NextNonComment = &Current;
1024 if (!CurrentState.ContainsLineBreak)
1026 CurrentState.ContainsLineBreak =
true;
1028 Penalty += State.NextToken->SplitPenalty;
1033 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&
1035 CurrentState.BreakBeforeParameter)) {
1039 State.Column = getNewLineColumn(State);
1053 if (State.Column > State.FirstIndent) {
1068 if (Current.isNot(TT_LambdaArrow) &&
1070 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
1072 CurrentState.NestedBlockIndent = State.Column;
1075 if (NextNonComment->isMemberAccess()) {
1076 if (CurrentState.CallContinuation == 0)
1077 CurrentState.CallContinuation = State.Column;
1078 }
else if (NextNonComment->is(TT_SelectorName)) {
1079 if (!CurrentState.ObjCSelectorNameFound) {
1080 if (NextNonComment->LongestObjCSelectorName == 0) {
1081 CurrentState.AlignColons =
false;
1083 CurrentState.ColonPos =
1085 ? std::max(CurrentState.Indent,
1087 : CurrentState.Indent) +
1089 NextNonComment->ColumnWidth);
1091 }
else if (CurrentState.AlignColons &&
1092 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {
1093 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;
1095 }
else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1096 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1106 if (State.Stack.size() > 1) {
1107 State.Stack[State.Stack.size() - 2].LastSpace =
1108 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1113 if ((PreviousNonComment &&
1114 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
1115 !CurrentState.AvoidBinPacking) ||
1117 CurrentState.BreakBeforeParameter =
false;
1119 if (PreviousNonComment &&
1120 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||
1121 PreviousNonComment->ClosesRequiresClause) &&
1122 Current.NestingLevel == 0) {
1123 CurrentState.BreakBeforeParameter =
false;
1125 if (NextNonComment->is(tok::question) ||
1126 (PreviousNonComment && PreviousNonComment->is(tok::question))) {
1127 CurrentState.BreakBeforeParameter =
true;
1129 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
1130 CurrentState.BreakBeforeParameter =
false;
1134 if (Current.is(tok::r_brace) && Current.MatchingParen &&
1137 !Current.MatchingParen->Children.empty()) {
1141 MaxEmptyLinesToKeep = 1;
1144 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
1145 bool ContinuePPDirective =
1148 CurrentState.IsAligned, ContinuePPDirective);
1151 if (!Current.isTrailingComment())
1152 CurrentState.LastSpace = State.Column;
1153 if (Current.is(tok::lessless)) {
1157 CurrentState.LastSpace += 3;
1160 State.StartOfLineLevel = Current.NestingLevel;
1161 State.LowestLevelOnLine = Current.NestingLevel;
1165 bool NestedBlockSpecialCase =
1166 (!Style.
isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
1167 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||
1171 NestedBlockSpecialCase =
1172 NestedBlockSpecialCase ||
1173 (Current.MatchingParen &&
1174 Current.MatchingParen->is(TT_RequiresExpressionLBrace));
1175 if (!NestedBlockSpecialCase) {
1176 auto ParentLevelIt = std::next(State.Stack.rbegin());
1178 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {
1193 auto FindCurrentLevel = [&](
const auto &It) {
1194 return std::find_if(It, State.Stack.rend(), [](
const auto &PState) {
1195 return PState.Tok != nullptr;
1198 auto MaybeIncrement = [&](
const auto &It) {
1199 return It != State.Stack.rend() ? std::next(It) : It;
1201 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());
1202 auto LevelContainingLambdaIt =
1203 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));
1204 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);
1206 for (
auto I = ParentLevelIt,
E = State.Stack.rend(); I !=
E; ++I)
1207 I->BreakBeforeParameter =
true;
1210 if (PreviousNonComment &&
1211 !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&
1212 ((PreviousNonComment->isNot(TT_TemplateCloser) &&
1213 !PreviousNonComment->ClosesRequiresClause) ||
1214 Current.NestingLevel != 0) &&
1215 !PreviousNonComment->isOneOf(
1216 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
1217 TT_LeadingJavaAnnotation) &&
1218 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
1222 Current.isNot(TT_LambdaLBrace))) {
1223 CurrentState.BreakBeforeParameter =
true;
1228 if (PreviousNonComment &&
1229 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1231 CurrentState.BreakBeforeClosingBrace =
true;
1234 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {
1235 CurrentState.BreakBeforeClosingParen =
1239 if (CurrentState.AvoidBinPacking) {
1244 bool PreviousIsBreakingCtorInitializerColon =
1245 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1247 bool AllowAllConstructorInitializersOnNextLine =
1250 if (!(
Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
1251 PreviousIsBreakingCtorInitializerColon) ||
1253 State.Line->MustBeDeclaration) ||
1255 !State.Line->MustBeDeclaration) ||
1256 (!AllowAllConstructorInitializersOnNextLine &&
1257 PreviousIsBreakingCtorInitializerColon) ||
1259 CurrentState.BreakBeforeParameter =
true;
1265 if (PreviousIsBreakingCtorInitializerColon &&
1266 AllowAllConstructorInitializersOnNextLine) {
1267 CurrentState.BreakBeforeParameter =
false;
1272 CurrentState.BreakBeforeParameter =
true;
1277unsigned ContinuationIndenter::getNewLineColumn(
const LineState &State) {
1278 if (!State.NextToken || !State.NextToken->Previous)
1281 FormatToken &Current = *State.NextToken;
1282 const auto &CurrentState = State.Stack.back();
1284 if (CurrentState.IsCSharpGenericTypeConstraint &&
1285 Current.isNot(TT_CSharpGenericTypeConstraint)) {
1286 return CurrentState.ColonPos + 2;
1289 const FormatToken &
Previous = *Current.Previous;
1291 unsigned ContinuationIndent =
1292 std::max(CurrentState.LastSpace, CurrentState.Indent) +
1294 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
1295 const FormatToken *NextNonComment =
Previous.getNextNonComment();
1296 if (!NextNonComment)
1297 NextNonComment = &Current;
1302 return std::max(CurrentState.LastSpace,
1308 if (Style.
isVerilog() && PreviousNonComment &&
1310 return State.FirstIndent;
1314 State.Line->First->is(tok::kw_enum)) {
1315 return (Style.
IndentWidth * State.Line->First->IndentLevel) +
1319 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(
BK_Block)) ||
1321 if (Current.NestingLevel == 0 ||
1323 State.NextToken->is(TT_LambdaLBrace))) {
1324 return State.FirstIndent;
1326 return CurrentState.Indent;
1328 if (Current.is(TT_LambdaArrow) &&
1329 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
1330 tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {
1331 return ContinuationIndent;
1333 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1335 State.Stack.size() > 1) {
1336 if (Current.closesBlockOrBlockTypeList(Style))
1337 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
1338 if (Current.MatchingParen && Current.MatchingParen->is(
BK_BracedInit))
1339 return State.Stack[State.Stack.size() - 2].LastSpace;
1340 return State.FirstIndent;
1357 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1359 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
1360 return State.Stack[State.Stack.size() - 2].LastSpace;
1364 if (Style.
isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&
1365 State.Stack.size() > 1) {
1366 return State.Stack[State.Stack.size() - 2].LastSpace;
1369 (Current.is(tok::r_paren) ||
1370 (Current.is(tok::r_brace) && Current.MatchingParen &&
1372 State.Stack.size() > 1) {
1373 return State.Stack[State.Stack.size() - 2].LastSpace;
1375 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
1376 return State.Stack[State.Stack.size() - 2].LastSpace;
1384 if (Current.is(tok::identifier) && Current.Next &&
1385 (!Style.
isVerilog() || Current.Next->is(tok::colon)) &&
1386 (Current.Next->is(TT_DictLiteral) ||
1387 (Style.
isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {
1388 return CurrentState.Indent;
1390 if (NextNonComment->is(TT_ObjCStringLiteral) &&
1391 State.StartOfStringLiteral != 0) {
1392 return State.StartOfStringLiteral - 1;
1394 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
1395 return State.StartOfStringLiteral;
1396 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)
1397 return CurrentState.FirstLessLess;
1398 if (NextNonComment->isMemberAccess()) {
1399 if (CurrentState.CallContinuation == 0)
1400 return ContinuationIndent;
1401 return CurrentState.CallContinuation;
1403 if (CurrentState.QuestionColumn != 0 &&
1404 ((NextNonComment->is(tok::colon) &&
1405 NextNonComment->is(TT_ConditionalExpr)) ||
1406 Previous.is(TT_ConditionalExpr))) {
1407 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&
1408 !NextNonComment->Next->FakeLParens.empty() &&
1410 (
Previous.is(tok::colon) && !Current.FakeLParens.empty() &&
1412 !CurrentState.IsWrappedConditional) {
1417 unsigned Indent = CurrentState.Indent;
1424 return CurrentState.QuestionColumn;
1426 if (
Previous.is(tok::comma) && CurrentState.VariablePos != 0)
1427 return CurrentState.VariablePos;
1428 if (Current.is(TT_RequiresClause)) {
1435 return CurrentState.Indent;
1440 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
1441 TT_InheritanceComma)) {
1444 if ((PreviousNonComment &&
1445 (PreviousNonComment->ClosesTemplateDeclaration ||
1446 PreviousNonComment->ClosesRequiresClause ||
1447 (PreviousNonComment->is(TT_AttributeMacro) &&
1448 Current.isNot(tok::l_paren)) ||
1449 PreviousNonComment->isOneOf(
1450 TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
1451 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
1453 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
1454 return std::max(CurrentState.LastSpace, CurrentState.Indent);
1456 if (NextNonComment->is(TT_SelectorName)) {
1457 if (!CurrentState.ObjCSelectorNameFound) {
1458 unsigned MinIndent = CurrentState.Indent;
1460 MinIndent = std::max(MinIndent,
1473 std::max(NextNonComment->LongestObjCSelectorName,
1474 NextNonComment->ColumnWidth) -
1475 NextNonComment->ColumnWidth;
1477 if (!CurrentState.AlignColons)
1478 return CurrentState.Indent;
1479 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)
1480 return CurrentState.ColonPos - NextNonComment->ColumnWidth;
1481 return CurrentState.Indent;
1483 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))
1484 return CurrentState.ColonPos;
1485 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {
1486 if (CurrentState.StartOfArraySubscripts != 0) {
1487 return CurrentState.StartOfArraySubscripts;
1490 return CurrentState.Indent;
1492 return ContinuationIndent;
1497 if (State.Line->InPragmaDirective) {
1498 FormatToken *PragmaType = State.Line->First->Next->Next;
1499 if (PragmaType && PragmaType->TokenText ==
"omp")
1505 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&
1506 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {
1507 return CurrentState.Indent;
1510 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||
1511 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {
1512 return ContinuationIndent;
1514 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
1515 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {
1516 return ContinuationIndent;
1518 if (NextNonComment->is(TT_CtorInitializerComma))
1519 return CurrentState.Indent;
1520 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&
1522 return CurrentState.Indent;
1524 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&
1526 return CurrentState.Indent;
1529 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1530 !Current.isBinaryOperator() &&
1531 !Current.isOneOf(tok::colon, tok::comment)) {
1532 return ContinuationIndent;
1534 if (Current.is(TT_ProtoExtensionLSquare))
1535 return CurrentState.Indent;
1536 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {
1537 return CurrentState.Indent - Current.Tok.getLength() -
1538 Current.SpacesRequiredBefore;
1540 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&
1541 CurrentState.UnindentOperator) {
1542 return CurrentState.Indent - NextNonComment->Tok.getLength() -
1543 NextNonComment->SpacesRequiredBefore;
1545 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
1546 !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {
1551 return CurrentState.Indent;
1566unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
1567 bool DryRun,
bool Newline) {
1568 assert(State.Stack.size());
1569 const FormatToken &Current = *State.NextToken;
1570 auto &CurrentState = State.Stack.back();
1572 if (Current.is(TT_CSharpGenericTypeConstraint))
1573 CurrentState.IsCSharpGenericTypeConstraint =
true;
1574 if (Current.isOneOf(tok::comma, TT_BinaryOperator))
1575 CurrentState.NoLineBreakInOperand =
false;
1576 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))
1577 CurrentState.AvoidBinPacking =
true;
1578 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
1579 if (CurrentState.FirstLessLess == 0)
1580 CurrentState.FirstLessLess = State.Column;
1582 CurrentState.LastOperatorWrapped = Newline;
1584 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
1585 CurrentState.LastOperatorWrapped = Newline;
1586 if (Current.is(TT_ConditionalExpr) && Current.Previous &&
1587 Current.Previous->isNot(TT_ConditionalExpr)) {
1588 CurrentState.LastOperatorWrapped = Newline;
1590 if (Current.is(TT_ArraySubscriptLSquare) &&
1591 CurrentState.StartOfArraySubscripts == 0) {
1592 CurrentState.StartOfArraySubscripts = State.Column;
1595 auto IsWrappedConditional = [](
const FormatToken &Tok) {
1596 if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question)))
1598 if (Tok.MustBreakBefore)
1601 const FormatToken *Next = Tok.getNextNonComment();
1602 return Next && Next->MustBreakBefore;
1604 if (IsWrappedConditional(Current))
1605 CurrentState.IsWrappedConditional =
true;
1607 CurrentState.QuestionColumn = State.Column;
1609 const FormatToken *
Previous = Current.Previous;
1613 CurrentState.QuestionColumn = State.Column;
1615 if (!Current.opensScope() && !Current.closesScope() &&
1616 Current.isNot(TT_PointerOrReference)) {
1617 State.LowestLevelOnLine =
1618 std::min(State.LowestLevelOnLine, Current.NestingLevel);
1620 if (Current.isMemberAccess())
1621 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;
1622 if (Current.is(TT_SelectorName))
1623 CurrentState.ObjCSelectorNameFound =
true;
1624 if (Current.is(TT_CtorInitializerColon) &&
1635 CurrentState.NestedBlockIndent = CurrentState.Indent;
1637 CurrentState.AvoidBinPacking =
true;
1638 CurrentState.BreakBeforeParameter =
1643 CurrentState.BreakBeforeParameter =
false;
1646 if (Current.is(TT_CtorInitializerColon) &&
1648 CurrentState.Indent =
1650 CurrentState.NestedBlockIndent = CurrentState.Indent;
1652 CurrentState.AvoidBinPacking =
true;
1654 CurrentState.BreakBeforeParameter =
false;
1656 if (Current.is(TT_InheritanceColon)) {
1657 CurrentState.Indent =
1660 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
1661 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
1662 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
1663 CurrentState.LastSpace = State.Column;
1664 if (Current.is(TT_RequiresExpression) &&
1666 CurrentState.NestedBlockIndent = State.Column;
1670 const FormatToken *
Previous = Current.getPreviousNonComment();
1678 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&
1680 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&
1681 !CurrentState.HasMultipleNestedBlocks) {
1682 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
1683 for (ParenState &PState : llvm::drop_end(State.Stack))
1684 PState.NoLineBreak =
true;
1685 State.Stack[State.Stack.size() - 2].NestedBlockInlined =
false;
1687 if (
Previous && (
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
1688 (
Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
1689 !
Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))) {
1690 CurrentState.NestedBlockInlined =
1694 moveStatePastFakeLParens(State, Newline);
1695 moveStatePastScopeCloser(State);
1698 bool AllowBreak = !State.Stack.back().NoLineBreak &&
1699 !State.Stack.back().NoLineBreakInOperand;
1700 moveStatePastScopeOpener(State, Newline);
1701 moveStatePastFakeRParens(State);
1703 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
1704 State.StartOfStringLiteral = State.Column + 1;
1705 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
1706 State.StartOfStringLiteral = State.Column + 1;
1707 }
else if (Current.is(TT_TableGenMultiLineString) &&
1708 State.StartOfStringLiteral == 0) {
1709 State.StartOfStringLiteral = State.Column + 1;
1710 }
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
1711 State.StartOfStringLiteral = State.Column;
1712 }
else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
1713 !Current.isStringLiteral()) {
1714 State.StartOfStringLiteral = 0;
1717 State.Column += Current.ColumnWidth;
1718 State.NextToken = State.NextToken->Next;
1723 if (Style.
isVerilog() && State.NextToken &&
1724 State.NextToken->MustBreakBefore &&
1727 CurrentState.Indent = State.FirstIndent;
1731 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
1734 Current.Role->formatFromToken(State,
this, DryRun);
1741 Penalty +=
Previous->Role->formatAfterToken(State,
this, DryRun);
1746void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
1748 const FormatToken &Current = *State.NextToken;
1749 if (Current.FakeLParens.empty())
1752 const FormatToken *
Previous = Current.getPreviousNonComment();
1757 bool SkipFirstExtraIndent =
1760 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||
1764 for (
const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {
1765 const auto &CurrentState = State.Stack.back();
1766 ParenState NewParenState = CurrentState;
1767 NewParenState.Tok =
nullptr;
1768 NewParenState.ContainsLineBreak =
false;
1769 NewParenState.LastOperatorWrapped =
true;
1770 NewParenState.IsChainedConditional =
false;
1771 NewParenState.IsWrappedConditional =
false;
1772 NewParenState.UnindentOperator =
false;
1773 NewParenState.NoLineBreak =
1774 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;
1778 NewParenState.AvoidBinPacking =
false;
1783 if (!Current.isTrailingComment() &&
1789 PrecedenceLevel >
prec::Comma || Current.NestingLevel == 0) &&
1792 TT_TableGenDAGArgListCommaToBreak)))) {
1793 NewParenState.Indent = std::max(
1794 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
1801 State.Stack.size() > 1) {
1802 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +
1814 NewParenState.UnindentOperator =
true;
1817 NewParenState.IsAligned =
true;
1827 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
1829 Current.isNot(TT_UnaryOperator) &&
1831 NewParenState.StartOfFunctionCall = State.Column;
1841 &PrecedenceLevel == &Current.FakeLParens.back() &&
1842 !CurrentState.IsWrappedConditional) {
1843 NewParenState.IsChainedConditional =
true;
1844 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;
1847 !Current.isTrailingComment())) {
1851 NewParenState.BreakBeforeParameter =
false;
1852 State.Stack.push_back(NewParenState);
1853 SkipFirstExtraIndent =
false;
1857void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
1858 for (
unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {
1859 unsigned VariablePos = State.Stack.back().VariablePos;
1860 if (State.Stack.size() == 1) {
1864 State.Stack.pop_back();
1865 State.Stack.back().VariablePos = VariablePos;
1871 State.Stack.back().LastSpace -= Style.
IndentWidth;
1875void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
1877 const FormatToken &Current = *State.NextToken;
1878 if (!Current.opensScope())
1881 const auto &CurrentState = State.Stack.back();
1884 if (Current.isOneOf(tok::less, tok::l_paren) &&
1885 CurrentState.IsCSharpGenericTypeConstraint) {
1889 if (Current.MatchingParen && Current.is(
BK_Block)) {
1890 moveStateToNewBlock(State, Newline);
1895 unsigned LastSpace = CurrentState.LastSpace;
1896 bool AvoidBinPacking;
1897 bool BreakBeforeParameter =
false;
1898 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,
1899 CurrentState.NestedBlockIndent);
1900 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
1902 if (Current.opensBlockOrBlockTypeList(Style)) {
1904 std::min(State.Column, CurrentState.NestedBlockIndent);
1905 }
else if (Current.is(tok::l_brace)) {
1912 const FormatToken *NextNonComment = Current.getNextNonComment();
1913 bool EndsInComma = Current.MatchingParen &&
1914 Current.MatchingParen->Previous &&
1915 Current.MatchingParen->Previous->is(tok::comma);
1916 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||
1918 (NextNonComment && NextNonComment->isOneOf(
1919 TT_DesignatedInitializerPeriod,
1920 TT_DesignatedInitializerLSquare));
1921 BreakBeforeParameter = EndsInComma;
1922 if (Current.ParameterCount > 1)
1923 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
1927 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
1929 if (Style.
isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
1935 const FormatToken *Next = Current.Next;
1936 if (Next && Next->is(TT_TableGenDAGArgOperatorID))
1937 NewIndent = State.Column + Next->TokenText.size() + 2;
1944 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
1945 NewIndent = std::max(NewIndent, CurrentState.Indent);
1946 LastSpace = std::max(LastSpace, CurrentState.Indent);
1950 Current.MatchingParen &&
1951 Current.MatchingParen->getPreviousNonComment() &&
1952 Current.MatchingParen->getPreviousNonComment()->is(tok::comma);
1956 bool ObjCBinPackProtocolList =
1961 bool BinPackDeclaration =
1964 (State.Line->Type ==
LT_ObjCDecl && ObjCBinPackProtocolList);
1966 bool GenericSelection =
1967 Current.getPreviousNonComment() &&
1968 Current.getPreviousNonComment()->is(tok::kw__Generic);
1971 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||
1973 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||
1979 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&
1986 BreakBeforeParameter =
true;
1991 for (
const FormatToken *Tok = &Current;
1992 Tok && Tok != Current.MatchingParen; Tok = Tok->Next) {
1993 if (Tok->MustBreakBefore ||
1994 (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) {
1995 BreakBeforeParameter =
true;
2003 BreakBeforeParameter =
true;
2009 Current.Children.empty() &&
2010 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
2011 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
2012 (Current.is(TT_TemplateOpener) &&
2013 CurrentState.ContainsUnwrappedBuilder));
2014 State.Stack.push_back(
2015 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
2016 auto &NewState = State.Stack.back();
2017 NewState.NestedBlockIndent = NestedBlockIndent;
2018 NewState.BreakBeforeParameter = BreakBeforeParameter;
2019 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
2022 Current.is(tok::l_paren)) {
2024 FormatToken
const *next = Current.Next;
2026 if (next->is(TT_LambdaLSquare)) {
2027 NewState.HasMultipleNestedBlocks =
true;
2034 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&
2036 Current.Previous->is(tok::at);
2039void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
2040 const FormatToken &Current = *State.NextToken;
2041 if (!Current.closesScope())
2046 if (State.Stack.size() > 1 &&
2047 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
2048 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
2049 State.NextToken->is(TT_TemplateCloser) ||
2050 State.NextToken->is(TT_TableGenListCloser) ||
2051 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
2052 State.Stack.pop_back();
2055 auto &CurrentState = State.Stack.back();
2067 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&
2068 Current.MatchingParen->Previous) {
2069 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;
2070 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&
2071 CurrentScopeOpener.MatchingParen) {
2072 int NecessarySpaceInLine =
2074 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;
2075 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=
2077 CurrentState.BreakBeforeParameter =
false;
2082 if (Current.is(tok::r_square)) {
2084 const FormatToken *NextNonComment = Current.getNextNonComment();
2085 if (NextNonComment && NextNonComment->isNot(tok::l_square))
2086 CurrentState.StartOfArraySubscripts = 0;
2090void ContinuationIndenter::moveStateToNewBlock(LineState &State,
bool NewLine) {
2092 State.NextToken->is(TT_LambdaLBrace) &&
2093 !State.Line->MightBeFunctionDecl) {
2094 State.Stack.back().NestedBlockIndent = State.FirstIndent;
2096 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
2098 unsigned NewIndent =
2099 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
2109 State.NextToken->is(TT_LambdaLBrace);
2111 State.Stack.push_back(ParenState(State.NextToken, NewIndent,
2112 State.Stack.back().LastSpace,
2113 true, NoLineBreak));
2114 State.Stack.back().NestedBlockIndent = NestedBlockIndent;
2115 State.Stack.back().BreakBeforeParameter =
true;
2121 size_t LastNewlinePos =
Text.find_last_of(
"\n");
2122 if (LastNewlinePos == StringRef::npos) {
2123 return StartColumn +
2127 0, TabWidth, Encoding);
2131unsigned ContinuationIndenter::reformatRawStringLiteral(
2132 const FormatToken &Current, LineState &State,
2133 const FormatStyle &RawStringStyle,
bool DryRun,
bool Newline) {
2134 unsigned StartColumn = State.Column - Current.ColumnWidth;
2136 StringRef NewDelimiter =
2138 if (NewDelimiter.empty())
2139 NewDelimiter = OldDelimiter;
2142 unsigned OldPrefixSize = 3 + OldDelimiter.size();
2143 unsigned OldSuffixSize = 2 + OldDelimiter.size();
2146 std::string RawText = std::string(
2147 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));
2148 if (NewDelimiter != OldDelimiter) {
2151 std::string CanonicalDelimiterSuffix = (
")" + NewDelimiter +
"\"").str();
2152 if (StringRef(RawText).contains(CanonicalDelimiterSuffix))
2153 NewDelimiter = OldDelimiter;
2156 unsigned NewPrefixSize = 3 + NewDelimiter.size();
2157 unsigned NewSuffixSize = 2 + NewDelimiter.size();
2160 unsigned FirstStartColumn = StartColumn + NewPrefixSize;
2171 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] ==
'\n';
2193 unsigned CurrentIndent =
2194 (!Newline && Current.Next && Current.Next->is(tok::r_paren))
2195 ? State.Stack.back().NestedBlockIndent
2196 : State.Stack.back().Indent;
2197 unsigned NextStartColumn = ContentStartsOnNewline
2209 unsigned LastStartColumn =
2210 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
2213 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
2214 FirstStartColumn, NextStartColumn, LastStartColumn,
"<stdin>",
2218 tooling::Replacements NoFixes;
2220 return addMultilineToken(Current, State);
2222 if (NewDelimiter != OldDelimiter) {
2225 SourceLocation PrefixDelimiterStart =
2226 Current.Tok.getLocation().getLocWithOffset(2);
2227 auto PrefixErr = Whitespaces.
addReplacement(tooling::Replacement(
2228 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2231 <<
"Failed to update the prefix delimiter of a raw string: "
2232 << llvm::toString(std::move(PrefixErr)) <<
"\n";
2236 SourceLocation SuffixDelimiterStart =
2237 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
2238 1 - OldDelimiter.size());
2239 auto SuffixErr = Whitespaces.
addReplacement(tooling::Replacement(
2240 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
2243 <<
"Failed to update the suffix delimiter of a raw string: "
2244 << llvm::toString(std::move(SuffixErr)) <<
"\n";
2247 SourceLocation OriginLoc =
2248 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
2249 for (
const tooling::Replacement &Fix : Fixes.first) {
2251 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
2252 Fix.getLength(), Fix.getReplacementText()));
2254 llvm::errs() <<
"Failed to reformat raw string: "
2255 << llvm::toString(std::move(Err)) <<
"\n";
2260 *NewCode, FirstStartColumn, Style.
TabWidth, Encoding);
2261 State.Column = RawLastLineEndColumn + NewSuffixSize;
2265 unsigned PrefixExcessCharacters =
2270 ContentStartsOnNewline || (NewCode->find(
'\n') != std::string::npos);
2273 for (ParenState &
Paren : State.Stack)
2274 Paren.BreakBeforeParameter =
true;
2279unsigned ContinuationIndenter::addMultilineToken(
const FormatToken &Current,
2282 for (ParenState &
Paren : State.Stack)
2283 Paren.BreakBeforeParameter =
true;
2285 unsigned ColumnsUsed = State.Column;
2288 State.Column = Current.LastLineColumnWidth;
2295unsigned ContinuationIndenter::handleEndOfLine(
const FormatToken &Current,
2296 LineState &State,
bool DryRun,
2297 bool AllowBreak,
bool Newline) {
2298 unsigned Penalty = 0;
2301 auto RawStringStyle = getRawStringStyle(Current, State);
2302 if (RawStringStyle && !Current.Finalized) {
2303 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
2305 }
else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
2308 Penalty = addMultilineToken(Current, State);
2311 LineState OriginalState = State;
2315 bool Strict =
false;
2318 bool Exceeded =
false;
2319 std::tie(Penalty, Exceeded) = breakProtrudingToken(
2320 Current, State, AllowBreak,
true, Strict);
2324 LineState StrictState = OriginalState;
2325 unsigned StrictPenalty =
2326 breakProtrudingToken(Current, StrictState, AllowBreak,
2329 Strict = StrictPenalty <= Penalty;
2331 Penalty = StrictPenalty;
2332 State = StrictState;
2338 breakProtrudingToken(Current, OriginalState, AllowBreak,
false,
2343 unsigned ExcessCharacters = State.Column -
getColumnLimit(State);
2354 if (!Tok || Tok->isNot(tok::l_paren))
2359 if (Tok->is(TT_TemplateCloser)) {
2364 if (!Tok || Tok->isNot(tok::identifier))
2369std::optional<FormatStyle>
2370ContinuationIndenter::getRawStringStyle(
const FormatToken &Current,
2371 const LineState &State) {
2372 if (!Current.isStringLiteral())
2373 return std::nullopt;
2376 return std::nullopt;
2378 if (!RawStringStyle && Delimiter->empty()) {
2382 if (!RawStringStyle)
2383 return std::nullopt;
2385 return RawStringStyle;
2388std::unique_ptr<BreakableToken>
2389ContinuationIndenter::createBreakableToken(
const FormatToken &Current,
2390 LineState &State,
bool AllowBreak) {
2391 unsigned StartColumn = State.Column - Current.ColumnWidth;
2392 if (Current.isStringLiteral()) {
2409 if (Current.IsUnterminatedLiteral)
2413 if (State.Stack.back().IsInsideObjCArrayLiteral)
2420 if (Style.
isVerilog() && Current.Previous &&
2421 Current.Previous->isOneOf(tok::kw_export, Keywords.
kw_import)) {
2424 StringRef
Text = Current.TokenText;
2430 unsigned UnbreakableTailLength = (State.NextToken &&
canBreak(State))
2432 : Current.UnbreakableTailLength;
2438 Text.ends_with(
"'")) {
2440 }
else if (Style.
isCSharp() &&
Text.starts_with(
"@\"") &&
2441 Text.ends_with(
"\"")) {
2443 }
else if (
Text.starts_with(
"\"") &&
Text.ends_with(
"\"")) {
2448 return std::make_unique<BreakableStringLiteralUsingOperators>(
2449 Current, QuoteStyle,
2451 UnbreakableTailLength, State.Line->InPPDirective, Encoding, Style);
2460 if ((
Text.ends_with(Postfix =
"\"") &&
2461 (
Text.starts_with(Prefix =
"@\"") ||
Text.starts_with(Prefix =
"\"") ||
2462 Text.starts_with(Prefix =
"u\"") ||
2463 Text.starts_with(Prefix =
"U\"") ||
2464 Text.starts_with(Prefix =
"u8\"") ||
2465 Text.starts_with(Prefix =
"L\""))) ||
2466 (
Text.starts_with(Prefix =
"_T(\"") &&
2467 Text.ends_with(Postfix =
"\")"))) {
2468 return std::make_unique<BreakableStringLiteral>(
2469 Current, StartColumn, Prefix, Postfix, UnbreakableTailLength,
2470 State.Line->InPPDirective, Encoding, Style);
2472 }
else if (Current.is(TT_BlockComment)) {
2480 return std::make_unique<BreakableBlockComment>(
2481 Current, StartColumn, Current.OriginalColumn, !Current.Previous,
2482 State.Line->InPPDirective, Encoding, Style, Whitespaces.
useCRLF());
2483 }
else if (Current.is(TT_LineComment) &&
2484 (!Current.Previous ||
2485 Current.Previous->isNot(TT_ImplicitStringLiteral))) {
2486 bool RegularComments = [&]() {
2487 for (
const FormatToken *
T = &Current;
T &&
T->is(TT_LineComment);
2489 if (!(
T->TokenText.starts_with(
"//") ||
T->TokenText.starts_with(
"#")))
2495 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
2499 return std::make_unique<BreakableLineCommentSection>(
2500 Current, StartColumn,
false, Encoding, Style);
2505std::pair<unsigned, bool>
2506ContinuationIndenter::breakProtrudingToken(
const FormatToken &Current,
2507 LineState &State,
bool AllowBreak,
2508 bool DryRun,
bool Strict) {
2509 std::unique_ptr<const BreakableToken> Token =
2510 createBreakableToken(Current, State, AllowBreak);
2513 assert(Token->getLineCount() > 0);
2515 if (Current.is(TT_LineComment)) {
2519 if (ColumnLimit == 0) {
2522 ColumnLimit = std::numeric_limits<
decltype(ColumnLimit)>
::max();
2524 if (Current.UnbreakableTailLength >= ColumnLimit)
2528 unsigned StartColumn = State.Column - Current.ColumnWidth;
2529 unsigned NewBreakPenalty = Current.isStringLiteral()
2534 bool Exceeded =
false;
2536 bool BreakInserted = Token->introducesBreakBeforeToken();
2539 bool NewBreakBefore =
false;
2543 bool Reflow =
false;
2546 unsigned TailOffset = 0;
2548 unsigned ContentStartColumn =
2549 Token->getContentStartColumn(0,
false);
2551 unsigned RemainingTokenColumns =
2552 Token->getRemainingLength(0, TailOffset, ContentStartColumn);
2555 Token->adaptStartOfLine(0, Whitespaces);
2557 unsigned ContentIndent = 0;
2558 unsigned Penalty = 0;
2559 LLVM_DEBUG(llvm::dbgs() <<
"Breaking protruding token at column "
2560 << StartColumn <<
".\n");
2561 for (
unsigned LineIndex = 0, EndIndex = Token->getLineCount();
2562 LineIndex != EndIndex; ++LineIndex) {
2563 LLVM_DEBUG(llvm::dbgs()
2564 <<
" Line: " << LineIndex <<
" (Reflow: " << Reflow <<
")\n");
2565 NewBreakBefore =
false;
2569 bool TryReflow = Reflow;
2571 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2572 LLVM_DEBUG(llvm::dbgs() <<
" Over limit, need: "
2573 << (ContentStartColumn + RemainingTokenColumns)
2574 <<
", space: " << ColumnLimit
2575 <<
", reflown prefix: " << ContentStartColumn
2576 <<
", offset in line: " << TailOffset <<
"\n");
2582 Token->getSplit(LineIndex, TailOffset, ColumnLimit,
2583 ContentStartColumn, CommentPragmasRegex);
2584 if (
Split.first == StringRef::npos) {
2587 if (LineIndex < EndIndex - 1) {
2591 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2593 LLVM_DEBUG(llvm::dbgs() <<
" No break opportunity.\n");
2596 assert(
Split.first != 0);
2598 if (Token->supportsReflow()) {
2618 unsigned ToSplitColumns = Token->getRangeLength(
2619 LineIndex, TailOffset,
Split.first, ContentStartColumn);
2620 LLVM_DEBUG(llvm::dbgs() <<
" ToSplit: " << ToSplitColumns <<
"\n");
2623 LineIndex, TailOffset +
Split.first +
Split.second, ColumnLimit,
2624 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);
2627 unsigned ToNextSplitColumns = 0;
2628 if (NextSplit.first == StringRef::npos) {
2629 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,
2630 ContentStartColumn);
2632 ToNextSplitColumns = Token->getRangeLength(
2633 LineIndex, TailOffset,
2634 Split.first +
Split.second + NextSplit.first, ContentStartColumn);
2638 ToNextSplitColumns =
2639 Token->getLengthAfterCompression(ToNextSplitColumns, Split);
2640 LLVM_DEBUG(llvm::dbgs()
2641 <<
" ContentStartColumn: " << ContentStartColumn <<
"\n");
2642 LLVM_DEBUG(llvm::dbgs()
2643 <<
" ToNextSplit: " << ToNextSplitColumns <<
"\n");
2646 bool ContinueOnLine =
2647 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;
2648 unsigned ExcessCharactersPenalty = 0;
2649 if (!ContinueOnLine && !Strict) {
2652 ExcessCharactersPenalty =
2653 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *
2655 LLVM_DEBUG(llvm::dbgs()
2656 <<
" Penalty excess: " << ExcessCharactersPenalty
2657 <<
"\n break : " << NewBreakPenalty <<
"\n");
2658 if (ExcessCharactersPenalty < NewBreakPenalty) {
2660 ContinueOnLine =
true;
2663 if (ContinueOnLine) {
2664 LLVM_DEBUG(llvm::dbgs() <<
" Continuing on line...\n");
2669 Token->compressWhitespace(LineIndex, TailOffset, Split,
2673 ContentStartColumn += ToSplitColumns + 1;
2674 Penalty += ExcessCharactersPenalty;
2676 RemainingTokenColumns = Token->getRemainingLength(
2677 LineIndex, TailOffset, ContentStartColumn);
2681 LLVM_DEBUG(llvm::dbgs() <<
" Breaking...\n");
2686 ContentIndent = Token->getContentIndent(LineIndex);
2687 LLVM_DEBUG(llvm::dbgs()
2688 <<
" ContentIndent: " << ContentIndent <<
"\n");
2689 ContentStartColumn = ContentIndent + Token->getContentStartColumn(
2692 unsigned NewRemainingTokenColumns = Token->getRemainingLength(
2693 LineIndex, TailOffset +
Split.first +
Split.second,
2694 ContentStartColumn);
2695 if (NewRemainingTokenColumns == 0) {
2698 ContentStartColumn =
2699 Token->getContentStartColumn(LineIndex,
true);
2700 NewRemainingTokenColumns = Token->getRemainingLength(
2701 LineIndex, TailOffset +
Split.first +
Split.second,
2702 ContentStartColumn);
2708 if (NewRemainingTokenColumns >= RemainingTokenColumns) {
2713 LLVM_DEBUG(llvm::dbgs() <<
" Breaking at: " << TailOffset +
Split.first
2714 <<
", " <<
Split.second <<
"\n");
2716 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
2720 Penalty += NewBreakPenalty;
2722 RemainingTokenColumns = NewRemainingTokenColumns;
2723 BreakInserted =
true;
2724 NewBreakBefore =
true;
2728 if (LineIndex + 1 != EndIndex) {
2729 unsigned NextLineIndex = LineIndex + 1;
2730 if (NewBreakBefore) {
2749 ContentStartColumn += RemainingTokenColumns + 1;
2754 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);
2755 LLVM_DEBUG(llvm::dbgs()
2756 <<
" Size of reflown text: " << ContentStartColumn
2757 <<
"\n Potential reflow split: ");
2758 if (SplitBeforeNext.first != StringRef::npos) {
2759 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first <<
", "
2760 << SplitBeforeNext.second <<
"\n");
2761 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;
2764 RemainingTokenColumns = Token->getRemainingLength(
2765 NextLineIndex, TailOffset, ContentStartColumn);
2767 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {
2768 LLVM_DEBUG(llvm::dbgs()
2769 <<
" Over limit after reflow, need: "
2770 << (ContentStartColumn + RemainingTokenColumns)
2771 <<
", space: " << ColumnLimit
2772 <<
", reflown prefix: " << ContentStartColumn
2773 <<
", offset in line: " << TailOffset <<
"\n");
2779 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,
2780 ContentStartColumn, CommentPragmasRegex);
2781 if (
Split.first == StringRef::npos) {
2782 LLVM_DEBUG(llvm::dbgs() <<
" Did not find later break\n");
2788 unsigned ToSplitColumns = Token->getRangeLength(
2789 NextLineIndex, TailOffset,
Split.first, ContentStartColumn);
2790 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {
2791 LLVM_DEBUG(llvm::dbgs() <<
" Next split protrudes, need: "
2792 << (ContentStartColumn + ToSplitColumns)
2793 <<
", space: " << ColumnLimit);
2794 unsigned ExcessCharactersPenalty =
2795 (ContentStartColumn + ToSplitColumns - ColumnLimit) *
2797 if (NewBreakPenalty < ExcessCharactersPenalty)
2803 LLVM_DEBUG(llvm::dbgs() <<
"not found.\n");
2811 ContentStartColumn =
2812 Token->getContentStartColumn(NextLineIndex,
false);
2813 RemainingTokenColumns = Token->getRemainingLength(
2814 NextLineIndex, TailOffset, ContentStartColumn);
2817 Token->adaptStartOfLine(NextLineIndex, Whitespaces);
2832 if (NewBreakBefore) {
2833 assert(Penalty >= NewBreakPenalty);
2834 Penalty -= NewBreakPenalty;
2837 Token->reflow(NextLineIndex, Whitespaces);
2843 Token->getSplitAfterLastLine(TailOffset);
2844 if (SplitAfterLastLine.first != StringRef::npos) {
2845 LLVM_DEBUG(llvm::dbgs() <<
"Replacing whitespace after last line.\n");
2850 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);
2853 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,
2856 ContentStartColumn =
2857 Token->getContentStartColumn(Token->getLineCount() - 1,
true);
2858 RemainingTokenColumns = Token->getRemainingLength(
2859 Token->getLineCount() - 1,
2860 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,
2861 ContentStartColumn);
2864 State.Column = ContentStartColumn + RemainingTokenColumns -
2865 Current.UnbreakableTailLength;
2867 if (BreakInserted) {
2869 Token->updateAfterBroken(Whitespaces);
2874 if (Current.isNot(TT_LineComment))
2875 for (ParenState &
Paren : State.Stack)
2876 Paren.BreakBeforeParameter =
true;
2878 if (Current.is(TT_BlockComment))
2879 State.NoContinuation =
true;
2881 State.Stack.back().LastSpace = StartColumn;
2884 Token->updateNextToken(State);
2886 return {Penalty, Exceeded};
2891 return Style.
ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
2894bool ContinuationIndenter::nextIsMultilineString(
const LineState &State) {
2896 if (!Current.isStringLiteral() || Current.is(TT_ImplicitStringLiteral))
2901 if (Current.TokenText.starts_with(
"R\""))
2903 if (Current.IsMultiline)
2905 if (Current.getNextNonComment() &&
2906 Current.getNextNonComment()->isStringLiteral()) {
2910 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