10b57cec5SDimitry Andric //===--- ContinuationIndenter.cpp - Format C++ code -----------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// This file implements the continuation indenter. 110b57cec5SDimitry Andric /// 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "ContinuationIndenter.h" 150b57cec5SDimitry Andric #include "BreakableToken.h" 160b57cec5SDimitry Andric #include "FormatInternal.h" 17349cc55cSDimitry Andric #include "FormatToken.h" 180b57cec5SDimitry Andric #include "WhitespaceManager.h" 190b57cec5SDimitry Andric #include "clang/Basic/OperatorPrecedence.h" 200b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h" 2106c3fb27SDimitry Andric #include "clang/Basic/TokenKinds.h" 220b57cec5SDimitry Andric #include "clang/Format/Format.h" 23349cc55cSDimitry Andric #include "llvm/ADT/StringSet.h" 240b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 25bdd1243dSDimitry Andric #include <optional> 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric #define DEBUG_TYPE "format-indenter" 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric namespace clang { 300b57cec5SDimitry Andric namespace format { 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric // Returns true if a TT_SelectorName should be indented when wrapped, 330b57cec5SDimitry Andric // false otherwise. 340b57cec5SDimitry Andric static bool shouldIndentWrappedSelectorName(const FormatStyle &Style, 350b57cec5SDimitry Andric LineType LineType) { 360b57cec5SDimitry Andric return Style.IndentWrappedFunctionNames || LineType == LT_ObjCMethodDecl; 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 395f757f3fSDimitry Andric // Returns true if a binary operator following \p Tok should be unindented when 405f757f3fSDimitry Andric // the style permits it. 415f757f3fSDimitry Andric static bool shouldUnindentNextOperator(const FormatToken &Tok) { 425f757f3fSDimitry Andric const FormatToken *Previous = Tok.getPreviousNonComment(); 435f757f3fSDimitry Andric return Previous && (Previous->getPrecedence() == prec::Assignment || 445f757f3fSDimitry Andric Previous->isOneOf(tok::kw_return, TT_RequiresClause)); 455f757f3fSDimitry Andric } 465f757f3fSDimitry Andric 470b57cec5SDimitry Andric // Returns the length of everything up to the first possible line break after 480b57cec5SDimitry Andric // the ), ], } or > matching \c Tok. 490b57cec5SDimitry Andric static unsigned getLengthToMatchingParen(const FormatToken &Tok, 50fcaf7f86SDimitry Andric ArrayRef<ParenState> Stack) { 510b57cec5SDimitry Andric // Normally whether or not a break before T is possible is calculated and 520b57cec5SDimitry Andric // stored in T.CanBreakBefore. Braces, array initializers and text proto 530b57cec5SDimitry Andric // messages like `key: < ... >` are an exception: a break is possible 540b57cec5SDimitry Andric // before a closing brace R if a break was inserted after the corresponding 550b57cec5SDimitry Andric // opening brace. The information about whether or not a break is needed 560b57cec5SDimitry Andric // before a closing brace R is stored in the ParenState field 570b57cec5SDimitry Andric // S.BreakBeforeClosingBrace where S is the state that R closes. 580b57cec5SDimitry Andric // 590b57cec5SDimitry Andric // In order to decide whether there can be a break before encountered right 600b57cec5SDimitry Andric // braces, this implementation iterates over the sequence of tokens and over 610b57cec5SDimitry Andric // the paren stack in lockstep, keeping track of the stack level which visited 620b57cec5SDimitry Andric // right braces correspond to in MatchingStackIndex. 630b57cec5SDimitry Andric // 640b57cec5SDimitry Andric // For example, consider: 650b57cec5SDimitry Andric // L. <- line number 660b57cec5SDimitry Andric // 1. { 670b57cec5SDimitry Andric // 2. {1}, 680b57cec5SDimitry Andric // 3. {2}, 690b57cec5SDimitry Andric // 4. {{3}}} 700b57cec5SDimitry Andric // ^ where we call this method with this token. 710b57cec5SDimitry Andric // The paren stack at this point contains 3 brace levels: 720b57cec5SDimitry Andric // 0. { at line 1, BreakBeforeClosingBrace: true 730b57cec5SDimitry Andric // 1. first { at line 4, BreakBeforeClosingBrace: false 740b57cec5SDimitry Andric // 2. second { at line 4, BreakBeforeClosingBrace: false, 750b57cec5SDimitry Andric // where there might be fake parens levels in-between these levels. 760b57cec5SDimitry Andric // The algorithm will start at the first } on line 4, which is the matching 770b57cec5SDimitry Andric // brace of the initial left brace and at level 2 of the stack. Then, 780b57cec5SDimitry Andric // examining BreakBeforeClosingBrace: false at level 2, it will continue to 790b57cec5SDimitry Andric // the second } on line 4, and will traverse the stack downwards until it 800b57cec5SDimitry Andric // finds the matching { on level 1. Then, examining BreakBeforeClosingBrace: 810b57cec5SDimitry Andric // false at level 1, it will continue to the third } on line 4 and will 820b57cec5SDimitry Andric // traverse the stack downwards until it finds the matching { on level 0. 830b57cec5SDimitry Andric // Then, examining BreakBeforeClosingBrace: true at level 0, the algorithm 840b57cec5SDimitry Andric // will stop and will use the second } on line 4 to determine the length to 850b57cec5SDimitry Andric // return, as in this example the range will include the tokens: {3}} 860b57cec5SDimitry Andric // 870b57cec5SDimitry Andric // The algorithm will only traverse the stack if it encounters braces, array 880b57cec5SDimitry Andric // initializer squares or text proto angle brackets. 890b57cec5SDimitry Andric if (!Tok.MatchingParen) 900b57cec5SDimitry Andric return 0; 910b57cec5SDimitry Andric FormatToken *End = Tok.MatchingParen; 920b57cec5SDimitry Andric // Maintains a stack level corresponding to the current End token. 930b57cec5SDimitry Andric int MatchingStackIndex = Stack.size() - 1; 940b57cec5SDimitry Andric // Traverses the stack downwards, looking for the level to which LBrace 950b57cec5SDimitry Andric // corresponds. Returns either a pointer to the matching level or nullptr if 960b57cec5SDimitry Andric // LParen is not found in the initial portion of the stack up to 970b57cec5SDimitry Andric // MatchingStackIndex. 980b57cec5SDimitry Andric auto FindParenState = [&](const FormatToken *LBrace) -> const ParenState * { 990b57cec5SDimitry Andric while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].Tok != LBrace) 1000b57cec5SDimitry Andric --MatchingStackIndex; 1010b57cec5SDimitry Andric return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] : nullptr; 1020b57cec5SDimitry Andric }; 1030b57cec5SDimitry Andric for (; End->Next; End = End->Next) { 1040b57cec5SDimitry Andric if (End->Next->CanBreakBefore) 1050b57cec5SDimitry Andric break; 1060b57cec5SDimitry Andric if (!End->Next->closesScope()) 1070b57cec5SDimitry Andric continue; 1080b57cec5SDimitry Andric if (End->Next->MatchingParen && 1090b57cec5SDimitry Andric End->Next->MatchingParen->isOneOf( 1100b57cec5SDimitry Andric tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) { 1110b57cec5SDimitry Andric const ParenState *State = FindParenState(End->Next->MatchingParen); 1120b57cec5SDimitry Andric if (State && State->BreakBeforeClosingBrace) 1130b57cec5SDimitry Andric break; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric return End->TotalLength - Tok.TotalLength + 1; 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric static unsigned getLengthToNextOperator(const FormatToken &Tok) { 1200b57cec5SDimitry Andric if (!Tok.NextOperator) 1210b57cec5SDimitry Andric return 0; 1220b57cec5SDimitry Andric return Tok.NextOperator->TotalLength - Tok.TotalLength; 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric // Returns \c true if \c Tok is the "." or "->" of a call and starts the next 1260b57cec5SDimitry Andric // segment of a builder type call. 1270b57cec5SDimitry Andric static bool startsSegmentOfBuilderTypeCall(const FormatToken &Tok) { 1280b57cec5SDimitry Andric return Tok.isMemberAccess() && Tok.Previous && Tok.Previous->closesScope(); 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric // Returns \c true if \c Current starts a new parameter. 1320b57cec5SDimitry Andric static bool startsNextParameter(const FormatToken &Current, 1330b57cec5SDimitry Andric const FormatStyle &Style) { 1340b57cec5SDimitry Andric const FormatToken &Previous = *Current.Previous; 1350b57cec5SDimitry Andric if (Current.is(TT_CtorInitializerComma) && 13681ad6265SDimitry Andric Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) { 1370b57cec5SDimitry Andric return true; 13881ad6265SDimitry Andric } 1390b57cec5SDimitry Andric if (Style.Language == FormatStyle::LK_Proto && Current.is(TT_SelectorName)) 1400b57cec5SDimitry Andric return true; 1410b57cec5SDimitry Andric return Previous.is(tok::comma) && !Current.isTrailingComment() && 1420b57cec5SDimitry Andric ((Previous.isNot(TT_CtorInitializerComma) || 1430b57cec5SDimitry Andric Style.BreakConstructorInitializers != 1440b57cec5SDimitry Andric FormatStyle::BCIS_BeforeComma) && 1450b57cec5SDimitry Andric (Previous.isNot(TT_InheritanceComma) || 1460b57cec5SDimitry Andric Style.BreakInheritanceList != FormatStyle::BILS_BeforeComma)); 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric static bool opensProtoMessageField(const FormatToken &LessTok, 1500b57cec5SDimitry Andric const FormatStyle &Style) { 1510b57cec5SDimitry Andric if (LessTok.isNot(tok::less)) 1520b57cec5SDimitry Andric return false; 1530b57cec5SDimitry Andric return Style.Language == FormatStyle::LK_TextProto || 1540b57cec5SDimitry Andric (Style.Language == FormatStyle::LK_Proto && 1550b57cec5SDimitry Andric (LessTok.NestingLevel > 0 || 1560b57cec5SDimitry Andric (LessTok.Previous && LessTok.Previous->is(tok::equal)))); 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 159bdd1243dSDimitry Andric // Returns the delimiter of a raw string literal, or std::nullopt if TokenText 160bdd1243dSDimitry Andric // is not the text of a raw string literal. The delimiter could be the empty 161bdd1243dSDimitry Andric // string. For example, the delimiter of R"deli(cont)deli" is deli. 162bdd1243dSDimitry Andric static std::optional<StringRef> getRawStringDelimiter(StringRef TokenText) { 1630b57cec5SDimitry Andric if (TokenText.size() < 5 // The smallest raw string possible is 'R"()"'. 1645f757f3fSDimitry Andric || !TokenText.starts_with("R\"") || !TokenText.ends_with("\"")) { 165bdd1243dSDimitry Andric return std::nullopt; 16681ad6265SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // A raw string starts with 'R"<delimiter>(' and delimiter is ascii and has 1690b57cec5SDimitry Andric // size at most 16 by the standard, so the first '(' must be among the first 1700b57cec5SDimitry Andric // 19 bytes. 1710b57cec5SDimitry Andric size_t LParenPos = TokenText.substr(0, 19).find_first_of('('); 1720b57cec5SDimitry Andric if (LParenPos == StringRef::npos) 173bdd1243dSDimitry Andric return std::nullopt; 1740b57cec5SDimitry Andric StringRef Delimiter = TokenText.substr(2, LParenPos - 2); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric // Check that the string ends in ')Delimiter"'. 1770b57cec5SDimitry Andric size_t RParenPos = TokenText.size() - Delimiter.size() - 2; 1780b57cec5SDimitry Andric if (TokenText[RParenPos] != ')') 179bdd1243dSDimitry Andric return std::nullopt; 1805f757f3fSDimitry Andric if (!TokenText.substr(RParenPos + 1).starts_with(Delimiter)) 181bdd1243dSDimitry Andric return std::nullopt; 1820b57cec5SDimitry Andric return Delimiter; 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric // Returns the canonical delimiter for \p Language, or the empty string if no 1860b57cec5SDimitry Andric // canonical delimiter is specified. 1870b57cec5SDimitry Andric static StringRef 1880b57cec5SDimitry Andric getCanonicalRawStringDelimiter(const FormatStyle &Style, 1890b57cec5SDimitry Andric FormatStyle::LanguageKind Language) { 19081ad6265SDimitry Andric for (const auto &Format : Style.RawStringFormats) 1910b57cec5SDimitry Andric if (Format.Language == Language) 1920b57cec5SDimitry Andric return StringRef(Format.CanonicalDelimiter); 1930b57cec5SDimitry Andric return ""; 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric RawStringFormatStyleManager::RawStringFormatStyleManager( 1970b57cec5SDimitry Andric const FormatStyle &CodeStyle) { 1980b57cec5SDimitry Andric for (const auto &RawStringFormat : CodeStyle.RawStringFormats) { 199bdd1243dSDimitry Andric std::optional<FormatStyle> LanguageStyle = 2000b57cec5SDimitry Andric CodeStyle.GetLanguageStyle(RawStringFormat.Language); 2010b57cec5SDimitry Andric if (!LanguageStyle) { 2020b57cec5SDimitry Andric FormatStyle PredefinedStyle; 2030b57cec5SDimitry Andric if (!getPredefinedStyle(RawStringFormat.BasedOnStyle, 2040b57cec5SDimitry Andric RawStringFormat.Language, &PredefinedStyle)) { 2050b57cec5SDimitry Andric PredefinedStyle = getLLVMStyle(); 2060b57cec5SDimitry Andric PredefinedStyle.Language = RawStringFormat.Language; 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric LanguageStyle = PredefinedStyle; 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit; 21181ad6265SDimitry Andric for (StringRef Delimiter : RawStringFormat.Delimiters) 2120b57cec5SDimitry Andric DelimiterStyle.insert({Delimiter, *LanguageStyle}); 21381ad6265SDimitry Andric for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions) 2140b57cec5SDimitry Andric EnclosingFunctionStyle.insert({EnclosingFunction, *LanguageStyle}); 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 218bdd1243dSDimitry Andric std::optional<FormatStyle> 2190b57cec5SDimitry Andric RawStringFormatStyleManager::getDelimiterStyle(StringRef Delimiter) const { 2200b57cec5SDimitry Andric auto It = DelimiterStyle.find(Delimiter); 2210b57cec5SDimitry Andric if (It == DelimiterStyle.end()) 222bdd1243dSDimitry Andric return std::nullopt; 2230b57cec5SDimitry Andric return It->second; 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 226bdd1243dSDimitry Andric std::optional<FormatStyle> 2270b57cec5SDimitry Andric RawStringFormatStyleManager::getEnclosingFunctionStyle( 2280b57cec5SDimitry Andric StringRef EnclosingFunction) const { 2290b57cec5SDimitry Andric auto It = EnclosingFunctionStyle.find(EnclosingFunction); 2300b57cec5SDimitry Andric if (It == EnclosingFunctionStyle.end()) 231bdd1243dSDimitry Andric return std::nullopt; 2320b57cec5SDimitry Andric return It->second; 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style, 2360b57cec5SDimitry Andric const AdditionalKeywords &Keywords, 2370b57cec5SDimitry Andric const SourceManager &SourceMgr, 2380b57cec5SDimitry Andric WhitespaceManager &Whitespaces, 2390b57cec5SDimitry Andric encoding::Encoding Encoding, 2400b57cec5SDimitry Andric bool BinPackInconclusiveFunctions) 2410b57cec5SDimitry Andric : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr), 2420b57cec5SDimitry Andric Whitespaces(Whitespaces), Encoding(Encoding), 2430b57cec5SDimitry Andric BinPackInconclusiveFunctions(BinPackInconclusiveFunctions), 2440b57cec5SDimitry Andric CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {} 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric LineState ContinuationIndenter::getInitialState(unsigned FirstIndent, 2470b57cec5SDimitry Andric unsigned FirstStartColumn, 2480b57cec5SDimitry Andric const AnnotatedLine *Line, 2490b57cec5SDimitry Andric bool DryRun) { 2500b57cec5SDimitry Andric LineState State; 2510b57cec5SDimitry Andric State.FirstIndent = FirstIndent; 2520b57cec5SDimitry Andric if (FirstStartColumn && Line->First->NewlinesBefore == 0) 2530b57cec5SDimitry Andric State.Column = FirstStartColumn; 2540b57cec5SDimitry Andric else 2550b57cec5SDimitry Andric State.Column = FirstIndent; 2560b57cec5SDimitry Andric // With preprocessor directive indentation, the line starts on column 0 2570b57cec5SDimitry Andric // since it's indented after the hash, but FirstIndent is set to the 2580b57cec5SDimitry Andric // preprocessor indent. 2590b57cec5SDimitry Andric if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash && 2600b57cec5SDimitry Andric (Line->Type == LT_PreprocessorDirective || 26181ad6265SDimitry Andric Line->Type == LT_ImportStatement)) { 2620b57cec5SDimitry Andric State.Column = 0; 26381ad6265SDimitry Andric } 2640b57cec5SDimitry Andric State.Line = Line; 2650b57cec5SDimitry Andric State.NextToken = Line->First; 2660b57cec5SDimitry Andric State.Stack.push_back(ParenState(/*Tok=*/nullptr, FirstIndent, FirstIndent, 2670b57cec5SDimitry Andric /*AvoidBinPacking=*/false, 2680b57cec5SDimitry Andric /*NoLineBreak=*/false)); 2690b57cec5SDimitry Andric State.NoContinuation = false; 2700b57cec5SDimitry Andric State.StartOfStringLiteral = 0; 2715f757f3fSDimitry Andric State.NoLineBreak = false; 2720b57cec5SDimitry Andric State.StartOfLineLevel = 0; 2730b57cec5SDimitry Andric State.LowestLevelOnLine = 0; 2740b57cec5SDimitry Andric State.IgnoreStackForComparison = false; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric if (Style.Language == FormatStyle::LK_TextProto) { 2770b57cec5SDimitry Andric // We need this in order to deal with the bin packing of text fields at 2780b57cec5SDimitry Andric // global scope. 27981ad6265SDimitry Andric auto &CurrentState = State.Stack.back(); 28081ad6265SDimitry Andric CurrentState.AvoidBinPacking = true; 28181ad6265SDimitry Andric CurrentState.BreakBeforeParameter = true; 28281ad6265SDimitry Andric CurrentState.AlignColons = false; 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric // The first token has already been indented and thus consumed. 2860b57cec5SDimitry Andric moveStateToNextToken(State, DryRun, /*Newline=*/false); 2870b57cec5SDimitry Andric return State; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric bool ContinuationIndenter::canBreak(const LineState &State) { 2910b57cec5SDimitry Andric const FormatToken &Current = *State.NextToken; 2920b57cec5SDimitry Andric const FormatToken &Previous = *Current.Previous; 29381ad6265SDimitry Andric const auto &CurrentState = State.Stack.back(); 2940b57cec5SDimitry Andric assert(&Previous == Current.Previous); 29581ad6265SDimitry Andric if (!Current.CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace && 29681ad6265SDimitry Andric Current.closesBlockOrBlockTypeList(Style))) { 2970b57cec5SDimitry Andric return false; 29881ad6265SDimitry Andric } 2990b57cec5SDimitry Andric // The opening "{" of a braced list has to be on the same line as the first 3000b57cec5SDimitry Andric // element if it is nested in another braced init list or function call. 3010b57cec5SDimitry Andric if (!Current.MustBreakBefore && Previous.is(tok::l_brace) && 302e8d8bef9SDimitry Andric Previous.isNot(TT_DictLiteral) && Previous.is(BK_BracedInit) && 3030b57cec5SDimitry Andric Previous.Previous && 30481ad6265SDimitry Andric Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) { 3050b57cec5SDimitry Andric return false; 30681ad6265SDimitry Andric } 3070b57cec5SDimitry Andric // This prevents breaks like: 3080b57cec5SDimitry Andric // ... 3090b57cec5SDimitry Andric // SomeParameter, OtherParameter).DoSomething( 3100b57cec5SDimitry Andric // ... 3110b57cec5SDimitry Andric // As they hide "DoSomething" and are generally bad for readability. 3120b57cec5SDimitry Andric if (Previous.opensScope() && Previous.isNot(tok::l_brace) && 3130b57cec5SDimitry Andric State.LowestLevelOnLine < State.StartOfLineLevel && 31481ad6265SDimitry Andric State.LowestLevelOnLine < Current.NestingLevel) { 3150b57cec5SDimitry Andric return false; 31681ad6265SDimitry Andric } 31781ad6265SDimitry Andric if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder) 3180b57cec5SDimitry Andric return false; 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric // Don't create a 'hanging' indent if there are multiple blocks in a single 3215f757f3fSDimitry Andric // statement and we are aligning lambda blocks to their signatures. 3220b57cec5SDimitry Andric if (Previous.is(tok::l_brace) && State.Stack.size() > 1 && 3230b57cec5SDimitry Andric State.Stack[State.Stack.size() - 2].NestedBlockInlined && 3245f757f3fSDimitry Andric State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks && 3255f757f3fSDimitry Andric Style.LambdaBodyIndentation == FormatStyle::LBI_Signature) { 3260b57cec5SDimitry Andric return false; 32781ad6265SDimitry Andric } 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric // Don't break after very short return types (e.g. "void") as that is often 3300b57cec5SDimitry Andric // unexpected. 3310fca6ea1SDimitry Andric if (Current.is(TT_FunctionDeclarationName)) { 3320fca6ea1SDimitry Andric if (Style.BreakAfterReturnType == FormatStyle::RTBS_None && 3330fca6ea1SDimitry Andric State.Column < 6) { 3340b57cec5SDimitry Andric return false; 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric 3370fca6ea1SDimitry Andric if (Style.BreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) { 3380fca6ea1SDimitry Andric assert(State.Column >= State.FirstIndent); 3390fca6ea1SDimitry Andric if (State.Column - State.FirstIndent < 6) 3400fca6ea1SDimitry Andric return false; 3410fca6ea1SDimitry Andric } 3420fca6ea1SDimitry Andric } 3430fca6ea1SDimitry Andric 3440b57cec5SDimitry Andric // If binary operators are moved to the next line (including commas for some 3450b57cec5SDimitry Andric // styles of constructor initializers), that's always ok. 3460b57cec5SDimitry Andric if (!Current.isOneOf(TT_BinaryOperator, tok::comma) && 3475f757f3fSDimitry Andric // Allow breaking opening brace of lambdas (when passed as function 3485f757f3fSDimitry Andric // arguments) to a new line when BeforeLambdaBody brace wrapping is 3495f757f3fSDimitry Andric // enabled. 3505f757f3fSDimitry Andric (!Style.BraceWrapping.BeforeLambdaBody || 3515f757f3fSDimitry Andric Current.isNot(TT_LambdaLBrace)) && 35281ad6265SDimitry Andric CurrentState.NoLineBreakInOperand) { 3530b57cec5SDimitry Andric return false; 35481ad6265SDimitry Andric } 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric if (Previous.is(tok::l_square) && Previous.is(TT_ObjCMethodExpr)) 3570b57cec5SDimitry Andric return false; 3580b57cec5SDimitry Andric 359bdd1243dSDimitry Andric if (Current.is(TT_ConditionalExpr) && Previous.is(tok::r_paren) && 360bdd1243dSDimitry Andric Previous.MatchingParen && Previous.MatchingParen->Previous && 361bdd1243dSDimitry Andric Previous.MatchingParen->Previous->MatchingParen && 362bdd1243dSDimitry Andric Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) { 363bdd1243dSDimitry Andric // We have a lambda within a conditional expression, allow breaking here. 364bdd1243dSDimitry Andric assert(Previous.MatchingParen->Previous->is(tok::r_brace)); 365bdd1243dSDimitry Andric return true; 366bdd1243dSDimitry Andric } 367bdd1243dSDimitry Andric 3685f757f3fSDimitry Andric return !State.NoLineBreak && !CurrentState.NoLineBreak; 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric bool ContinuationIndenter::mustBreak(const LineState &State) { 3720b57cec5SDimitry Andric const FormatToken &Current = *State.NextToken; 3730b57cec5SDimitry Andric const FormatToken &Previous = *Current.Previous; 37481ad6265SDimitry Andric const auto &CurrentState = State.Stack.back(); 3755ffd83dbSDimitry Andric if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore && 3765ffd83dbSDimitry Andric Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) { 3775ffd83dbSDimitry Andric auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack); 37881ad6265SDimitry Andric return LambdaBodyLength > getColumnLimit(State); 3795ffd83dbSDimitry Andric } 380bdd1243dSDimitry Andric if (Current.MustBreakBefore || 381bdd1243dSDimitry Andric (Current.is(TT_InlineASMColon) && 382bdd1243dSDimitry Andric (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always || 38306c3fb27SDimitry Andric (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline && 38406c3fb27SDimitry Andric Style.ColumnLimit > 0)))) { 3850b57cec5SDimitry Andric return true; 386bdd1243dSDimitry Andric } 38781ad6265SDimitry Andric if (CurrentState.BreakBeforeClosingBrace && 38806c3fb27SDimitry Andric (Current.closesBlockOrBlockTypeList(Style) || 38906c3fb27SDimitry Andric (Current.is(tok::r_brace) && 39006c3fb27SDimitry Andric Current.isBlockIndentedInitRBrace(Style)))) { 3910b57cec5SDimitry Andric return true; 39281ad6265SDimitry Andric } 39381ad6265SDimitry Andric if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) 3940b57cec5SDimitry Andric return true; 3950b57cec5SDimitry Andric if (Style.Language == FormatStyle::LK_ObjC && 3965ffd83dbSDimitry Andric Style.ObjCBreakBeforeNestedBlockParam && 3970b57cec5SDimitry Andric Current.ObjCSelectorNameParts > 1 && 3980b57cec5SDimitry Andric Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) { 3990b57cec5SDimitry Andric return true; 4000b57cec5SDimitry Andric } 4015ffd83dbSDimitry Andric // Avoid producing inconsistent states by requiring breaks where they are not 4025ffd83dbSDimitry Andric // permitted for C# generic type constraints. 40381ad6265SDimitry Andric if (CurrentState.IsCSharpGenericTypeConstraint && 40481ad6265SDimitry Andric Previous.isNot(TT_CSharpGenericTypeConstraintComma)) { 4055ffd83dbSDimitry Andric return false; 40681ad6265SDimitry Andric } 4070b57cec5SDimitry Andric if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || 4080b57cec5SDimitry Andric (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) && 409647cbc5dSDimitry Andric State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() && 4100b57cec5SDimitry Andric // FIXME: This is a temporary workaround for the case where clang-format 4110b57cec5SDimitry Andric // sets BreakBeforeParameter to avoid bin packing and this creates a 4120b57cec5SDimitry Andric // completely unnecessary line break after a template type that isn't 4130b57cec5SDimitry Andric // line-wrapped. 4140b57cec5SDimitry Andric (Previous.NestingLevel == 1 || Style.BinPackParameters)) || 4150b57cec5SDimitry Andric (Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) && 4160b57cec5SDimitry Andric Previous.isNot(tok::question)) || 4170b57cec5SDimitry Andric (!Style.BreakBeforeTernaryOperators && 4180b57cec5SDimitry Andric Previous.is(TT_ConditionalExpr))) && 41981ad6265SDimitry Andric CurrentState.BreakBeforeParameter && !Current.isTrailingComment() && 42081ad6265SDimitry Andric !Current.isOneOf(tok::r_paren, tok::r_brace)) { 4210b57cec5SDimitry Andric return true; 42281ad6265SDimitry Andric } 42381ad6265SDimitry Andric if (CurrentState.IsChainedConditional && 4245ffd83dbSDimitry Andric ((Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) && 4255ffd83dbSDimitry Andric Current.is(tok::colon)) || 4265ffd83dbSDimitry Andric (!Style.BreakBeforeTernaryOperators && Previous.is(TT_ConditionalExpr) && 42781ad6265SDimitry Andric Previous.is(tok::colon)))) { 4285ffd83dbSDimitry Andric return true; 42981ad6265SDimitry Andric } 4300b57cec5SDimitry Andric if (((Previous.is(TT_DictLiteral) && Previous.is(tok::l_brace)) || 4310b57cec5SDimitry Andric (Previous.is(TT_ArrayInitializerLSquare) && 4320b57cec5SDimitry Andric Previous.ParameterCount > 1) || 4330b57cec5SDimitry Andric opensProtoMessageField(Previous, Style)) && 4340b57cec5SDimitry Andric Style.ColumnLimit > 0 && 4350b57cec5SDimitry Andric getLengthToMatchingParen(Previous, State.Stack) + State.Column - 1 > 43681ad6265SDimitry Andric getColumnLimit(State)) { 4370b57cec5SDimitry Andric return true; 43881ad6265SDimitry Andric } 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric const FormatToken &BreakConstructorInitializersToken = 4410b57cec5SDimitry Andric Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon 4420b57cec5SDimitry Andric ? Previous 4430b57cec5SDimitry Andric : Current; 4440b57cec5SDimitry Andric if (BreakConstructorInitializersToken.is(TT_CtorInitializerColon) && 4450b57cec5SDimitry Andric (State.Column + State.Line->Last->TotalLength - Previous.TotalLength > 4460b57cec5SDimitry Andric getColumnLimit(State) || 44781ad6265SDimitry Andric CurrentState.BreakBeforeParameter) && 448753f127fSDimitry Andric (!Current.isTrailingComment() || Current.NewlinesBefore > 0) && 4490b57cec5SDimitry Andric (Style.AllowShortFunctionsOnASingleLine != FormatStyle::SFS_All || 4500b57cec5SDimitry Andric Style.BreakConstructorInitializers != FormatStyle::BCIS_BeforeColon || 45181ad6265SDimitry Andric Style.ColumnLimit != 0)) { 4520b57cec5SDimitry Andric return true; 45381ad6265SDimitry Andric } 4540b57cec5SDimitry Andric 4555f757f3fSDimitry Andric if (Current.is(TT_ObjCMethodExpr) && Previous.isNot(TT_SelectorName) && 45681ad6265SDimitry Andric State.Line->startsWith(TT_ObjCMethodSpecifier)) { 4570b57cec5SDimitry Andric return true; 45881ad6265SDimitry Andric } 4595f757f3fSDimitry Andric if (Current.is(TT_SelectorName) && Previous.isNot(tok::at) && 46081ad6265SDimitry Andric CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter && 461e8d8bef9SDimitry Andric (Style.ObjCBreakBeforeNestedBlockParam || 46281ad6265SDimitry Andric !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) { 4630b57cec5SDimitry Andric return true; 46481ad6265SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric unsigned NewLineColumn = getNewLineColumn(State); 4670b57cec5SDimitry Andric if (Current.isMemberAccess() && Style.ColumnLimit != 0 && 4680b57cec5SDimitry Andric State.Column + getLengthToNextOperator(Current) > Style.ColumnLimit && 4690b57cec5SDimitry Andric (State.Column > NewLineColumn || 47081ad6265SDimitry Andric Current.NestingLevel < State.StartOfLineLevel)) { 4710b57cec5SDimitry Andric return true; 47281ad6265SDimitry Andric } 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric if (startsSegmentOfBuilderTypeCall(Current) && 47581ad6265SDimitry Andric (CurrentState.CallContinuation != 0 || 47681ad6265SDimitry Andric CurrentState.BreakBeforeParameter) && 4770b57cec5SDimitry Andric // JavaScript is treated different here as there is a frequent pattern: 4780b57cec5SDimitry Andric // SomeFunction(function() { 4790b57cec5SDimitry Andric // ... 4800b57cec5SDimitry Andric // }.bind(...)); 4810b57cec5SDimitry Andric // FIXME: We should find a more generic solution to this problem. 4820eae32dcSDimitry Andric !(State.Column <= NewLineColumn && Style.isJavaScript()) && 48381ad6265SDimitry Andric !(Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) { 4840b57cec5SDimitry Andric return true; 48581ad6265SDimitry Andric } 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric // If the template declaration spans multiple lines, force wrap before the 488bdd1243dSDimitry Andric // function/class declaration. 48981ad6265SDimitry Andric if (Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter && 49081ad6265SDimitry Andric Current.CanBreakBefore) { 4910b57cec5SDimitry Andric return true; 49281ad6265SDimitry Andric } 4930b57cec5SDimitry Andric 4945f757f3fSDimitry Andric if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn) 4950b57cec5SDimitry Andric return false; 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric if (Style.AlwaysBreakBeforeMultilineStrings && 4980b57cec5SDimitry Andric (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth || 4990b57cec5SDimitry Andric Previous.is(tok::comma) || Current.NestingLevel < 2) && 5000b57cec5SDimitry Andric !Previous.isOneOf(tok::kw_return, tok::lessless, tok::at, 5010b57cec5SDimitry Andric Keywords.kw_dollar) && 5020b57cec5SDimitry Andric !Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) && 50381ad6265SDimitry Andric nextIsMultilineString(State)) { 5040b57cec5SDimitry Andric return true; 50581ad6265SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric // Using CanBreakBefore here and below takes care of the decision whether the 5080b57cec5SDimitry Andric // current style uses wrapping before or after operators for the given 5090b57cec5SDimitry Andric // operator. 5100b57cec5SDimitry Andric if (Previous.is(TT_BinaryOperator) && Current.CanBreakBefore) { 51181ad6265SDimitry Andric const auto PreviousPrecedence = Previous.getPrecedence(); 51281ad6265SDimitry Andric if (PreviousPrecedence != prec::Assignment && 51381ad6265SDimitry Andric CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) { 51481ad6265SDimitry Andric const bool LHSIsBinaryExpr = 51581ad6265SDimitry Andric Previous.Previous && Previous.Previous->EndsBinaryExpression; 51681ad6265SDimitry Andric if (LHSIsBinaryExpr) 51781ad6265SDimitry Andric return true; 5180b57cec5SDimitry Andric // If we need to break somewhere inside the LHS of a binary expression, we 5190b57cec5SDimitry Andric // should also break after the operator. Otherwise, the formatting would 5200b57cec5SDimitry Andric // hide the operator precedence, e.g. in: 5210b57cec5SDimitry Andric // if (aaaaaaaaaaaaaa == 5220b57cec5SDimitry Andric // bbbbbbbbbbbbbb && c) {.. 5230b57cec5SDimitry Andric // For comparisons, we only apply this rule, if the LHS is a binary 5240b57cec5SDimitry Andric // expression itself as otherwise, the line breaks seem superfluous. 5250b57cec5SDimitry Andric // We need special cases for ">>" which we have split into two ">" while 5260b57cec5SDimitry Andric // lexing in order to make template parsing easier. 52781ad6265SDimitry Andric const bool IsComparison = 52881ad6265SDimitry Andric (PreviousPrecedence == prec::Relational || 52981ad6265SDimitry Andric PreviousPrecedence == prec::Equality || 53081ad6265SDimitry Andric PreviousPrecedence == prec::Spaceship) && 5310b57cec5SDimitry Andric Previous.Previous && 5320b57cec5SDimitry Andric Previous.Previous->isNot(TT_BinaryOperator); // For >>. 53381ad6265SDimitry Andric if (!IsComparison) 5340b57cec5SDimitry Andric return true; 53581ad6265SDimitry Andric } 5360b57cec5SDimitry Andric } else if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore && 53781ad6265SDimitry Andric CurrentState.BreakBeforeParameter) { 5380b57cec5SDimitry Andric return true; 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric // Same as above, but for the first "<<" operator. 5420b57cec5SDimitry Andric if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) && 54381ad6265SDimitry Andric CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) { 5440b57cec5SDimitry Andric return true; 54581ad6265SDimitry Andric } 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric if (Current.NestingLevel == 0 && !Current.isTrailingComment()) { 54881ad6265SDimitry Andric // Always break after "template <...>"(*) and leading annotations. This is 54981ad6265SDimitry Andric // only for cases where the entire line does not fit on a single line as a 5500b57cec5SDimitry Andric // different LineFormatter would be used otherwise. 55181ad6265SDimitry Andric // *: Except when another option interferes with that, like concepts. 55281ad6265SDimitry Andric if (Previous.ClosesTemplateDeclaration) { 55381ad6265SDimitry Andric if (Current.is(tok::kw_concept)) { 55481ad6265SDimitry Andric switch (Style.BreakBeforeConceptDeclarations) { 55581ad6265SDimitry Andric case FormatStyle::BBCDS_Allowed: 55681ad6265SDimitry Andric break; 55781ad6265SDimitry Andric case FormatStyle::BBCDS_Always: 55881ad6265SDimitry Andric return true; 55981ad6265SDimitry Andric case FormatStyle::BBCDS_Never: 56081ad6265SDimitry Andric return false; 56181ad6265SDimitry Andric } 56281ad6265SDimitry Andric } 56381ad6265SDimitry Andric if (Current.is(TT_RequiresClause)) { 56481ad6265SDimitry Andric switch (Style.RequiresClausePosition) { 56581ad6265SDimitry Andric case FormatStyle::RCPS_SingleLine: 56681ad6265SDimitry Andric case FormatStyle::RCPS_WithPreceding: 56781ad6265SDimitry Andric return false; 56881ad6265SDimitry Andric default: 56981ad6265SDimitry Andric return true; 57081ad6265SDimitry Andric } 57181ad6265SDimitry Andric } 5720fca6ea1SDimitry Andric return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No && 5730fca6ea1SDimitry Andric (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave || 5740fca6ea1SDimitry Andric Current.NewlinesBefore > 0); 57581ad6265SDimitry Andric } 57604eeddc0SDimitry Andric if (Previous.is(TT_FunctionAnnotationRParen) && 57781ad6265SDimitry Andric State.Line->Type != LT_PreprocessorDirective) { 5780b57cec5SDimitry Andric return true; 57981ad6265SDimitry Andric } 5800b57cec5SDimitry Andric if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) && 58181ad6265SDimitry Andric Current.isNot(TT_LeadingJavaAnnotation)) { 5820b57cec5SDimitry Andric return true; 5830b57cec5SDimitry Andric } 58481ad6265SDimitry Andric } 5850b57cec5SDimitry Andric 5860eae32dcSDimitry Andric if (Style.isJavaScript() && Previous.is(tok::r_paren) && 5870eae32dcSDimitry Andric Previous.is(TT_JavaAnnotation)) { 588349cc55cSDimitry Andric // Break after the closing parenthesis of TypeScript decorators before 589349cc55cSDimitry Andric // functions, getters and setters. 590349cc55cSDimitry Andric static const llvm::StringSet<> BreakBeforeDecoratedTokens = {"get", "set", 591349cc55cSDimitry Andric "function"}; 5920eae32dcSDimitry Andric if (BreakBeforeDecoratedTokens.contains(Current.TokenText)) 593349cc55cSDimitry Andric return true; 594349cc55cSDimitry Andric } 595349cc55cSDimitry Andric 596cb14a3feSDimitry Andric if (Current.is(TT_FunctionDeclarationName) && 597bdd1243dSDimitry Andric !State.Line->ReturnTypeWrapped && 598bdd1243dSDimitry Andric // Don't break before a C# function when no break after return type. 599a7dea167SDimitry Andric (!Style.isCSharp() || 6000fca6ea1SDimitry Andric Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) && 601349cc55cSDimitry Andric // Don't always break between a JavaScript `function` and the function 602349cc55cSDimitry Andric // name. 603cb14a3feSDimitry Andric !Style.isJavaScript() && Previous.isNot(tok::kw_template) && 604cb14a3feSDimitry Andric CurrentState.BreakBeforeParameter) { 6050b57cec5SDimitry Andric return true; 60681ad6265SDimitry Andric } 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric // The following could be precomputed as they do not depend on the state. 6090b57cec5SDimitry Andric // However, as they should take effect only if the UnwrappedLine does not fit 6100b57cec5SDimitry Andric // into the ColumnLimit, they are checked here in the ContinuationIndenter. 611e8d8bef9SDimitry Andric if (Style.ColumnLimit != 0 && Previous.is(BK_Block) && 61281ad6265SDimitry Andric Previous.is(tok::l_brace) && 61381ad6265SDimitry Andric !Current.isOneOf(tok::r_brace, tok::comment)) { 6140b57cec5SDimitry Andric return true; 61581ad6265SDimitry Andric } 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric if (Current.is(tok::lessless) && 6180b57cec5SDimitry Andric ((Previous.is(tok::identifier) && Previous.TokenText == "endl") || 6195f757f3fSDimitry Andric (Previous.Tok.isLiteral() && (Previous.TokenText.ends_with("\\n\"") || 62081ad6265SDimitry Andric Previous.TokenText == "\'\\n\'")))) { 6210b57cec5SDimitry Andric return true; 62281ad6265SDimitry Andric } 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric if (Previous.is(TT_BlockComment) && Previous.IsMultiline) 6250b57cec5SDimitry Andric return true; 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric if (State.NoContinuation) 6280b57cec5SDimitry Andric return true; 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric return false; 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline, 6340b57cec5SDimitry Andric bool DryRun, 6350b57cec5SDimitry Andric unsigned ExtraSpaces) { 6360b57cec5SDimitry Andric const FormatToken &Current = *State.NextToken; 63704eeddc0SDimitry Andric assert(State.NextToken->Previous); 63804eeddc0SDimitry Andric const FormatToken &Previous = *State.NextToken->Previous; 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric assert(!State.Stack.empty()); 6410b57cec5SDimitry Andric State.NoContinuation = false; 6420b57cec5SDimitry Andric 64306c3fb27SDimitry Andric if (Current.is(TT_ImplicitStringLiteral) && 64406c3fb27SDimitry Andric (!Previous.Tok.getIdentifierInfo() || 64504eeddc0SDimitry Andric Previous.Tok.getIdentifierInfo()->getPPKeywordID() == 64606c3fb27SDimitry Andric tok::pp_not_keyword)) { 6470b57cec5SDimitry Andric unsigned EndColumn = 6480b57cec5SDimitry Andric SourceMgr.getSpellingColumnNumber(Current.WhitespaceRange.getEnd()); 6490b57cec5SDimitry Andric if (Current.LastNewlineOffset != 0) { 6500b57cec5SDimitry Andric // If there is a newline within this token, the final column will solely 6510b57cec5SDimitry Andric // determined by the current end column. 6520b57cec5SDimitry Andric State.Column = EndColumn; 6530b57cec5SDimitry Andric } else { 6540b57cec5SDimitry Andric unsigned StartColumn = 6550b57cec5SDimitry Andric SourceMgr.getSpellingColumnNumber(Current.WhitespaceRange.getBegin()); 6560b57cec5SDimitry Andric assert(EndColumn >= StartColumn); 6570b57cec5SDimitry Andric State.Column += EndColumn - StartColumn; 6580b57cec5SDimitry Andric } 6590b57cec5SDimitry Andric moveStateToNextToken(State, DryRun, /*Newline=*/false); 6600b57cec5SDimitry Andric return 0; 6610b57cec5SDimitry Andric } 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric unsigned Penalty = 0; 6640b57cec5SDimitry Andric if (Newline) 6650b57cec5SDimitry Andric Penalty = addTokenOnNewLine(State, DryRun); 6660b57cec5SDimitry Andric else 6670b57cec5SDimitry Andric addTokenOnCurrentLine(State, DryRun, ExtraSpaces); 6680b57cec5SDimitry Andric 6690b57cec5SDimitry Andric return moveStateToNextToken(State, DryRun, Newline) + Penalty; 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, 6730b57cec5SDimitry Andric unsigned ExtraSpaces) { 6740b57cec5SDimitry Andric FormatToken &Current = *State.NextToken; 67504eeddc0SDimitry Andric assert(State.NextToken->Previous); 6760b57cec5SDimitry Andric const FormatToken &Previous = *State.NextToken->Previous; 67781ad6265SDimitry Andric auto &CurrentState = State.Stack.back(); 67804eeddc0SDimitry Andric 6795f757f3fSDimitry Andric bool DisallowLineBreaksOnThisLine = 6805f757f3fSDimitry Andric Style.LambdaBodyIndentation == FormatStyle::LBI_Signature && 6815f757f3fSDimitry Andric Style.isCpp() && [&Current] { 6825f757f3fSDimitry Andric // Deal with lambda arguments in C++. The aim here is to ensure that we 6835f757f3fSDimitry Andric // don't over-indent lambda function bodies when lambdas are passed as 6845f757f3fSDimitry Andric // arguments to function calls. We do this by ensuring that either all 6855f757f3fSDimitry Andric // arguments (including any lambdas) go on the same line as the function 6865f757f3fSDimitry Andric // call, or we break before the first argument. 6875678d1d9SDimitry Andric const auto *Prev = Current.Previous; 6885678d1d9SDimitry Andric if (!Prev) 6895678d1d9SDimitry Andric return false; 6905678d1d9SDimitry Andric // For example, `/*Newline=*/false`. 6915678d1d9SDimitry Andric if (Prev->is(TT_BlockComment) && Current.SpacesRequiredBefore == 0) 6925678d1d9SDimitry Andric return false; 6935678d1d9SDimitry Andric const auto *PrevNonComment = Current.getPreviousNonComment(); 6945f757f3fSDimitry Andric if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren)) 6955f757f3fSDimitry Andric return false; 6965f757f3fSDimitry Andric if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare)) 6975f757f3fSDimitry Andric return false; 6985f757f3fSDimitry Andric auto BlockParameterCount = PrevNonComment->BlockParameterCount; 6995f757f3fSDimitry Andric if (BlockParameterCount == 0) 7005f757f3fSDimitry Andric return false; 7015f757f3fSDimitry Andric 7025f757f3fSDimitry Andric // Multiple lambdas in the same function call. 7035f757f3fSDimitry Andric if (BlockParameterCount > 1) 7045f757f3fSDimitry Andric return true; 7055f757f3fSDimitry Andric 7065f757f3fSDimitry Andric // A lambda followed by another arg. 7075f757f3fSDimitry Andric if (!PrevNonComment->Role) 7085f757f3fSDimitry Andric return false; 7095f757f3fSDimitry Andric auto Comma = PrevNonComment->Role->lastComma(); 7105f757f3fSDimitry Andric if (!Comma) 7115f757f3fSDimitry Andric return false; 7125f757f3fSDimitry Andric auto Next = Comma->getNextNonComment(); 7135f757f3fSDimitry Andric return Next && 7145f757f3fSDimitry Andric !Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret); 7155f757f3fSDimitry Andric }(); 7165f757f3fSDimitry Andric 7175f757f3fSDimitry Andric if (DisallowLineBreaksOnThisLine) 7185f757f3fSDimitry Andric State.NoLineBreak = true; 7195f757f3fSDimitry Andric 7200b57cec5SDimitry Andric if (Current.is(tok::equal) && 7210b57cec5SDimitry Andric (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) && 7227a6dacacSDimitry Andric CurrentState.VariablePos == 0 && 7237a6dacacSDimitry Andric (!Previous.Previous || 7247a6dacacSDimitry Andric Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) { 72581ad6265SDimitry Andric CurrentState.VariablePos = State.Column; 7260b57cec5SDimitry Andric // Move over * and & if they are bound to the variable name. 7270b57cec5SDimitry Andric const FormatToken *Tok = &Previous; 72881ad6265SDimitry Andric while (Tok && CurrentState.VariablePos >= Tok->ColumnWidth) { 72981ad6265SDimitry Andric CurrentState.VariablePos -= Tok->ColumnWidth; 7300b57cec5SDimitry Andric if (Tok->SpacesRequiredBefore != 0) 7310b57cec5SDimitry Andric break; 7320b57cec5SDimitry Andric Tok = Tok->Previous; 7330b57cec5SDimitry Andric } 7340b57cec5SDimitry Andric if (Previous.PartOfMultiVariableDeclStmt) 73581ad6265SDimitry Andric CurrentState.LastSpace = CurrentState.VariablePos; 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces; 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric // Indent preprocessor directives after the hash if required. 7410b57cec5SDimitry Andric int PPColumnCorrection = 0; 7420b57cec5SDimitry Andric if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash && 7430b57cec5SDimitry Andric Previous.is(tok::hash) && State.FirstIndent > 0 && 744fcaf7f86SDimitry Andric &Previous == State.Line->First && 7450b57cec5SDimitry Andric (State.Line->Type == LT_PreprocessorDirective || 7460b57cec5SDimitry Andric State.Line->Type == LT_ImportStatement)) { 7470b57cec5SDimitry Andric Spaces += State.FirstIndent; 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric // For preprocessor indent with tabs, State.Column will be 1 because of the 7500b57cec5SDimitry Andric // hash. This causes second-level indents onward to have an extra space 7510b57cec5SDimitry Andric // after the tabs. We avoid this misalignment by subtracting 1 from the 7520b57cec5SDimitry Andric // column value passed to replaceWhitespace(). 7530b57cec5SDimitry Andric if (Style.UseTab != FormatStyle::UT_Never) 7540b57cec5SDimitry Andric PPColumnCorrection = -1; 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric 75781ad6265SDimitry Andric if (!DryRun) { 7580b57cec5SDimitry Andric Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, Spaces, 7597a6dacacSDimitry Andric State.Column + Spaces + PPColumnCorrection, 7607a6dacacSDimitry Andric /*IsAligned=*/false, State.Line->InMacroBody); 76181ad6265SDimitry Andric } 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric // If "BreakBeforeInheritanceComma" mode, don't break within the inheritance 7640b57cec5SDimitry Andric // declaration unless there is multiple inheritance. 7650b57cec5SDimitry Andric if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma && 76681ad6265SDimitry Andric Current.is(TT_InheritanceColon)) { 76781ad6265SDimitry Andric CurrentState.NoLineBreak = true; 76881ad6265SDimitry Andric } 7690b57cec5SDimitry Andric if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon && 77081ad6265SDimitry Andric Previous.is(TT_InheritanceColon)) { 77181ad6265SDimitry Andric CurrentState.NoLineBreak = true; 77281ad6265SDimitry Andric } 7730b57cec5SDimitry Andric 77481ad6265SDimitry Andric if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) { 77581ad6265SDimitry Andric unsigned MinIndent = std::max( 77681ad6265SDimitry Andric State.FirstIndent + Style.ContinuationIndentWidth, CurrentState.Indent); 7770b57cec5SDimitry Andric unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth; 7780b57cec5SDimitry Andric if (Current.LongestObjCSelectorName == 0) 77981ad6265SDimitry Andric CurrentState.AlignColons = false; 7800b57cec5SDimitry Andric else if (MinIndent + Current.LongestObjCSelectorName > FirstColonPos) 78181ad6265SDimitry Andric CurrentState.ColonPos = MinIndent + Current.LongestObjCSelectorName; 7820b57cec5SDimitry Andric else 78381ad6265SDimitry Andric CurrentState.ColonPos = FirstColonPos; 7840b57cec5SDimitry Andric } 7850b57cec5SDimitry Andric 78604eeddc0SDimitry Andric // In "AlwaysBreak" or "BlockIndent" mode, enforce wrapping directly after the 78704eeddc0SDimitry Andric // parenthesis by disallowing any further line breaks if there is no line 78804eeddc0SDimitry Andric // break after the opening parenthesis. Don't break if it doesn't conserve 78904eeddc0SDimitry Andric // columns. 7907a6dacacSDimitry Andric auto IsOpeningBracket = [&](const FormatToken &Tok) { 7917a6dacacSDimitry Andric auto IsStartOfBracedList = [&]() { 7927a6dacacSDimitry Andric return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) && 7937a6dacacSDimitry Andric Style.Cpp11BracedListStyle; 7947a6dacacSDimitry Andric }; 7957a6dacacSDimitry Andric if (!Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) && 7967a6dacacSDimitry Andric !IsStartOfBracedList()) { 7977a6dacacSDimitry Andric return false; 7987a6dacacSDimitry Andric } 7997a6dacacSDimitry Andric if (!Tok.Previous) 8007a6dacacSDimitry Andric return true; 8017a6dacacSDimitry Andric if (Tok.Previous->isIf()) 8027a6dacacSDimitry Andric return Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak; 8037a6dacacSDimitry Andric return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, 8047a6dacacSDimitry Andric tok::kw_switch); 8057a6dacacSDimitry Andric }; 80604eeddc0SDimitry Andric if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || 80704eeddc0SDimitry Andric Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) && 8087a6dacacSDimitry Andric IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && 8090b57cec5SDimitry Andric // Don't do this for simple (no expressions) one-argument function calls 8100b57cec5SDimitry Andric // as that feels like needlessly wasting whitespace, e.g.: 8110b57cec5SDimitry Andric // 8120b57cec5SDimitry Andric // caaaaaaaaaaaall( 8130b57cec5SDimitry Andric // caaaaaaaaaaaall( 8140b57cec5SDimitry Andric // caaaaaaaaaaaall( 8150b57cec5SDimitry Andric // caaaaaaaaaaaaaaaaaaaaaaall(aaaaaaaaaaaaaa, aaaaaaaaa)))); 8160b57cec5SDimitry Andric Current.FakeLParens.size() > 0 && 81781ad6265SDimitry Andric Current.FakeLParens.back() > prec::Unknown) { 81881ad6265SDimitry Andric CurrentState.NoLineBreak = true; 81981ad6265SDimitry Andric } 8200b57cec5SDimitry Andric if (Previous.is(TT_TemplateString) && Previous.opensScope()) 82181ad6265SDimitry Andric CurrentState.NoLineBreak = true; 8220b57cec5SDimitry Andric 82306c3fb27SDimitry Andric // Align following lines within parentheses / brackets if configured. 82406c3fb27SDimitry Andric // Note: This doesn't apply to macro expansion lines, which are MACRO( , , ) 82506c3fb27SDimitry Andric // with args as children of the '(' and ',' tokens. It does not make sense to 82606c3fb27SDimitry Andric // align the commas with the opening paren. 8270b57cec5SDimitry Andric if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign && 82881ad6265SDimitry Andric !CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() && 82981ad6265SDimitry Andric Previous.isNot(TT_ObjCMethodExpr) && Previous.isNot(TT_RequiresClause) && 8300fca6ea1SDimitry Andric Previous.isNot(TT_TableGenDAGArgOpener) && 8310fca6ea1SDimitry Andric Previous.isNot(TT_TableGenDAGArgOpenerToBreak) && 83206c3fb27SDimitry Andric !(Current.MacroParent && Previous.MacroParent) && 83306c3fb27SDimitry Andric (Current.isNot(TT_LineComment) || 83406c3fb27SDimitry Andric Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) { 83581ad6265SDimitry Andric CurrentState.Indent = State.Column + Spaces; 83681ad6265SDimitry Andric CurrentState.IsAligned = true; 8375ffd83dbSDimitry Andric } 83881ad6265SDimitry Andric if (CurrentState.AvoidBinPacking && startsNextParameter(Current, Style)) 83981ad6265SDimitry Andric CurrentState.NoLineBreak = true; 8400b57cec5SDimitry Andric if (startsSegmentOfBuilderTypeCall(Current) && 84181ad6265SDimitry Andric State.Column > getNewLineColumn(State)) { 84281ad6265SDimitry Andric CurrentState.ContainsUnwrappedBuilder = true; 84381ad6265SDimitry Andric } 8440b57cec5SDimitry Andric 845*6c4b055cSDimitry Andric if (Current.is(TT_LambdaArrow) && Style.Language == FormatStyle::LK_Java) 84681ad6265SDimitry Andric CurrentState.NoLineBreak = true; 8470b57cec5SDimitry Andric if (Current.isMemberAccess() && Previous.is(tok::r_paren) && 8480b57cec5SDimitry Andric (Previous.MatchingParen && 84981ad6265SDimitry Andric (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) { 8500b57cec5SDimitry Andric // If there is a function call with long parameters, break before trailing 8510b57cec5SDimitry Andric // calls. This prevents things like: 8520b57cec5SDimitry Andric // EXPECT_CALL(SomeLongParameter).Times( 8530b57cec5SDimitry Andric // 2); 8540b57cec5SDimitry Andric // We don't want to do this for short parameters as they can just be 8550b57cec5SDimitry Andric // indexes. 85681ad6265SDimitry Andric CurrentState.NoLineBreak = true; 85781ad6265SDimitry Andric } 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andric // Don't allow the RHS of an operator to be split over multiple lines unless 8600b57cec5SDimitry Andric // there is a line-break right after the operator. 8610b57cec5SDimitry Andric // Exclude relational operators, as there, it is always more desirable to 8620b57cec5SDimitry Andric // have the LHS 'left' of the RHS. 8630b57cec5SDimitry Andric const FormatToken *P = Current.getPreviousNonComment(); 8645f757f3fSDimitry Andric if (Current.isNot(tok::comment) && P && 8650b57cec5SDimitry Andric (P->isOneOf(TT_BinaryOperator, tok::comma) || 8660b57cec5SDimitry Andric (P->is(TT_ConditionalExpr) && P->is(tok::colon))) && 8670b57cec5SDimitry Andric !P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) && 8680b57cec5SDimitry Andric P->getPrecedence() != prec::Assignment && 8690b57cec5SDimitry Andric P->getPrecedence() != prec::Relational && 8700b57cec5SDimitry Andric P->getPrecedence() != prec::Spaceship) { 8710b57cec5SDimitry Andric bool BreakBeforeOperator = 8720b57cec5SDimitry Andric P->MustBreakBefore || P->is(tok::lessless) || 8730b57cec5SDimitry Andric (P->is(TT_BinaryOperator) && 8740b57cec5SDimitry Andric Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) || 8750b57cec5SDimitry Andric (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators); 8760b57cec5SDimitry Andric // Don't do this if there are only two operands. In these cases, there is 8770b57cec5SDimitry Andric // always a nice vertical separation between them and the extra line break 8780b57cec5SDimitry Andric // does not help. 8795f757f3fSDimitry Andric bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator && 8805f757f3fSDimitry Andric P->isNot(TT_ConditionalExpr); 8815ffd83dbSDimitry Andric if ((!BreakBeforeOperator && 8825ffd83dbSDimitry Andric !(HasTwoOperands && 8835ffd83dbSDimitry Andric Style.AlignOperands != FormatStyle::OAS_DontAlign)) || 88481ad6265SDimitry Andric (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) { 88581ad6265SDimitry Andric CurrentState.NoLineBreakInOperand = true; 88681ad6265SDimitry Andric } 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andric State.Column += Spaces; 8900b57cec5SDimitry Andric if (Current.isNot(tok::comment) && Previous.is(tok::l_paren) && 8910b57cec5SDimitry Andric Previous.Previous && 892a7dea167SDimitry Andric (Previous.Previous->is(tok::kw_for) || Previous.Previous->isIf())) { 8930b57cec5SDimitry Andric // Treat the condition inside an if as if it was a second function 8940b57cec5SDimitry Andric // parameter, i.e. let nested calls have a continuation indent. 89581ad6265SDimitry Andric CurrentState.LastSpace = State.Column; 89681ad6265SDimitry Andric CurrentState.NestedBlockIndent = State.Column; 8970b57cec5SDimitry Andric } else if (!Current.isOneOf(tok::comment, tok::caret) && 8980b57cec5SDimitry Andric ((Previous.is(tok::comma) && 8995f757f3fSDimitry Andric Previous.isNot(TT_OverloadedOperator)) || 9000b57cec5SDimitry Andric (Previous.is(tok::colon) && Previous.is(TT_ObjCMethodExpr)))) { 90181ad6265SDimitry Andric CurrentState.LastSpace = State.Column; 9020b57cec5SDimitry Andric } else if (Previous.is(TT_CtorInitializerColon) && 903753f127fSDimitry Andric (!Current.isTrailingComment() || Current.NewlinesBefore > 0) && 9040b57cec5SDimitry Andric Style.BreakConstructorInitializers == 9050b57cec5SDimitry Andric FormatStyle::BCIS_AfterColon) { 90681ad6265SDimitry Andric CurrentState.Indent = State.Column; 90781ad6265SDimitry Andric CurrentState.LastSpace = State.Column; 9085f757f3fSDimitry Andric } else if (Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) { 9095f757f3fSDimitry Andric CurrentState.LastSpace = State.Column; 9105f757f3fSDimitry Andric } else if (Previous.is(TT_BinaryOperator) && 9110b57cec5SDimitry Andric ((Previous.getPrecedence() != prec::Assignment && 9120b57cec5SDimitry Andric (Previous.isNot(tok::lessless) || Previous.OperatorIndex != 0 || 9130b57cec5SDimitry Andric Previous.NextOperator)) || 9140b57cec5SDimitry Andric Current.StartsBinaryExpression)) { 9150b57cec5SDimitry Andric // Indent relative to the RHS of the expression unless this is a simple 9165f757f3fSDimitry Andric // assignment without binary expression on the RHS. 9170b57cec5SDimitry Andric if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None) 91881ad6265SDimitry Andric CurrentState.LastSpace = State.Column; 9190b57cec5SDimitry Andric } else if (Previous.is(TT_InheritanceColon)) { 92081ad6265SDimitry Andric CurrentState.Indent = State.Column; 92181ad6265SDimitry Andric CurrentState.LastSpace = State.Column; 9225ffd83dbSDimitry Andric } else if (Current.is(TT_CSharpGenericTypeConstraintColon)) { 92381ad6265SDimitry Andric CurrentState.ColonPos = State.Column; 9240b57cec5SDimitry Andric } else if (Previous.opensScope()) { 9250b57cec5SDimitry Andric // If a function has a trailing call, indent all parameters from the 9260b57cec5SDimitry Andric // opening parenthesis. This avoids confusing indents like: 9270b57cec5SDimitry Andric // OuterFunction(InnerFunctionCall( // break 9280b57cec5SDimitry Andric // ParameterToInnerFunction)) // break 9290b57cec5SDimitry Andric // .SecondInnerFunctionCall(); 9300b57cec5SDimitry Andric if (Previous.MatchingParen) { 9310b57cec5SDimitry Andric const FormatToken *Next = Previous.MatchingParen->getNextNonComment(); 93281ad6265SDimitry Andric if (Next && Next->isMemberAccess() && State.Stack.size() > 1 && 93381ad6265SDimitry Andric State.Stack[State.Stack.size() - 2].CallContinuation == 0) { 93481ad6265SDimitry Andric CurrentState.LastSpace = State.Column; 9350b57cec5SDimitry Andric } 93681ad6265SDimitry Andric } 9370b57cec5SDimitry Andric } 9380b57cec5SDimitry Andric } 9390b57cec5SDimitry Andric 9400b57cec5SDimitry Andric unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, 9410b57cec5SDimitry Andric bool DryRun) { 9420b57cec5SDimitry Andric FormatToken &Current = *State.NextToken; 94304eeddc0SDimitry Andric assert(State.NextToken->Previous); 9440b57cec5SDimitry Andric const FormatToken &Previous = *State.NextToken->Previous; 94581ad6265SDimitry Andric auto &CurrentState = State.Stack.back(); 9460b57cec5SDimitry Andric 9470b57cec5SDimitry Andric // Extra penalty that needs to be added because of the way certain line 9480b57cec5SDimitry Andric // breaks are chosen. 9490b57cec5SDimitry Andric unsigned Penalty = 0; 9500b57cec5SDimitry Andric 9510b57cec5SDimitry Andric const FormatToken *PreviousNonComment = Current.getPreviousNonComment(); 9520b57cec5SDimitry Andric const FormatToken *NextNonComment = Previous.getNextNonComment(); 9530b57cec5SDimitry Andric if (!NextNonComment) 9540b57cec5SDimitry Andric NextNonComment = &Current; 9550b57cec5SDimitry Andric // The first line break on any NestingLevel causes an extra penalty in order 9560b57cec5SDimitry Andric // prefer similar line breaks. 95781ad6265SDimitry Andric if (!CurrentState.ContainsLineBreak) 9580b57cec5SDimitry Andric Penalty += 15; 95981ad6265SDimitry Andric CurrentState.ContainsLineBreak = true; 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric Penalty += State.NextToken->SplitPenalty; 9620b57cec5SDimitry Andric 9630b57cec5SDimitry Andric // Breaking before the first "<<" is generally not desirable if the LHS is 9640b57cec5SDimitry Andric // short. Also always add the penalty if the LHS is split over multiple lines 9650b57cec5SDimitry Andric // to avoid unnecessary line breaks that just work around this penalty. 96681ad6265SDimitry Andric if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 && 9670b57cec5SDimitry Andric (State.Column <= Style.ColumnLimit / 3 || 96881ad6265SDimitry Andric CurrentState.BreakBeforeParameter)) { 9690b57cec5SDimitry Andric Penalty += Style.PenaltyBreakFirstLessLess; 97081ad6265SDimitry Andric } 9710b57cec5SDimitry Andric 9720b57cec5SDimitry Andric State.Column = getNewLineColumn(State); 9730b57cec5SDimitry Andric 974e8d8bef9SDimitry Andric // Add Penalty proportional to amount of whitespace away from FirstColumn 975e8d8bef9SDimitry Andric // This tends to penalize several lines that are far-right indented, 976e8d8bef9SDimitry Andric // and prefers a line-break prior to such a block, e.g: 977e8d8bef9SDimitry Andric // 978e8d8bef9SDimitry Andric // Constructor() : 979e8d8bef9SDimitry Andric // member(value), looooooooooooooooong_member( 980e8d8bef9SDimitry Andric // looooooooooong_call(param_1, param_2, param_3)) 981e8d8bef9SDimitry Andric // would then become 982e8d8bef9SDimitry Andric // Constructor() : 983e8d8bef9SDimitry Andric // member(value), 984e8d8bef9SDimitry Andric // looooooooooooooooong_member( 985e8d8bef9SDimitry Andric // looooooooooong_call(param_1, param_2, param_3)) 98681ad6265SDimitry Andric if (State.Column > State.FirstIndent) { 987e8d8bef9SDimitry Andric Penalty += 988e8d8bef9SDimitry Andric Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent); 98981ad6265SDimitry Andric } 990e8d8bef9SDimitry Andric 9910b57cec5SDimitry Andric // Indent nested blocks relative to this column, unless in a very specific 9920b57cec5SDimitry Andric // JavaScript special case where: 9930b57cec5SDimitry Andric // 9940b57cec5SDimitry Andric // var loooooong_name = 9950b57cec5SDimitry Andric // function() { 9960b57cec5SDimitry Andric // // code 9970b57cec5SDimitry Andric // } 9980b57cec5SDimitry Andric // 9990b57cec5SDimitry Andric // is common and should be formatted like a free-standing function. The same 10000b57cec5SDimitry Andric // goes for wrapping before the lambda return type arrow. 1001*6c4b055cSDimitry Andric if (Current.isNot(TT_LambdaArrow) && 10020eae32dcSDimitry Andric (!Style.isJavaScript() || Current.NestingLevel != 0 || 10035f757f3fSDimitry Andric !PreviousNonComment || PreviousNonComment->isNot(tok::equal) || 100481ad6265SDimitry Andric !Current.isOneOf(Keywords.kw_async, Keywords.kw_function))) { 100581ad6265SDimitry Andric CurrentState.NestedBlockIndent = State.Column; 100681ad6265SDimitry Andric } 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric if (NextNonComment->isMemberAccess()) { 100981ad6265SDimitry Andric if (CurrentState.CallContinuation == 0) 101081ad6265SDimitry Andric CurrentState.CallContinuation = State.Column; 10110b57cec5SDimitry Andric } else if (NextNonComment->is(TT_SelectorName)) { 101281ad6265SDimitry Andric if (!CurrentState.ObjCSelectorNameFound) { 10130b57cec5SDimitry Andric if (NextNonComment->LongestObjCSelectorName == 0) { 101481ad6265SDimitry Andric CurrentState.AlignColons = false; 10150b57cec5SDimitry Andric } else { 101681ad6265SDimitry Andric CurrentState.ColonPos = 10170b57cec5SDimitry Andric (shouldIndentWrappedSelectorName(Style, State.Line->Type) 101881ad6265SDimitry Andric ? std::max(CurrentState.Indent, 10190b57cec5SDimitry Andric State.FirstIndent + Style.ContinuationIndentWidth) 102081ad6265SDimitry Andric : CurrentState.Indent) + 10210b57cec5SDimitry Andric std::max(NextNonComment->LongestObjCSelectorName, 10220b57cec5SDimitry Andric NextNonComment->ColumnWidth); 10230b57cec5SDimitry Andric } 102481ad6265SDimitry Andric } else if (CurrentState.AlignColons && 102581ad6265SDimitry Andric CurrentState.ColonPos <= NextNonComment->ColumnWidth) { 102681ad6265SDimitry Andric CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth; 10270b57cec5SDimitry Andric } 10280b57cec5SDimitry Andric } else if (PreviousNonComment && PreviousNonComment->is(tok::colon) && 10290b57cec5SDimitry Andric PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) { 10300b57cec5SDimitry Andric // FIXME: This is hacky, find a better way. The problem is that in an ObjC 10310b57cec5SDimitry Andric // method expression, the block should be aligned to the line starting it, 10320b57cec5SDimitry Andric // e.g.: 10330b57cec5SDimitry Andric // [aaaaaaaaaaaaaaa aaaaaaaaa: \\ break for some reason 10340b57cec5SDimitry Andric // ^(int *i) { 10350b57cec5SDimitry Andric // // ... 10360b57cec5SDimitry Andric // }]; 10370b57cec5SDimitry Andric // Thus, we set LastSpace of the next higher NestingLevel, to which we move 10380b57cec5SDimitry Andric // when we consume all of the "}"'s FakeRParens at the "{". 103981ad6265SDimitry Andric if (State.Stack.size() > 1) { 10400b57cec5SDimitry Andric State.Stack[State.Stack.size() - 2].LastSpace = 104181ad6265SDimitry Andric std::max(CurrentState.LastSpace, CurrentState.Indent) + 10420b57cec5SDimitry Andric Style.ContinuationIndentWidth; 10430b57cec5SDimitry Andric } 104481ad6265SDimitry Andric } 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric if ((PreviousNonComment && 10470b57cec5SDimitry Andric PreviousNonComment->isOneOf(tok::comma, tok::semi) && 104881ad6265SDimitry Andric !CurrentState.AvoidBinPacking) || 104981ad6265SDimitry Andric Previous.is(TT_BinaryOperator)) { 105081ad6265SDimitry Andric CurrentState.BreakBeforeParameter = false; 105181ad6265SDimitry Andric } 10520b57cec5SDimitry Andric if (PreviousNonComment && 105381ad6265SDimitry Andric (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) || 105481ad6265SDimitry Andric PreviousNonComment->ClosesRequiresClause) && 105581ad6265SDimitry Andric Current.NestingLevel == 0) { 105681ad6265SDimitry Andric CurrentState.BreakBeforeParameter = false; 105781ad6265SDimitry Andric } 10580b57cec5SDimitry Andric if (NextNonComment->is(tok::question) || 105981ad6265SDimitry Andric (PreviousNonComment && PreviousNonComment->is(tok::question))) { 106081ad6265SDimitry Andric CurrentState.BreakBeforeParameter = true; 106181ad6265SDimitry Andric } 10620b57cec5SDimitry Andric if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore) 106381ad6265SDimitry Andric CurrentState.BreakBeforeParameter = false; 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric if (!DryRun) { 10660b57cec5SDimitry Andric unsigned MaxEmptyLinesToKeep = Style.MaxEmptyLinesToKeep + 1; 10670b57cec5SDimitry Andric if (Current.is(tok::r_brace) && Current.MatchingParen && 10680b57cec5SDimitry Andric // Only strip trailing empty lines for l_braces that have children, i.e. 10690b57cec5SDimitry Andric // for function expressions (lambdas, arrows, etc). 10700b57cec5SDimitry Andric !Current.MatchingParen->Children.empty()) { 10710b57cec5SDimitry Andric // lambdas and arrow functions are expressions, thus their r_brace is not 10720b57cec5SDimitry Andric // on its own line, and thus not covered by UnwrappedLineFormatter's logic 10730b57cec5SDimitry Andric // about removing empty lines on closing blocks. Special case them here. 10740b57cec5SDimitry Andric MaxEmptyLinesToKeep = 1; 10750b57cec5SDimitry Andric } 10760b57cec5SDimitry Andric unsigned Newlines = 10770b57cec5SDimitry Andric std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep)); 10780b57cec5SDimitry Andric bool ContinuePPDirective = 10790b57cec5SDimitry Andric State.Line->InPPDirective && State.Line->Type != LT_ImportStatement; 10800b57cec5SDimitry Andric Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column, 108181ad6265SDimitry Andric CurrentState.IsAligned, ContinuePPDirective); 10820b57cec5SDimitry Andric } 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric if (!Current.isTrailingComment()) 108581ad6265SDimitry Andric CurrentState.LastSpace = State.Column; 108681ad6265SDimitry Andric if (Current.is(tok::lessless)) { 10870b57cec5SDimitry Andric // If we are breaking before a "<<", we always want to indent relative to 10880b57cec5SDimitry Andric // RHS. This is necessary only for "<<", as we special-case it and don't 10890b57cec5SDimitry Andric // always indent relative to the RHS. 109081ad6265SDimitry Andric CurrentState.LastSpace += 3; // 3 -> width of "<< ". 109181ad6265SDimitry Andric } 10920b57cec5SDimitry Andric 10930b57cec5SDimitry Andric State.StartOfLineLevel = Current.NestingLevel; 10940b57cec5SDimitry Andric State.LowestLevelOnLine = Current.NestingLevel; 10950b57cec5SDimitry Andric 10960b57cec5SDimitry Andric // Any break on this level means that the parent level has been broken 10970b57cec5SDimitry Andric // and we need to avoid bin packing there. 10980b57cec5SDimitry Andric bool NestedBlockSpecialCase = 10995ffd83dbSDimitry Andric (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 && 11005ffd83dbSDimitry Andric State.Stack[State.Stack.size() - 2].NestedBlockInlined) || 11015ffd83dbSDimitry Andric (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) && 11025ffd83dbSDimitry Andric State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam); 110381ad6265SDimitry Andric // Do not force parameter break for statements with requires expressions. 110481ad6265SDimitry Andric NestedBlockSpecialCase = 110581ad6265SDimitry Andric NestedBlockSpecialCase || 110681ad6265SDimitry Andric (Current.MatchingParen && 110781ad6265SDimitry Andric Current.MatchingParen->is(TT_RequiresExpressionLBrace)); 11085f757f3fSDimitry Andric if (!NestedBlockSpecialCase) { 11095f757f3fSDimitry Andric auto ParentLevelIt = std::next(State.Stack.rbegin()); 11105f757f3fSDimitry Andric if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope && 11115f757f3fSDimitry Andric Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) { 11125f757f3fSDimitry Andric // If the first character on the new line is a lambda's closing brace, the 11135f757f3fSDimitry Andric // stack still contains that lambda's parenthesis. As such, we need to 11145f757f3fSDimitry Andric // recurse further down the stack than usual to find the parenthesis level 11155f757f3fSDimitry Andric // containing the lambda, which is where we want to set 11165f757f3fSDimitry Andric // BreakBeforeParameter. 11175f757f3fSDimitry Andric // 11185f757f3fSDimitry Andric // We specifically special case "OuterScope"-formatted lambdas here 11195f757f3fSDimitry Andric // because, when using that setting, breaking before the parameter 11205f757f3fSDimitry Andric // directly following the lambda is particularly unsightly. However, when 11215f757f3fSDimitry Andric // "OuterScope" is not set, the logic to find the parent parenthesis level 11225f757f3fSDimitry Andric // still appears to be sometimes incorrect. It has not been fixed yet 11235f757f3fSDimitry Andric // because it would lead to significant changes in existing behaviour. 11245f757f3fSDimitry Andric // 11255f757f3fSDimitry Andric // TODO: fix the non-"OuterScope" case too. 11265f757f3fSDimitry Andric auto FindCurrentLevel = [&](const auto &It) { 11275f757f3fSDimitry Andric return std::find_if(It, State.Stack.rend(), [](const auto &PState) { 11285f757f3fSDimitry Andric return PState.Tok != nullptr; // Ignore fake parens. 11295f757f3fSDimitry Andric }); 11305f757f3fSDimitry Andric }; 11315f757f3fSDimitry Andric auto MaybeIncrement = [&](const auto &It) { 11325f757f3fSDimitry Andric return It != State.Stack.rend() ? std::next(It) : It; 11335f757f3fSDimitry Andric }; 11345f757f3fSDimitry Andric auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin()); 11355f757f3fSDimitry Andric auto LevelContainingLambdaIt = 11365f757f3fSDimitry Andric FindCurrentLevel(MaybeIncrement(LambdaLevelIt)); 11375f757f3fSDimitry Andric ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt); 11385f757f3fSDimitry Andric } 11395f757f3fSDimitry Andric for (auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I) 11405f757f3fSDimitry Andric I->BreakBeforeParameter = true; 11415f757f3fSDimitry Andric } 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric if (PreviousNonComment && 11440b57cec5SDimitry Andric !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) && 114581ad6265SDimitry Andric ((PreviousNonComment->isNot(TT_TemplateCloser) && 114681ad6265SDimitry Andric !PreviousNonComment->ClosesRequiresClause) || 11470b57cec5SDimitry Andric Current.NestingLevel != 0) && 11480b57cec5SDimitry Andric !PreviousNonComment->isOneOf( 11490b57cec5SDimitry Andric TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation, 11500b57cec5SDimitry Andric TT_LeadingJavaAnnotation) && 11515f757f3fSDimitry Andric Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() && 11525f757f3fSDimitry Andric // We don't want to enforce line breaks for subsequent arguments just 11535f757f3fSDimitry Andric // because we have been forced to break before a lambda body. 11545f757f3fSDimitry Andric (!Style.BraceWrapping.BeforeLambdaBody || 11555f757f3fSDimitry Andric Current.isNot(TT_LambdaLBrace))) { 115681ad6265SDimitry Andric CurrentState.BreakBeforeParameter = true; 115781ad6265SDimitry Andric } 11580b57cec5SDimitry Andric 11590b57cec5SDimitry Andric // If we break after { or the [ of an array initializer, we should also break 11600b57cec5SDimitry Andric // before the corresponding } or ]. 11610b57cec5SDimitry Andric if (PreviousNonComment && 11620b57cec5SDimitry Andric (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) || 116381ad6265SDimitry Andric opensProtoMessageField(*PreviousNonComment, Style))) { 116481ad6265SDimitry Andric CurrentState.BreakBeforeClosingBrace = true; 116581ad6265SDimitry Andric } 11660b57cec5SDimitry Andric 116781ad6265SDimitry Andric if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) { 116881ad6265SDimitry Andric CurrentState.BreakBeforeClosingParen = 116904eeddc0SDimitry Andric Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; 117081ad6265SDimitry Andric } 117104eeddc0SDimitry Andric 117281ad6265SDimitry Andric if (CurrentState.AvoidBinPacking) { 11730b57cec5SDimitry Andric // If we are breaking after '(', '{', '<', or this is the break after a ':' 11745f757f3fSDimitry Andric // to start a member initializer list in a constructor, this should not 11750b57cec5SDimitry Andric // be considered bin packing unless the relevant AllowAll option is false or 11760b57cec5SDimitry Andric // this is a dict/object literal. 11770b57cec5SDimitry Andric bool PreviousIsBreakingCtorInitializerColon = 1178753f127fSDimitry Andric PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) && 11790b57cec5SDimitry Andric Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon; 118006c3fb27SDimitry Andric bool AllowAllConstructorInitializersOnNextLine = 118106c3fb27SDimitry Andric Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine || 118206c3fb27SDimitry Andric Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly; 11830b57cec5SDimitry Andric if (!(Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) || 11840b57cec5SDimitry Andric PreviousIsBreakingCtorInitializerColon) || 11850b57cec5SDimitry Andric (!Style.AllowAllParametersOfDeclarationOnNextLine && 11860b57cec5SDimitry Andric State.Line->MustBeDeclaration) || 11870b57cec5SDimitry Andric (!Style.AllowAllArgumentsOnNextLine && 11880b57cec5SDimitry Andric !State.Line->MustBeDeclaration) || 118906c3fb27SDimitry Andric (!AllowAllConstructorInitializersOnNextLine && 11900b57cec5SDimitry Andric PreviousIsBreakingCtorInitializerColon) || 119181ad6265SDimitry Andric Previous.is(TT_DictLiteral)) { 119281ad6265SDimitry Andric CurrentState.BreakBeforeParameter = true; 119381ad6265SDimitry Andric } 11940b57cec5SDimitry Andric 11950b57cec5SDimitry Andric // If we are breaking after a ':' to start a member initializer list, 11960b57cec5SDimitry Andric // and we allow all arguments on the next line, we should not break 11970b57cec5SDimitry Andric // before the next parameter. 11980b57cec5SDimitry Andric if (PreviousIsBreakingCtorInitializerColon && 119906c3fb27SDimitry Andric AllowAllConstructorInitializersOnNextLine) { 120081ad6265SDimitry Andric CurrentState.BreakBeforeParameter = false; 120181ad6265SDimitry Andric } 12020b57cec5SDimitry Andric } 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric return Penalty; 12050b57cec5SDimitry Andric } 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andric unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { 12080b57cec5SDimitry Andric if (!State.NextToken || !State.NextToken->Previous) 12090b57cec5SDimitry Andric return 0; 12105ffd83dbSDimitry Andric 12110b57cec5SDimitry Andric FormatToken &Current = *State.NextToken; 121281ad6265SDimitry Andric const auto &CurrentState = State.Stack.back(); 12135ffd83dbSDimitry Andric 121481ad6265SDimitry Andric if (CurrentState.IsCSharpGenericTypeConstraint && 121581ad6265SDimitry Andric Current.isNot(TT_CSharpGenericTypeConstraint)) { 121681ad6265SDimitry Andric return CurrentState.ColonPos + 2; 121781ad6265SDimitry Andric } 12185ffd83dbSDimitry Andric 12190b57cec5SDimitry Andric const FormatToken &Previous = *Current.Previous; 12200b57cec5SDimitry Andric // If we are continuing an expression, we want to use the continuation indent. 12210b57cec5SDimitry Andric unsigned ContinuationIndent = 122281ad6265SDimitry Andric std::max(CurrentState.LastSpace, CurrentState.Indent) + 12230b57cec5SDimitry Andric Style.ContinuationIndentWidth; 12240b57cec5SDimitry Andric const FormatToken *PreviousNonComment = Current.getPreviousNonComment(); 12250b57cec5SDimitry Andric const FormatToken *NextNonComment = Previous.getNextNonComment(); 12260b57cec5SDimitry Andric if (!NextNonComment) 12270b57cec5SDimitry Andric NextNonComment = &Current; 12280b57cec5SDimitry Andric 12290b57cec5SDimitry Andric // Java specific bits. 12300b57cec5SDimitry Andric if (Style.Language == FormatStyle::LK_Java && 123181ad6265SDimitry Andric Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) { 123281ad6265SDimitry Andric return std::max(CurrentState.LastSpace, 123381ad6265SDimitry Andric CurrentState.Indent + Style.ContinuationIndentWidth); 123481ad6265SDimitry Andric } 12350b57cec5SDimitry Andric 12365f757f3fSDimitry Andric // Indentation of the statement following a Verilog case label is taken care 12375f757f3fSDimitry Andric // of in moveStateToNextToken. 12385f757f3fSDimitry Andric if (Style.isVerilog() && PreviousNonComment && 12395f757f3fSDimitry Andric Keywords.isVerilogEndOfLabel(*PreviousNonComment)) { 12405f757f3fSDimitry Andric return State.FirstIndent; 12415f757f3fSDimitry Andric } 12425f757f3fSDimitry Andric 12435f757f3fSDimitry Andric if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths && 12445f757f3fSDimitry Andric State.Line->First->is(tok::kw_enum)) { 1245a7dea167SDimitry Andric return (Style.IndentWidth * State.Line->First->IndentLevel) + 1246a7dea167SDimitry Andric Style.IndentWidth; 124781ad6265SDimitry Andric } 1248a7dea167SDimitry Andric 124906c3fb27SDimitry Andric if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) || 125006c3fb27SDimitry Andric (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) { 125106c3fb27SDimitry Andric if (Current.NestingLevel == 0 || 125206c3fb27SDimitry Andric (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope && 125306c3fb27SDimitry Andric State.NextToken->is(TT_LambdaLBrace))) { 125406c3fb27SDimitry Andric return State.FirstIndent; 125506c3fb27SDimitry Andric } 125606c3fb27SDimitry Andric return CurrentState.Indent; 125706c3fb27SDimitry Andric } 1258*6c4b055cSDimitry Andric if (Current.is(TT_LambdaArrow) && 12590fca6ea1SDimitry Andric Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr, 12600fca6ea1SDimitry Andric tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) { 12610fca6ea1SDimitry Andric return ContinuationIndent; 12620fca6ea1SDimitry Andric } 12630b57cec5SDimitry Andric if ((Current.isOneOf(tok::r_brace, tok::r_square) || 12640fca6ea1SDimitry Andric (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) && 12650b57cec5SDimitry Andric State.Stack.size() > 1) { 12660b57cec5SDimitry Andric if (Current.closesBlockOrBlockTypeList(Style)) 12670b57cec5SDimitry Andric return State.Stack[State.Stack.size() - 2].NestedBlockIndent; 1268e8d8bef9SDimitry Andric if (Current.MatchingParen && Current.MatchingParen->is(BK_BracedInit)) 12690b57cec5SDimitry Andric return State.Stack[State.Stack.size() - 2].LastSpace; 12700b57cec5SDimitry Andric return State.FirstIndent; 12710b57cec5SDimitry Andric } 12720b57cec5SDimitry Andric // Indent a closing parenthesis at the previous level if followed by a semi, 12730b57cec5SDimitry Andric // const, or opening brace. This allows indentations such as: 12740b57cec5SDimitry Andric // foo( 12750b57cec5SDimitry Andric // a, 12760b57cec5SDimitry Andric // ); 12770b57cec5SDimitry Andric // int Foo::getter( 12780b57cec5SDimitry Andric // // 12790b57cec5SDimitry Andric // ) const { 12800b57cec5SDimitry Andric // return foo; 12810b57cec5SDimitry Andric // } 12820b57cec5SDimitry Andric // function foo( 12830b57cec5SDimitry Andric // a, 12840b57cec5SDimitry Andric // ) { 12850b57cec5SDimitry Andric // code(); // 12860b57cec5SDimitry Andric // } 12870b57cec5SDimitry Andric if (Current.is(tok::r_paren) && State.Stack.size() > 1 && 12880b57cec5SDimitry Andric (!Current.Next || 128981ad6265SDimitry Andric Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) { 12900b57cec5SDimitry Andric return State.Stack[State.Stack.size() - 2].LastSpace; 129181ad6265SDimitry Andric } 12920fca6ea1SDimitry Andric // When DAGArg closer exists top of line, it should be aligned in the similar 12930fca6ea1SDimitry Andric // way as function call above. 12940fca6ea1SDimitry Andric if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) && 12950fca6ea1SDimitry Andric State.Stack.size() > 1) { 12960fca6ea1SDimitry Andric return State.Stack[State.Stack.size() - 2].LastSpace; 12970fca6ea1SDimitry Andric } 129804eeddc0SDimitry Andric if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && 129906c3fb27SDimitry Andric (Current.is(tok::r_paren) || 13005f757f3fSDimitry Andric (Current.is(tok::r_brace) && Current.MatchingParen && 130106c3fb27SDimitry Andric Current.MatchingParen->is(BK_BracedInit))) && 130206c3fb27SDimitry Andric State.Stack.size() > 1) { 130304eeddc0SDimitry Andric return State.Stack[State.Stack.size() - 2].LastSpace; 130481ad6265SDimitry Andric } 13050b57cec5SDimitry Andric if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope()) 13060b57cec5SDimitry Andric return State.Stack[State.Stack.size() - 2].LastSpace; 130706c3fb27SDimitry Andric // Field labels in a nested type should be aligned to the brace. For example 130806c3fb27SDimitry Andric // in ProtoBuf: 130906c3fb27SDimitry Andric // optional int32 b = 2 [(foo_options) = {aaaaaaaaaaaaaaaaaaa: 123, 131006c3fb27SDimitry Andric // bbbbbbbbbbbbbbbbbbbbbbbb:"baz"}]; 131106c3fb27SDimitry Andric // For Verilog, a quote following a brace is treated as an identifier. And 131206c3fb27SDimitry Andric // Both braces and colons get annotated as TT_DictLiteral. So we have to 131306c3fb27SDimitry Andric // check. 13140b57cec5SDimitry Andric if (Current.is(tok::identifier) && Current.Next && 131506c3fb27SDimitry Andric (!Style.isVerilog() || Current.Next->is(tok::colon)) && 13160b57cec5SDimitry Andric (Current.Next->is(TT_DictLiteral) || 13175f757f3fSDimitry Andric (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) { 131881ad6265SDimitry Andric return CurrentState.Indent; 131981ad6265SDimitry Andric } 13200b57cec5SDimitry Andric if (NextNonComment->is(TT_ObjCStringLiteral) && 132181ad6265SDimitry Andric State.StartOfStringLiteral != 0) { 13220b57cec5SDimitry Andric return State.StartOfStringLiteral - 1; 132381ad6265SDimitry Andric } 13240b57cec5SDimitry Andric if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0) 13250b57cec5SDimitry Andric return State.StartOfStringLiteral; 132681ad6265SDimitry Andric if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0) 132781ad6265SDimitry Andric return CurrentState.FirstLessLess; 13280b57cec5SDimitry Andric if (NextNonComment->isMemberAccess()) { 132981ad6265SDimitry Andric if (CurrentState.CallContinuation == 0) 13300b57cec5SDimitry Andric return ContinuationIndent; 133181ad6265SDimitry Andric return CurrentState.CallContinuation; 13320b57cec5SDimitry Andric } 133381ad6265SDimitry Andric if (CurrentState.QuestionColumn != 0 && 13340b57cec5SDimitry Andric ((NextNonComment->is(tok::colon) && 13350b57cec5SDimitry Andric NextNonComment->is(TT_ConditionalExpr)) || 13365ffd83dbSDimitry Andric Previous.is(TT_ConditionalExpr))) { 13375ffd83dbSDimitry Andric if (((NextNonComment->is(tok::colon) && NextNonComment->Next && 13385ffd83dbSDimitry Andric !NextNonComment->Next->FakeLParens.empty() && 13395ffd83dbSDimitry Andric NextNonComment->Next->FakeLParens.back() == prec::Conditional) || 13405ffd83dbSDimitry Andric (Previous.is(tok::colon) && !Current.FakeLParens.empty() && 13415ffd83dbSDimitry Andric Current.FakeLParens.back() == prec::Conditional)) && 134281ad6265SDimitry Andric !CurrentState.IsWrappedConditional) { 13435ffd83dbSDimitry Andric // NOTE: we may tweak this slightly: 13445ffd83dbSDimitry Andric // * not remove the 'lead' ContinuationIndentWidth 13455ffd83dbSDimitry Andric // * always un-indent by the operator when 13465ffd83dbSDimitry Andric // BreakBeforeTernaryOperators=true 134781ad6265SDimitry Andric unsigned Indent = CurrentState.Indent; 134881ad6265SDimitry Andric if (Style.AlignOperands != FormatStyle::OAS_DontAlign) 13495ffd83dbSDimitry Andric Indent -= Style.ContinuationIndentWidth; 135081ad6265SDimitry Andric if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator) 13515ffd83dbSDimitry Andric Indent -= 2; 13525ffd83dbSDimitry Andric return Indent; 13535ffd83dbSDimitry Andric } 135481ad6265SDimitry Andric return CurrentState.QuestionColumn; 13555ffd83dbSDimitry Andric } 135681ad6265SDimitry Andric if (Previous.is(tok::comma) && CurrentState.VariablePos != 0) 135781ad6265SDimitry Andric return CurrentState.VariablePos; 135881ad6265SDimitry Andric if (Current.is(TT_RequiresClause)) { 135981ad6265SDimitry Andric if (Style.IndentRequiresClause) 136081ad6265SDimitry Andric return CurrentState.Indent + Style.IndentWidth; 136181ad6265SDimitry Andric switch (Style.RequiresClausePosition) { 136281ad6265SDimitry Andric case FormatStyle::RCPS_OwnLine: 136381ad6265SDimitry Andric case FormatStyle::RCPS_WithFollowing: 136481ad6265SDimitry Andric return CurrentState.Indent; 136581ad6265SDimitry Andric default: 136681ad6265SDimitry Andric break; 136781ad6265SDimitry Andric } 136881ad6265SDimitry Andric } 1369fcaf7f86SDimitry Andric if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon, 1370fcaf7f86SDimitry Andric TT_InheritanceComma)) { 1371fcaf7f86SDimitry Andric return State.FirstIndent + Style.ConstructorInitializerIndentWidth; 1372fcaf7f86SDimitry Andric } 13730b57cec5SDimitry Andric if ((PreviousNonComment && 13740b57cec5SDimitry Andric (PreviousNonComment->ClosesTemplateDeclaration || 137581ad6265SDimitry Andric PreviousNonComment->ClosesRequiresClause || 13765f757f3fSDimitry Andric (PreviousNonComment->is(TT_AttributeMacro) && 13775f757f3fSDimitry Andric Current.isNot(tok::l_paren)) || 13780b57cec5SDimitry Andric PreviousNonComment->isOneOf( 13795f757f3fSDimitry Andric TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen, 13800b57cec5SDimitry Andric TT_JavaAnnotation, TT_LeadingJavaAnnotation))) || 13810b57cec5SDimitry Andric (!Style.IndentWrappedFunctionNames && 138281ad6265SDimitry Andric NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) { 138381ad6265SDimitry Andric return std::max(CurrentState.LastSpace, CurrentState.Indent); 138481ad6265SDimitry Andric } 13850b57cec5SDimitry Andric if (NextNonComment->is(TT_SelectorName)) { 138681ad6265SDimitry Andric if (!CurrentState.ObjCSelectorNameFound) { 138781ad6265SDimitry Andric unsigned MinIndent = CurrentState.Indent; 138881ad6265SDimitry Andric if (shouldIndentWrappedSelectorName(Style, State.Line->Type)) { 13890b57cec5SDimitry Andric MinIndent = std::max(MinIndent, 13900b57cec5SDimitry Andric State.FirstIndent + Style.ContinuationIndentWidth); 139181ad6265SDimitry Andric } 13920b57cec5SDimitry Andric // If LongestObjCSelectorName is 0, we are indenting the first 13930b57cec5SDimitry Andric // part of an ObjC selector (or a selector component which is 13940b57cec5SDimitry Andric // not colon-aligned due to block formatting). 13950b57cec5SDimitry Andric // 13960b57cec5SDimitry Andric // Otherwise, we are indenting a subsequent part of an ObjC 13970b57cec5SDimitry Andric // selector which should be colon-aligned to the longest 13980b57cec5SDimitry Andric // component of the ObjC selector. 13990b57cec5SDimitry Andric // 14000b57cec5SDimitry Andric // In either case, we want to respect Style.IndentWrappedFunctionNames. 14010b57cec5SDimitry Andric return MinIndent + 14020b57cec5SDimitry Andric std::max(NextNonComment->LongestObjCSelectorName, 14030b57cec5SDimitry Andric NextNonComment->ColumnWidth) - 14040b57cec5SDimitry Andric NextNonComment->ColumnWidth; 14050b57cec5SDimitry Andric } 140681ad6265SDimitry Andric if (!CurrentState.AlignColons) 140781ad6265SDimitry Andric return CurrentState.Indent; 140881ad6265SDimitry Andric if (CurrentState.ColonPos > NextNonComment->ColumnWidth) 140981ad6265SDimitry Andric return CurrentState.ColonPos - NextNonComment->ColumnWidth; 141081ad6265SDimitry Andric return CurrentState.Indent; 14110b57cec5SDimitry Andric } 14120b57cec5SDimitry Andric if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr)) 141381ad6265SDimitry Andric return CurrentState.ColonPos; 14140b57cec5SDimitry Andric if (NextNonComment->is(TT_ArraySubscriptLSquare)) { 141581ad6265SDimitry Andric if (CurrentState.StartOfArraySubscripts != 0) { 141681ad6265SDimitry Andric return CurrentState.StartOfArraySubscripts; 141781ad6265SDimitry Andric } else if (Style.isCSharp()) { // C# allows `["key"] = value` inside object 14185ffd83dbSDimitry Andric // initializers. 141981ad6265SDimitry Andric return CurrentState.Indent; 142081ad6265SDimitry Andric } 14210b57cec5SDimitry Andric return ContinuationIndent; 14220b57cec5SDimitry Andric } 14230b57cec5SDimitry Andric 142406c3fb27SDimitry Andric // OpenMP clauses want to get additional indentation when they are pushed onto 142506c3fb27SDimitry Andric // the next line. 142606c3fb27SDimitry Andric if (State.Line->InPragmaDirective) { 142706c3fb27SDimitry Andric FormatToken *PragmaType = State.Line->First->Next->Next; 14280fca6ea1SDimitry Andric if (PragmaType && PragmaType->TokenText == "omp") 1429bdd1243dSDimitry Andric return CurrentState.Indent + Style.ContinuationIndentWidth; 143006c3fb27SDimitry Andric } 1431bdd1243dSDimitry Andric 14320b57cec5SDimitry Andric // This ensure that we correctly format ObjC methods calls without inputs, 14330b57cec5SDimitry Andric // i.e. where the last element isn't selector like: [callee method]; 14340b57cec5SDimitry Andric if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 && 143581ad6265SDimitry Andric NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) { 143681ad6265SDimitry Andric return CurrentState.Indent; 143781ad6265SDimitry Andric } 14380b57cec5SDimitry Andric 14390b57cec5SDimitry Andric if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) || 144081ad6265SDimitry Andric Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) { 14410b57cec5SDimitry Andric return ContinuationIndent; 144281ad6265SDimitry Andric } 14430b57cec5SDimitry Andric if (PreviousNonComment && PreviousNonComment->is(tok::colon) && 144481ad6265SDimitry Andric PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) { 14450b57cec5SDimitry Andric return ContinuationIndent; 144681ad6265SDimitry Andric } 14470b57cec5SDimitry Andric if (NextNonComment->is(TT_CtorInitializerComma)) 144881ad6265SDimitry Andric return CurrentState.Indent; 14490b57cec5SDimitry Andric if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) && 145081ad6265SDimitry Andric Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) { 145181ad6265SDimitry Andric return CurrentState.Indent; 145281ad6265SDimitry Andric } 14530b57cec5SDimitry Andric if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) && 145481ad6265SDimitry Andric Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) { 145581ad6265SDimitry Andric return CurrentState.Indent; 145681ad6265SDimitry Andric } 14570fca6ea1SDimitry Andric if (Previous.is(tok::r_paren) && 14580fca6ea1SDimitry Andric Previous.isNot(TT_TableGenDAGArgOperatorToBreak) && 14590fca6ea1SDimitry Andric !Current.isBinaryOperator() && 146081ad6265SDimitry Andric !Current.isOneOf(tok::colon, tok::comment)) { 14610b57cec5SDimitry Andric return ContinuationIndent; 146281ad6265SDimitry Andric } 14630b57cec5SDimitry Andric if (Current.is(TT_ProtoExtensionLSquare)) 146481ad6265SDimitry Andric return CurrentState.Indent; 146581ad6265SDimitry Andric if (Current.isBinaryOperator() && CurrentState.UnindentOperator) { 146681ad6265SDimitry Andric return CurrentState.Indent - Current.Tok.getLength() - 14675ffd83dbSDimitry Andric Current.SpacesRequiredBefore; 146881ad6265SDimitry Andric } 14695f757f3fSDimitry Andric if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() && 14705f757f3fSDimitry Andric CurrentState.UnindentOperator) { 147181ad6265SDimitry Andric return CurrentState.Indent - NextNonComment->Tok.getLength() - 14725ffd83dbSDimitry Andric NextNonComment->SpacesRequiredBefore; 147381ad6265SDimitry Andric } 147481ad6265SDimitry Andric if (CurrentState.Indent == State.FirstIndent && PreviousNonComment && 147581ad6265SDimitry Andric !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) { 14760b57cec5SDimitry Andric // Ensure that we fall back to the continuation indent width instead of 14770b57cec5SDimitry Andric // just flushing continuations left. 147881ad6265SDimitry Andric return CurrentState.Indent + Style.ContinuationIndentWidth; 147981ad6265SDimitry Andric } 148081ad6265SDimitry Andric return CurrentState.Indent; 14810b57cec5SDimitry Andric } 14820b57cec5SDimitry Andric 14835ffd83dbSDimitry Andric static bool hasNestedBlockInlined(const FormatToken *Previous, 14845ffd83dbSDimitry Andric const FormatToken &Current, 14855ffd83dbSDimitry Andric const FormatStyle &Style) { 14865ffd83dbSDimitry Andric if (Previous->isNot(tok::l_paren)) 14875ffd83dbSDimitry Andric return true; 14885ffd83dbSDimitry Andric if (Previous->ParameterCount > 1) 14895ffd83dbSDimitry Andric return true; 14905ffd83dbSDimitry Andric 1491bdd1243dSDimitry Andric // Also a nested block if contains a lambda inside function with 1 parameter. 149281ad6265SDimitry Andric return Style.BraceWrapping.BeforeLambdaBody && Current.is(TT_LambdaLSquare); 14935ffd83dbSDimitry Andric } 14945ffd83dbSDimitry Andric 14950b57cec5SDimitry Andric unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, 14960b57cec5SDimitry Andric bool DryRun, bool Newline) { 14970b57cec5SDimitry Andric assert(State.Stack.size()); 14980b57cec5SDimitry Andric const FormatToken &Current = *State.NextToken; 149981ad6265SDimitry Andric auto &CurrentState = State.Stack.back(); 15000b57cec5SDimitry Andric 15015ffd83dbSDimitry Andric if (Current.is(TT_CSharpGenericTypeConstraint)) 150281ad6265SDimitry Andric CurrentState.IsCSharpGenericTypeConstraint = true; 15030b57cec5SDimitry Andric if (Current.isOneOf(tok::comma, TT_BinaryOperator)) 150481ad6265SDimitry Andric CurrentState.NoLineBreakInOperand = false; 15055ffd83dbSDimitry Andric if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon)) 150681ad6265SDimitry Andric CurrentState.AvoidBinPacking = true; 15070b57cec5SDimitry Andric if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) { 150881ad6265SDimitry Andric if (CurrentState.FirstLessLess == 0) 150981ad6265SDimitry Andric CurrentState.FirstLessLess = State.Column; 15100b57cec5SDimitry Andric else 151181ad6265SDimitry Andric CurrentState.LastOperatorWrapped = Newline; 15120b57cec5SDimitry Andric } 15130b57cec5SDimitry Andric if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless)) 151481ad6265SDimitry Andric CurrentState.LastOperatorWrapped = Newline; 15150b57cec5SDimitry Andric if (Current.is(TT_ConditionalExpr) && Current.Previous && 15165f757f3fSDimitry Andric Current.Previous->isNot(TT_ConditionalExpr)) { 151781ad6265SDimitry Andric CurrentState.LastOperatorWrapped = Newline; 151881ad6265SDimitry Andric } 15190b57cec5SDimitry Andric if (Current.is(TT_ArraySubscriptLSquare) && 152081ad6265SDimitry Andric CurrentState.StartOfArraySubscripts == 0) { 152181ad6265SDimitry Andric CurrentState.StartOfArraySubscripts = State.Column; 152281ad6265SDimitry Andric } 152381ad6265SDimitry Andric 152481ad6265SDimitry Andric auto IsWrappedConditional = [](const FormatToken &Tok) { 152581ad6265SDimitry Andric if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question))) 152681ad6265SDimitry Andric return false; 152781ad6265SDimitry Andric if (Tok.MustBreakBefore) 152881ad6265SDimitry Andric return true; 152981ad6265SDimitry Andric 153081ad6265SDimitry Andric const FormatToken *Next = Tok.getNextNonComment(); 153181ad6265SDimitry Andric return Next && Next->MustBreakBefore; 153281ad6265SDimitry Andric }; 153381ad6265SDimitry Andric if (IsWrappedConditional(Current)) 153481ad6265SDimitry Andric CurrentState.IsWrappedConditional = true; 15350b57cec5SDimitry Andric if (Style.BreakBeforeTernaryOperators && Current.is(tok::question)) 153681ad6265SDimitry Andric CurrentState.QuestionColumn = State.Column; 15370b57cec5SDimitry Andric if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) { 15380b57cec5SDimitry Andric const FormatToken *Previous = Current.Previous; 15390b57cec5SDimitry Andric while (Previous && Previous->isTrailingComment()) 15400b57cec5SDimitry Andric Previous = Previous->Previous; 15410b57cec5SDimitry Andric if (Previous && Previous->is(tok::question)) 154281ad6265SDimitry Andric CurrentState.QuestionColumn = State.Column; 15430b57cec5SDimitry Andric } 15440b57cec5SDimitry Andric if (!Current.opensScope() && !Current.closesScope() && 15455f757f3fSDimitry Andric Current.isNot(TT_PointerOrReference)) { 15460b57cec5SDimitry Andric State.LowestLevelOnLine = 15470b57cec5SDimitry Andric std::min(State.LowestLevelOnLine, Current.NestingLevel); 154881ad6265SDimitry Andric } 15490b57cec5SDimitry Andric if (Current.isMemberAccess()) 155081ad6265SDimitry Andric CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column; 15510b57cec5SDimitry Andric if (Current.is(TT_SelectorName)) 155281ad6265SDimitry Andric CurrentState.ObjCSelectorNameFound = true; 15530b57cec5SDimitry Andric if (Current.is(TT_CtorInitializerColon) && 15540b57cec5SDimitry Andric Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) { 15550b57cec5SDimitry Andric // Indent 2 from the column, so: 15560b57cec5SDimitry Andric // SomeClass::SomeClass() 15570b57cec5SDimitry Andric // : First(...), ... 15580b57cec5SDimitry Andric // Next(...) 15590b57cec5SDimitry Andric // ^ line up here. 156081ad6265SDimitry Andric CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers == 156181ad6265SDimitry Andric FormatStyle::BCIS_BeforeComma 15620b57cec5SDimitry Andric ? 0 15630b57cec5SDimitry Andric : 2); 156481ad6265SDimitry Andric CurrentState.NestedBlockIndent = CurrentState.Indent; 1565349cc55cSDimitry Andric if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) { 156681ad6265SDimitry Andric CurrentState.AvoidBinPacking = true; 156781ad6265SDimitry Andric CurrentState.BreakBeforeParameter = 15685f757f3fSDimitry Andric Style.ColumnLimit > 0 && 156906c3fb27SDimitry Andric Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine && 157006c3fb27SDimitry Andric Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly; 15710b57cec5SDimitry Andric } else { 157281ad6265SDimitry Andric CurrentState.BreakBeforeParameter = false; 15730b57cec5SDimitry Andric } 15740b57cec5SDimitry Andric } 15750b57cec5SDimitry Andric if (Current.is(TT_CtorInitializerColon) && 15760b57cec5SDimitry Andric Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) { 157781ad6265SDimitry Andric CurrentState.Indent = 15780b57cec5SDimitry Andric State.FirstIndent + Style.ConstructorInitializerIndentWidth; 157981ad6265SDimitry Andric CurrentState.NestedBlockIndent = CurrentState.Indent; 1580349cc55cSDimitry Andric if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) 158181ad6265SDimitry Andric CurrentState.AvoidBinPacking = true; 15825f757f3fSDimitry Andric else 15835f757f3fSDimitry Andric CurrentState.BreakBeforeParameter = false; 15840b57cec5SDimitry Andric } 158581ad6265SDimitry Andric if (Current.is(TT_InheritanceColon)) { 158681ad6265SDimitry Andric CurrentState.Indent = 15870b57cec5SDimitry Andric State.FirstIndent + Style.ConstructorInitializerIndentWidth; 158881ad6265SDimitry Andric } 15890b57cec5SDimitry Andric if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline) 159081ad6265SDimitry Andric CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1; 1591*6c4b055cSDimitry Andric if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow)) 159281ad6265SDimitry Andric CurrentState.LastSpace = State.Column; 1593bdd1243dSDimitry Andric if (Current.is(TT_RequiresExpression) && 1594bdd1243dSDimitry Andric Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) { 159581ad6265SDimitry Andric CurrentState.NestedBlockIndent = State.Column; 1596bdd1243dSDimitry Andric } 15970b57cec5SDimitry Andric 15980b57cec5SDimitry Andric // Insert scopes created by fake parenthesis. 15990b57cec5SDimitry Andric const FormatToken *Previous = Current.getPreviousNonComment(); 16000b57cec5SDimitry Andric 16010b57cec5SDimitry Andric // Add special behavior to support a format commonly used for JavaScript 16020b57cec5SDimitry Andric // closures: 16030b57cec5SDimitry Andric // SomeFunction(function() { 16040b57cec5SDimitry Andric // foo(); 16050b57cec5SDimitry Andric // bar(); 16060b57cec5SDimitry Andric // }, a, b, c); 160781ad6265SDimitry Andric if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause && 160881ad6265SDimitry Andric Previous && Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) && 16095f757f3fSDimitry Andric Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 && 161081ad6265SDimitry Andric !CurrentState.HasMultipleNestedBlocks) { 16110b57cec5SDimitry Andric if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline) 161281ad6265SDimitry Andric for (ParenState &PState : llvm::drop_end(State.Stack)) 161381ad6265SDimitry Andric PState.NoLineBreak = true; 16140b57cec5SDimitry Andric State.Stack[State.Stack.size() - 2].NestedBlockInlined = false; 16150b57cec5SDimitry Andric } 161604eeddc0SDimitry Andric if (Previous && (Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) || 161704eeddc0SDimitry Andric (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) && 161804eeddc0SDimitry Andric !Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))) { 161981ad6265SDimitry Andric CurrentState.NestedBlockInlined = 16205ffd83dbSDimitry Andric !Newline && hasNestedBlockInlined(Previous, Current, Style); 16210b57cec5SDimitry Andric } 16220b57cec5SDimitry Andric 16230b57cec5SDimitry Andric moveStatePastFakeLParens(State, Newline); 16240b57cec5SDimitry Andric moveStatePastScopeCloser(State); 162581ad6265SDimitry Andric // Do not use CurrentState here, since the two functions before may change the 162681ad6265SDimitry Andric // Stack. 16270b57cec5SDimitry Andric bool AllowBreak = !State.Stack.back().NoLineBreak && 16280b57cec5SDimitry Andric !State.Stack.back().NoLineBreakInOperand; 16290b57cec5SDimitry Andric moveStatePastScopeOpener(State, Newline); 16300b57cec5SDimitry Andric moveStatePastFakeRParens(State); 16310b57cec5SDimitry Andric 16320b57cec5SDimitry Andric if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0) 16330b57cec5SDimitry Andric State.StartOfStringLiteral = State.Column + 1; 163481ad6265SDimitry Andric if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) { 16350b57cec5SDimitry Andric State.StartOfStringLiteral = State.Column + 1; 16367a6dacacSDimitry Andric } else if (Current.is(TT_TableGenMultiLineString) && 16377a6dacacSDimitry Andric State.StartOfStringLiteral == 0) { 16387a6dacacSDimitry Andric State.StartOfStringLiteral = State.Column + 1; 163981ad6265SDimitry Andric } else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) { 16400b57cec5SDimitry Andric State.StartOfStringLiteral = State.Column; 164181ad6265SDimitry Andric } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) && 164281ad6265SDimitry Andric !Current.isStringLiteral()) { 16430b57cec5SDimitry Andric State.StartOfStringLiteral = 0; 164481ad6265SDimitry Andric } 16450b57cec5SDimitry Andric 16460b57cec5SDimitry Andric State.Column += Current.ColumnWidth; 16470b57cec5SDimitry Andric State.NextToken = State.NextToken->Next; 16485f757f3fSDimitry Andric // Verilog case labels are on the same unwrapped lines as the statements that 16495f757f3fSDimitry Andric // follow. TokenAnnotator identifies them and sets MustBreakBefore. 16505f757f3fSDimitry Andric // Indentation is taken care of here. A case label can only have 1 statement 16515f757f3fSDimitry Andric // in Verilog, so we don't have to worry about lines that follow. 16525f757f3fSDimitry Andric if (Style.isVerilog() && State.NextToken && 16535f757f3fSDimitry Andric State.NextToken->MustBreakBefore && 16545f757f3fSDimitry Andric Keywords.isVerilogEndOfLabel(Current)) { 16555f757f3fSDimitry Andric State.FirstIndent += Style.IndentWidth; 16565f757f3fSDimitry Andric CurrentState.Indent = State.FirstIndent; 16575f757f3fSDimitry Andric } 16580b57cec5SDimitry Andric 16590b57cec5SDimitry Andric unsigned Penalty = 16600b57cec5SDimitry Andric handleEndOfLine(Current, State, DryRun, AllowBreak, Newline); 16610b57cec5SDimitry Andric 16620b57cec5SDimitry Andric if (Current.Role) 16630b57cec5SDimitry Andric Current.Role->formatFromToken(State, this, DryRun); 16640b57cec5SDimitry Andric // If the previous has a special role, let it consume tokens as appropriate. 16650b57cec5SDimitry Andric // It is necessary to start at the previous token for the only implemented 16660b57cec5SDimitry Andric // role (comma separated list). That way, the decision whether or not to break 16670b57cec5SDimitry Andric // after the "{" is already done and both options are tried and evaluated. 16680b57cec5SDimitry Andric // FIXME: This is ugly, find a better way. 16690b57cec5SDimitry Andric if (Previous && Previous->Role) 16700b57cec5SDimitry Andric Penalty += Previous->Role->formatAfterToken(State, this, DryRun); 16710b57cec5SDimitry Andric 16720b57cec5SDimitry Andric return Penalty; 16730b57cec5SDimitry Andric } 16740b57cec5SDimitry Andric 16750b57cec5SDimitry Andric void ContinuationIndenter::moveStatePastFakeLParens(LineState &State, 16760b57cec5SDimitry Andric bool Newline) { 16770b57cec5SDimitry Andric const FormatToken &Current = *State.NextToken; 16780eae32dcSDimitry Andric if (Current.FakeLParens.empty()) 16790eae32dcSDimitry Andric return; 16800eae32dcSDimitry Andric 16810b57cec5SDimitry Andric const FormatToken *Previous = Current.getPreviousNonComment(); 16820b57cec5SDimitry Andric 16830b57cec5SDimitry Andric // Don't add extra indentation for the first fake parenthesis after 168481ad6265SDimitry Andric // 'return', assignments, opening <({[, or requires clauses. The indentation 168581ad6265SDimitry Andric // for these cases is special cased. 16860b57cec5SDimitry Andric bool SkipFirstExtraIndent = 168781ad6265SDimitry Andric Previous && 168881ad6265SDimitry Andric (Previous->opensScope() || 168981ad6265SDimitry Andric Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) || 16900b57cec5SDimitry Andric (Previous->getPrecedence() == prec::Assignment && 16915ffd83dbSDimitry Andric Style.AlignOperands != FormatStyle::OAS_DontAlign) || 169281ad6265SDimitry Andric Previous->is(TT_ObjCMethodExpr)); 16930eae32dcSDimitry Andric for (const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) { 169481ad6265SDimitry Andric const auto &CurrentState = State.Stack.back(); 169581ad6265SDimitry Andric ParenState NewParenState = CurrentState; 16960b57cec5SDimitry Andric NewParenState.Tok = nullptr; 16970b57cec5SDimitry Andric NewParenState.ContainsLineBreak = false; 16980b57cec5SDimitry Andric NewParenState.LastOperatorWrapped = true; 16995ffd83dbSDimitry Andric NewParenState.IsChainedConditional = false; 17005ffd83dbSDimitry Andric NewParenState.IsWrappedConditional = false; 17015ffd83dbSDimitry Andric NewParenState.UnindentOperator = false; 17020b57cec5SDimitry Andric NewParenState.NoLineBreak = 170381ad6265SDimitry Andric NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand; 17040b57cec5SDimitry Andric 17050b57cec5SDimitry Andric // Don't propagate AvoidBinPacking into subexpressions of arg/param lists. 17060eae32dcSDimitry Andric if (PrecedenceLevel > prec::Comma) 17070b57cec5SDimitry Andric NewParenState.AvoidBinPacking = false; 17080b57cec5SDimitry Andric 17090b57cec5SDimitry Andric // Indent from 'LastSpace' unless these are fake parentheses encapsulating 17100b57cec5SDimitry Andric // a builder type call after 'return' or, if the alignment after opening 17110b57cec5SDimitry Andric // brackets is disabled. 17120b57cec5SDimitry Andric if (!Current.isTrailingComment() && 17135ffd83dbSDimitry Andric (Style.AlignOperands != FormatStyle::OAS_DontAlign || 17140eae32dcSDimitry Andric PrecedenceLevel < prec::Assignment) && 17150b57cec5SDimitry Andric (!Previous || Previous->isNot(tok::kw_return) || 17160eae32dcSDimitry Andric (Style.Language != FormatStyle::LK_Java && PrecedenceLevel > 0)) && 17170b57cec5SDimitry Andric (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign || 17180fca6ea1SDimitry Andric PrecedenceLevel > prec::Comma || Current.NestingLevel == 0) && 17190fca6ea1SDimitry Andric (!Style.isTableGen() || 17200fca6ea1SDimitry Andric (Previous && Previous->isOneOf(TT_TableGenDAGArgListComma, 17210fca6ea1SDimitry Andric TT_TableGenDAGArgListCommaToBreak)))) { 172281ad6265SDimitry Andric NewParenState.Indent = std::max( 172381ad6265SDimitry Andric std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace); 17245ffd83dbSDimitry Andric } 17255ffd83dbSDimitry Andric 1726bdd1243dSDimitry Andric // Special case for generic selection expressions, its comma-separated 1727bdd1243dSDimitry Andric // expressions are not aligned to the opening paren like regular calls, but 1728bdd1243dSDimitry Andric // rather continuation-indented relative to the _Generic keyword. 17290fca6ea1SDimitry Andric if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic) && 17300fca6ea1SDimitry Andric State.Stack.size() > 1) { 17310fca6ea1SDimitry Andric NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent + 17320fca6ea1SDimitry Andric Style.ContinuationIndentWidth; 17330fca6ea1SDimitry Andric } 1734bdd1243dSDimitry Andric 17355f757f3fSDimitry Andric if ((shouldUnindentNextOperator(Current) || 17365f757f3fSDimitry Andric (Previous && 17375f757f3fSDimitry Andric (PrecedenceLevel == prec::Conditional && 17385f757f3fSDimitry Andric Previous->is(tok::question) && Previous->is(TT_ConditionalExpr)))) && 1739e8d8bef9SDimitry Andric !Newline) { 1740e8d8bef9SDimitry Andric // If BreakBeforeBinaryOperators is set, un-indent a bit to account for 1741bdd1243dSDimitry Andric // the operator and keep the operands aligned. 1742e8d8bef9SDimitry Andric if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator) 17435ffd83dbSDimitry Andric NewParenState.UnindentOperator = true; 1744e8d8bef9SDimitry Andric // Mark indentation as alignment if the expression is aligned. 1745e8d8bef9SDimitry Andric if (Style.AlignOperands != FormatStyle::OAS_DontAlign) 1746e8d8bef9SDimitry Andric NewParenState.IsAligned = true; 1747e8d8bef9SDimitry Andric } 17480b57cec5SDimitry Andric 17490b57cec5SDimitry Andric // Do not indent relative to the fake parentheses inserted for "." or "->". 17500b57cec5SDimitry Andric // This is a special case to make the following to statements consistent: 17510b57cec5SDimitry Andric // OuterFunction(InnerFunctionCall( // break 17520b57cec5SDimitry Andric // ParameterToInnerFunction)); 17530b57cec5SDimitry Andric // OuterFunction(SomeObject.InnerFunctionCall( // break 17540b57cec5SDimitry Andric // ParameterToInnerFunction)); 17550eae32dcSDimitry Andric if (PrecedenceLevel > prec::Unknown) 17560b57cec5SDimitry Andric NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column); 17575f757f3fSDimitry Andric if (PrecedenceLevel != prec::Conditional && 17585f757f3fSDimitry Andric Current.isNot(TT_UnaryOperator) && 175981ad6265SDimitry Andric Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) { 17600b57cec5SDimitry Andric NewParenState.StartOfFunctionCall = State.Column; 176181ad6265SDimitry Andric } 17620b57cec5SDimitry Andric 17635ffd83dbSDimitry Andric // Indent conditional expressions, unless they are chained "else-if" 17645ffd83dbSDimitry Andric // conditionals. Never indent expression where the 'operator' is ',', ';' or 17655ffd83dbSDimitry Andric // an assignment (i.e. *I <= prec::Assignment) as those have different 17665ffd83dbSDimitry Andric // indentation rules. Indent other expression, unless the indentation needs 17675ffd83dbSDimitry Andric // to be skipped. 17680eae32dcSDimitry Andric if (PrecedenceLevel == prec::Conditional && Previous && 17690eae32dcSDimitry Andric Previous->is(tok::colon) && Previous->is(TT_ConditionalExpr) && 17700eae32dcSDimitry Andric &PrecedenceLevel == &Current.FakeLParens.back() && 177181ad6265SDimitry Andric !CurrentState.IsWrappedConditional) { 17725ffd83dbSDimitry Andric NewParenState.IsChainedConditional = true; 17735ffd83dbSDimitry Andric NewParenState.UnindentOperator = State.Stack.back().UnindentOperator; 17740eae32dcSDimitry Andric } else if (PrecedenceLevel == prec::Conditional || 17750eae32dcSDimitry Andric (!SkipFirstExtraIndent && PrecedenceLevel > prec::Assignment && 17765ffd83dbSDimitry Andric !Current.isTrailingComment())) { 17770b57cec5SDimitry Andric NewParenState.Indent += Style.ContinuationIndentWidth; 17785ffd83dbSDimitry Andric } 17790eae32dcSDimitry Andric if ((Previous && !Previous->opensScope()) || PrecedenceLevel != prec::Comma) 17800b57cec5SDimitry Andric NewParenState.BreakBeforeParameter = false; 17810b57cec5SDimitry Andric State.Stack.push_back(NewParenState); 17820b57cec5SDimitry Andric SkipFirstExtraIndent = false; 17830b57cec5SDimitry Andric } 17840b57cec5SDimitry Andric } 17850b57cec5SDimitry Andric 17860b57cec5SDimitry Andric void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) { 17870b57cec5SDimitry Andric for (unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) { 17880b57cec5SDimitry Andric unsigned VariablePos = State.Stack.back().VariablePos; 17890b57cec5SDimitry Andric if (State.Stack.size() == 1) { 17900b57cec5SDimitry Andric // Do not pop the last element. 17910b57cec5SDimitry Andric break; 17920b57cec5SDimitry Andric } 17930b57cec5SDimitry Andric State.Stack.pop_back(); 17940b57cec5SDimitry Andric State.Stack.back().VariablePos = VariablePos; 17950b57cec5SDimitry Andric } 179681ad6265SDimitry Andric 179781ad6265SDimitry Andric if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) { 179881ad6265SDimitry Andric // Remove the indentation of the requires clauses (which is not in Indent, 179981ad6265SDimitry Andric // but in LastSpace). 180081ad6265SDimitry Andric State.Stack.back().LastSpace -= Style.IndentWidth; 180181ad6265SDimitry Andric } 18020b57cec5SDimitry Andric } 18030b57cec5SDimitry Andric 18040b57cec5SDimitry Andric void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, 18050b57cec5SDimitry Andric bool Newline) { 18060b57cec5SDimitry Andric const FormatToken &Current = *State.NextToken; 18070b57cec5SDimitry Andric if (!Current.opensScope()) 18080b57cec5SDimitry Andric return; 18090b57cec5SDimitry Andric 181081ad6265SDimitry Andric const auto &CurrentState = State.Stack.back(); 181181ad6265SDimitry Andric 18125ffd83dbSDimitry Andric // Don't allow '<' or '(' in C# generic type constraints to start new scopes. 18135ffd83dbSDimitry Andric if (Current.isOneOf(tok::less, tok::l_paren) && 181481ad6265SDimitry Andric CurrentState.IsCSharpGenericTypeConstraint) { 18155ffd83dbSDimitry Andric return; 181681ad6265SDimitry Andric } 18175ffd83dbSDimitry Andric 1818e8d8bef9SDimitry Andric if (Current.MatchingParen && Current.is(BK_Block)) { 18190fca6ea1SDimitry Andric moveStateToNewBlock(State, Newline); 18200b57cec5SDimitry Andric return; 18210b57cec5SDimitry Andric } 18220b57cec5SDimitry Andric 18230b57cec5SDimitry Andric unsigned NewIndent; 182481ad6265SDimitry Andric unsigned LastSpace = CurrentState.LastSpace; 18250b57cec5SDimitry Andric bool AvoidBinPacking; 18260b57cec5SDimitry Andric bool BreakBeforeParameter = false; 182781ad6265SDimitry Andric unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall, 182881ad6265SDimitry Andric CurrentState.NestedBlockIndent); 18290b57cec5SDimitry Andric if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) || 18300b57cec5SDimitry Andric opensProtoMessageField(Current, Style)) { 18310b57cec5SDimitry Andric if (Current.opensBlockOrBlockTypeList(Style)) { 18320b57cec5SDimitry Andric NewIndent = Style.IndentWidth + 183381ad6265SDimitry Andric std::min(State.Column, CurrentState.NestedBlockIndent); 183406c3fb27SDimitry Andric } else if (Current.is(tok::l_brace)) { 183506c3fb27SDimitry Andric NewIndent = 183606c3fb27SDimitry Andric CurrentState.LastSpace + Style.BracedInitializerIndentWidth.value_or( 183706c3fb27SDimitry Andric Style.ContinuationIndentWidth); 18380b57cec5SDimitry Andric } else { 183981ad6265SDimitry Andric NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth; 18400b57cec5SDimitry Andric } 184106c3fb27SDimitry Andric const FormatToken *NextNonComment = Current.getNextNonComment(); 18420b57cec5SDimitry Andric bool EndsInComma = Current.MatchingParen && 18430b57cec5SDimitry Andric Current.MatchingParen->Previous && 18440b57cec5SDimitry Andric Current.MatchingParen->Previous->is(tok::comma); 18450b57cec5SDimitry Andric AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) || 18465f757f3fSDimitry Andric Style.isProto() || !Style.BinPackArguments || 184706c3fb27SDimitry Andric (NextNonComment && NextNonComment->isOneOf( 184806c3fb27SDimitry Andric TT_DesignatedInitializerPeriod, 18490b57cec5SDimitry Andric TT_DesignatedInitializerLSquare)); 18500b57cec5SDimitry Andric BreakBeforeParameter = EndsInComma; 18510b57cec5SDimitry Andric if (Current.ParameterCount > 1) 18520b57cec5SDimitry Andric NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1); 18530b57cec5SDimitry Andric } else { 185481ad6265SDimitry Andric NewIndent = 185581ad6265SDimitry Andric Style.ContinuationIndentWidth + 185681ad6265SDimitry Andric std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall); 18570b57cec5SDimitry Andric 18580fca6ea1SDimitry Andric if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) && 18590fca6ea1SDimitry Andric Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) { 18600fca6ea1SDimitry Andric // For the case the next token is a TableGen DAGArg operator identifier 18610fca6ea1SDimitry Andric // that is not marked to have a line break after it. 18620fca6ea1SDimitry Andric // In this case the option DAS_BreakElements requires to align the 18630fca6ea1SDimitry Andric // DAGArg elements to the operator. 18640fca6ea1SDimitry Andric const FormatToken *Next = Current.Next; 18650fca6ea1SDimitry Andric if (Next && Next->is(TT_TableGenDAGArgOperatorID)) 18660fca6ea1SDimitry Andric NewIndent = State.Column + Next->TokenText.size() + 2; 18670fca6ea1SDimitry Andric } 18680fca6ea1SDimitry Andric 18690b57cec5SDimitry Andric // Ensure that different different brackets force relative alignment, e.g.: 18700b57cec5SDimitry Andric // void SomeFunction(vector< // break 18710b57cec5SDimitry Andric // int> v); 18720b57cec5SDimitry Andric // FIXME: We likely want to do this for more combinations of brackets. 18730b57cec5SDimitry Andric if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) { 187481ad6265SDimitry Andric NewIndent = std::max(NewIndent, CurrentState.Indent); 187581ad6265SDimitry Andric LastSpace = std::max(LastSpace, CurrentState.Indent); 18760b57cec5SDimitry Andric } 18770b57cec5SDimitry Andric 18780b57cec5SDimitry Andric bool EndsInComma = 18790b57cec5SDimitry Andric Current.MatchingParen && 18800b57cec5SDimitry Andric Current.MatchingParen->getPreviousNonComment() && 18810b57cec5SDimitry Andric Current.MatchingParen->getPreviousNonComment()->is(tok::comma); 18820b57cec5SDimitry Andric 18830b57cec5SDimitry Andric // If ObjCBinPackProtocolList is unspecified, fall back to BinPackParameters 18840b57cec5SDimitry Andric // for backwards compatibility. 18850b57cec5SDimitry Andric bool ObjCBinPackProtocolList = 18860b57cec5SDimitry Andric (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto && 18870b57cec5SDimitry Andric Style.BinPackParameters) || 18880b57cec5SDimitry Andric Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always; 18890b57cec5SDimitry Andric 18900b57cec5SDimitry Andric bool BinPackDeclaration = 18910b57cec5SDimitry Andric (State.Line->Type != LT_ObjCDecl && Style.BinPackParameters) || 18920b57cec5SDimitry Andric (State.Line->Type == LT_ObjCDecl && ObjCBinPackProtocolList); 18930b57cec5SDimitry Andric 1894bdd1243dSDimitry Andric bool GenericSelection = 1895bdd1243dSDimitry Andric Current.getPreviousNonComment() && 1896bdd1243dSDimitry Andric Current.getPreviousNonComment()->is(tok::kw__Generic); 1897bdd1243dSDimitry Andric 18980b57cec5SDimitry Andric AvoidBinPacking = 1899bdd1243dSDimitry Andric (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection || 19000eae32dcSDimitry Andric (Style.isJavaScript() && EndsInComma) || 19010b57cec5SDimitry Andric (State.Line->MustBeDeclaration && !BinPackDeclaration) || 19020b57cec5SDimitry Andric (!State.Line->MustBeDeclaration && !Style.BinPackArguments) || 19030b57cec5SDimitry Andric (Style.ExperimentalAutoDetectBinPacking && 1904e8d8bef9SDimitry Andric (Current.is(PPK_OnePerLine) || 1905e8d8bef9SDimitry Andric (!BinPackInconclusiveFunctions && Current.is(PPK_Inconclusive)))); 19060b57cec5SDimitry Andric 19075ffd83dbSDimitry Andric if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen && 19085ffd83dbSDimitry Andric Style.ObjCBreakBeforeNestedBlockParam) { 19090b57cec5SDimitry Andric if (Style.ColumnLimit) { 19100b57cec5SDimitry Andric // If this '[' opens an ObjC call, determine whether all parameters fit 19110b57cec5SDimitry Andric // into one line and put one per line if they don't. 19120b57cec5SDimitry Andric if (getLengthToMatchingParen(Current, State.Stack) + State.Column > 191381ad6265SDimitry Andric getColumnLimit(State)) { 19140b57cec5SDimitry Andric BreakBeforeParameter = true; 191581ad6265SDimitry Andric } 19160b57cec5SDimitry Andric } else { 19170b57cec5SDimitry Andric // For ColumnLimit = 0, we have to figure out whether there is or has to 19180b57cec5SDimitry Andric // be a line break within this call. 19190b57cec5SDimitry Andric for (const FormatToken *Tok = &Current; 19200b57cec5SDimitry Andric Tok && Tok != Current.MatchingParen; Tok = Tok->Next) { 19210b57cec5SDimitry Andric if (Tok->MustBreakBefore || 19220b57cec5SDimitry Andric (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) { 19230b57cec5SDimitry Andric BreakBeforeParameter = true; 19240b57cec5SDimitry Andric break; 19250b57cec5SDimitry Andric } 19260b57cec5SDimitry Andric } 19270b57cec5SDimitry Andric } 19280b57cec5SDimitry Andric } 19290b57cec5SDimitry Andric 19300eae32dcSDimitry Andric if (Style.isJavaScript() && EndsInComma) 19310b57cec5SDimitry Andric BreakBeforeParameter = true; 19320b57cec5SDimitry Andric } 19330b57cec5SDimitry Andric // Generally inherit NoLineBreak from the current scope to nested scope. 19340b57cec5SDimitry Andric // However, don't do this for non-empty nested blocks, dict literals and 19350b57cec5SDimitry Andric // array literals as these follow different indentation rules. 19360b57cec5SDimitry Andric bool NoLineBreak = 19370b57cec5SDimitry Andric Current.Children.empty() && 19380b57cec5SDimitry Andric !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) && 193981ad6265SDimitry Andric (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand || 19400b57cec5SDimitry Andric (Current.is(TT_TemplateOpener) && 194181ad6265SDimitry Andric CurrentState.ContainsUnwrappedBuilder)); 19420b57cec5SDimitry Andric State.Stack.push_back( 19430b57cec5SDimitry Andric ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak)); 194481ad6265SDimitry Andric auto &NewState = State.Stack.back(); 194581ad6265SDimitry Andric NewState.NestedBlockIndent = NestedBlockIndent; 194681ad6265SDimitry Andric NewState.BreakBeforeParameter = BreakBeforeParameter; 194781ad6265SDimitry Andric NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1); 19485ffd83dbSDimitry Andric 194906c3fb27SDimitry Andric if (Style.BraceWrapping.BeforeLambdaBody && Current.Next && 195081ad6265SDimitry Andric Current.is(tok::l_paren)) { 1951bdd1243dSDimitry Andric // Search for any parameter that is a lambda. 19525ffd83dbSDimitry Andric FormatToken const *next = Current.Next; 195306c3fb27SDimitry Andric while (next) { 19545ffd83dbSDimitry Andric if (next->is(TT_LambdaLSquare)) { 195581ad6265SDimitry Andric NewState.HasMultipleNestedBlocks = true; 19565ffd83dbSDimitry Andric break; 19575ffd83dbSDimitry Andric } 19585ffd83dbSDimitry Andric next = next->Next; 19595ffd83dbSDimitry Andric } 19605ffd83dbSDimitry Andric } 19615ffd83dbSDimitry Andric 196281ad6265SDimitry Andric NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) && 196381ad6265SDimitry Andric Current.Previous && 19640b57cec5SDimitry Andric Current.Previous->is(tok::at); 19650b57cec5SDimitry Andric } 19660b57cec5SDimitry Andric 19670b57cec5SDimitry Andric void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) { 19680b57cec5SDimitry Andric const FormatToken &Current = *State.NextToken; 19690b57cec5SDimitry Andric if (!Current.closesScope()) 19700b57cec5SDimitry Andric return; 19710b57cec5SDimitry Andric 19720b57cec5SDimitry Andric // If we encounter a closing ), ], } or >, we can remove a level from our 19730b57cec5SDimitry Andric // stacks. 19740b57cec5SDimitry Andric if (State.Stack.size() > 1 && 19750b57cec5SDimitry Andric (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) || 19760b57cec5SDimitry Andric (Current.is(tok::r_brace) && State.NextToken != State.Line->First) || 19770b57cec5SDimitry Andric State.NextToken->is(TT_TemplateCloser) || 19780fca6ea1SDimitry Andric State.NextToken->is(TT_TableGenListCloser) || 197981ad6265SDimitry Andric (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) { 19800b57cec5SDimitry Andric State.Stack.pop_back(); 198181ad6265SDimitry Andric } 198281ad6265SDimitry Andric 198381ad6265SDimitry Andric auto &CurrentState = State.Stack.back(); 19840b57cec5SDimitry Andric 19850b57cec5SDimitry Andric // Reevaluate whether ObjC message arguments fit into one line. 19860b57cec5SDimitry Andric // If a receiver spans multiple lines, e.g.: 19870b57cec5SDimitry Andric // [[object block:^{ 19880b57cec5SDimitry Andric // return 42; 19890b57cec5SDimitry Andric // }] a:42 b:42]; 19900b57cec5SDimitry Andric // BreakBeforeParameter is calculated based on an incorrect assumption 19910b57cec5SDimitry Andric // (it is checked whether the whole expression fits into one line without 19920b57cec5SDimitry Andric // considering a line break inside a message receiver). 1993349cc55cSDimitry Andric // We check whether arguments fit after receiver scope closer (into the same 19940b57cec5SDimitry Andric // line). 199581ad6265SDimitry Andric if (CurrentState.BreakBeforeParameter && Current.MatchingParen && 19960b57cec5SDimitry Andric Current.MatchingParen->Previous) { 19970b57cec5SDimitry Andric const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous; 19980b57cec5SDimitry Andric if (CurrentScopeOpener.is(TT_ObjCMethodExpr) && 19990b57cec5SDimitry Andric CurrentScopeOpener.MatchingParen) { 20000b57cec5SDimitry Andric int NecessarySpaceInLine = 20010b57cec5SDimitry Andric getLengthToMatchingParen(CurrentScopeOpener, State.Stack) + 20020b57cec5SDimitry Andric CurrentScopeOpener.TotalLength - Current.TotalLength - 1; 20030b57cec5SDimitry Andric if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <= 200481ad6265SDimitry Andric Style.ColumnLimit) { 200581ad6265SDimitry Andric CurrentState.BreakBeforeParameter = false; 200681ad6265SDimitry Andric } 20070b57cec5SDimitry Andric } 20080b57cec5SDimitry Andric } 20090b57cec5SDimitry Andric 20100b57cec5SDimitry Andric if (Current.is(tok::r_square)) { 20110b57cec5SDimitry Andric // If this ends the array subscript expr, reset the corresponding value. 20120b57cec5SDimitry Andric const FormatToken *NextNonComment = Current.getNextNonComment(); 20130b57cec5SDimitry Andric if (NextNonComment && NextNonComment->isNot(tok::l_square)) 201481ad6265SDimitry Andric CurrentState.StartOfArraySubscripts = 0; 20150b57cec5SDimitry Andric } 20160b57cec5SDimitry Andric } 20170b57cec5SDimitry Andric 20180fca6ea1SDimitry Andric void ContinuationIndenter::moveStateToNewBlock(LineState &State, bool NewLine) { 201906c3fb27SDimitry Andric if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope && 20205f757f3fSDimitry Andric State.NextToken->is(TT_LambdaLBrace) && 20215f757f3fSDimitry Andric !State.Line->MightBeFunctionDecl) { 202206c3fb27SDimitry Andric State.Stack.back().NestedBlockIndent = State.FirstIndent; 202306c3fb27SDimitry Andric } 20240b57cec5SDimitry Andric unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent; 20250b57cec5SDimitry Andric // ObjC block sometimes follow special indentation rules. 20260b57cec5SDimitry Andric unsigned NewIndent = 20270b57cec5SDimitry Andric NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace) 20280b57cec5SDimitry Andric ? Style.ObjCBlockIndentWidth 20290b57cec5SDimitry Andric : Style.IndentWidth); 20300fca6ea1SDimitry Andric 20310fca6ea1SDimitry Andric // Even when wrapping before lambda body, the left brace can still be added to 20320fca6ea1SDimitry Andric // the same line. This occurs when checking whether the whole lambda body can 20330fca6ea1SDimitry Andric // go on a single line. In this case we have to make sure there are no line 20340fca6ea1SDimitry Andric // breaks in the body, otherwise we could just end up with a regular lambda 20350fca6ea1SDimitry Andric // body without the brace wrapped. 20360fca6ea1SDimitry Andric bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine && 20370fca6ea1SDimitry Andric State.NextToken->is(TT_LambdaLBrace); 20380fca6ea1SDimitry Andric 20390b57cec5SDimitry Andric State.Stack.push_back(ParenState(State.NextToken, NewIndent, 20400b57cec5SDimitry Andric State.Stack.back().LastSpace, 20410fca6ea1SDimitry Andric /*AvoidBinPacking=*/true, NoLineBreak)); 20420b57cec5SDimitry Andric State.Stack.back().NestedBlockIndent = NestedBlockIndent; 20430b57cec5SDimitry Andric State.Stack.back().BreakBeforeParameter = true; 20440b57cec5SDimitry Andric } 20450b57cec5SDimitry Andric 20460b57cec5SDimitry Andric static unsigned getLastLineEndColumn(StringRef Text, unsigned StartColumn, 20470b57cec5SDimitry Andric unsigned TabWidth, 20480b57cec5SDimitry Andric encoding::Encoding Encoding) { 20490b57cec5SDimitry Andric size_t LastNewlinePos = Text.find_last_of("\n"); 20500b57cec5SDimitry Andric if (LastNewlinePos == StringRef::npos) { 20510b57cec5SDimitry Andric return StartColumn + 20520b57cec5SDimitry Andric encoding::columnWidthWithTabs(Text, StartColumn, TabWidth, Encoding); 20530b57cec5SDimitry Andric } else { 20540b57cec5SDimitry Andric return encoding::columnWidthWithTabs(Text.substr(LastNewlinePos), 20550b57cec5SDimitry Andric /*StartColumn=*/0, TabWidth, Encoding); 20560b57cec5SDimitry Andric } 20570b57cec5SDimitry Andric } 20580b57cec5SDimitry Andric 20590b57cec5SDimitry Andric unsigned ContinuationIndenter::reformatRawStringLiteral( 20600b57cec5SDimitry Andric const FormatToken &Current, LineState &State, 20610b57cec5SDimitry Andric const FormatStyle &RawStringStyle, bool DryRun, bool Newline) { 20620b57cec5SDimitry Andric unsigned StartColumn = State.Column - Current.ColumnWidth; 20630b57cec5SDimitry Andric StringRef OldDelimiter = *getRawStringDelimiter(Current.TokenText); 20640b57cec5SDimitry Andric StringRef NewDelimiter = 20650b57cec5SDimitry Andric getCanonicalRawStringDelimiter(Style, RawStringStyle.Language); 2066fe6060f1SDimitry Andric if (NewDelimiter.empty()) 20670b57cec5SDimitry Andric NewDelimiter = OldDelimiter; 20680b57cec5SDimitry Andric // The text of a raw string is between the leading 'R"delimiter(' and the 20690b57cec5SDimitry Andric // trailing 'delimiter)"'. 20700b57cec5SDimitry Andric unsigned OldPrefixSize = 3 + OldDelimiter.size(); 20710b57cec5SDimitry Andric unsigned OldSuffixSize = 2 + OldDelimiter.size(); 20720b57cec5SDimitry Andric // We create a virtual text environment which expects a null-terminated 20730b57cec5SDimitry Andric // string, so we cannot use StringRef. 20745ffd83dbSDimitry Andric std::string RawText = std::string( 20755ffd83dbSDimitry Andric Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize)); 20760b57cec5SDimitry Andric if (NewDelimiter != OldDelimiter) { 20770b57cec5SDimitry Andric // Don't update to the canonical delimiter 'deli' if ')deli"' occurs in the 20780b57cec5SDimitry Andric // raw string. 20790b57cec5SDimitry Andric std::string CanonicalDelimiterSuffix = (")" + NewDelimiter + "\"").str(); 20800b57cec5SDimitry Andric if (StringRef(RawText).contains(CanonicalDelimiterSuffix)) 20810b57cec5SDimitry Andric NewDelimiter = OldDelimiter; 20820b57cec5SDimitry Andric } 20830b57cec5SDimitry Andric 20840b57cec5SDimitry Andric unsigned NewPrefixSize = 3 + NewDelimiter.size(); 20850b57cec5SDimitry Andric unsigned NewSuffixSize = 2 + NewDelimiter.size(); 20860b57cec5SDimitry Andric 20870b57cec5SDimitry Andric // The first start column is the column the raw text starts after formatting. 20880b57cec5SDimitry Andric unsigned FirstStartColumn = StartColumn + NewPrefixSize; 20890b57cec5SDimitry Andric 20900b57cec5SDimitry Andric // The next start column is the intended indentation a line break inside 20910b57cec5SDimitry Andric // the raw string at level 0. It is determined by the following rules: 20920b57cec5SDimitry Andric // - if the content starts on newline, it is one level more than the current 20930b57cec5SDimitry Andric // indent, and 20940b57cec5SDimitry Andric // - if the content does not start on a newline, it is the first start 20950b57cec5SDimitry Andric // column. 20960b57cec5SDimitry Andric // These rules have the advantage that the formatted content both does not 20970b57cec5SDimitry Andric // violate the rectangle rule and visually flows within the surrounding 20980b57cec5SDimitry Andric // source. 20990b57cec5SDimitry Andric bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] == '\n'; 21000b57cec5SDimitry Andric // If this token is the last parameter (checked by looking if it's followed by 21010b57cec5SDimitry Andric // `)` and is not on a newline, the base the indent off the line's nested 21020b57cec5SDimitry Andric // block indent. Otherwise, base the indent off the arguments indent, so we 21030b57cec5SDimitry Andric // can achieve: 21040b57cec5SDimitry Andric // 21050b57cec5SDimitry Andric // fffffffffff(1, 2, 3, R"pb( 21060b57cec5SDimitry Andric // key1: 1 # 21070b57cec5SDimitry Andric // key2: 2)pb"); 21080b57cec5SDimitry Andric // 21090b57cec5SDimitry Andric // fffffffffff(1, 2, 3, 21100b57cec5SDimitry Andric // R"pb( 21110b57cec5SDimitry Andric // key1: 1 # 21120b57cec5SDimitry Andric // key2: 2 21130b57cec5SDimitry Andric // )pb"); 21140b57cec5SDimitry Andric // 21150b57cec5SDimitry Andric // fffffffffff(1, 2, 3, 21160b57cec5SDimitry Andric // R"pb( 21170b57cec5SDimitry Andric // key1: 1 # 21180b57cec5SDimitry Andric // key2: 2 21190b57cec5SDimitry Andric // )pb", 21200b57cec5SDimitry Andric // 5); 21210b57cec5SDimitry Andric unsigned CurrentIndent = 21220b57cec5SDimitry Andric (!Newline && Current.Next && Current.Next->is(tok::r_paren)) 21230b57cec5SDimitry Andric ? State.Stack.back().NestedBlockIndent 21240b57cec5SDimitry Andric : State.Stack.back().Indent; 21250b57cec5SDimitry Andric unsigned NextStartColumn = ContentStartsOnNewline 21260b57cec5SDimitry Andric ? CurrentIndent + Style.IndentWidth 21270b57cec5SDimitry Andric : FirstStartColumn; 21280b57cec5SDimitry Andric 21290b57cec5SDimitry Andric // The last start column is the column the raw string suffix starts if it is 21300b57cec5SDimitry Andric // put on a newline. 21310b57cec5SDimitry Andric // The last start column is the intended indentation of the raw string postfix 21320b57cec5SDimitry Andric // if it is put on a newline. It is determined by the following rules: 21330b57cec5SDimitry Andric // - if the raw string prefix starts on a newline, it is the column where 21340b57cec5SDimitry Andric // that raw string prefix starts, and 21350b57cec5SDimitry Andric // - if the raw string prefix does not start on a newline, it is the current 21360b57cec5SDimitry Andric // indent. 21370b57cec5SDimitry Andric unsigned LastStartColumn = 21380b57cec5SDimitry Andric Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent; 21390b57cec5SDimitry Andric 21400b57cec5SDimitry Andric std::pair<tooling::Replacements, unsigned> Fixes = internal::reformat( 21410b57cec5SDimitry Andric RawStringStyle, RawText, {tooling::Range(0, RawText.size())}, 21420b57cec5SDimitry Andric FirstStartColumn, NextStartColumn, LastStartColumn, "<stdin>", 21430b57cec5SDimitry Andric /*Status=*/nullptr); 21440b57cec5SDimitry Andric 21450b57cec5SDimitry Andric auto NewCode = applyAllReplacements(RawText, Fixes.first); 21460b57cec5SDimitry Andric tooling::Replacements NoFixes; 214781ad6265SDimitry Andric if (!NewCode) 21480b57cec5SDimitry Andric return addMultilineToken(Current, State); 21490b57cec5SDimitry Andric if (!DryRun) { 21500b57cec5SDimitry Andric if (NewDelimiter != OldDelimiter) { 21510b57cec5SDimitry Andric // In 'R"delimiter(...', the delimiter starts 2 characters after the start 21520b57cec5SDimitry Andric // of the token. 21530b57cec5SDimitry Andric SourceLocation PrefixDelimiterStart = 21540b57cec5SDimitry Andric Current.Tok.getLocation().getLocWithOffset(2); 21550b57cec5SDimitry Andric auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement( 21560b57cec5SDimitry Andric SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter)); 21570b57cec5SDimitry Andric if (PrefixErr) { 21580b57cec5SDimitry Andric llvm::errs() 21590b57cec5SDimitry Andric << "Failed to update the prefix delimiter of a raw string: " 21600b57cec5SDimitry Andric << llvm::toString(std::move(PrefixErr)) << "\n"; 21610b57cec5SDimitry Andric } 21620b57cec5SDimitry Andric // In 'R"delimiter(...)delimiter"', the suffix delimiter starts at 21630b57cec5SDimitry Andric // position length - 1 - |delimiter|. 21640b57cec5SDimitry Andric SourceLocation SuffixDelimiterStart = 21650b57cec5SDimitry Andric Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() - 21660b57cec5SDimitry Andric 1 - OldDelimiter.size()); 21670b57cec5SDimitry Andric auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement( 21680b57cec5SDimitry Andric SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter)); 21690b57cec5SDimitry Andric if (SuffixErr) { 21700b57cec5SDimitry Andric llvm::errs() 21710b57cec5SDimitry Andric << "Failed to update the suffix delimiter of a raw string: " 21720b57cec5SDimitry Andric << llvm::toString(std::move(SuffixErr)) << "\n"; 21730b57cec5SDimitry Andric } 21740b57cec5SDimitry Andric } 21750b57cec5SDimitry Andric SourceLocation OriginLoc = 21760b57cec5SDimitry Andric Current.Tok.getLocation().getLocWithOffset(OldPrefixSize); 21770b57cec5SDimitry Andric for (const tooling::Replacement &Fix : Fixes.first) { 21780b57cec5SDimitry Andric auto Err = Whitespaces.addReplacement(tooling::Replacement( 21790b57cec5SDimitry Andric SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()), 21800b57cec5SDimitry Andric Fix.getLength(), Fix.getReplacementText())); 21810b57cec5SDimitry Andric if (Err) { 21820b57cec5SDimitry Andric llvm::errs() << "Failed to reformat raw string: " 21830b57cec5SDimitry Andric << llvm::toString(std::move(Err)) << "\n"; 21840b57cec5SDimitry Andric } 21850b57cec5SDimitry Andric } 21860b57cec5SDimitry Andric } 21870b57cec5SDimitry Andric unsigned RawLastLineEndColumn = getLastLineEndColumn( 21880b57cec5SDimitry Andric *NewCode, FirstStartColumn, Style.TabWidth, Encoding); 21890b57cec5SDimitry Andric State.Column = RawLastLineEndColumn + NewSuffixSize; 21900b57cec5SDimitry Andric // Since we're updating the column to after the raw string literal here, we 21910b57cec5SDimitry Andric // have to manually add the penalty for the prefix R"delim( over the column 21920b57cec5SDimitry Andric // limit. 21930b57cec5SDimitry Andric unsigned PrefixExcessCharacters = 21940b57cec5SDimitry Andric StartColumn + NewPrefixSize > Style.ColumnLimit 21950b57cec5SDimitry Andric ? StartColumn + NewPrefixSize - Style.ColumnLimit 21960b57cec5SDimitry Andric : 0; 21970b57cec5SDimitry Andric bool IsMultiline = 21980b57cec5SDimitry Andric ContentStartsOnNewline || (NewCode->find('\n') != std::string::npos); 21990b57cec5SDimitry Andric if (IsMultiline) { 22000b57cec5SDimitry Andric // Break before further function parameters on all levels. 22011fd87a68SDimitry Andric for (ParenState &Paren : State.Stack) 22021fd87a68SDimitry Andric Paren.BreakBeforeParameter = true; 22030b57cec5SDimitry Andric } 22040b57cec5SDimitry Andric return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter; 22050b57cec5SDimitry Andric } 22060b57cec5SDimitry Andric 22070b57cec5SDimitry Andric unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current, 22080b57cec5SDimitry Andric LineState &State) { 22090b57cec5SDimitry Andric // Break before further function parameters on all levels. 22101fd87a68SDimitry Andric for (ParenState &Paren : State.Stack) 22111fd87a68SDimitry Andric Paren.BreakBeforeParameter = true; 22120b57cec5SDimitry Andric 22130b57cec5SDimitry Andric unsigned ColumnsUsed = State.Column; 22140b57cec5SDimitry Andric // We can only affect layout of the first and the last line, so the penalty 22150b57cec5SDimitry Andric // for all other lines is constant, and we ignore it. 22160b57cec5SDimitry Andric State.Column = Current.LastLineColumnWidth; 22170b57cec5SDimitry Andric 22180b57cec5SDimitry Andric if (ColumnsUsed > getColumnLimit(State)) 22190b57cec5SDimitry Andric return Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit(State)); 22200b57cec5SDimitry Andric return 0; 22210b57cec5SDimitry Andric } 22220b57cec5SDimitry Andric 22230b57cec5SDimitry Andric unsigned ContinuationIndenter::handleEndOfLine(const FormatToken &Current, 22240b57cec5SDimitry Andric LineState &State, bool DryRun, 22250b57cec5SDimitry Andric bool AllowBreak, bool Newline) { 22260b57cec5SDimitry Andric unsigned Penalty = 0; 22270b57cec5SDimitry Andric // Compute the raw string style to use in case this is a raw string literal 22280b57cec5SDimitry Andric // that can be reformatted. 22290b57cec5SDimitry Andric auto RawStringStyle = getRawStringStyle(Current, State); 22300b57cec5SDimitry Andric if (RawStringStyle && !Current.Finalized) { 22310b57cec5SDimitry Andric Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun, 22320b57cec5SDimitry Andric Newline); 22330b57cec5SDimitry Andric } else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) { 22340b57cec5SDimitry Andric // Don't break multi-line tokens other than block comments and raw string 22350b57cec5SDimitry Andric // literals. Instead, just update the state. 22360b57cec5SDimitry Andric Penalty = addMultilineToken(Current, State); 22370b57cec5SDimitry Andric } else if (State.Line->Type != LT_ImportStatement) { 22380b57cec5SDimitry Andric // We generally don't break import statements. 22390b57cec5SDimitry Andric LineState OriginalState = State; 22400b57cec5SDimitry Andric 22410b57cec5SDimitry Andric // Whether we force the reflowing algorithm to stay strictly within the 22420b57cec5SDimitry Andric // column limit. 22430b57cec5SDimitry Andric bool Strict = false; 22440b57cec5SDimitry Andric // Whether the first non-strict attempt at reflowing did intentionally 22450b57cec5SDimitry Andric // exceed the column limit. 22460b57cec5SDimitry Andric bool Exceeded = false; 22470b57cec5SDimitry Andric std::tie(Penalty, Exceeded) = breakProtrudingToken( 22480b57cec5SDimitry Andric Current, State, AllowBreak, /*DryRun=*/true, Strict); 22490b57cec5SDimitry Andric if (Exceeded) { 22500b57cec5SDimitry Andric // If non-strict reflowing exceeds the column limit, try whether strict 22510b57cec5SDimitry Andric // reflowing leads to an overall lower penalty. 22520b57cec5SDimitry Andric LineState StrictState = OriginalState; 22530b57cec5SDimitry Andric unsigned StrictPenalty = 22540b57cec5SDimitry Andric breakProtrudingToken(Current, StrictState, AllowBreak, 22550b57cec5SDimitry Andric /*DryRun=*/true, /*Strict=*/true) 22560b57cec5SDimitry Andric .first; 22570b57cec5SDimitry Andric Strict = StrictPenalty <= Penalty; 22580b57cec5SDimitry Andric if (Strict) { 22590b57cec5SDimitry Andric Penalty = StrictPenalty; 22600b57cec5SDimitry Andric State = StrictState; 22610b57cec5SDimitry Andric } 22620b57cec5SDimitry Andric } 22630b57cec5SDimitry Andric if (!DryRun) { 22640b57cec5SDimitry Andric // If we're not in dry-run mode, apply the changes with the decision on 22650b57cec5SDimitry Andric // strictness made above. 22660b57cec5SDimitry Andric breakProtrudingToken(Current, OriginalState, AllowBreak, /*DryRun=*/false, 22670b57cec5SDimitry Andric Strict); 22680b57cec5SDimitry Andric } 22690b57cec5SDimitry Andric } 22700b57cec5SDimitry Andric if (State.Column > getColumnLimit(State)) { 22710b57cec5SDimitry Andric unsigned ExcessCharacters = State.Column - getColumnLimit(State); 22720b57cec5SDimitry Andric Penalty += Style.PenaltyExcessCharacter * ExcessCharacters; 22730b57cec5SDimitry Andric } 22740b57cec5SDimitry Andric return Penalty; 22750b57cec5SDimitry Andric } 22760b57cec5SDimitry Andric 22770b57cec5SDimitry Andric // Returns the enclosing function name of a token, or the empty string if not 22780b57cec5SDimitry Andric // found. 22790b57cec5SDimitry Andric static StringRef getEnclosingFunctionName(const FormatToken &Current) { 22800b57cec5SDimitry Andric // Look for: 'function(' or 'function<templates>(' before Current. 22810b57cec5SDimitry Andric auto Tok = Current.getPreviousNonComment(); 22825f757f3fSDimitry Andric if (!Tok || Tok->isNot(tok::l_paren)) 22830b57cec5SDimitry Andric return ""; 22840b57cec5SDimitry Andric Tok = Tok->getPreviousNonComment(); 22850b57cec5SDimitry Andric if (!Tok) 22860b57cec5SDimitry Andric return ""; 22870b57cec5SDimitry Andric if (Tok->is(TT_TemplateCloser)) { 22880b57cec5SDimitry Andric Tok = Tok->MatchingParen; 22890b57cec5SDimitry Andric if (Tok) 22900b57cec5SDimitry Andric Tok = Tok->getPreviousNonComment(); 22910b57cec5SDimitry Andric } 22925f757f3fSDimitry Andric if (!Tok || Tok->isNot(tok::identifier)) 22930b57cec5SDimitry Andric return ""; 22940b57cec5SDimitry Andric return Tok->TokenText; 22950b57cec5SDimitry Andric } 22960b57cec5SDimitry Andric 2297bdd1243dSDimitry Andric std::optional<FormatStyle> 22980b57cec5SDimitry Andric ContinuationIndenter::getRawStringStyle(const FormatToken &Current, 22990b57cec5SDimitry Andric const LineState &State) { 23000b57cec5SDimitry Andric if (!Current.isStringLiteral()) 2301bdd1243dSDimitry Andric return std::nullopt; 23020b57cec5SDimitry Andric auto Delimiter = getRawStringDelimiter(Current.TokenText); 23030b57cec5SDimitry Andric if (!Delimiter) 2304bdd1243dSDimitry Andric return std::nullopt; 23050b57cec5SDimitry Andric auto RawStringStyle = RawStringFormats.getDelimiterStyle(*Delimiter); 230681ad6265SDimitry Andric if (!RawStringStyle && Delimiter->empty()) { 23070b57cec5SDimitry Andric RawStringStyle = RawStringFormats.getEnclosingFunctionStyle( 23080b57cec5SDimitry Andric getEnclosingFunctionName(Current)); 230981ad6265SDimitry Andric } 23100b57cec5SDimitry Andric if (!RawStringStyle) 2311bdd1243dSDimitry Andric return std::nullopt; 23120b57cec5SDimitry Andric RawStringStyle->ColumnLimit = getColumnLimit(State); 23130b57cec5SDimitry Andric return RawStringStyle; 23140b57cec5SDimitry Andric } 23150b57cec5SDimitry Andric 23160b57cec5SDimitry Andric std::unique_ptr<BreakableToken> 23170b57cec5SDimitry Andric ContinuationIndenter::createBreakableToken(const FormatToken &Current, 23180b57cec5SDimitry Andric LineState &State, bool AllowBreak) { 23190b57cec5SDimitry Andric unsigned StartColumn = State.Column - Current.ColumnWidth; 23200b57cec5SDimitry Andric if (Current.isStringLiteral()) { 23215f757f3fSDimitry Andric // Strings in JSON cannot be broken. Breaking strings in JavaScript is 23225f757f3fSDimitry Andric // disabled for now. 23235f757f3fSDimitry Andric if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals || 232481ad6265SDimitry Andric !AllowBreak) { 23250b57cec5SDimitry Andric return nullptr; 232681ad6265SDimitry Andric } 23270b57cec5SDimitry Andric 23280b57cec5SDimitry Andric // Don't break string literals inside preprocessor directives (except for 23290b57cec5SDimitry Andric // #define directives, as their contents are stored in separate lines and 23300b57cec5SDimitry Andric // are not affected by this check). 23310b57cec5SDimitry Andric // This way we avoid breaking code with line directives and unknown 23320b57cec5SDimitry Andric // preprocessor directives that contain long string literals. 23330b57cec5SDimitry Andric if (State.Line->Type == LT_PreprocessorDirective) 23340b57cec5SDimitry Andric return nullptr; 23350b57cec5SDimitry Andric // Exempts unterminated string literals from line breaking. The user will 23360b57cec5SDimitry Andric // likely want to terminate the string before any line breaking is done. 23370b57cec5SDimitry Andric if (Current.IsUnterminatedLiteral) 23380b57cec5SDimitry Andric return nullptr; 23390b57cec5SDimitry Andric // Don't break string literals inside Objective-C array literals (doing so 23400b57cec5SDimitry Andric // raises the warning -Wobjc-string-concatenation). 234181ad6265SDimitry Andric if (State.Stack.back().IsInsideObjCArrayLiteral) 23420b57cec5SDimitry Andric return nullptr; 23430b57cec5SDimitry Andric 23445f757f3fSDimitry Andric // The "DPI"/"DPI-C" in SystemVerilog direct programming interface 23455f757f3fSDimitry Andric // imports/exports cannot be split, e.g. 23465f757f3fSDimitry Andric // `import "DPI" function foo();` 23475f757f3fSDimitry Andric // FIXME: make this use same infra as C++ import checks 23485f757f3fSDimitry Andric if (Style.isVerilog() && Current.Previous && 23495f757f3fSDimitry Andric Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) { 23505f757f3fSDimitry Andric return nullptr; 23515f757f3fSDimitry Andric } 23520b57cec5SDimitry Andric StringRef Text = Current.TokenText; 23535f757f3fSDimitry Andric 23545f757f3fSDimitry Andric // We need this to address the case where there is an unbreakable tail only 23555f757f3fSDimitry Andric // if certain other formatting decisions have been taken. The 23565f757f3fSDimitry Andric // UnbreakableTailLength of Current is an overapproximation in that case and 23575f757f3fSDimitry Andric // we need to be correct here. 23585f757f3fSDimitry Andric unsigned UnbreakableTailLength = (State.NextToken && canBreak(State)) 23595f757f3fSDimitry Andric ? 0 23605f757f3fSDimitry Andric : Current.UnbreakableTailLength; 23615f757f3fSDimitry Andric 23625f757f3fSDimitry Andric if (Style.isVerilog() || Style.Language == FormatStyle::LK_Java || 23635f757f3fSDimitry Andric Style.isJavaScript() || Style.isCSharp()) { 23645f757f3fSDimitry Andric BreakableStringLiteralUsingOperators::QuoteStyleType QuoteStyle; 23655f757f3fSDimitry Andric if (Style.isJavaScript() && Text.starts_with("'") && 23665f757f3fSDimitry Andric Text.ends_with("'")) { 23675f757f3fSDimitry Andric QuoteStyle = BreakableStringLiteralUsingOperators::SingleQuotes; 23685f757f3fSDimitry Andric } else if (Style.isCSharp() && Text.starts_with("@\"") && 23695f757f3fSDimitry Andric Text.ends_with("\"")) { 23705f757f3fSDimitry Andric QuoteStyle = BreakableStringLiteralUsingOperators::AtDoubleQuotes; 23715f757f3fSDimitry Andric } else if (Text.starts_with("\"") && Text.ends_with("\"")) { 23725f757f3fSDimitry Andric QuoteStyle = BreakableStringLiteralUsingOperators::DoubleQuotes; 23735f757f3fSDimitry Andric } else { 23745f757f3fSDimitry Andric return nullptr; 23755f757f3fSDimitry Andric } 23765f757f3fSDimitry Andric return std::make_unique<BreakableStringLiteralUsingOperators>( 23775f757f3fSDimitry Andric Current, QuoteStyle, 23785f757f3fSDimitry Andric /*UnindentPlus=*/shouldUnindentNextOperator(Current), StartColumn, 23795f757f3fSDimitry Andric UnbreakableTailLength, State.Line->InPPDirective, Encoding, Style); 23805f757f3fSDimitry Andric } 23815f757f3fSDimitry Andric 23820b57cec5SDimitry Andric StringRef Prefix; 23830b57cec5SDimitry Andric StringRef Postfix; 23840b57cec5SDimitry Andric // FIXME: Handle whitespace between '_T', '(', '"..."', and ')'. 23850b57cec5SDimitry Andric // FIXME: Store Prefix and Suffix (or PrefixLength and SuffixLength to 23860b57cec5SDimitry Andric // reduce the overhead) for each FormatToken, which is a string, so that we 23870b57cec5SDimitry Andric // don't run multiple checks here on the hot path. 23885f757f3fSDimitry Andric if ((Text.ends_with(Postfix = "\"") && 23895f757f3fSDimitry Andric (Text.starts_with(Prefix = "@\"") || Text.starts_with(Prefix = "\"") || 23905f757f3fSDimitry Andric Text.starts_with(Prefix = "u\"") || 23915f757f3fSDimitry Andric Text.starts_with(Prefix = "U\"") || 23925f757f3fSDimitry Andric Text.starts_with(Prefix = "u8\"") || 23935f757f3fSDimitry Andric Text.starts_with(Prefix = "L\""))) || 23945f757f3fSDimitry Andric (Text.starts_with(Prefix = "_T(\"") && 23955f757f3fSDimitry Andric Text.ends_with(Postfix = "\")"))) { 2396a7dea167SDimitry Andric return std::make_unique<BreakableStringLiteral>( 23970b57cec5SDimitry Andric Current, StartColumn, Prefix, Postfix, UnbreakableTailLength, 23980b57cec5SDimitry Andric State.Line->InPPDirective, Encoding, Style); 23990b57cec5SDimitry Andric } 24000b57cec5SDimitry Andric } else if (Current.is(TT_BlockComment)) { 24010b57cec5SDimitry Andric if (!Style.ReflowComments || 24020b57cec5SDimitry Andric // If a comment token switches formatting, like 24030b57cec5SDimitry Andric // /* clang-format on */, we don't want to break it further, 24040b57cec5SDimitry Andric // but we may still want to adjust its indentation. 24050b57cec5SDimitry Andric switchesFormatting(Current)) { 24060b57cec5SDimitry Andric return nullptr; 24070b57cec5SDimitry Andric } 2408a7dea167SDimitry Andric return std::make_unique<BreakableBlockComment>( 24090b57cec5SDimitry Andric Current, StartColumn, Current.OriginalColumn, !Current.Previous, 24100b57cec5SDimitry Andric State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF()); 24110b57cec5SDimitry Andric } else if (Current.is(TT_LineComment) && 241206c3fb27SDimitry Andric (!Current.Previous || 24130b57cec5SDimitry Andric Current.Previous->isNot(TT_ImplicitStringLiteral))) { 24144824e7fdSDimitry Andric bool RegularComments = [&]() { 24154824e7fdSDimitry Andric for (const FormatToken *T = &Current; T && T->is(TT_LineComment); 24164824e7fdSDimitry Andric T = T->Next) { 24175f757f3fSDimitry Andric if (!(T->TokenText.starts_with("//") || T->TokenText.starts_with("#"))) 24184824e7fdSDimitry Andric return false; 24194824e7fdSDimitry Andric } 24204824e7fdSDimitry Andric return true; 24214824e7fdSDimitry Andric }(); 24220b57cec5SDimitry Andric if (!Style.ReflowComments || 24230b57cec5SDimitry Andric CommentPragmasRegex.match(Current.TokenText.substr(2)) || 242481ad6265SDimitry Andric switchesFormatting(Current) || !RegularComments) { 24250b57cec5SDimitry Andric return nullptr; 242681ad6265SDimitry Andric } 2427a7dea167SDimitry Andric return std::make_unique<BreakableLineCommentSection>( 2428e8d8bef9SDimitry Andric Current, StartColumn, /*InPPDirective=*/false, Encoding, Style); 24290b57cec5SDimitry Andric } 24300b57cec5SDimitry Andric return nullptr; 24310b57cec5SDimitry Andric } 24320b57cec5SDimitry Andric 24330b57cec5SDimitry Andric std::pair<unsigned, bool> 24340b57cec5SDimitry Andric ContinuationIndenter::breakProtrudingToken(const FormatToken &Current, 24350b57cec5SDimitry Andric LineState &State, bool AllowBreak, 24360b57cec5SDimitry Andric bool DryRun, bool Strict) { 24370b57cec5SDimitry Andric std::unique_ptr<const BreakableToken> Token = 24380b57cec5SDimitry Andric createBreakableToken(Current, State, AllowBreak); 24390b57cec5SDimitry Andric if (!Token) 24400b57cec5SDimitry Andric return {0, false}; 24410b57cec5SDimitry Andric assert(Token->getLineCount() > 0); 24420b57cec5SDimitry Andric unsigned ColumnLimit = getColumnLimit(State); 24430b57cec5SDimitry Andric if (Current.is(TT_LineComment)) { 24440b57cec5SDimitry Andric // We don't insert backslashes when breaking line comments. 24450b57cec5SDimitry Andric ColumnLimit = Style.ColumnLimit; 24460b57cec5SDimitry Andric } 2447fe6060f1SDimitry Andric if (ColumnLimit == 0) { 2448fe6060f1SDimitry Andric // To make the rest of the function easier set the column limit to the 2449fe6060f1SDimitry Andric // maximum, if there should be no limit. 2450fe6060f1SDimitry Andric ColumnLimit = std::numeric_limits<decltype(ColumnLimit)>::max(); 2451fe6060f1SDimitry Andric } 24520b57cec5SDimitry Andric if (Current.UnbreakableTailLength >= ColumnLimit) 24530b57cec5SDimitry Andric return {0, false}; 24540b57cec5SDimitry Andric // ColumnWidth was already accounted into State.Column before calling 24550b57cec5SDimitry Andric // breakProtrudingToken. 24560b57cec5SDimitry Andric unsigned StartColumn = State.Column - Current.ColumnWidth; 24570b57cec5SDimitry Andric unsigned NewBreakPenalty = Current.isStringLiteral() 24580b57cec5SDimitry Andric ? Style.PenaltyBreakString 24590b57cec5SDimitry Andric : Style.PenaltyBreakComment; 24600b57cec5SDimitry Andric // Stores whether we intentionally decide to let a line exceed the column 24610b57cec5SDimitry Andric // limit. 24620b57cec5SDimitry Andric bool Exceeded = false; 24630b57cec5SDimitry Andric // Stores whether we introduce a break anywhere in the token. 24640b57cec5SDimitry Andric bool BreakInserted = Token->introducesBreakBeforeToken(); 24650b57cec5SDimitry Andric // Store whether we inserted a new line break at the end of the previous 24660b57cec5SDimitry Andric // logical line. 24670b57cec5SDimitry Andric bool NewBreakBefore = false; 24680b57cec5SDimitry Andric // We use a conservative reflowing strategy. Reflow starts after a line is 24690b57cec5SDimitry Andric // broken or the corresponding whitespace compressed. Reflow ends as soon as a 24700b57cec5SDimitry Andric // line that doesn't get reflown with the previous line is reached. 24710b57cec5SDimitry Andric bool Reflow = false; 24720b57cec5SDimitry Andric // Keep track of where we are in the token: 24730b57cec5SDimitry Andric // Where we are in the content of the current logical line. 24740b57cec5SDimitry Andric unsigned TailOffset = 0; 24750b57cec5SDimitry Andric // The column number we're currently at. 24760b57cec5SDimitry Andric unsigned ContentStartColumn = 24770b57cec5SDimitry Andric Token->getContentStartColumn(0, /*Break=*/false); 24780b57cec5SDimitry Andric // The number of columns left in the current logical line after TailOffset. 24790b57cec5SDimitry Andric unsigned RemainingTokenColumns = 24800b57cec5SDimitry Andric Token->getRemainingLength(0, TailOffset, ContentStartColumn); 24810b57cec5SDimitry Andric // Adapt the start of the token, for example indent. 24820b57cec5SDimitry Andric if (!DryRun) 24830b57cec5SDimitry Andric Token->adaptStartOfLine(0, Whitespaces); 24840b57cec5SDimitry Andric 24850b57cec5SDimitry Andric unsigned ContentIndent = 0; 24860b57cec5SDimitry Andric unsigned Penalty = 0; 24870b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << "Breaking protruding token at column " 24880b57cec5SDimitry Andric << StartColumn << ".\n"); 24890b57cec5SDimitry Andric for (unsigned LineIndex = 0, EndIndex = Token->getLineCount(); 24900b57cec5SDimitry Andric LineIndex != EndIndex; ++LineIndex) { 24910b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 24920b57cec5SDimitry Andric << " Line: " << LineIndex << " (Reflow: " << Reflow << ")\n"); 24930b57cec5SDimitry Andric NewBreakBefore = false; 24940b57cec5SDimitry Andric // If we did reflow the previous line, we'll try reflowing again. Otherwise 24950b57cec5SDimitry Andric // we'll start reflowing if the current line is broken or whitespace is 24960b57cec5SDimitry Andric // compressed. 24970b57cec5SDimitry Andric bool TryReflow = Reflow; 24980b57cec5SDimitry Andric // Break the current token until we can fit the rest of the line. 24990b57cec5SDimitry Andric while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) { 25000b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << " Over limit, need: " 25010b57cec5SDimitry Andric << (ContentStartColumn + RemainingTokenColumns) 25020b57cec5SDimitry Andric << ", space: " << ColumnLimit 25030b57cec5SDimitry Andric << ", reflown prefix: " << ContentStartColumn 25040b57cec5SDimitry Andric << ", offset in line: " << TailOffset << "\n"); 25050b57cec5SDimitry Andric // If the current token doesn't fit, find the latest possible split in the 25060b57cec5SDimitry Andric // current line so that breaking at it will be under the column limit. 25070b57cec5SDimitry Andric // FIXME: Use the earliest possible split while reflowing to correctly 25080b57cec5SDimitry Andric // compress whitespace within a line. 25090b57cec5SDimitry Andric BreakableToken::Split Split = 25100b57cec5SDimitry Andric Token->getSplit(LineIndex, TailOffset, ColumnLimit, 25110b57cec5SDimitry Andric ContentStartColumn, CommentPragmasRegex); 25120b57cec5SDimitry Andric if (Split.first == StringRef::npos) { 25130b57cec5SDimitry Andric // No break opportunity - update the penalty and continue with the next 25140b57cec5SDimitry Andric // logical line. 251581ad6265SDimitry Andric if (LineIndex < EndIndex - 1) { 25160b57cec5SDimitry Andric // The last line's penalty is handled in addNextStateToQueue() or when 25170b57cec5SDimitry Andric // calling replaceWhitespaceAfterLastLine below. 25180b57cec5SDimitry Andric Penalty += Style.PenaltyExcessCharacter * 25190b57cec5SDimitry Andric (ContentStartColumn + RemainingTokenColumns - ColumnLimit); 252081ad6265SDimitry Andric } 25210b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << " No break opportunity.\n"); 25220b57cec5SDimitry Andric break; 25230b57cec5SDimitry Andric } 25240b57cec5SDimitry Andric assert(Split.first != 0); 25250b57cec5SDimitry Andric 25260b57cec5SDimitry Andric if (Token->supportsReflow()) { 25270b57cec5SDimitry Andric // Check whether the next natural split point after the current one can 25280b57cec5SDimitry Andric // still fit the line, either because we can compress away whitespace, 25290b57cec5SDimitry Andric // or because the penalty the excess characters introduce is lower than 25300b57cec5SDimitry Andric // the break penalty. 25310b57cec5SDimitry Andric // We only do this for tokens that support reflowing, and thus allow us 25320b57cec5SDimitry Andric // to change the whitespace arbitrarily (e.g. comments). 25330b57cec5SDimitry Andric // Other tokens, like string literals, can be broken on arbitrary 25340b57cec5SDimitry Andric // positions. 25350b57cec5SDimitry Andric 25360b57cec5SDimitry Andric // First, compute the columns from TailOffset to the next possible split 25370b57cec5SDimitry Andric // position. 25380b57cec5SDimitry Andric // For example: 25390b57cec5SDimitry Andric // ColumnLimit: | 25400b57cec5SDimitry Andric // // Some text that breaks 25410b57cec5SDimitry Andric // ^ tail offset 25420b57cec5SDimitry Andric // ^-- split 25430b57cec5SDimitry Andric // ^-------- to split columns 25440b57cec5SDimitry Andric // ^--- next split 25450b57cec5SDimitry Andric // ^--------------- to next split columns 25460b57cec5SDimitry Andric unsigned ToSplitColumns = Token->getRangeLength( 25470b57cec5SDimitry Andric LineIndex, TailOffset, Split.first, ContentStartColumn); 25480b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << " ToSplit: " << ToSplitColumns << "\n"); 25490b57cec5SDimitry Andric 25500b57cec5SDimitry Andric BreakableToken::Split NextSplit = Token->getSplit( 25510b57cec5SDimitry Andric LineIndex, TailOffset + Split.first + Split.second, ColumnLimit, 25520b57cec5SDimitry Andric ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex); 25530b57cec5SDimitry Andric // Compute the columns necessary to fit the next non-breakable sequence 25540b57cec5SDimitry Andric // into the current line. 25550b57cec5SDimitry Andric unsigned ToNextSplitColumns = 0; 25560b57cec5SDimitry Andric if (NextSplit.first == StringRef::npos) { 25570b57cec5SDimitry Andric ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset, 25580b57cec5SDimitry Andric ContentStartColumn); 25590b57cec5SDimitry Andric } else { 25600b57cec5SDimitry Andric ToNextSplitColumns = Token->getRangeLength( 25610b57cec5SDimitry Andric LineIndex, TailOffset, 25620b57cec5SDimitry Andric Split.first + Split.second + NextSplit.first, ContentStartColumn); 25630b57cec5SDimitry Andric } 25640b57cec5SDimitry Andric // Compress the whitespace between the break and the start of the next 25650b57cec5SDimitry Andric // unbreakable sequence. 25660b57cec5SDimitry Andric ToNextSplitColumns = 25670b57cec5SDimitry Andric Token->getLengthAfterCompression(ToNextSplitColumns, Split); 25680b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 25690b57cec5SDimitry Andric << " ContentStartColumn: " << ContentStartColumn << "\n"); 25700b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 25710b57cec5SDimitry Andric << " ToNextSplit: " << ToNextSplitColumns << "\n"); 25720b57cec5SDimitry Andric // If the whitespace compression makes us fit, continue on the current 25730b57cec5SDimitry Andric // line. 25740b57cec5SDimitry Andric bool ContinueOnLine = 25750b57cec5SDimitry Andric ContentStartColumn + ToNextSplitColumns <= ColumnLimit; 25760b57cec5SDimitry Andric unsigned ExcessCharactersPenalty = 0; 25770b57cec5SDimitry Andric if (!ContinueOnLine && !Strict) { 25780b57cec5SDimitry Andric // Similarly, if the excess characters' penalty is lower than the 25790b57cec5SDimitry Andric // penalty of introducing a new break, continue on the current line. 25800b57cec5SDimitry Andric ExcessCharactersPenalty = 25810b57cec5SDimitry Andric (ContentStartColumn + ToNextSplitColumns - ColumnLimit) * 25820b57cec5SDimitry Andric Style.PenaltyExcessCharacter; 25830b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 25840b57cec5SDimitry Andric << " Penalty excess: " << ExcessCharactersPenalty 25850b57cec5SDimitry Andric << "\n break : " << NewBreakPenalty << "\n"); 25860b57cec5SDimitry Andric if (ExcessCharactersPenalty < NewBreakPenalty) { 25870b57cec5SDimitry Andric Exceeded = true; 25880b57cec5SDimitry Andric ContinueOnLine = true; 25890b57cec5SDimitry Andric } 25900b57cec5SDimitry Andric } 25910b57cec5SDimitry Andric if (ContinueOnLine) { 25920b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << " Continuing on line...\n"); 25930b57cec5SDimitry Andric // The current line fits after compressing the whitespace - reflow 25940b57cec5SDimitry Andric // the next line into it if possible. 25950b57cec5SDimitry Andric TryReflow = true; 259681ad6265SDimitry Andric if (!DryRun) { 25970b57cec5SDimitry Andric Token->compressWhitespace(LineIndex, TailOffset, Split, 25980b57cec5SDimitry Andric Whitespaces); 259981ad6265SDimitry Andric } 26000b57cec5SDimitry Andric // When we continue on the same line, leave one space between content. 26010b57cec5SDimitry Andric ContentStartColumn += ToSplitColumns + 1; 26020b57cec5SDimitry Andric Penalty += ExcessCharactersPenalty; 26030b57cec5SDimitry Andric TailOffset += Split.first + Split.second; 26040b57cec5SDimitry Andric RemainingTokenColumns = Token->getRemainingLength( 26050b57cec5SDimitry Andric LineIndex, TailOffset, ContentStartColumn); 26060b57cec5SDimitry Andric continue; 26070b57cec5SDimitry Andric } 26080b57cec5SDimitry Andric } 26090b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << " Breaking...\n"); 26100b57cec5SDimitry Andric // Update the ContentIndent only if the current line was not reflown with 26110b57cec5SDimitry Andric // the previous line, since in that case the previous line should still 26120b57cec5SDimitry Andric // determine the ContentIndent. Also never intent the last line. 26130b57cec5SDimitry Andric if (!Reflow) 26140b57cec5SDimitry Andric ContentIndent = Token->getContentIndent(LineIndex); 26150b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 26160b57cec5SDimitry Andric << " ContentIndent: " << ContentIndent << "\n"); 26170b57cec5SDimitry Andric ContentStartColumn = ContentIndent + Token->getContentStartColumn( 26180b57cec5SDimitry Andric LineIndex, /*Break=*/true); 26190b57cec5SDimitry Andric 26200b57cec5SDimitry Andric unsigned NewRemainingTokenColumns = Token->getRemainingLength( 26210b57cec5SDimitry Andric LineIndex, TailOffset + Split.first + Split.second, 26220b57cec5SDimitry Andric ContentStartColumn); 26230b57cec5SDimitry Andric if (NewRemainingTokenColumns == 0) { 26240b57cec5SDimitry Andric // No content to indent. 26250b57cec5SDimitry Andric ContentIndent = 0; 26260b57cec5SDimitry Andric ContentStartColumn = 26270b57cec5SDimitry Andric Token->getContentStartColumn(LineIndex, /*Break=*/true); 26280b57cec5SDimitry Andric NewRemainingTokenColumns = Token->getRemainingLength( 26290b57cec5SDimitry Andric LineIndex, TailOffset + Split.first + Split.second, 26300b57cec5SDimitry Andric ContentStartColumn); 26310b57cec5SDimitry Andric } 26320b57cec5SDimitry Andric 26330b57cec5SDimitry Andric // When breaking before a tab character, it may be moved by a few columns, 26340b57cec5SDimitry Andric // but will still be expanded to the next tab stop, so we don't save any 26350b57cec5SDimitry Andric // columns. 26364824e7fdSDimitry Andric if (NewRemainingTokenColumns >= RemainingTokenColumns) { 26370b57cec5SDimitry Andric // FIXME: Do we need to adjust the penalty? 26380b57cec5SDimitry Andric break; 26390b57cec5SDimitry Andric } 26400b57cec5SDimitry Andric 26410b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << " Breaking at: " << TailOffset + Split.first 26420b57cec5SDimitry Andric << ", " << Split.second << "\n"); 264381ad6265SDimitry Andric if (!DryRun) { 26440b57cec5SDimitry Andric Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent, 26450b57cec5SDimitry Andric Whitespaces); 264681ad6265SDimitry Andric } 26470b57cec5SDimitry Andric 26480b57cec5SDimitry Andric Penalty += NewBreakPenalty; 26490b57cec5SDimitry Andric TailOffset += Split.first + Split.second; 26500b57cec5SDimitry Andric RemainingTokenColumns = NewRemainingTokenColumns; 26510b57cec5SDimitry Andric BreakInserted = true; 26520b57cec5SDimitry Andric NewBreakBefore = true; 26530b57cec5SDimitry Andric } 26540b57cec5SDimitry Andric // In case there's another line, prepare the state for the start of the next 26550b57cec5SDimitry Andric // line. 26560b57cec5SDimitry Andric if (LineIndex + 1 != EndIndex) { 26570b57cec5SDimitry Andric unsigned NextLineIndex = LineIndex + 1; 265881ad6265SDimitry Andric if (NewBreakBefore) { 26590b57cec5SDimitry Andric // After breaking a line, try to reflow the next line into the current 26600b57cec5SDimitry Andric // one once RemainingTokenColumns fits. 26610b57cec5SDimitry Andric TryReflow = true; 266281ad6265SDimitry Andric } 26630b57cec5SDimitry Andric if (TryReflow) { 26640b57cec5SDimitry Andric // We decided that we want to try reflowing the next line into the 26650b57cec5SDimitry Andric // current one. 26660b57cec5SDimitry Andric // We will now adjust the state as if the reflow is successful (in 26670b57cec5SDimitry Andric // preparation for the next line), and see whether that works. If we 26680b57cec5SDimitry Andric // decide that we cannot reflow, we will later reset the state to the 26690b57cec5SDimitry Andric // start of the next line. 26700b57cec5SDimitry Andric Reflow = false; 26710b57cec5SDimitry Andric // As we did not continue breaking the line, RemainingTokenColumns is 26720b57cec5SDimitry Andric // known to fit after ContentStartColumn. Adapt ContentStartColumn to 26730b57cec5SDimitry Andric // the position at which we want to format the next line if we do 26740b57cec5SDimitry Andric // actually reflow. 26750b57cec5SDimitry Andric // When we reflow, we need to add a space between the end of the current 26760b57cec5SDimitry Andric // line and the next line's start column. 26770b57cec5SDimitry Andric ContentStartColumn += RemainingTokenColumns + 1; 26780b57cec5SDimitry Andric // Get the split that we need to reflow next logical line into the end 26790b57cec5SDimitry Andric // of the current one; the split will include any leading whitespace of 26800b57cec5SDimitry Andric // the next logical line. 26810b57cec5SDimitry Andric BreakableToken::Split SplitBeforeNext = 26820b57cec5SDimitry Andric Token->getReflowSplit(NextLineIndex, CommentPragmasRegex); 26830b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 26840b57cec5SDimitry Andric << " Size of reflown text: " << ContentStartColumn 26850b57cec5SDimitry Andric << "\n Potential reflow split: "); 26860b57cec5SDimitry Andric if (SplitBeforeNext.first != StringRef::npos) { 26870b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first << ", " 26880b57cec5SDimitry Andric << SplitBeforeNext.second << "\n"); 26890b57cec5SDimitry Andric TailOffset = SplitBeforeNext.first + SplitBeforeNext.second; 26900b57cec5SDimitry Andric // If the rest of the next line fits into the current line below the 26910b57cec5SDimitry Andric // column limit, we can safely reflow. 26920b57cec5SDimitry Andric RemainingTokenColumns = Token->getRemainingLength( 26930b57cec5SDimitry Andric NextLineIndex, TailOffset, ContentStartColumn); 26940b57cec5SDimitry Andric Reflow = true; 26950b57cec5SDimitry Andric if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) { 26960b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 26970b57cec5SDimitry Andric << " Over limit after reflow, need: " 26980b57cec5SDimitry Andric << (ContentStartColumn + RemainingTokenColumns) 26990b57cec5SDimitry Andric << ", space: " << ColumnLimit 27000b57cec5SDimitry Andric << ", reflown prefix: " << ContentStartColumn 27010b57cec5SDimitry Andric << ", offset in line: " << TailOffset << "\n"); 27020b57cec5SDimitry Andric // If the whole next line does not fit, try to find a point in 27030b57cec5SDimitry Andric // the next line at which we can break so that attaching the part 27040b57cec5SDimitry Andric // of the next line to that break point onto the current line is 27050b57cec5SDimitry Andric // below the column limit. 27060b57cec5SDimitry Andric BreakableToken::Split Split = 27070b57cec5SDimitry Andric Token->getSplit(NextLineIndex, TailOffset, ColumnLimit, 27080b57cec5SDimitry Andric ContentStartColumn, CommentPragmasRegex); 27090b57cec5SDimitry Andric if (Split.first == StringRef::npos) { 27100b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << " Did not find later break\n"); 27110b57cec5SDimitry Andric Reflow = false; 27120b57cec5SDimitry Andric } else { 27130b57cec5SDimitry Andric // Check whether the first split point gets us below the column 27140b57cec5SDimitry Andric // limit. Note that we will execute this split below as part of 27150b57cec5SDimitry Andric // the normal token breaking and reflow logic within the line. 27160b57cec5SDimitry Andric unsigned ToSplitColumns = Token->getRangeLength( 27170b57cec5SDimitry Andric NextLineIndex, TailOffset, Split.first, ContentStartColumn); 27180b57cec5SDimitry Andric if (ContentStartColumn + ToSplitColumns > ColumnLimit) { 27190b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << " Next split protrudes, need: " 27200b57cec5SDimitry Andric << (ContentStartColumn + ToSplitColumns) 27210b57cec5SDimitry Andric << ", space: " << ColumnLimit); 27220b57cec5SDimitry Andric unsigned ExcessCharactersPenalty = 27230b57cec5SDimitry Andric (ContentStartColumn + ToSplitColumns - ColumnLimit) * 27240b57cec5SDimitry Andric Style.PenaltyExcessCharacter; 272581ad6265SDimitry Andric if (NewBreakPenalty < ExcessCharactersPenalty) 27260b57cec5SDimitry Andric Reflow = false; 27270b57cec5SDimitry Andric } 27280b57cec5SDimitry Andric } 27290b57cec5SDimitry Andric } 27300b57cec5SDimitry Andric } else { 27310b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << "not found.\n"); 27320b57cec5SDimitry Andric } 27330b57cec5SDimitry Andric } 27340b57cec5SDimitry Andric if (!Reflow) { 27350b57cec5SDimitry Andric // If we didn't reflow into the next line, the only space to consider is 27360b57cec5SDimitry Andric // the next logical line. Reset our state to match the start of the next 27370b57cec5SDimitry Andric // line. 27380b57cec5SDimitry Andric TailOffset = 0; 27390b57cec5SDimitry Andric ContentStartColumn = 27400b57cec5SDimitry Andric Token->getContentStartColumn(NextLineIndex, /*Break=*/false); 27410b57cec5SDimitry Andric RemainingTokenColumns = Token->getRemainingLength( 27420b57cec5SDimitry Andric NextLineIndex, TailOffset, ContentStartColumn); 27430b57cec5SDimitry Andric // Adapt the start of the token, for example indent. 27440b57cec5SDimitry Andric if (!DryRun) 27450b57cec5SDimitry Andric Token->adaptStartOfLine(NextLineIndex, Whitespaces); 27460b57cec5SDimitry Andric } else { 27470b57cec5SDimitry Andric // If we found a reflow split and have added a new break before the next 27480b57cec5SDimitry Andric // line, we are going to remove the line break at the start of the next 27490b57cec5SDimitry Andric // logical line. For example, here we'll add a new line break after 27500b57cec5SDimitry Andric // 'text', and subsequently delete the line break between 'that' and 27510b57cec5SDimitry Andric // 'reflows'. 27520b57cec5SDimitry Andric // // some text that 27530b57cec5SDimitry Andric // // reflows 27540b57cec5SDimitry Andric // -> 27550b57cec5SDimitry Andric // // some text 27560b57cec5SDimitry Andric // // that reflows 27570b57cec5SDimitry Andric // When adding the line break, we also added the penalty for it, so we 27580b57cec5SDimitry Andric // need to subtract that penalty again when we remove the line break due 27590b57cec5SDimitry Andric // to reflowing. 27600b57cec5SDimitry Andric if (NewBreakBefore) { 27610b57cec5SDimitry Andric assert(Penalty >= NewBreakPenalty); 27620b57cec5SDimitry Andric Penalty -= NewBreakPenalty; 27630b57cec5SDimitry Andric } 27640b57cec5SDimitry Andric if (!DryRun) 27650b57cec5SDimitry Andric Token->reflow(NextLineIndex, Whitespaces); 27660b57cec5SDimitry Andric } 27670b57cec5SDimitry Andric } 27680b57cec5SDimitry Andric } 27690b57cec5SDimitry Andric 27700b57cec5SDimitry Andric BreakableToken::Split SplitAfterLastLine = 27710b57cec5SDimitry Andric Token->getSplitAfterLastLine(TailOffset); 27720b57cec5SDimitry Andric if (SplitAfterLastLine.first != StringRef::npos) { 27730b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << "Replacing whitespace after last line.\n"); 27740b57cec5SDimitry Andric 27750b57cec5SDimitry Andric // We add the last line's penalty here, since that line is going to be split 27760b57cec5SDimitry Andric // now. 27770b57cec5SDimitry Andric Penalty += Style.PenaltyExcessCharacter * 27780b57cec5SDimitry Andric (ContentStartColumn + RemainingTokenColumns - ColumnLimit); 27790b57cec5SDimitry Andric 278081ad6265SDimitry Andric if (!DryRun) { 27810b57cec5SDimitry Andric Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine, 27820b57cec5SDimitry Andric Whitespaces); 278381ad6265SDimitry Andric } 27840b57cec5SDimitry Andric ContentStartColumn = 27850b57cec5SDimitry Andric Token->getContentStartColumn(Token->getLineCount() - 1, /*Break=*/true); 27860b57cec5SDimitry Andric RemainingTokenColumns = Token->getRemainingLength( 27870b57cec5SDimitry Andric Token->getLineCount() - 1, 27880b57cec5SDimitry Andric TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second, 27890b57cec5SDimitry Andric ContentStartColumn); 27900b57cec5SDimitry Andric } 27910b57cec5SDimitry Andric 27920b57cec5SDimitry Andric State.Column = ContentStartColumn + RemainingTokenColumns - 27930b57cec5SDimitry Andric Current.UnbreakableTailLength; 27940b57cec5SDimitry Andric 27950b57cec5SDimitry Andric if (BreakInserted) { 27965f757f3fSDimitry Andric if (!DryRun) 27975f757f3fSDimitry Andric Token->updateAfterBroken(Whitespaces); 27985f757f3fSDimitry Andric 27990b57cec5SDimitry Andric // If we break the token inside a parameter list, we need to break before 28000b57cec5SDimitry Andric // the next parameter on all levels, so that the next parameter is clearly 28010b57cec5SDimitry Andric // visible. Line comments already introduce a break. 280281ad6265SDimitry Andric if (Current.isNot(TT_LineComment)) 28031fd87a68SDimitry Andric for (ParenState &Paren : State.Stack) 28041fd87a68SDimitry Andric Paren.BreakBeforeParameter = true; 28050b57cec5SDimitry Andric 28060b57cec5SDimitry Andric if (Current.is(TT_BlockComment)) 28070b57cec5SDimitry Andric State.NoContinuation = true; 28080b57cec5SDimitry Andric 28090b57cec5SDimitry Andric State.Stack.back().LastSpace = StartColumn; 28100b57cec5SDimitry Andric } 28110b57cec5SDimitry Andric 28120b57cec5SDimitry Andric Token->updateNextToken(State); 28130b57cec5SDimitry Andric 28140b57cec5SDimitry Andric return {Penalty, Exceeded}; 28150b57cec5SDimitry Andric } 28160b57cec5SDimitry Andric 28170b57cec5SDimitry Andric unsigned ContinuationIndenter::getColumnLimit(const LineState &State) const { 2818bdd1243dSDimitry Andric // In preprocessor directives reserve two chars for trailing " \". 28190b57cec5SDimitry Andric return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0); 28200b57cec5SDimitry Andric } 28210b57cec5SDimitry Andric 28220b57cec5SDimitry Andric bool ContinuationIndenter::nextIsMultilineString(const LineState &State) { 28230b57cec5SDimitry Andric const FormatToken &Current = *State.NextToken; 28240b57cec5SDimitry Andric if (!Current.isStringLiteral() || Current.is(TT_ImplicitStringLiteral)) 28250b57cec5SDimitry Andric return false; 28260b57cec5SDimitry Andric // We never consider raw string literals "multiline" for the purpose of 28270b57cec5SDimitry Andric // AlwaysBreakBeforeMultilineStrings implementation as they are special-cased 28280b57cec5SDimitry Andric // (see TokenAnnotator::mustBreakBefore(). 28295f757f3fSDimitry Andric if (Current.TokenText.starts_with("R\"")) 28300b57cec5SDimitry Andric return false; 28310b57cec5SDimitry Andric if (Current.IsMultiline) 28320b57cec5SDimitry Andric return true; 28330b57cec5SDimitry Andric if (Current.getNextNonComment() && 283481ad6265SDimitry Andric Current.getNextNonComment()->isStringLiteral()) { 28350b57cec5SDimitry Andric return true; // Implicit concatenation. 283681ad6265SDimitry Andric } 28370b57cec5SDimitry Andric if (Style.ColumnLimit != 0 && Style.BreakStringLiterals && 28380b57cec5SDimitry Andric State.Column + Current.ColumnWidth + Current.UnbreakableTailLength > 283981ad6265SDimitry Andric Style.ColumnLimit) { 28400b57cec5SDimitry Andric return true; // String will be split. 284181ad6265SDimitry Andric } 28420b57cec5SDimitry Andric return false; 28430b57cec5SDimitry Andric } 28440b57cec5SDimitry Andric 28450b57cec5SDimitry Andric } // namespace format 28460b57cec5SDimitry Andric } // namespace clang 2847