1*de0328aeSDaniel Jasper //===--- ContinuationIndenter.cpp - Format C++ code -----------------------===// 2*de0328aeSDaniel Jasper // 3*de0328aeSDaniel Jasper // The LLVM Compiler Infrastructure 4*de0328aeSDaniel Jasper // 5*de0328aeSDaniel Jasper // This file is distributed under the University of Illinois Open Source 6*de0328aeSDaniel Jasper // License. See LICENSE.TXT for details. 7*de0328aeSDaniel Jasper // 8*de0328aeSDaniel Jasper //===----------------------------------------------------------------------===// 9*de0328aeSDaniel Jasper /// 10*de0328aeSDaniel Jasper /// \file 11*de0328aeSDaniel Jasper /// \brief This file implements the continuation indenter. 12*de0328aeSDaniel Jasper /// 13*de0328aeSDaniel Jasper //===----------------------------------------------------------------------===// 14*de0328aeSDaniel Jasper 15*de0328aeSDaniel Jasper #define DEBUG_TYPE "format-formatter" 16*de0328aeSDaniel Jasper 17*de0328aeSDaniel Jasper #include "BreakableToken.h" 18*de0328aeSDaniel Jasper #include "ContinuationIndenter.h" 19*de0328aeSDaniel Jasper #include "WhitespaceManager.h" 20*de0328aeSDaniel Jasper #include "clang/Basic/OperatorPrecedence.h" 21*de0328aeSDaniel Jasper #include "clang/Basic/SourceManager.h" 22*de0328aeSDaniel Jasper #include "clang/Format/Format.h" 23*de0328aeSDaniel Jasper #include "llvm/Support/Debug.h" 24*de0328aeSDaniel Jasper #include <string> 25*de0328aeSDaniel Jasper 26*de0328aeSDaniel Jasper namespace clang { 27*de0328aeSDaniel Jasper namespace format { 28*de0328aeSDaniel Jasper 29*de0328aeSDaniel Jasper // Returns the length of everything up to the first possible line break after 30*de0328aeSDaniel Jasper // the ), ], } or > matching \c Tok. 31*de0328aeSDaniel Jasper static unsigned getLengthToMatchingParen(const FormatToken &Tok) { 32*de0328aeSDaniel Jasper if (Tok.MatchingParen == NULL) 33*de0328aeSDaniel Jasper return 0; 34*de0328aeSDaniel Jasper FormatToken *End = Tok.MatchingParen; 35*de0328aeSDaniel Jasper while (End->Next && !End->Next->CanBreakBefore) { 36*de0328aeSDaniel Jasper End = End->Next; 37*de0328aeSDaniel Jasper } 38*de0328aeSDaniel Jasper return End->TotalLength - Tok.TotalLength + 1; 39*de0328aeSDaniel Jasper } 40*de0328aeSDaniel Jasper 41*de0328aeSDaniel Jasper ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style, 42*de0328aeSDaniel Jasper SourceManager &SourceMgr, 43*de0328aeSDaniel Jasper const AnnotatedLine &Line, 44*de0328aeSDaniel Jasper unsigned FirstIndent, 45*de0328aeSDaniel Jasper WhitespaceManager &Whitespaces, 46*de0328aeSDaniel Jasper encoding::Encoding Encoding, 47*de0328aeSDaniel Jasper bool BinPackInconclusiveFunctions) 48*de0328aeSDaniel Jasper : Style(Style), SourceMgr(SourceMgr), Line(Line), FirstIndent(FirstIndent), 49*de0328aeSDaniel Jasper Whitespaces(Whitespaces), Encoding(Encoding), 50*de0328aeSDaniel Jasper BinPackInconclusiveFunctions(BinPackInconclusiveFunctions) {} 51*de0328aeSDaniel Jasper 52*de0328aeSDaniel Jasper LineState ContinuationIndenter::getInitialState() { 53*de0328aeSDaniel Jasper // Initialize state dependent on indent. 54*de0328aeSDaniel Jasper LineState State; 55*de0328aeSDaniel Jasper State.Column = FirstIndent; 56*de0328aeSDaniel Jasper State.NextToken = Line.First; 57*de0328aeSDaniel Jasper State.Stack.push_back(ParenState(FirstIndent, FirstIndent, 58*de0328aeSDaniel Jasper /*AvoidBinPacking=*/false, 59*de0328aeSDaniel Jasper /*NoLineBreak=*/false)); 60*de0328aeSDaniel Jasper State.LineContainsContinuedForLoopSection = false; 61*de0328aeSDaniel Jasper State.ParenLevel = 0; 62*de0328aeSDaniel Jasper State.StartOfStringLiteral = 0; 63*de0328aeSDaniel Jasper State.StartOfLineLevel = State.ParenLevel; 64*de0328aeSDaniel Jasper State.LowestLevelOnLine = State.ParenLevel; 65*de0328aeSDaniel Jasper State.IgnoreStackForComparison = false; 66*de0328aeSDaniel Jasper 67*de0328aeSDaniel Jasper // The first token has already been indented and thus consumed. 68*de0328aeSDaniel Jasper moveStateToNextToken(State, /*DryRun=*/false, 69*de0328aeSDaniel Jasper /*Newline=*/false); 70*de0328aeSDaniel Jasper return State; 71*de0328aeSDaniel Jasper } 72*de0328aeSDaniel Jasper 73*de0328aeSDaniel Jasper bool ContinuationIndenter::canBreak(const LineState &State) { 74*de0328aeSDaniel Jasper const FormatToken &Current = *State.NextToken; 75*de0328aeSDaniel Jasper const FormatToken &Previous = *Current.Previous; 76*de0328aeSDaniel Jasper assert(&Previous == Current.Previous); 77*de0328aeSDaniel Jasper if (!Current.CanBreakBefore && 78*de0328aeSDaniel Jasper !(Current.is(tok::r_brace) && State.Stack.back().BreakBeforeClosingBrace)) 79*de0328aeSDaniel Jasper return false; 80*de0328aeSDaniel Jasper // The opening "{" of a braced list has to be on the same line as the first 81*de0328aeSDaniel Jasper // element if it is nested in another braced init list or function call. 82*de0328aeSDaniel Jasper if (!Current.MustBreakBefore && Previous.is(tok::l_brace) && 83*de0328aeSDaniel Jasper Previous.Previous && 84*de0328aeSDaniel Jasper Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) 85*de0328aeSDaniel Jasper return false; 86*de0328aeSDaniel Jasper // This prevents breaks like: 87*de0328aeSDaniel Jasper // ... 88*de0328aeSDaniel Jasper // SomeParameter, OtherParameter).DoSomething( 89*de0328aeSDaniel Jasper // ... 90*de0328aeSDaniel Jasper // As they hide "DoSomething" and are generally bad for readability. 91*de0328aeSDaniel Jasper if (Previous.opensScope() && State.LowestLevelOnLine < State.StartOfLineLevel) 92*de0328aeSDaniel Jasper return false; 93*de0328aeSDaniel Jasper return !State.Stack.back().NoLineBreak; 94*de0328aeSDaniel Jasper } 95*de0328aeSDaniel Jasper 96*de0328aeSDaniel Jasper bool ContinuationIndenter::mustBreak(const LineState &State) { 97*de0328aeSDaniel Jasper const FormatToken &Current = *State.NextToken; 98*de0328aeSDaniel Jasper const FormatToken &Previous = *Current.Previous; 99*de0328aeSDaniel Jasper if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon) 100*de0328aeSDaniel Jasper return true; 101*de0328aeSDaniel Jasper if (!Style.Cpp11BracedListStyle && Current.is(tok::r_brace) && 102*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeClosingBrace) 103*de0328aeSDaniel Jasper return true; 104*de0328aeSDaniel Jasper if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection) 105*de0328aeSDaniel Jasper return true; 106*de0328aeSDaniel Jasper if (Style.BreakConstructorInitializersBeforeComma) { 107*de0328aeSDaniel Jasper if (Previous.Type == TT_CtorInitializerComma) 108*de0328aeSDaniel Jasper return false; 109*de0328aeSDaniel Jasper if (Current.Type == TT_CtorInitializerComma) 110*de0328aeSDaniel Jasper return true; 111*de0328aeSDaniel Jasper } 112*de0328aeSDaniel Jasper if ((Previous.isOneOf(tok::comma, tok::semi) || Current.is(tok::question) || 113*de0328aeSDaniel Jasper (Current.Type == TT_ConditionalExpr && 114*de0328aeSDaniel Jasper !(Current.is(tok::colon) && Previous.is(tok::question)))) && 115*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter && !Current.isTrailingComment() && 116*de0328aeSDaniel Jasper !Current.isOneOf(tok::r_paren, tok::r_brace)) 117*de0328aeSDaniel Jasper return true; 118*de0328aeSDaniel Jasper if (Style.AlwaysBreakBeforeMultilineStrings && 119*de0328aeSDaniel Jasper State.Column > State.Stack.back().Indent && 120*de0328aeSDaniel Jasper Current.is(tok::string_literal) && Previous.isNot(tok::lessless) && 121*de0328aeSDaniel Jasper Previous.Type != TT_InlineASMColon && 122*de0328aeSDaniel Jasper ((Current.getNextNonComment() && 123*de0328aeSDaniel Jasper Current.getNextNonComment()->is(tok::string_literal)) || 124*de0328aeSDaniel Jasper (Current.TokenText.find("\\\n") != StringRef::npos))) 125*de0328aeSDaniel Jasper return true; 126*de0328aeSDaniel Jasper 127*de0328aeSDaniel Jasper if (!Style.BreakBeforeBinaryOperators) { 128*de0328aeSDaniel Jasper // If we need to break somewhere inside the LHS of a binary expression, we 129*de0328aeSDaniel Jasper // should also break after the operator. Otherwise, the formatting would 130*de0328aeSDaniel Jasper // hide the operator precedence, e.g. in: 131*de0328aeSDaniel Jasper // if (aaaaaaaaaaaaaa == 132*de0328aeSDaniel Jasper // bbbbbbbbbbbbbb && c) {.. 133*de0328aeSDaniel Jasper // For comparisons, we only apply this rule, if the LHS is a binary 134*de0328aeSDaniel Jasper // expression itself as otherwise, the line breaks seem superfluous. 135*de0328aeSDaniel Jasper // We need special cases for ">>" which we have split into two ">" while 136*de0328aeSDaniel Jasper // lexing in order to make template parsing easier. 137*de0328aeSDaniel Jasper // 138*de0328aeSDaniel Jasper // FIXME: We'll need something similar for styles that break before binary 139*de0328aeSDaniel Jasper // operators. 140*de0328aeSDaniel Jasper bool IsComparison = (Previous.getPrecedence() == prec::Relational || 141*de0328aeSDaniel Jasper Previous.getPrecedence() == prec::Equality) && 142*de0328aeSDaniel Jasper Previous.Previous && 143*de0328aeSDaniel Jasper Previous.Previous->Type != TT_BinaryOperator; // For >>. 144*de0328aeSDaniel Jasper bool LHSIsBinaryExpr = 145*de0328aeSDaniel Jasper Previous.Previous && Previous.Previous->FakeRParens > 0; 146*de0328aeSDaniel Jasper if (Previous.Type == TT_BinaryOperator && 147*de0328aeSDaniel Jasper (!IsComparison || LHSIsBinaryExpr) && 148*de0328aeSDaniel Jasper Current.Type != TT_BinaryOperator && // For >>. 149*de0328aeSDaniel Jasper !Current.isTrailingComment() && 150*de0328aeSDaniel Jasper !Previous.isOneOf(tok::lessless, tok::question) && 151*de0328aeSDaniel Jasper Previous.getPrecedence() != prec::Assignment && 152*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter) 153*de0328aeSDaniel Jasper return true; 154*de0328aeSDaniel Jasper } 155*de0328aeSDaniel Jasper 156*de0328aeSDaniel Jasper // Same as above, but for the first "<<" operator. 157*de0328aeSDaniel Jasper if (Current.is(tok::lessless) && State.Stack.back().BreakBeforeParameter && 158*de0328aeSDaniel Jasper State.Stack.back().FirstLessLess == 0) 159*de0328aeSDaniel Jasper return true; 160*de0328aeSDaniel Jasper 161*de0328aeSDaniel Jasper // FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding 162*de0328aeSDaniel Jasper // out whether it is the first parameter. Clean this up. 163*de0328aeSDaniel Jasper if (Current.Type == TT_ObjCSelectorName && 164*de0328aeSDaniel Jasper Current.LongestObjCSelectorName == 0 && 165*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter) 166*de0328aeSDaniel Jasper return true; 167*de0328aeSDaniel Jasper if ((Current.Type == TT_CtorInitializerColon || 168*de0328aeSDaniel Jasper (Previous.ClosesTemplateDeclaration && State.ParenLevel == 0))) 169*de0328aeSDaniel Jasper return true; 170*de0328aeSDaniel Jasper 171*de0328aeSDaniel Jasper if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) && 172*de0328aeSDaniel Jasper Line.MightBeFunctionDecl && State.Stack.back().BreakBeforeParameter && 173*de0328aeSDaniel Jasper State.ParenLevel == 0) 174*de0328aeSDaniel Jasper return true; 175*de0328aeSDaniel Jasper return false; 176*de0328aeSDaniel Jasper } 177*de0328aeSDaniel Jasper 178*de0328aeSDaniel Jasper unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline, 179*de0328aeSDaniel Jasper bool DryRun) { 180*de0328aeSDaniel Jasper const FormatToken &Current = *State.NextToken; 181*de0328aeSDaniel Jasper const FormatToken &Previous = *State.NextToken->Previous; 182*de0328aeSDaniel Jasper 183*de0328aeSDaniel Jasper // Extra penalty that needs to be added because of the way certain line 184*de0328aeSDaniel Jasper // breaks are chosen. 185*de0328aeSDaniel Jasper unsigned ExtraPenalty = 0; 186*de0328aeSDaniel Jasper 187*de0328aeSDaniel Jasper if (State.Stack.size() == 0 || Current.Type == TT_ImplicitStringLiteral) { 188*de0328aeSDaniel Jasper // FIXME: Is this correct? 189*de0328aeSDaniel Jasper int WhitespaceLength = SourceMgr.getSpellingColumnNumber( 190*de0328aeSDaniel Jasper State.NextToken->WhitespaceRange.getEnd()) - 191*de0328aeSDaniel Jasper SourceMgr.getSpellingColumnNumber( 192*de0328aeSDaniel Jasper State.NextToken->WhitespaceRange.getBegin()); 193*de0328aeSDaniel Jasper State.Column += WhitespaceLength + State.NextToken->CodePointCount; 194*de0328aeSDaniel Jasper State.NextToken = State.NextToken->Next; 195*de0328aeSDaniel Jasper return 0; 196*de0328aeSDaniel Jasper } 197*de0328aeSDaniel Jasper 198*de0328aeSDaniel Jasper // If we are continuing an expression, we want to indent an extra 4 spaces. 199*de0328aeSDaniel Jasper unsigned ContinuationIndent = 200*de0328aeSDaniel Jasper std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 4; 201*de0328aeSDaniel Jasper if (Newline) { 202*de0328aeSDaniel Jasper // Breaking before the first "<<" is generally not desirable if the LHS is 203*de0328aeSDaniel Jasper // short. 204*de0328aeSDaniel Jasper if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0 && 205*de0328aeSDaniel Jasper State.Column <= Style.ColumnLimit / 2) 206*de0328aeSDaniel Jasper ExtraPenalty += Style.PenaltyBreakFirstLessLess; 207*de0328aeSDaniel Jasper 208*de0328aeSDaniel Jasper State.Stack.back().ContainsLineBreak = true; 209*de0328aeSDaniel Jasper if (Current.is(tok::r_brace)) { 210*de0328aeSDaniel Jasper if (Current.BlockKind == BK_BracedInit) 211*de0328aeSDaniel Jasper State.Column = State.Stack[State.Stack.size() - 2].LastSpace; 212*de0328aeSDaniel Jasper else 213*de0328aeSDaniel Jasper State.Column = FirstIndent; 214*de0328aeSDaniel Jasper } else if (Current.is(tok::string_literal) && 215*de0328aeSDaniel Jasper State.StartOfStringLiteral != 0) { 216*de0328aeSDaniel Jasper State.Column = State.StartOfStringLiteral; 217*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter = true; 218*de0328aeSDaniel Jasper } else if (Current.is(tok::lessless) && 219*de0328aeSDaniel Jasper State.Stack.back().FirstLessLess != 0) { 220*de0328aeSDaniel Jasper State.Column = State.Stack.back().FirstLessLess; 221*de0328aeSDaniel Jasper } else if (Current.isOneOf(tok::period, tok::arrow) && 222*de0328aeSDaniel Jasper Current.Type != TT_DesignatedInitializerPeriod) { 223*de0328aeSDaniel Jasper if (State.Stack.back().CallContinuation == 0) { 224*de0328aeSDaniel Jasper State.Column = ContinuationIndent; 225*de0328aeSDaniel Jasper State.Stack.back().CallContinuation = State.Column; 226*de0328aeSDaniel Jasper } else { 227*de0328aeSDaniel Jasper State.Column = State.Stack.back().CallContinuation; 228*de0328aeSDaniel Jasper } 229*de0328aeSDaniel Jasper } else if (Current.Type == TT_ConditionalExpr) { 230*de0328aeSDaniel Jasper State.Column = State.Stack.back().QuestionColumn; 231*de0328aeSDaniel Jasper } else if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) { 232*de0328aeSDaniel Jasper State.Column = State.Stack.back().VariablePos; 233*de0328aeSDaniel Jasper } else if (Previous.ClosesTemplateDeclaration || 234*de0328aeSDaniel Jasper ((Current.Type == TT_StartOfName || 235*de0328aeSDaniel Jasper Current.is(tok::kw_operator)) && 236*de0328aeSDaniel Jasper State.ParenLevel == 0 && 237*de0328aeSDaniel Jasper (!Style.IndentFunctionDeclarationAfterType || 238*de0328aeSDaniel Jasper Line.StartsDefinition))) { 239*de0328aeSDaniel Jasper State.Column = State.Stack.back().Indent; 240*de0328aeSDaniel Jasper } else if (Current.Type == TT_ObjCSelectorName) { 241*de0328aeSDaniel Jasper if (State.Stack.back().ColonPos > Current.CodePointCount) { 242*de0328aeSDaniel Jasper State.Column = State.Stack.back().ColonPos - Current.CodePointCount; 243*de0328aeSDaniel Jasper } else { 244*de0328aeSDaniel Jasper State.Column = State.Stack.back().Indent; 245*de0328aeSDaniel Jasper State.Stack.back().ColonPos = State.Column + Current.CodePointCount; 246*de0328aeSDaniel Jasper } 247*de0328aeSDaniel Jasper } else if (Current.is(tok::l_square) && Current.Type != TT_ObjCMethodExpr) { 248*de0328aeSDaniel Jasper if (State.Stack.back().StartOfArraySubscripts != 0) 249*de0328aeSDaniel Jasper State.Column = State.Stack.back().StartOfArraySubscripts; 250*de0328aeSDaniel Jasper else 251*de0328aeSDaniel Jasper State.Column = ContinuationIndent; 252*de0328aeSDaniel Jasper } else if (Current.Type == TT_StartOfName || 253*de0328aeSDaniel Jasper Previous.isOneOf(tok::coloncolon, tok::equal) || 254*de0328aeSDaniel Jasper Previous.Type == TT_ObjCMethodExpr) { 255*de0328aeSDaniel Jasper State.Column = ContinuationIndent; 256*de0328aeSDaniel Jasper } else if (Current.Type == TT_CtorInitializerColon) { 257*de0328aeSDaniel Jasper State.Column = FirstIndent + Style.ConstructorInitializerIndentWidth; 258*de0328aeSDaniel Jasper } else if (Current.Type == TT_CtorInitializerComma) { 259*de0328aeSDaniel Jasper State.Column = State.Stack.back().Indent; 260*de0328aeSDaniel Jasper } else { 261*de0328aeSDaniel Jasper State.Column = State.Stack.back().Indent; 262*de0328aeSDaniel Jasper // Ensure that we fall back to indenting 4 spaces instead of just 263*de0328aeSDaniel Jasper // flushing continuations left. 264*de0328aeSDaniel Jasper if (State.Column == FirstIndent) 265*de0328aeSDaniel Jasper State.Column += 4; 266*de0328aeSDaniel Jasper } 267*de0328aeSDaniel Jasper 268*de0328aeSDaniel Jasper if (Current.is(tok::question)) 269*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter = true; 270*de0328aeSDaniel Jasper if ((Previous.isOneOf(tok::comma, tok::semi) && 271*de0328aeSDaniel Jasper !State.Stack.back().AvoidBinPacking) || 272*de0328aeSDaniel Jasper Previous.Type == TT_BinaryOperator) 273*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter = false; 274*de0328aeSDaniel Jasper if (Previous.Type == TT_TemplateCloser && State.ParenLevel == 0) 275*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter = false; 276*de0328aeSDaniel Jasper 277*de0328aeSDaniel Jasper if (!DryRun) { 278*de0328aeSDaniel Jasper unsigned NewLines = 1; 279*de0328aeSDaniel Jasper if (Current.is(tok::comment)) 280*de0328aeSDaniel Jasper NewLines = std::max(NewLines, std::min(Current.NewlinesBefore, 281*de0328aeSDaniel Jasper Style.MaxEmptyLinesToKeep + 1)); 282*de0328aeSDaniel Jasper Whitespaces.replaceWhitespace(Current, NewLines, State.Column, 283*de0328aeSDaniel Jasper State.Column, Line.InPPDirective); 284*de0328aeSDaniel Jasper } 285*de0328aeSDaniel Jasper 286*de0328aeSDaniel Jasper if (!Current.isTrailingComment()) 287*de0328aeSDaniel Jasper State.Stack.back().LastSpace = State.Column; 288*de0328aeSDaniel Jasper if (Current.isOneOf(tok::arrow, tok::period) && 289*de0328aeSDaniel Jasper Current.Type != TT_DesignatedInitializerPeriod) 290*de0328aeSDaniel Jasper State.Stack.back().LastSpace += Current.CodePointCount; 291*de0328aeSDaniel Jasper State.StartOfLineLevel = State.ParenLevel; 292*de0328aeSDaniel Jasper State.LowestLevelOnLine = State.ParenLevel; 293*de0328aeSDaniel Jasper 294*de0328aeSDaniel Jasper // Any break on this level means that the parent level has been broken 295*de0328aeSDaniel Jasper // and we need to avoid bin packing there. 296*de0328aeSDaniel Jasper for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) { 297*de0328aeSDaniel Jasper State.Stack[i].BreakBeforeParameter = true; 298*de0328aeSDaniel Jasper } 299*de0328aeSDaniel Jasper const FormatToken *TokenBefore = Current.getPreviousNonComment(); 300*de0328aeSDaniel Jasper if (TokenBefore && !TokenBefore->isOneOf(tok::comma, tok::semi) && 301*de0328aeSDaniel Jasper TokenBefore->Type != TT_TemplateCloser && 302*de0328aeSDaniel Jasper TokenBefore->Type != TT_BinaryOperator && !TokenBefore->opensScope()) 303*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter = true; 304*de0328aeSDaniel Jasper 305*de0328aeSDaniel Jasper // If we break after {, we should also break before the corresponding }. 306*de0328aeSDaniel Jasper if (Previous.is(tok::l_brace)) 307*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeClosingBrace = true; 308*de0328aeSDaniel Jasper 309*de0328aeSDaniel Jasper if (State.Stack.back().AvoidBinPacking) { 310*de0328aeSDaniel Jasper // If we are breaking after '(', '{', '<', this is not bin packing 311*de0328aeSDaniel Jasper // unless AllowAllParametersOfDeclarationOnNextLine is false. 312*de0328aeSDaniel Jasper if (!(Previous.isOneOf(tok::l_paren, tok::l_brace) || 313*de0328aeSDaniel Jasper Previous.Type == TT_BinaryOperator) || 314*de0328aeSDaniel Jasper (!Style.AllowAllParametersOfDeclarationOnNextLine && 315*de0328aeSDaniel Jasper Line.MustBeDeclaration)) 316*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter = true; 317*de0328aeSDaniel Jasper } 318*de0328aeSDaniel Jasper 319*de0328aeSDaniel Jasper } else { 320*de0328aeSDaniel Jasper if (Current.is(tok::equal) && 321*de0328aeSDaniel Jasper (Line.First->is(tok::kw_for) || State.ParenLevel == 0) && 322*de0328aeSDaniel Jasper State.Stack.back().VariablePos == 0) { 323*de0328aeSDaniel Jasper State.Stack.back().VariablePos = State.Column; 324*de0328aeSDaniel Jasper // Move over * and & if they are bound to the variable name. 325*de0328aeSDaniel Jasper const FormatToken *Tok = &Previous; 326*de0328aeSDaniel Jasper while (Tok && State.Stack.back().VariablePos >= Tok->CodePointCount) { 327*de0328aeSDaniel Jasper State.Stack.back().VariablePos -= Tok->CodePointCount; 328*de0328aeSDaniel Jasper if (Tok->SpacesRequiredBefore != 0) 329*de0328aeSDaniel Jasper break; 330*de0328aeSDaniel Jasper Tok = Tok->Previous; 331*de0328aeSDaniel Jasper } 332*de0328aeSDaniel Jasper if (Previous.PartOfMultiVariableDeclStmt) 333*de0328aeSDaniel Jasper State.Stack.back().LastSpace = State.Stack.back().VariablePos; 334*de0328aeSDaniel Jasper } 335*de0328aeSDaniel Jasper 336*de0328aeSDaniel Jasper unsigned Spaces = State.NextToken->SpacesRequiredBefore; 337*de0328aeSDaniel Jasper 338*de0328aeSDaniel Jasper if (!DryRun) 339*de0328aeSDaniel Jasper Whitespaces.replaceWhitespace(Current, 0, Spaces, State.Column + Spaces); 340*de0328aeSDaniel Jasper 341*de0328aeSDaniel Jasper if (Current.Type == TT_ObjCSelectorName && 342*de0328aeSDaniel Jasper State.Stack.back().ColonPos == 0) { 343*de0328aeSDaniel Jasper if (State.Stack.back().Indent + Current.LongestObjCSelectorName > 344*de0328aeSDaniel Jasper State.Column + Spaces + Current.CodePointCount) 345*de0328aeSDaniel Jasper State.Stack.back().ColonPos = 346*de0328aeSDaniel Jasper State.Stack.back().Indent + Current.LongestObjCSelectorName; 347*de0328aeSDaniel Jasper else 348*de0328aeSDaniel Jasper State.Stack.back().ColonPos = 349*de0328aeSDaniel Jasper State.Column + Spaces + Current.CodePointCount; 350*de0328aeSDaniel Jasper } 351*de0328aeSDaniel Jasper 352*de0328aeSDaniel Jasper if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr && 353*de0328aeSDaniel Jasper Current.Type != TT_LineComment) 354*de0328aeSDaniel Jasper State.Stack.back().Indent = State.Column + Spaces; 355*de0328aeSDaniel Jasper if (Previous.is(tok::comma) && !Current.isTrailingComment() && 356*de0328aeSDaniel Jasper State.Stack.back().AvoidBinPacking) 357*de0328aeSDaniel Jasper State.Stack.back().NoLineBreak = true; 358*de0328aeSDaniel Jasper 359*de0328aeSDaniel Jasper State.Column += Spaces; 360*de0328aeSDaniel Jasper if (Current.is(tok::l_paren) && Previous.isOneOf(tok::kw_if, tok::kw_for)) 361*de0328aeSDaniel Jasper // Treat the condition inside an if as if it was a second function 362*de0328aeSDaniel Jasper // parameter, i.e. let nested calls have an indent of 4. 363*de0328aeSDaniel Jasper State.Stack.back().LastSpace = State.Column + 1; // 1 is length of "(". 364*de0328aeSDaniel Jasper else if (Previous.is(tok::comma)) 365*de0328aeSDaniel Jasper State.Stack.back().LastSpace = State.Column; 366*de0328aeSDaniel Jasper else if ((Previous.Type == TT_BinaryOperator || 367*de0328aeSDaniel Jasper Previous.Type == TT_ConditionalExpr || 368*de0328aeSDaniel Jasper Previous.Type == TT_CtorInitializerColon) && 369*de0328aeSDaniel Jasper !(Previous.getPrecedence() == prec::Assignment && 370*de0328aeSDaniel Jasper Current.FakeLParens.empty())) 371*de0328aeSDaniel Jasper // Always indent relative to the RHS of the expression unless this is a 372*de0328aeSDaniel Jasper // simple assignment without binary expression on the RHS. 373*de0328aeSDaniel Jasper State.Stack.back().LastSpace = State.Column; 374*de0328aeSDaniel Jasper else if (Previous.Type == TT_InheritanceColon) 375*de0328aeSDaniel Jasper State.Stack.back().Indent = State.Column; 376*de0328aeSDaniel Jasper else if (Previous.opensScope()) { 377*de0328aeSDaniel Jasper // If a function has multiple parameters (including a single parameter 378*de0328aeSDaniel Jasper // that is a binary expression) or a trailing call, indent all 379*de0328aeSDaniel Jasper // parameters from the opening parenthesis. This avoids confusing 380*de0328aeSDaniel Jasper // indents like: 381*de0328aeSDaniel Jasper // OuterFunction(InnerFunctionCall( 382*de0328aeSDaniel Jasper // ParameterToInnerFunction), 383*de0328aeSDaniel Jasper // SecondParameterToOuterFunction); 384*de0328aeSDaniel Jasper bool HasMultipleParameters = !Current.FakeLParens.empty(); 385*de0328aeSDaniel Jasper bool HasTrailingCall = false; 386*de0328aeSDaniel Jasper if (Previous.MatchingParen) { 387*de0328aeSDaniel Jasper const FormatToken *Next = Previous.MatchingParen->getNextNonComment(); 388*de0328aeSDaniel Jasper if (Next && Next->isOneOf(tok::period, tok::arrow)) 389*de0328aeSDaniel Jasper HasTrailingCall = true; 390*de0328aeSDaniel Jasper } 391*de0328aeSDaniel Jasper if (HasMultipleParameters || HasTrailingCall) 392*de0328aeSDaniel Jasper State.Stack.back().LastSpace = State.Column; 393*de0328aeSDaniel Jasper } 394*de0328aeSDaniel Jasper } 395*de0328aeSDaniel Jasper 396*de0328aeSDaniel Jasper return moveStateToNextToken(State, DryRun, Newline) + ExtraPenalty; 397*de0328aeSDaniel Jasper } 398*de0328aeSDaniel Jasper 399*de0328aeSDaniel Jasper unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, 400*de0328aeSDaniel Jasper bool DryRun, bool Newline) { 401*de0328aeSDaniel Jasper const FormatToken &Current = *State.NextToken; 402*de0328aeSDaniel Jasper assert(State.Stack.size()); 403*de0328aeSDaniel Jasper 404*de0328aeSDaniel Jasper if (Current.Type == TT_InheritanceColon) 405*de0328aeSDaniel Jasper State.Stack.back().AvoidBinPacking = true; 406*de0328aeSDaniel Jasper if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0) 407*de0328aeSDaniel Jasper State.Stack.back().FirstLessLess = State.Column; 408*de0328aeSDaniel Jasper if (Current.is(tok::l_square) && 409*de0328aeSDaniel Jasper State.Stack.back().StartOfArraySubscripts == 0) 410*de0328aeSDaniel Jasper State.Stack.back().StartOfArraySubscripts = State.Column; 411*de0328aeSDaniel Jasper if (Current.is(tok::question)) 412*de0328aeSDaniel Jasper State.Stack.back().QuestionColumn = State.Column; 413*de0328aeSDaniel Jasper if (!Current.opensScope() && !Current.closesScope()) 414*de0328aeSDaniel Jasper State.LowestLevelOnLine = 415*de0328aeSDaniel Jasper std::min(State.LowestLevelOnLine, State.ParenLevel); 416*de0328aeSDaniel Jasper if (Current.isOneOf(tok::period, tok::arrow) && 417*de0328aeSDaniel Jasper Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0) 418*de0328aeSDaniel Jasper State.Stack.back().StartOfFunctionCall = 419*de0328aeSDaniel Jasper Current.LastInChainOfCalls ? 0 : State.Column + Current.CodePointCount; 420*de0328aeSDaniel Jasper if (Current.Type == TT_CtorInitializerColon) { 421*de0328aeSDaniel Jasper // Indent 2 from the column, so: 422*de0328aeSDaniel Jasper // SomeClass::SomeClass() 423*de0328aeSDaniel Jasper // : First(...), ... 424*de0328aeSDaniel Jasper // Next(...) 425*de0328aeSDaniel Jasper // ^ line up here. 426*de0328aeSDaniel Jasper State.Stack.back().Indent = 427*de0328aeSDaniel Jasper State.Column + (Style.BreakConstructorInitializersBeforeComma ? 0 : 2); 428*de0328aeSDaniel Jasper if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine) 429*de0328aeSDaniel Jasper State.Stack.back().AvoidBinPacking = true; 430*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter = false; 431*de0328aeSDaniel Jasper } 432*de0328aeSDaniel Jasper 433*de0328aeSDaniel Jasper // If return returns a binary expression, align after it. 434*de0328aeSDaniel Jasper if (Current.is(tok::kw_return) && !Current.FakeLParens.empty()) 435*de0328aeSDaniel Jasper State.Stack.back().LastSpace = State.Column + 7; 436*de0328aeSDaniel Jasper 437*de0328aeSDaniel Jasper // In ObjC method declaration we align on the ":" of parameters, but we need 438*de0328aeSDaniel Jasper // to ensure that we indent parameters on subsequent lines by at least 4. 439*de0328aeSDaniel Jasper if (Current.Type == TT_ObjCMethodSpecifier) 440*de0328aeSDaniel Jasper State.Stack.back().Indent += 4; 441*de0328aeSDaniel Jasper 442*de0328aeSDaniel Jasper // Insert scopes created by fake parenthesis. 443*de0328aeSDaniel Jasper const FormatToken *Previous = Current.getPreviousNonComment(); 444*de0328aeSDaniel Jasper // Don't add extra indentation for the first fake parenthesis after 445*de0328aeSDaniel Jasper // 'return', assignements or opening <({[. The indentation for these cases 446*de0328aeSDaniel Jasper // is special cased. 447*de0328aeSDaniel Jasper bool SkipFirstExtraIndent = 448*de0328aeSDaniel Jasper Current.is(tok::kw_return) || 449*de0328aeSDaniel Jasper (Previous && (Previous->opensScope() || 450*de0328aeSDaniel Jasper Previous->getPrecedence() == prec::Assignment)); 451*de0328aeSDaniel Jasper for (SmallVectorImpl<prec::Level>::const_reverse_iterator 452*de0328aeSDaniel Jasper I = Current.FakeLParens.rbegin(), 453*de0328aeSDaniel Jasper E = Current.FakeLParens.rend(); 454*de0328aeSDaniel Jasper I != E; ++I) { 455*de0328aeSDaniel Jasper ParenState NewParenState = State.Stack.back(); 456*de0328aeSDaniel Jasper NewParenState.ContainsLineBreak = false; 457*de0328aeSDaniel Jasper NewParenState.Indent = 458*de0328aeSDaniel Jasper std::max(std::max(State.Column, NewParenState.Indent), 459*de0328aeSDaniel Jasper State.Stack.back().LastSpace); 460*de0328aeSDaniel Jasper 461*de0328aeSDaniel Jasper // Always indent conditional expressions. Never indent expression where 462*de0328aeSDaniel Jasper // the 'operator' is ',', ';' or an assignment (i.e. *I <= 463*de0328aeSDaniel Jasper // prec::Assignment) as those have different indentation rules. Indent 464*de0328aeSDaniel Jasper // other expression, unless the indentation needs to be skipped. 465*de0328aeSDaniel Jasper if (*I == prec::Conditional || 466*de0328aeSDaniel Jasper (!SkipFirstExtraIndent && *I > prec::Assignment && 467*de0328aeSDaniel Jasper !Style.BreakBeforeBinaryOperators)) 468*de0328aeSDaniel Jasper NewParenState.Indent += 4; 469*de0328aeSDaniel Jasper if (Previous && !Previous->opensScope()) 470*de0328aeSDaniel Jasper NewParenState.BreakBeforeParameter = false; 471*de0328aeSDaniel Jasper State.Stack.push_back(NewParenState); 472*de0328aeSDaniel Jasper SkipFirstExtraIndent = false; 473*de0328aeSDaniel Jasper } 474*de0328aeSDaniel Jasper 475*de0328aeSDaniel Jasper // If we encounter an opening (, [, { or <, we add a level to our stacks to 476*de0328aeSDaniel Jasper // prepare for the following tokens. 477*de0328aeSDaniel Jasper if (Current.opensScope()) { 478*de0328aeSDaniel Jasper unsigned NewIndent; 479*de0328aeSDaniel Jasper unsigned LastSpace = State.Stack.back().LastSpace; 480*de0328aeSDaniel Jasper bool AvoidBinPacking; 481*de0328aeSDaniel Jasper if (Current.is(tok::l_brace)) { 482*de0328aeSDaniel Jasper NewIndent = 483*de0328aeSDaniel Jasper LastSpace + (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth); 484*de0328aeSDaniel Jasper const FormatToken *NextNoComment = Current.getNextNonComment(); 485*de0328aeSDaniel Jasper AvoidBinPacking = NextNoComment && 486*de0328aeSDaniel Jasper NextNoComment->Type == TT_DesignatedInitializerPeriod; 487*de0328aeSDaniel Jasper } else { 488*de0328aeSDaniel Jasper NewIndent = 489*de0328aeSDaniel Jasper 4 + std::max(LastSpace, State.Stack.back().StartOfFunctionCall); 490*de0328aeSDaniel Jasper AvoidBinPacking = !Style.BinPackParameters || 491*de0328aeSDaniel Jasper (Style.ExperimentalAutoDetectBinPacking && 492*de0328aeSDaniel Jasper (Current.PackingKind == PPK_OnePerLine || 493*de0328aeSDaniel Jasper (!BinPackInconclusiveFunctions && 494*de0328aeSDaniel Jasper Current.PackingKind == PPK_Inconclusive))); 495*de0328aeSDaniel Jasper } 496*de0328aeSDaniel Jasper 497*de0328aeSDaniel Jasper State.Stack.push_back(ParenState(NewIndent, LastSpace, AvoidBinPacking, 498*de0328aeSDaniel Jasper State.Stack.back().NoLineBreak)); 499*de0328aeSDaniel Jasper ++State.ParenLevel; 500*de0328aeSDaniel Jasper } 501*de0328aeSDaniel Jasper 502*de0328aeSDaniel Jasper // If this '[' opens an ObjC call, determine whether all parameters fit into 503*de0328aeSDaniel Jasper // one line and put one per line if they don't. 504*de0328aeSDaniel Jasper if (Current.is(tok::l_square) && Current.Type == TT_ObjCMethodExpr && 505*de0328aeSDaniel Jasper Current.MatchingParen != NULL) { 506*de0328aeSDaniel Jasper if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit()) 507*de0328aeSDaniel Jasper State.Stack.back().BreakBeforeParameter = true; 508*de0328aeSDaniel Jasper } 509*de0328aeSDaniel Jasper 510*de0328aeSDaniel Jasper // If we encounter a closing ), ], } or >, we can remove a level from our 511*de0328aeSDaniel Jasper // stacks. 512*de0328aeSDaniel Jasper if (Current.isOneOf(tok::r_paren, tok::r_square) || 513*de0328aeSDaniel Jasper (Current.is(tok::r_brace) && State.NextToken != Line.First) || 514*de0328aeSDaniel Jasper State.NextToken->Type == TT_TemplateCloser) { 515*de0328aeSDaniel Jasper State.Stack.pop_back(); 516*de0328aeSDaniel Jasper --State.ParenLevel; 517*de0328aeSDaniel Jasper } 518*de0328aeSDaniel Jasper if (Current.is(tok::r_square)) { 519*de0328aeSDaniel Jasper // If this ends the array subscript expr, reset the corresponding value. 520*de0328aeSDaniel Jasper const FormatToken *NextNonComment = Current.getNextNonComment(); 521*de0328aeSDaniel Jasper if (NextNonComment && NextNonComment->isNot(tok::l_square)) 522*de0328aeSDaniel Jasper State.Stack.back().StartOfArraySubscripts = 0; 523*de0328aeSDaniel Jasper } 524*de0328aeSDaniel Jasper 525*de0328aeSDaniel Jasper // Remove scopes created by fake parenthesis. 526*de0328aeSDaniel Jasper for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) { 527*de0328aeSDaniel Jasper unsigned VariablePos = State.Stack.back().VariablePos; 528*de0328aeSDaniel Jasper State.Stack.pop_back(); 529*de0328aeSDaniel Jasper State.Stack.back().VariablePos = VariablePos; 530*de0328aeSDaniel Jasper } 531*de0328aeSDaniel Jasper 532*de0328aeSDaniel Jasper if (Current.is(tok::string_literal) && State.StartOfStringLiteral == 0) { 533*de0328aeSDaniel Jasper State.StartOfStringLiteral = State.Column; 534*de0328aeSDaniel Jasper } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash, 535*de0328aeSDaniel Jasper tok::string_literal)) { 536*de0328aeSDaniel Jasper State.StartOfStringLiteral = 0; 537*de0328aeSDaniel Jasper } 538*de0328aeSDaniel Jasper 539*de0328aeSDaniel Jasper State.Column += Current.CodePointCount; 540*de0328aeSDaniel Jasper 541*de0328aeSDaniel Jasper State.NextToken = State.NextToken->Next; 542*de0328aeSDaniel Jasper 543*de0328aeSDaniel Jasper if (!Newline && Style.AlwaysBreakBeforeMultilineStrings && 544*de0328aeSDaniel Jasper Current.is(tok::string_literal) && Current.CanBreakBefore) 545*de0328aeSDaniel Jasper return 0; 546*de0328aeSDaniel Jasper 547*de0328aeSDaniel Jasper return breakProtrudingToken(Current, State, DryRun); 548*de0328aeSDaniel Jasper } 549*de0328aeSDaniel Jasper 550*de0328aeSDaniel Jasper unsigned ContinuationIndenter::breakProtrudingToken(const FormatToken &Current, 551*de0328aeSDaniel Jasper LineState &State, 552*de0328aeSDaniel Jasper bool DryRun) { 553*de0328aeSDaniel Jasper llvm::OwningPtr<BreakableToken> Token; 554*de0328aeSDaniel Jasper unsigned StartColumn = State.Column - Current.CodePointCount; 555*de0328aeSDaniel Jasper unsigned OriginalStartColumn = 556*de0328aeSDaniel Jasper SourceMgr.getSpellingColumnNumber(Current.getStartOfNonWhitespace()) - 1; 557*de0328aeSDaniel Jasper 558*de0328aeSDaniel Jasper if (Current.is(tok::string_literal) && 559*de0328aeSDaniel Jasper Current.Type != TT_ImplicitStringLiteral) { 560*de0328aeSDaniel Jasper // Only break up default narrow strings. 561*de0328aeSDaniel Jasper if (!Current.TokenText.startswith("\"")) 562*de0328aeSDaniel Jasper return 0; 563*de0328aeSDaniel Jasper // Don't break string literals with escaped newlines. As clang-format must 564*de0328aeSDaniel Jasper // not change the string's content, it is unlikely that we'll end up with 565*de0328aeSDaniel Jasper // a better format. 566*de0328aeSDaniel Jasper if (Current.TokenText.find("\\\n") != StringRef::npos) 567*de0328aeSDaniel Jasper return 0; 568*de0328aeSDaniel Jasper // Exempts unterminated string literals from line breaking. The user will 569*de0328aeSDaniel Jasper // likely want to terminate the string before any line breaking is done. 570*de0328aeSDaniel Jasper if (Current.IsUnterminatedLiteral) 571*de0328aeSDaniel Jasper return 0; 572*de0328aeSDaniel Jasper 573*de0328aeSDaniel Jasper Token.reset(new BreakableStringLiteral(Current, StartColumn, 574*de0328aeSDaniel Jasper Line.InPPDirective, Encoding)); 575*de0328aeSDaniel Jasper } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) { 576*de0328aeSDaniel Jasper Token.reset(new BreakableBlockComment( 577*de0328aeSDaniel Jasper Style, Current, StartColumn, OriginalStartColumn, !Current.Previous, 578*de0328aeSDaniel Jasper Line.InPPDirective, Encoding)); 579*de0328aeSDaniel Jasper } else if (Current.Type == TT_LineComment && 580*de0328aeSDaniel Jasper (Current.Previous == NULL || 581*de0328aeSDaniel Jasper Current.Previous->Type != TT_ImplicitStringLiteral)) { 582*de0328aeSDaniel Jasper // Don't break line comments with escaped newlines. These look like 583*de0328aeSDaniel Jasper // separate line comments, but in fact contain a single line comment with 584*de0328aeSDaniel Jasper // multiple lines including leading whitespace and the '//' markers. 585*de0328aeSDaniel Jasper // 586*de0328aeSDaniel Jasper // FIXME: If we want to handle them correctly, we'll need to adjust 587*de0328aeSDaniel Jasper // leading whitespace in consecutive lines when changing indentation of 588*de0328aeSDaniel Jasper // the first line similar to what we do with block comments. 589*de0328aeSDaniel Jasper StringRef::size_type EscapedNewlinePos = Current.TokenText.find("\\\n"); 590*de0328aeSDaniel Jasper if (EscapedNewlinePos != StringRef::npos) { 591*de0328aeSDaniel Jasper State.Column = 592*de0328aeSDaniel Jasper StartColumn + 593*de0328aeSDaniel Jasper encoding::getCodePointCount( 594*de0328aeSDaniel Jasper Current.TokenText.substr(0, EscapedNewlinePos), Encoding) + 595*de0328aeSDaniel Jasper 1; 596*de0328aeSDaniel Jasper return 0; 597*de0328aeSDaniel Jasper } 598*de0328aeSDaniel Jasper 599*de0328aeSDaniel Jasper Token.reset(new BreakableLineComment(Current, StartColumn, 600*de0328aeSDaniel Jasper Line.InPPDirective, Encoding)); 601*de0328aeSDaniel Jasper } else { 602*de0328aeSDaniel Jasper return 0; 603*de0328aeSDaniel Jasper } 604*de0328aeSDaniel Jasper if (Current.UnbreakableTailLength >= getColumnLimit()) 605*de0328aeSDaniel Jasper return 0; 606*de0328aeSDaniel Jasper 607*de0328aeSDaniel Jasper unsigned RemainingSpace = getColumnLimit() - Current.UnbreakableTailLength; 608*de0328aeSDaniel Jasper bool BreakInserted = false; 609*de0328aeSDaniel Jasper unsigned Penalty = 0; 610*de0328aeSDaniel Jasper unsigned RemainingTokenColumns = 0; 611*de0328aeSDaniel Jasper for (unsigned LineIndex = 0, EndIndex = Token->getLineCount(); 612*de0328aeSDaniel Jasper LineIndex != EndIndex; ++LineIndex) { 613*de0328aeSDaniel Jasper if (!DryRun) 614*de0328aeSDaniel Jasper Token->replaceWhitespaceBefore(LineIndex, Whitespaces); 615*de0328aeSDaniel Jasper unsigned TailOffset = 0; 616*de0328aeSDaniel Jasper RemainingTokenColumns = 617*de0328aeSDaniel Jasper Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos); 618*de0328aeSDaniel Jasper while (RemainingTokenColumns > RemainingSpace) { 619*de0328aeSDaniel Jasper BreakableToken::Split Split = 620*de0328aeSDaniel Jasper Token->getSplit(LineIndex, TailOffset, getColumnLimit()); 621*de0328aeSDaniel Jasper if (Split.first == StringRef::npos) { 622*de0328aeSDaniel Jasper // The last line's penalty is handled in addNextStateToQueue(). 623*de0328aeSDaniel Jasper if (LineIndex < EndIndex - 1) 624*de0328aeSDaniel Jasper Penalty += Style.PenaltyExcessCharacter * 625*de0328aeSDaniel Jasper (RemainingTokenColumns - RemainingSpace); 626*de0328aeSDaniel Jasper break; 627*de0328aeSDaniel Jasper } 628*de0328aeSDaniel Jasper assert(Split.first != 0); 629*de0328aeSDaniel Jasper unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit( 630*de0328aeSDaniel Jasper LineIndex, TailOffset + Split.first + Split.second, StringRef::npos); 631*de0328aeSDaniel Jasper assert(NewRemainingTokenColumns < RemainingTokenColumns); 632*de0328aeSDaniel Jasper if (!DryRun) 633*de0328aeSDaniel Jasper Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces); 634*de0328aeSDaniel Jasper Penalty += Current.is(tok::string_literal) ? Style.PenaltyBreakString 635*de0328aeSDaniel Jasper : Style.PenaltyBreakComment; 636*de0328aeSDaniel Jasper unsigned ColumnsUsed = 637*de0328aeSDaniel Jasper Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first); 638*de0328aeSDaniel Jasper if (ColumnsUsed > getColumnLimit()) { 639*de0328aeSDaniel Jasper Penalty += 640*de0328aeSDaniel Jasper Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit()); 641*de0328aeSDaniel Jasper } 642*de0328aeSDaniel Jasper TailOffset += Split.first + Split.second; 643*de0328aeSDaniel Jasper RemainingTokenColumns = NewRemainingTokenColumns; 644*de0328aeSDaniel Jasper BreakInserted = true; 645*de0328aeSDaniel Jasper } 646*de0328aeSDaniel Jasper } 647*de0328aeSDaniel Jasper 648*de0328aeSDaniel Jasper State.Column = RemainingTokenColumns; 649*de0328aeSDaniel Jasper 650*de0328aeSDaniel Jasper if (BreakInserted) { 651*de0328aeSDaniel Jasper // If we break the token inside a parameter list, we need to break before 652*de0328aeSDaniel Jasper // the next parameter on all levels, so that the next parameter is clearly 653*de0328aeSDaniel Jasper // visible. Line comments already introduce a break. 654*de0328aeSDaniel Jasper if (Current.Type != TT_LineComment) { 655*de0328aeSDaniel Jasper for (unsigned i = 0, e = State.Stack.size(); i != e; ++i) 656*de0328aeSDaniel Jasper State.Stack[i].BreakBeforeParameter = true; 657*de0328aeSDaniel Jasper } 658*de0328aeSDaniel Jasper 659*de0328aeSDaniel Jasper State.Stack.back().LastSpace = StartColumn; 660*de0328aeSDaniel Jasper } 661*de0328aeSDaniel Jasper return Penalty; 662*de0328aeSDaniel Jasper } 663*de0328aeSDaniel Jasper 664*de0328aeSDaniel Jasper unsigned ContinuationIndenter::getColumnLimit() const { 665*de0328aeSDaniel Jasper // In preprocessor directives reserve two chars for trailing " \" 666*de0328aeSDaniel Jasper return Style.ColumnLimit - (Line.InPPDirective ? 2 : 0); 667*de0328aeSDaniel Jasper } 668*de0328aeSDaniel Jasper 669*de0328aeSDaniel Jasper } // namespace format 670*de0328aeSDaniel Jasper } // namespace clang 671