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