clang: lib/Format/ContinuationIndenter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

23#include "llvm/ADT/StringSet.h"

24#include "llvm/Support/Debug.h"

25#include

26

27#define DEBUG_TYPE "format-indenter"

28

30namespace format {

31

32

33

38

39

40

44 Previous->isOneOf(tok::kw_return, TT_RequiresClause));

45}

46

47

48

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89 if (Tok.MatchingParen)

90 return 0;

92

93 int MatchingStackIndex = Stack.size() - 1;

94

95

96

97

99 while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].Tok != LBrace)

100 --MatchingStackIndex;

101 return MatchingStackIndex >= 0 ? &Stack[MatchingStackIndex] : nullptr;

102 };

103 for (; End->Next; End = End->Next) {

105 break;

106 if (!End->Next->closesScope())

107 continue;

110 tok::l_brace, TT_ArrayInitializerLSquare, tok::less)) {

112 if (State && State->BreakBeforeClosingBrace)

113 break;

114 }

115 }

117}

118

120 if (Tok.NextOperator)

121 return 0;

122 return Tok.NextOperator->TotalLength - Tok.TotalLength;

123}

124

125

126

128 return Tok.isMemberAccess() && Tok.Previous && Tok.Previous->closesScope();

129}

130

131

133

134 bool HasTwoOperands = Token.OperatorIndex == 0 && Token.NextOperator;

135 return Token.is(TT_BinaryOperator) && !HasTwoOperands &&

138}

139

140

146

147

149 const FormatStyle &Style) {

150 return Style.BreakBinaryOperations != FormatStyle::BBO_Never &&

152 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None

155}

156

158 const FormatStyle &Style) {

159 if (LessTok.isNot(tok::less))

160 return false;

161 return Style.isTextProto() ||

162 (Style.Language == FormatStyle::LK_Proto &&

165}

166

167

168

169

171 if (TokenText.size() < 5

173 return std::nullopt;

174 }

175

176

177

178

179 size_t LParenPos = TokenText.substr(0, 19).find_first_of('(');

180 if (LParenPos == StringRef::npos)

181 return std::nullopt;

182 StringRef Delimiter = TokenText.substr(2, LParenPos - 2);

183

184

185 size_t RParenPos = TokenText.size() - Delimiter.size() - 2;

187 return std::nullopt;

188 if (TokenText.substr(RParenPos + 1).starts_with(Delimiter))

189 return std::nullopt;

190 return Delimiter;

191}

192

193

194

195static StringRef

197 FormatStyle::LanguageKind Language) {

198 for (const auto &Format : Style.RawStringFormats)

199 if (Format.Language == Language)

200 return StringRef(Format.CanonicalDelimiter);

201 return "";

202}

203

205 const FormatStyle &CodeStyle) {

206 for (const auto &RawStringFormat : CodeStyle.RawStringFormats) {

207 std::optional LanguageStyle =

209 if (!LanguageStyle) {

210 FormatStyle PredefinedStyle;

215 }

216 LanguageStyle = PredefinedStyle;

217 }

218 LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit;

223 }

224}

225

226std::optional

230 return std::nullopt;

231 return It->second;

232}

233

234std::optional

236 StringRef EnclosingFunction) const {

239 return std::nullopt;

240 return It->second;

241}

242

247

252

257

259 *this = *this + Spaces;

260 return *this;

261}

262

266

269

281

287 bool BinPackInconclusiveFunctions)

288 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),

289 Whitespaces(Whitespaces), Encoding(Encoding),

290 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),

291 CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {}

292

294 unsigned FirstStartColumn,

296 bool DryRun) {

299 if (FirstStartColumn && Line->First->NewlinesBefore == 0)

300 State.Column = FirstStartColumn;

301 else

302 State.Column = FirstIndent;

303

304

305

306 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&

309 State.Column = 0;

310 }

311 State.Line = Line;

312 State.NextToken = Line->First;

313 State.Stack.push_back(ParenState(nullptr, FirstIndent, FirstIndent,

314 false,

315 false));

316 State.NoContinuation = false;

317 State.StartOfStringLiteral = 0;

318 State.NoLineBreak = false;

319 State.StartOfLineLevel = 0;

320 State.LowestLevelOnLine = 0;

321 State.IgnoreStackForComparison = false;

322

323 if (Style.isTextProto()) {

324

325

326 auto &CurrentState = State.Stack.back();

327 CurrentState.AvoidBinPacking = true;

328 CurrentState.BreakBeforeParameter = true;

329 CurrentState.AlignColons = false;

330 }

331

332

333 moveStateToNextToken(State, DryRun, false);

334 return State;

335}

336

338 const FormatToken &Current = *State.NextToken;

340 const auto &CurrentState = State.Stack.back();

342 if (!Current.CanBreakBefore && !(CurrentState.BreakBeforeClosingBrace &&

343 Current.closesBlockOrBlockTypeList(Style))) {

344 return false;

345 }

346

347

351 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) {

352 return false;

353 }

354

355

356

357

358

360 State.LowestLevelOnLine < State.StartOfLineLevel &&

361 State.LowestLevelOnLine < Current.NestingLevel) {

362 return false;

363 }

364 if (Current.isMemberAccess() && CurrentState.ContainsUnwrappedBuilder)

365 return false;

366

367

368

369 if (Previous.is(tok::l_brace) && State.Stack.size() > 1 &&

370 State.Stack[State.Stack.size() - 2].NestedBlockInlined &&

371 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) {

372 return Style.isCpp() &&

373 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope;

374 }

375

376

377

378 if (Current.is(TT_FunctionDeclarationName)) {

379 if (Style.BreakAfterReturnType == FormatStyle::RTBS_None &&

380 State.Column < 6) {

381 return false;

382 }

383

384 if (Style.BreakAfterReturnType == FormatStyle::RTBS_ExceptShortType) {

385 assert(State.Column >= State.FirstIndent);

386 if (State.Column - State.FirstIndent < 6)

387 return false;

388 }

389 }

390

391

392

394 Current.isBlockIndentedInitRBrace(Style)) {

395 return CurrentState.BreakBeforeClosingBrace;

396 }

397

398

399

400 if ((Style.BreakBeforeCloseBracketFunction ||

401 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||

402 Style.BreakBeforeCloseBracketSwitch) &&

403 Current.is(tok::r_paren)) {

404 return CurrentState.BreakBeforeClosingParen;

405 }

406

407 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser))

408 return CurrentState.BreakBeforeClosingAngle;

409

410

411

412 if (Current.isNoneOf(TT_BinaryOperator, tok::comma) &&

413

414

415

416 (!Style.BraceWrapping.BeforeLambdaBody ||

417 Current.isNot(TT_LambdaLBrace)) &&

418 CurrentState.NoLineBreakInOperand) {

419 return false;

420 }

421

422 if (Previous.is(tok::l_square) && Previous.is(TT_ObjCMethodExpr))

423 return false;

424

425 if (Current.is(TT_ConditionalExpr) && Previous.is(tok::r_paren) &&

426 Previous.MatchingParen && Previous.MatchingParen->Previous &&

427 Previous.MatchingParen->Previous->MatchingParen &&

428 Previous.MatchingParen->Previous->MatchingParen->is(TT_LambdaLBrace)) {

429

430 assert(Previous.MatchingParen->Previous->is(tok::r_brace));

431 return true;

432 }

433

434 return !State.NoLineBreak && !CurrentState.NoLineBreak;

435}

436

438 const FormatToken &Current = *State.NextToken;

440 const auto &CurrentState = State.Stack.back();

441 if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore &&

442 Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) {

445 }

447 (Current.is(TT_InlineASMColon) &&

448 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||

449 (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline &&

450 Style.ColumnLimit > 0)))) {

451 return true;

452 }

453 if (CurrentState.BreakBeforeClosingBrace &&

454 (Current.closesBlockOrBlockTypeList(Style) ||

456 Current.isBlockIndentedInitRBrace(Style)))) {

457 return true;

458 }

459 if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren))

460 return true;

461 if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser))

462 return true;

463 if (Style.Language == FormatStyle::LK_ObjC &&

464 Style.ObjCBreakBeforeNestedBlockParam &&

466 Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) {

467 return true;

468 }

469

470

471 if (CurrentState.IsCSharpGenericTypeConstraint &&

472 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {

473 return false;

474 }

476 (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&

477 State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&

478

479

480

481

482 (Previous.NestingLevel == 1 ||

483 Style.BinPackParameters == FormatStyle::BPPS_BinPack)) ||

484 (Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) &&

485 Previous.isNot(tok::question)) ||

486 (!Style.BreakBeforeTernaryOperators &&

487 Previous.is(TT_ConditionalExpr))) &&

488 CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&

489 Current.isNoneOf(tok::r_paren, tok::r_brace)) {

490 return true;

491 }

492 if (CurrentState.IsChainedConditional &&

493 ((Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) &&

494 Current.is(tok::colon)) ||

495 (!Style.BreakBeforeTernaryOperators && Previous.is(TT_ConditionalExpr) &&

497 return true;

498 }

499 if (((Previous.is(TT_DictLiteral) && Previous.is(tok::l_brace)) ||

500 (Previous.is(TT_ArrayInitializerLSquare) &&

501 Previous.ParameterCount > 1) ||

503 Style.ColumnLimit > 0 &&

506 return true;

507 }

508

509 const FormatToken &BreakConstructorInitializersToken =

510 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon

512 : Current;

513 if (BreakConstructorInitializersToken.is(TT_CtorInitializerColon) &&

514 (State.Column + State.Line->Last->TotalLength - Previous.TotalLength >

516 CurrentState.BreakBeforeParameter) &&

517 ((!Current.isTrailingComment() && Style.ColumnLimit > 0) ||

519 return true;

520 }

521

522 if (Current.is(TT_ObjCMethodExpr) && Previous.isNot(TT_SelectorName) &&

523 State.Line->startsWith(TT_ObjCMethodSpecifier)) {

524 return true;

525 }

526 if (Current.is(TT_SelectorName) && Previous.isNot(tok::at) &&

527 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&

528 (Style.ObjCBreakBeforeNestedBlockParam ||

529 !Current.startsSequence(TT_SelectorName, tok::colon, tok::caret))) {

530 return true;

531 }

532

533 unsigned NewLineColumn = getNewLineColumn(State).Total;

534 if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&

536 (State.Column > NewLineColumn ||

537 Current.NestingLevel < State.StartOfLineLevel)) {

538 return true;

539 }

540

542 (CurrentState.CallContinuation != 0 ||

543 CurrentState.BreakBeforeParameter) &&

544

545

546

547

548

549 !(State.Column <= NewLineColumn && Style.isJavaScript()) &&

550 !(Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn)) {

551 return true;

552 }

553

554

555

556 if (Previous.ClosesTemplateDeclaration && CurrentState.BreakBeforeParameter &&

558 return true;

559 }

560

561 if (State.Line->First->isNot(tok::kw_enum) && State.Column <= NewLineColumn)

562 return false;

563

564 if (Style.AlwaysBreakBeforeMultilineStrings &&

565 (NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||

567 Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,

568 Keywords.kw_dollar) &&

569 Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&

570 nextIsMultilineString(State)) {

571 return true;

572 }

573

574

575

576

578 const auto PreviousPrecedence = Previous.getPrecedence();

580 CurrentState.BreakBeforeParameter && !Current.isTrailingComment()) {

581 const bool LHSIsBinaryExpr =

582 Previous.Previous && Previous.Previous->EndsBinaryExpression;

583 if (LHSIsBinaryExpr)

584 return true;

585

586

587

588

589

590

591

592

593

594 const bool IsComparison =

599 Previous.Previous->isNot(TT_BinaryOperator);

600 if (!IsComparison)

601 return true;

602 }

603 } else if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore &&

605 CurrentState.BreakBeforeParameter) {

606 return true;

607 }

608

609

610 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&

611 CurrentState.BreakBeforeParameter && CurrentState.FirstLessLess == 0) {

612 return true;

613 }

614

615 if (Current.NestingLevel == 0 && !Current.isTrailingComment()) {

616

617

618

619

620 if (Previous.ClosesTemplateDeclaration) {

621 if (Current.is(tok::kw_concept)) {

622 switch (Style.BreakBeforeConceptDeclarations) {

623 case FormatStyle::BBCDS_Allowed:

624 break;

625 case FormatStyle::BBCDS_Always:

626 return true;

627 case FormatStyle::BBCDS_Never:

628 return false;

629 }

630 }

631 if (Current.is(TT_RequiresClause)) {

632 switch (Style.RequiresClausePosition) {

633 case FormatStyle::RCPS_SingleLine:

634 case FormatStyle::RCPS_WithPreceding:

635 return false;

636 default:

637 return true;

638 }

639 }

640 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_No &&

641 (Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||

643 }

644 if (Previous.is(TT_FunctionAnnotationRParen) &&

646 return true;

647 }

648 if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&

649 Current.isNot(TT_LeadingJavaAnnotation)) {

650 return true;

651 }

652 }

653

654 if (Style.isJavaScript() && Previous.is(tok::r_paren) &&

655 Previous.is(TT_JavaAnnotation)) {

656

657

658 static const llvm::StringSet<> BreakBeforeDecoratedTokens = {"get", "set",

659 "function"};

660 if (BreakBeforeDecoratedTokens.contains(Current.TokenText))

661 return true;

662 }

663

664 if (Current.is(TT_FunctionDeclarationName) &&

665 !State.Line->ReturnTypeWrapped &&

666

667 (!Style.isCSharp() ||

668 Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&

669

670

671 !Style.isJavaScript() && Previous.isNot(tok::kw_template) &&

672 CurrentState.BreakBeforeParameter) {

674 if (Tok->is(TT_LineComment))

675 return false;

676 if (Tok->is(TT_TemplateCloser)) {

677 Tok = Tok->MatchingParen;

678 assert(Tok);

679 }

680 if (Tok->FirstAfterPPLine)

681 return false;

682 }

683

684 return true;

685 }

686

687

688

689

692 Current.isNoneOf(tok::r_brace, tok::comment)) {

693 return true;

694 }

695

696 if (Current.is(tok::lessless) &&

697 ((Previous.is(tok::identifier) && Previous.TokenText == "endl") ||

698 (Previous.Tok.isLiteral() && (Previous.TokenText.ends_with("\\n\"") ||

699 Previous.TokenText == "\'\\n\'")))) {

700 return true;

701 }

702

704 return true;

705

706 if (State.NoContinuation)

707 return true;

708

709 return false;

710}

711

713 bool DryRun,

714 unsigned ExtraSpaces) {

715 const FormatToken &Current = *State.NextToken;

716 assert(State.NextToken->Previous);

718

719 assert(!State.Stack.empty());

720 State.NoContinuation = false;

721

722 if (Current.is(TT_ImplicitStringLiteral) &&

723 (Previous.Tok.getIdentifierInfo() ||

724 Previous.Tok.getIdentifierInfo()->getPPKeywordID() ==

725 tok::pp_not_keyword)) {

726 unsigned EndColumn =

729

730

731 State.Column = EndColumn;

732 } else {

733 unsigned StartColumn =

735 assert(EndColumn >= StartColumn);

736 State.Column += EndColumn - StartColumn;

737 }

738 moveStateToNextToken(State, DryRun, false);

739 return 0;

740 }

741

742 unsigned Penalty = 0;

743 if (Newline)

744 Penalty = addTokenOnNewLine(State, DryRun);

745 else

746 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);

747

748 return moveStateToNextToken(State, DryRun, Newline) + Penalty;

749}

750

751void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,

752 unsigned ExtraSpaces) {

754 assert(State.NextToken->Previous);

756 auto &CurrentState = State.Stack.back();

757

758

759

760

761

762

763 auto DisallowLineBreaks = [&] {

764 if (!Style.isCpp() ||

765 Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope) {

766 return false;

767 }

768

769

771 return false;

772

773 if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))

774 return false;

775

776 const auto *Prev = Current.getPreviousNonComment();

777 if (!Prev || Prev->isNot(tok::l_paren))

778 return false;

779

780 if (Prev->BlockParameterCount == 0)

781 return false;

782

783

784 if (Prev->BlockParameterCount > 1)

785 return true;

786

787

788 if (!Prev->Role)

789 return false;

790

791 const auto *Comma = Prev->Role->lastComma();

792 if (!Comma)

793 return false;

794

795 const auto *Next = Comma->getNextNonComment();

796 return Next && Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);

797 };

798

799 if (DisallowLineBreaks())

800 State.NoLineBreak = true;

801

802 if (Current.is(tok::equal) &&

803 (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&

804 CurrentState.VariablePos == 0 &&

806 Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) {

807 CurrentState.VariablePos = State.Column;

808

810 while (Tok && CurrentState.VariablePos >= Tok->ColumnWidth) {

811 CurrentState.VariablePos -= Tok->ColumnWidth;

812 if (Tok->SpacesRequiredBefore != 0)

813 break;

815 }

816 if (Previous.PartOfMultiVariableDeclStmt)

817 CurrentState.LastSpace = CurrentState.VariablePos;

818 }

819

821

822

823 int PPColumnCorrection = 0;

827 if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) {

829

830

831

832

833

834 if (Style.UseTab != FormatStyle::UT_Never)

835 PPColumnCorrection = -1;

836 } else if (Style.IndentPPDirectives == FormatStyle::PPDIS_Leave) {

838 }

839 }

840

841 if (!DryRun) {

842 const bool ContinuePPDirective =

844 Whitespaces.replaceWhitespace(Current, 0, Spaces,

845 State.Column + Spaces + PPColumnCorrection,

846 false, ContinuePPDirective);

847 }

848

849

850

851 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&

852 Current.is(TT_InheritanceColon)) {

853 CurrentState.NoLineBreak = true;

854 }

855 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterColon &&

856 Previous.is(TT_InheritanceColon)) {

857 CurrentState.NoLineBreak = true;

858 }

859

860 if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {

861 unsigned MinIndent =

862 std::max(State.FirstIndent + Style.ContinuationIndentWidth,

863 CurrentState.Indent.Total);

864 unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth;

866 CurrentState.AlignColons = false;

869 else

870 CurrentState.ColonPos = FirstColonPos;

871 }

872

873

874

875

876

877 auto IsOpeningBracket = [&](const FormatToken &Tok) {

878 auto IsStartOfBracedList = [&]() {

879 return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) &&

880 Style.Cpp11BracedListStyle != FormatStyle::BLS_Block;

881 };

882 if (IsStartOfBracedList())

883 return Style.BreakAfterOpenBracketBracedList;

884 if (Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square))

885 return false;

886 if (Tok.Previous)

887 return true;

888 if (Tok.Previous->isIf())

889 return Style.BreakAfterOpenBracketIf;

890 if (Tok.Previous->isLoop(Style))

891 return Style.BreakAfterOpenBracketLoop;

892 if (Tok.Previous->is(tok::kw_switch))

893 return Style.BreakAfterOpenBracketSwitch;

894 if (Style.BreakAfterOpenBracketFunction) {

895 return Tok.Previous->is(TT_CastRParen) &&

896 !(Style.isJavaScript() && Tok.is(Keywords.kw_await));

897 }

898 return false;

899 };

900 auto IsFunctionCallParen = [](const FormatToken &Tok) {

901 return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous &&

902 Tok.Previous->is(tok::identifier);

903 };

904 auto IsInTemplateString = [this](const FormatToken &Tok, bool NestBlocks) {

905 if (!Style.isJavaScript())

906 return false;

907 for (const auto *Prev = &Tok; Prev; Prev = Prev->Previous) {

908 if (Prev->is(TT_TemplateString) && Prev->opensScope())

909 return true;

910 if (Prev->opensScope() && !NestBlocks)

911 return false;

912 if (Prev->is(TT_TemplateString) && Prev->closesScope())

913 return false;

914 }

915 return false;

916 };

917

918 auto StartsSimpleOneArgList = [&](const FormatToken &TokAfterLParen) {

919 assert(TokAfterLParen.isNot(tok::comment) || TokAfterLParen.Next);

920 const auto &Tok =

921 TokAfterLParen.is(tok::comment) ? *TokAfterLParen.Next : TokAfterLParen;

923 return false;

924

925

926

927

928 if (Tok.is(tok::kw_new) || Tok.startsSequence(tok::coloncolon, tok::kw_new))

929 return true;

930 if (Tok.is(TT_UnaryOperator) ||

931 (Style.isJavaScript() &&

932 Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {

933 return true;

934 }

935 const auto *Previous = TokAfterLParen.Previous;

936 assert(Previous);

938 (Previous->Previous->isIf() || Previous->Previous->isLoop(Style) ||

939 Previous->Previous->is(tok::kw_switch))) {

940 return false;

941 }

942 if (Previous->isNoneOf(TT_FunctionDeclarationLParen,

943 TT_LambdaDefinitionLParen) &&

944 !IsFunctionCallParen(*Previous)) {

945 return true;

946 }

947 if (IsOpeningBracket(Tok) || IsInTemplateString(Tok, true))

948 return true;

949 const auto *Next = Tok.Next;

950 return Next || Next->isMemberAccess() ||

951 Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next);

952 };

953 if (IsOpeningBracket(Previous) &&

954 State.Column > getNewLineColumn(State).Total &&

955

956

957

958

959

960

961

962

963

964

965 !StartsSimpleOneArgList(Current)) {

966 CurrentState.NoLineBreak = true;

967 }

968

970 CurrentState.NoLineBreak = true;

971

972

973

974

975

976 if (Style.AlignAfterOpenBracket &&

977 !CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() &&

978 Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,

979 TT_TableGenDAGArgOpener,

980 TT_TableGenDAGArgOpenerToBreak) &&

982 (Current.isNot(TT_LineComment) ||

984 (Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall ||

986 Previous.Previous->isNoneOf(tok::identifier, tok::l_paren,

988 Previous.is(TT_VerilogMultiLineListLParen)) &&

989 !IsInTemplateString(Current, false)) {

990 CurrentState.Indent = State.Column + Spaces;

991 CurrentState.IsAligned = true;

992 }

994 CurrentState.NoLineBreak = true;

996 CurrentState.NoLineBreak = true;

997

999 State.Column > getNewLineColumn(State).Total) {

1000 CurrentState.ContainsUnwrappedBuilder = true;

1001 }

1002

1003 if (Current.is(TT_LambdaArrow) && Style.isJava())

1004 CurrentState.NoLineBreak = true;

1005 if (Current.isMemberAccess() && Previous.is(tok::r_paren) &&

1007 (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) {

1008

1009

1010

1011

1012

1013

1014 CurrentState.NoLineBreak = true;

1015 }

1016

1017

1018

1019

1020

1021 const FormatToken *P = Current.getPreviousNonComment();

1022 if (Current.isNot(tok::comment) && P &&

1023 (P->isOneOf(TT_BinaryOperator, tok::comma) ||

1024 (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&

1025 P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&

1029 bool BreakBeforeOperator =

1030 P->MustBreakBefore || P->is(tok::lessless) ||

1031 (P->is(TT_BinaryOperator) &&

1032 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||

1033 (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);

1034

1035

1036

1037 bool HasTwoOperands = P->OperatorIndex == 0 && !P->NextOperator &&

1038 P->isNot(TT_ConditionalExpr);

1039 if ((!BreakBeforeOperator &&

1040 !(HasTwoOperands &&

1041 Style.AlignOperands != FormatStyle::OAS_DontAlign)) ||

1042 (!CurrentState.LastOperatorWrapped && BreakBeforeOperator)) {

1043 CurrentState.NoLineBreakInOperand = true;

1044 }

1045 }

1046

1047 State.Column += Spaces;

1048 if (Current.isNot(tok::comment) && Previous.is(tok::l_paren) &&

1050 (Previous.Previous->is(tok::kw_for) || Previous.Previous->isIf())) {

1051

1052

1053 CurrentState.LastSpace = State.Column;

1054 CurrentState.NestedBlockIndent = State.Column;

1055 } else if (Current.isNoneOf(tok::comment, tok::caret) &&

1056 ((Previous.is(tok::comma) &&

1057 Previous.isNot(TT_OverloadedOperator)) ||

1058 (Previous.is(tok::colon) && Previous.is(TT_ObjCMethodExpr)))) {

1059 CurrentState.LastSpace = State.Column;

1060 } else if (Previous.is(TT_CtorInitializerColon) &&

1061 (!Current.isTrailingComment() || Current.NewlinesBefore > 0) &&

1062 Style.BreakConstructorInitializers ==

1063 FormatStyle::BCIS_AfterColon) {

1064 CurrentState.Indent = State.Column;

1065 CurrentState.LastSpace = State.Column;

1066 } else if (Previous.isOneOf(TT_ConditionalExpr, TT_CtorInitializerColon)) {

1067 CurrentState.LastSpace = State.Column;

1068 } else if (Previous.is(TT_BinaryOperator) &&

1070 (Previous.isNot(tok::lessless) || Previous.OperatorIndex != 0 ||

1073

1074

1075 if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None)

1076 CurrentState.LastSpace = State.Column;

1077 } else if (Previous.is(TT_InheritanceColon)) {

1078 CurrentState.Indent = State.Column;

1079 CurrentState.LastSpace = State.Column;

1080 } else if (Current.is(TT_CSharpGenericTypeConstraintColon)) {

1081 CurrentState.ColonPos = State.Column;

1082 } else if (Previous.opensScope()) {

1083

1084

1085

1086

1087

1088 if (Previous.MatchingParen) {

1090 if (Next && Next->isMemberAccess() && State.Stack.size() > 1 &&

1091 State.Stack[State.Stack.size() - 2].CallContinuation == 0) {

1092 CurrentState.LastSpace = State.Column;

1093 }

1094 }

1095 }

1096}

1097

1098unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,

1099 bool DryRun) {

1100 FormatToken &Current = *State.NextToken;

1101 assert(State.NextToken->Previous);

1103 auto &CurrentState = State.Stack.back();

1104

1105

1106

1107 unsigned Penalty = 0;

1108

1109 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();

1111 if (!NextNonComment)

1112 NextNonComment = &Current;

1113

1114

1115 if (!CurrentState.ContainsLineBreak)

1116 Penalty += 15;

1117 CurrentState.ContainsLineBreak = true;

1118

1119 Penalty += State.NextToken->SplitPenalty;

1120

1121

1122

1123

1124 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess == 0 &&

1125 (State.Column <= Style.ColumnLimit / 3 ||

1126 CurrentState.BreakBeforeParameter)) {

1127 Penalty += Style.PenaltyBreakFirstLessLess;

1128 }

1129

1130 const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);

1131 State.Column = TotalColumn;

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1145 if (State.Column > State.FirstIndent) {

1146 Penalty +=

1147 Style.PenaltyIndentedWhitespace * (State.Column - State.FirstIndent);

1148 }

1149

1150

1151

1152

1153

1154

1155

1156

1157

1158

1159

1160 if (Current.isNot(TT_LambdaArrow) &&

1161 (!Style.isJavaScript() || Current.NestingLevel != 0 ||

1162 !PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||

1163 Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {

1164 CurrentState.NestedBlockIndent = State.Column;

1165 }

1166

1167 if (NextNonComment->isMemberAccess()) {

1168 if (CurrentState.CallContinuation == 0)

1169 CurrentState.CallContinuation = State.Column;

1170 } else if (NextNonComment->is(TT_SelectorName)) {

1171 if (!CurrentState.ObjCSelectorNameFound) {

1172 if (NextNonComment->LongestObjCSelectorName == 0) {

1173 CurrentState.AlignColons = false;

1174 } else {

1175 CurrentState.ColonPos =

1177 ? std::max(CurrentState.Indent.Total,

1178 State.FirstIndent + Style.ContinuationIndentWidth)

1179 : CurrentState.Indent.Total) +

1182 }

1183 } else if (CurrentState.AlignColons &&

1184 CurrentState.ColonPos <= NextNonComment->ColumnWidth) {

1185 CurrentState.ColonPos = State.Column + NextNonComment->ColumnWidth;

1186 }

1187 } else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&

1188 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {

1189

1190

1191

1192

1193

1194

1195

1196

1197

1198 if (State.Stack.size() > 1) {

1199 State.Stack[State.Stack.size() - 2].LastSpace =

1200 std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +

1201 Style.ContinuationIndentWidth;

1202 }

1203 }

1204

1205 if ((PreviousNonComment &&

1206 PreviousNonComment->isOneOf(tok::comma, tok::semi) &&

1207 !CurrentState.AvoidBinPacking) ||

1208 Previous.is(TT_BinaryOperator)) {

1209 CurrentState.BreakBeforeParameter = false;

1210 }

1211 if (PreviousNonComment &&

1212 (PreviousNonComment->isOneOf(TT_TemplateCloser, TT_JavaAnnotation) ||

1213 PreviousNonComment->ClosesRequiresClause) &&

1214 Current.NestingLevel == 0) {

1215 CurrentState.BreakBeforeParameter = false;

1216 }

1217 if (NextNonComment->is(tok::question) ||

1218 (PreviousNonComment && PreviousNonComment->is(tok::question))) {

1219 CurrentState.BreakBeforeParameter = true;

1220 }

1221 if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)

1222 CurrentState.BreakBeforeParameter = false;

1223

1224 if (!DryRun) {

1226 if (Current.is(tok::r_brace) && Current.MatchingParen &&

1227

1228

1229 !Current.MatchingParen->Children.empty()) {

1230

1231

1232

1234 }

1237 const bool ContinuePPDirective = State.Line->InPPDirective &&

1239 Current.isNot(TT_LineComment);

1240 Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,

1241 CurrentState.IsAligned, ContinuePPDirective,

1242 IndentedFromColumn);

1243 }

1244

1245 if (!Current.isTrailingComment())

1246 CurrentState.LastSpace = State.Column;

1247 if (Current.is(tok::lessless)) {

1248

1249

1250

1251 CurrentState.LastSpace += 3;

1252 }

1253

1254 State.StartOfLineLevel = Current.NestingLevel;

1255 State.LowestLevelOnLine = Current.NestingLevel;

1256

1257

1258

1259 bool NestedBlockSpecialCase =

1260 (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&

1261 State.Stack[State.Stack.size() - 2].NestedBlockInlined) ||

1262 (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) &&

1263 State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam);

1264

1265 NestedBlockSpecialCase =

1266 NestedBlockSpecialCase ||

1267 (Current.MatchingParen &&

1268 Current.MatchingParen->is(TT_RequiresExpressionLBrace));

1269 if (!NestedBlockSpecialCase) {

1270 auto ParentLevelIt = std::next(State.Stack.rbegin());

1271 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&

1272 Current.MatchingParen && Current.MatchingParen->is(TT_LambdaLBrace)) {

1273

1274

1275

1276

1277

1278

1279

1280

1281

1282

1283

1284

1285

1286

1287 auto FindCurrentLevel = [&](const auto &It) {

1288 return std::find_if(It, State.Stack.rend(), [](const auto &PState) {

1289 return PState.Tok != nullptr;

1290 });

1291 };

1292 auto MaybeIncrement = [&](const auto &It) {

1293 return It != State.Stack.rend() ? std::next(It) : It;

1294 };

1295 auto LambdaLevelIt = FindCurrentLevel(State.Stack.rbegin());

1296 auto LevelContainingLambdaIt =

1297 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));

1298 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);

1299 }

1300 for (auto I = ParentLevelIt, E = State.Stack.rend(); I != E; ++I)

1301 I->BreakBeforeParameter = true;

1302 }

1303

1304 if (PreviousNonComment &&

1305 PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&

1306 ((PreviousNonComment->isNot(TT_TemplateCloser) &&

1307 !PreviousNonComment->ClosesRequiresClause) ||

1308 Current.NestingLevel != 0) &&

1309 PreviousNonComment->isNoneOf(

1310 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,

1311 TT_LeadingJavaAnnotation) &&

1312 Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&

1313

1314

1315 (!Style.BraceWrapping.BeforeLambdaBody ||

1316 Current.isNot(TT_LambdaLBrace))) {

1317 CurrentState.BreakBeforeParameter = true;

1318 }

1319

1320

1321

1322 if (PreviousNonComment &&

1323 (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||

1325 CurrentState.BreakBeforeClosingBrace = true;

1326 }

1327

1328 if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) {

1329 if (auto Previous = PreviousNonComment->Previous) {

1331 CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf;

1332 } else if (Previous->isLoop(Style)) {

1333 CurrentState.BreakBeforeClosingParen =

1334 Style.BreakBeforeCloseBracketLoop;

1335 } else if (Previous->is(tok::kw_switch)) {

1336 CurrentState.BreakBeforeClosingParen =

1337 Style.BreakBeforeCloseBracketSwitch;

1338 } else {

1339 CurrentState.BreakBeforeClosingParen =

1340 Style.BreakBeforeCloseBracketFunction;

1341 }

1342 }

1343 }

1344

1345 if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener))

1346 CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser;

1347

1348 if (CurrentState.AvoidBinPacking) {

1349

1350

1351

1352

1353 bool PreviousIsBreakingCtorInitializerColon =

1354 PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&

1355 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;

1356 bool AllowAllConstructorInitializersOnNextLine =

1357 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||

1358 Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;

1359 if ((Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&

1360 !PreviousIsBreakingCtorInitializerColon) ||

1361 (!Style.AllowAllParametersOfDeclarationOnNextLine &&

1362 State.Line->MustBeDeclaration) ||

1363 (!Style.AllowAllArgumentsOnNextLine &&

1364 !State.Line->MustBeDeclaration) ||

1365 (!AllowAllConstructorInitializersOnNextLine &&

1366 PreviousIsBreakingCtorInitializerColon) ||

1367 Previous.is(TT_DictLiteral)) {

1368 CurrentState.BreakBeforeParameter = true;

1369 }

1370

1371

1372

1373

1374 if (PreviousIsBreakingCtorInitializerColon &&

1375 AllowAllConstructorInitializersOnNextLine) {

1376 CurrentState.BreakBeforeParameter = false;

1377 }

1378 }

1379

1381 CurrentState.BreakBeforeParameter = true;

1382

1383 return Penalty;

1384}

1385

1387ContinuationIndenter::getNewLineColumn(const LineState &State) {

1388 if (!State.NextToken || !State.NextToken->Previous)

1389 return 0;

1390

1391 FormatToken &Current = *State.NextToken;

1392 const auto &CurrentState = State.Stack.back();

1393

1394 if (CurrentState.IsCSharpGenericTypeConstraint &&

1395 Current.isNot(TT_CSharpGenericTypeConstraint)) {

1396 return CurrentState.ColonPos + 2;

1397 }

1398

1400

1401 const auto ContinuationIndent =

1402 std::max(IndentationAndAlignment(CurrentState.LastSpace),

1403 CurrentState.Indent) +

1404 Style.ContinuationIndentWidth;

1405 const FormatToken *PreviousNonComment = Current.getPreviousNonComment();

1407 if (!NextNonComment)

1408 NextNonComment = &Current;

1409

1410

1411 if (Style.isJava() &&

1412 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {

1413 return std::max(IndentationAndAlignment(CurrentState.LastSpace),

1414 CurrentState.Indent + Style.ContinuationIndentWidth);

1415 }

1416

1417

1418

1419 if (Style.isVerilog() && PreviousNonComment &&

1420 Keywords.isVerilogEndOfLabel(*PreviousNonComment)) {

1421 return State.FirstIndent;

1422 }

1423

1424 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&

1425 State.Line->First->is(tok::kw_enum)) {

1426 return IndentationAndAlignment(Style.IndentWidth *

1427 State.Line->First->IndentLevel) +

1428 Style.IndentWidth;

1429 }

1430

1431 if (Style.BraceWrapping.BeforeLambdaBody &&

1432 Style.BraceWrapping.IndentBraces && Current.is(TT_LambdaLBrace)) {

1433 const auto From = Style.LambdaBodyIndentation == FormatStyle::LBI_Signature

1434 ? CurrentState.Indent

1435 : State.FirstIndent;

1436 return From + Style.IndentWidth;

1437 }

1438

1439 if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) ||

1440 (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {

1441 if (Current.NestingLevel == 0 ||

1442 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&

1443 State.NextToken->is(TT_LambdaLBrace))) {

1444 return State.FirstIndent;

1445 }

1446 return CurrentState.Indent;

1447 }

1448 if (Current.is(TT_LambdaArrow) &&

1449 Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,

1450 tok::kw_consteval, tok::kw_static,

1451 TT_AttributeRSquare)) {

1452 return ContinuationIndent;

1453 }

1454 if ((Current.isOneOf(tok::r_brace, tok::r_square) ||

1455 (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&

1456 State.Stack.size() > 1) {

1457 if (Current.closesBlockOrBlockTypeList(Style))

1458 return State.Stack[State.Stack.size() - 2].NestedBlockIndent;

1459 if (Current.MatchingParen && Current.MatchingParen->is(BK_BracedInit))

1460 return State.Stack[State.Stack.size() - 2].LastSpace;

1461 return State.FirstIndent;

1462 }

1463

1464

1465

1466

1467

1468

1469

1470

1471

1472

1473

1474

1475

1476

1477

1478 if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&

1479 (!Current.Next ||

1480 Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {

1481 return State.Stack[State.Stack.size() - 2].LastSpace;

1482 }

1483

1484

1485 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgCloser) &&

1486 State.Stack.size() > 1) {

1487 return State.Stack[State.Stack.size() - 2].LastSpace;

1488 }

1489 if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) &&

1490 Current.MatchingParen && Current.MatchingParen->is(BK_BracedInit) &&

1491 State.Stack.size() > 1) {

1492 return State.Stack[State.Stack.size() - 2].LastSpace;

1493 }

1494 if ((Style.BreakBeforeCloseBracketFunction ||

1495 Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop ||

1496 Style.BreakBeforeCloseBracketSwitch) &&

1497 Current.is(tok::r_paren) && State.Stack.size() > 1) {

1498 return State.Stack[State.Stack.size() - 2].LastSpace;

1499 }

1500 if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) &&

1501 State.Stack.size() > 1) {

1502 return State.Stack[State.Stack.size() - 2].LastSpace;

1503 }

1504 if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())

1505 return State.Stack[State.Stack.size() - 2].LastSpace;

1506

1507

1508

1509

1510

1511

1512

1513 if (Current.is(tok::identifier) && Current.Next &&

1514 (!Style.isVerilog() || Current.Next->is(tok::colon)) &&

1515 (Current.Next->is(TT_DictLiteral) ||

1516 (Style.isProto() && Current.Next->isOneOf(tok::less, tok::l_brace)))) {

1517 return CurrentState.Indent;

1518 }

1519 if (NextNonComment->is(TT_ObjCStringLiteral) &&

1520 State.StartOfStringLiteral != 0) {

1521 return State.StartOfStringLiteral - 1;

1522 }

1523 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)

1524 return State.StartOfStringLiteral;

1525 if (NextNonComment->is(tok::lessless) && CurrentState.FirstLessLess != 0)

1526 return CurrentState.FirstLessLess;

1527 if (NextNonComment->isMemberAccess()) {

1528 if (CurrentState.CallContinuation == 0)

1529 return ContinuationIndent;

1530 return CurrentState.CallContinuation;

1531 }

1532 if (CurrentState.QuestionColumn != 0 &&

1533 ((NextNonComment->is(tok::colon) &&

1534 NextNonComment->is(TT_ConditionalExpr)) ||

1535 Previous.is(TT_ConditionalExpr))) {

1536 if (((NextNonComment->is(tok::colon) && NextNonComment->Next &&

1537 !NextNonComment->Next->FakeLParens.empty() &&

1538 NextNonComment->Next->FakeLParens.back() == prec::Conditional) ||

1539 (Previous.is(tok::colon) && !Current.FakeLParens.empty() &&

1541 !CurrentState.IsWrappedConditional) {

1542

1543

1544

1545

1546 unsigned Indent = CurrentState.Indent.Total;

1547 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)

1548 Indent -= Style.ContinuationIndentWidth;

1549 if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)

1552 }

1553 return CurrentState.QuestionColumn;

1554 }

1555 if (Previous.is(tok::comma) && CurrentState.VariablePos != 0)

1556 return CurrentState.VariablePos;

1557 if (Current.is(TT_RequiresClause)) {

1558 if (Style.IndentRequiresClause)

1559 return CurrentState.Indent + Style.IndentWidth;

1560 switch (Style.RequiresClausePosition) {

1561 case FormatStyle::RCPS_OwnLine:

1562 case FormatStyle::RCPS_WithFollowing:

1563 case FormatStyle::RCPS_OwnLineWithBrace:

1564 return CurrentState.Indent;

1565 default:

1566 break;

1567 }

1568 }

1569 if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,

1570 TT_InheritanceComma)) {

1571 return State.FirstIndent + Style.ConstructorInitializerIndentWidth;

1572 }

1573 if ((PreviousNonComment &&

1574 (PreviousNonComment->ClosesTemplateDeclaration ||

1575 PreviousNonComment->ClosesRequiresClause ||

1576 (PreviousNonComment->is(TT_AttributeMacro) &&

1577 Current.isNot(tok::l_paren) &&

1578 !Current.endsSequence(TT_StartOfName, TT_AttributeMacro,

1579 TT_PointerOrReference)) ||

1580 PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,

1581 TT_FunctionAnnotationRParen,

1582 TT_JavaAnnotation,

1583 TT_LeadingJavaAnnotation))) ||

1584 (!Style.IndentWrappedFunctionNames &&

1585 NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {

1586 return std::max(IndentationAndAlignment(CurrentState.LastSpace),

1587 CurrentState.Indent);

1588 }

1589 if (NextNonComment->is(TT_SelectorName)) {

1590 if (!CurrentState.ObjCSelectorNameFound) {

1591 auto MinIndent = CurrentState.Indent;

1593 MinIndent =

1594 std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +

1595 Style.ContinuationIndentWidth);

1596 }

1597

1598

1599

1600

1601

1602

1603

1604

1605

1606 return MinIndent.addPadding(

1607 std::max(NextNonComment->LongestObjCSelectorName,

1608 NextNonComment->ColumnWidth) -

1609 NextNonComment->ColumnWidth);

1610 }

1611 if (!CurrentState.AlignColons)

1612 return CurrentState.Indent;

1613 if (CurrentState.ColonPos > NextNonComment->ColumnWidth)

1614 return CurrentState.ColonPos - NextNonComment->ColumnWidth;

1615 return CurrentState.Indent;

1616 }

1617 if (NextNonComment->is(tok::colon) && NextNonComment->is(TT_ObjCMethodExpr))

1618 return CurrentState.ColonPos;

1619 if (NextNonComment->is(TT_ArraySubscriptLSquare)) {

1620 if (CurrentState.StartOfArraySubscripts != 0) {

1621 return CurrentState.StartOfArraySubscripts;

1622 } else if (Style.isCSharp()) {

1623

1624 return CurrentState.Indent;

1625 }

1626 return ContinuationIndent;

1627 }

1628

1629

1630

1631 if (State.Line->InPragmaDirective) {

1632 FormatToken *PragmaType = State.Line->First->Next->Next;

1633 if (PragmaType && PragmaType->TokenText == "omp")

1634 return CurrentState.Indent + Style.ContinuationIndentWidth;

1635 }

1636

1637

1638

1639 if (NextNonComment->is(tok::identifier) && NextNonComment->FakeRParens == 0 &&

1640 NextNonComment->Next && NextNonComment->Next->is(TT_ObjCMethodExpr)) {

1641 return CurrentState.Indent;

1642 }

1643

1644 if (NextNonComment->isOneOf(TT_StartOfName, TT_PointerOrReference) ||

1645 Previous.isOneOf(tok::coloncolon, tok::equal, TT_JsTypeColon)) {

1646 return ContinuationIndent;

1647 }

1648 if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&

1649 PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)) {

1650 return ContinuationIndent;

1651 }

1652 if (NextNonComment->is(TT_CtorInitializerComma))

1653 return CurrentState.Indent;

1654 if (PreviousNonComment && PreviousNonComment->is(TT_CtorInitializerColon) &&

1655 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {

1656 return CurrentState.Indent;

1657 }

1658 if (PreviousNonComment && PreviousNonComment->is(TT_InheritanceColon) &&

1659 Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {

1660 return CurrentState.Indent;

1661 }

1662 if (Previous.is(tok::r_paren) &&

1663 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&

1664 !Current.isBinaryOperator() &&

1665 Current.isNoneOf(tok::colon, tok::comment)) {

1666 return ContinuationIndent;

1667 }

1668 if (Current.is(TT_ProtoExtensionLSquare))

1669 return CurrentState.Indent;

1670 if (Current.isBinaryOperator() && CurrentState.UnindentOperator) {

1671 return CurrentState.Indent - Current.Tok.getLength() -

1672 Current.SpacesRequiredBefore;

1673 }

1674 if (Current.is(tok::comment) && NextNonComment->isBinaryOperator() &&

1675 CurrentState.UnindentOperator) {

1676 return CurrentState.Indent - NextNonComment->Tok.getLength() -

1677 NextNonComment->SpacesRequiredBefore;

1678 }

1679 if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&

1680 PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {

1681

1682

1683 return CurrentState.Indent + Style.ContinuationIndentWidth;

1684 }

1685 return CurrentState.Indent;

1686}

1687

1690 const FormatStyle &Style) {

1691 if (Previous->isNot(tok::l_paren))

1692 return true;

1693 if (Previous->ParameterCount > 1)

1694 return true;

1695

1696

1697 return Style.BraceWrapping.BeforeLambdaBody && Current.is(TT_LambdaLSquare);

1698}

1699

1700unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,

1701 bool DryRun, bool Newline) {

1702 assert(State.Stack.size());

1703 const FormatToken &Current = *State.NextToken;

1704 auto &CurrentState = State.Stack.back();

1705

1706 if (Current.is(TT_CSharpGenericTypeConstraint))

1707 CurrentState.IsCSharpGenericTypeConstraint = true;

1708 if (Current.isOneOf(tok::comma, TT_BinaryOperator))

1709 CurrentState.NoLineBreakInOperand = false;

1710 if (Current.isOneOf(TT_InheritanceColon, TT_CSharpGenericTypeConstraintColon))

1711 CurrentState.AvoidBinPacking = true;

1712 if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {

1713 if (CurrentState.FirstLessLess == 0)

1714 CurrentState.FirstLessLess = State.Column;

1715 else

1716 CurrentState.LastOperatorWrapped = Newline;

1717 }

1718 if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))

1719 CurrentState.LastOperatorWrapped = Newline;

1720 if (Current.is(TT_ConditionalExpr) && Current.Previous &&

1721 Current.Previous->isNot(TT_ConditionalExpr)) {

1722 CurrentState.LastOperatorWrapped = Newline;

1723 }

1724 if (Current.is(TT_ArraySubscriptLSquare) &&

1725 CurrentState.StartOfArraySubscripts == 0) {

1726 CurrentState.StartOfArraySubscripts = State.Column;

1727 }

1728

1729 auto IsWrappedConditional = [](const FormatToken &Tok) {

1730 if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question)))

1731 return false;

1732 if (Tok.MustBreakBefore)

1733 return true;

1734

1736 return Next && Next->MustBreakBefore;

1737 };

1738 if (IsWrappedConditional(Current))

1739 CurrentState.IsWrappedConditional = true;

1740 if (Style.BreakBeforeTernaryOperators && Current.is(tok::question))

1741 CurrentState.QuestionColumn = State.Column;

1742 if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) {

1747 CurrentState.QuestionColumn = State.Column;

1748 }

1749 if (!Current.opensScope() && !Current.closesScope() &&

1750 Current.isNot(TT_PointerOrReference)) {

1751 State.LowestLevelOnLine =

1752 std::min(State.LowestLevelOnLine, Current.NestingLevel);

1753 }

1754 if (Current.isMemberAccess())

1755 CurrentState.StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column;

1756 if (Current.is(TT_SelectorName))

1757 CurrentState.ObjCSelectorNameFound = true;

1758 if (Current.is(TT_CtorInitializerColon) &&

1759 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) {

1760

1761

1762

1763

1764

1765 CurrentState.Indent = State.Column + (Style.BreakConstructorInitializers ==

1766 FormatStyle::BCIS_BeforeComma

1767 ? 0

1768 : 2);

1769 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;

1770 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {

1771 CurrentState.AvoidBinPacking = true;

1772 CurrentState.BreakBeforeParameter =

1773 Style.ColumnLimit > 0 &&

1774 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLine &&

1775 Style.PackConstructorInitializers != FormatStyle::PCIS_NextLineOnly;

1776 } else {

1777 CurrentState.BreakBeforeParameter = false;

1778 }

1779 }

1780 if (Current.is(TT_CtorInitializerColon) &&

1781 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {

1782 CurrentState.Indent =

1783 State.FirstIndent + Style.ConstructorInitializerIndentWidth;

1784 CurrentState.NestedBlockIndent = CurrentState.Indent.Total;

1785 if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)

1786 CurrentState.AvoidBinPacking = true;

1787 else

1788 CurrentState.BreakBeforeParameter = false;

1789 }

1790 if (Current.is(TT_InheritanceColon)) {

1791 CurrentState.Indent =

1792 State.FirstIndent + Style.ConstructorInitializerIndentWidth;

1793 }

1794 if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)

1795 CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;

1796 if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))

1797 CurrentState.LastSpace = State.Column;

1798 if (Current.is(TT_RequiresExpression) &&

1799 Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {

1800 CurrentState.NestedBlockIndent = State.Column;

1801 }

1802

1803

1805

1806

1807

1808

1809

1810

1811

1812 if (Current.isNot(tok::comment) && !Current.ClosesRequiresClause &&

1813 Previous && Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&

1814 Previous->isNot(TT_DictLiteral) && State.Stack.size() > 1 &&

1815 !CurrentState.HasMultipleNestedBlocks) {

1816 if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)

1817 for (ParenState &PState : llvm::drop_end(State.Stack))

1818 PState.NoLineBreak = true;

1819 State.Stack[State.Stack.size() - 2].NestedBlockInlined = false;

1820 }

1821 if (Previous && (Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||

1822 (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&

1823 Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,

1824 TT_CtorInitializerColon)))) {

1825 CurrentState.NestedBlockInlined =

1827 }

1828

1829 moveStatePastFakeLParens(State, Newline);

1830 moveStatePastScopeCloser(State);

1831

1832

1833 bool AllowBreak = !State.Stack.back().NoLineBreak &&

1834 !State.Stack.back().NoLineBreakInOperand;

1835 moveStatePastScopeOpener(State, Newline);

1836 moveStatePastFakeRParens(State);

1837

1838 if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)

1839 State.StartOfStringLiteral = State.Column + 1;

1840 if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {

1841 State.StartOfStringLiteral = State.Column + 1;

1842 } else if (Current.is(TT_TableGenMultiLineString) &&

1843 State.StartOfStringLiteral == 0) {

1844 State.StartOfStringLiteral = State.Column + 1;

1845 } else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {

1846 State.StartOfStringLiteral = State.Column;

1847 } else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&

1848 !Current.isStringLiteral()) {

1849 State.StartOfStringLiteral = 0;

1850 }

1851

1852 State.Column += Current.ColumnWidth;

1853 State.NextToken = State.NextToken->Next;

1854

1855

1856

1857

1858 if (Style.isVerilog() && State.NextToken &&

1859 State.NextToken->MustBreakBefore &&

1860 Keywords.isVerilogEndOfLabel(Current)) {

1861 State.FirstIndent += Style.IndentWidth;

1862 CurrentState.Indent = State.FirstIndent;

1863 }

1864

1865 unsigned Penalty =

1866 handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);

1867

1868 if (Current.Role)

1869 Current.Role->formatFromToken(State, this, DryRun);

1870

1871

1872

1873

1874

1876 Penalty += Previous->Role->formatAfterToken(State, this, DryRun);

1877

1878 return Penalty;

1879}

1880

1881void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,

1882 bool Newline) {

1883 const FormatToken &Current = *State.NextToken;

1884 if (Current.FakeLParens.empty())

1885 return;

1886

1888

1889

1890

1891

1892 bool SkipFirstExtraIndent =

1895 Previous->isOneOf(tok::semi, tok::kw_return, TT_RequiresClause) ||

1897 Style.AlignOperands != FormatStyle::OAS_DontAlign) ||

1898 Previous->is(TT_ObjCMethodExpr));

1899 for (const auto &PrecedenceLevel : llvm::reverse(Current.FakeLParens)) {

1900 const auto &CurrentState = State.Stack.back();

1901 ParenState NewParenState = CurrentState;

1902 NewParenState.Tok = nullptr;

1903 NewParenState.ContainsLineBreak = false;

1904 NewParenState.LastOperatorWrapped = true;

1905 NewParenState.IsChainedConditional = false;

1906 NewParenState.IsWrappedConditional = false;

1907 NewParenState.UnindentOperator = false;

1908 NewParenState.NoLineBreak =

1909 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;

1910

1911

1913 NewParenState.AvoidBinPacking = false;

1914

1915

1916

1917

1918 if (!Current.isTrailingComment() &&

1919 (Style.AlignOperands != FormatStyle::OAS_DontAlign ||

1922 (!Style.isJava() && PrecedenceLevel > 0)) &&

1923 (Style.AlignAfterOpenBracket || PrecedenceLevel > prec::Comma ||

1924 Current.NestingLevel == 0) &&

1925 (!Style.isTableGen() ||

1927 TT_TableGenDAGArgListCommaToBreak)))) {

1928 NewParenState.Indent =

1929 std::max({IndentationAndAlignment(State.Column), NewParenState.Indent,

1930 IndentationAndAlignment(CurrentState.LastSpace)});

1931 }

1932

1933

1934

1935

1936 if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic) &&

1937 State.Stack.size() > 1) {

1938 NewParenState.Indent = State.Stack[State.Stack.size() - 2].Indent +

1939 Style.ContinuationIndentWidth;

1940 }

1941

1945 Previous->is(tok::question) && Previous->is(TT_ConditionalExpr)))) &&

1946 !Newline) {

1947

1948

1949 if (Style.AlignOperands == FormatStyle::OAS_AlignAfterOperator)

1950 NewParenState.UnindentOperator = true;

1951

1952 if (Style.AlignOperands != FormatStyle::OAS_DontAlign)

1953 NewParenState.IsAligned = true;

1954 }

1955

1956

1957

1958

1959

1960

1961

1963 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);

1965 Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) {

1966 NewParenState.StartOfFunctionCall = State.Column;

1967 }

1968

1969

1970

1971

1972

1973

1975 Previous->is(tok::colon) && Previous->is(TT_ConditionalExpr) &&

1976 &PrecedenceLevel == &Current.FakeLParens.back() &&

1977 !CurrentState.IsWrappedConditional) {

1978 NewParenState.IsChainedConditional = true;

1979 NewParenState.UnindentOperator = State.Stack.back().UnindentOperator;

1981 (!SkipFirstExtraIndent && PrecedenceLevel > prec::Assignment &&

1982 !Current.isTrailingComment())) {

1983 NewParenState.Indent += Style.ContinuationIndentWidth;

1984 }

1986 NewParenState.BreakBeforeParameter = false;

1987 State.Stack.push_back(NewParenState);

1988 SkipFirstExtraIndent = false;

1989 }

1990}

1991

1992void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {

1993 for (unsigned i = 0, e = State.NextToken->FakeRParens; i != e; ++i) {

1994 unsigned VariablePos = State.Stack.back().VariablePos;

1995 if (State.Stack.size() == 1) {

1996

1997 break;

1998 }

1999 State.Stack.pop_back();

2000 State.Stack.back().VariablePos = VariablePos;

2001 }

2002

2003 if (State.NextToken->ClosesRequiresClause && Style.IndentRequiresClause) {

2004

2005

2006 State.Stack.back().LastSpace -= Style.IndentWidth;

2007 }

2008}

2009

2010void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,

2011 bool Newline) {

2012 const FormatToken &Current = *State.NextToken;

2013 if (!Current.opensScope())

2014 return;

2015

2016 const auto &CurrentState = State.Stack.back();

2017

2018

2019 if (Current.isOneOf(tok::less, tok::l_paren) &&

2020 CurrentState.IsCSharpGenericTypeConstraint) {

2021 return;

2022 }

2023

2024 if (Current.MatchingParen && Current.is(BK_Block)) {

2025 moveStateToNewBlock(State, Newline);

2026 return;

2027 }

2028

2029 const bool EndsInComma = [](const FormatToken *Tok) {

2030 if (Tok)

2031 return false;

2032 const auto *Prev = Tok->getPreviousNonComment();

2033 if (!Prev)

2034 return false;

2035 return Prev->is(tok::comma);

2036 }(Current.MatchingParen);

2037

2038 IndentationAndAlignment NewIndent = 0;

2039 unsigned LastSpace = CurrentState.LastSpace;

2040 bool AvoidBinPacking;

2041 bool BreakBeforeParameter = false;

2042 unsigned NestedBlockIndent = std::max(CurrentState.StartOfFunctionCall,

2043 CurrentState.NestedBlockIndent);

2044 if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||

2046 if (Current.opensBlockOrBlockTypeList(Style)) {

2047 NewIndent = Style.IndentWidth +

2048 std::min(State.Column, CurrentState.NestedBlockIndent);

2049 } else if (Current.is(tok::l_brace)) {

2050 const auto Width = Style.BracedInitializerIndentWidth;

2051 NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +

2052 (Width < 0 ? Style.ContinuationIndentWidth : Width);

2053 } else {

2054 NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;

2055 }

2056 const FormatToken *NextNonComment = Current.getNextNonComment();

2057 AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) ||

2058 Style.isProto() || !Style.BinPackArguments ||

2059 (NextNonComment && NextNonComment->isOneOf(

2060 TT_DesignatedInitializerPeriod,

2061 TT_DesignatedInitializerLSquare));

2062 BreakBeforeParameter = EndsInComma;

2063 if (Current.ParameterCount > 1)

2064 NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);

2065 } else {

2066 NewIndent = IndentationAndAlignment(std::max(

2067 CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +

2068 Style.ContinuationIndentWidth;

2069

2070 if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&

2071 Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {

2072

2073

2074

2075

2077 if (Next && Next->is(TT_TableGenDAGArgOperatorID))

2078 NewIndent = State.Column + Next->TokenText.size() + 2;

2079 }

2080

2081

2082

2083

2084

2085 if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {

2086 NewIndent = std::max(NewIndent, CurrentState.Indent);

2087 LastSpace = std::max(LastSpace, CurrentState.Indent.Total);

2088 }

2089

2090

2091

2093 (Style.ObjCBinPackProtocolList == FormatStyle::BPS_Auto &&

2094 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||

2095 Style.ObjCBinPackProtocolList == FormatStyle::BPS_Always;

2096

2097 bool BinPackDeclaration =

2099 Style.BinPackParameters == FormatStyle::BPPS_BinPack) ||

2101

2102 bool GenericSelection =

2103 Current.getPreviousNonComment() &&

2104 Current.getPreviousNonComment()->is(tok::kw__Generic);

2105

2106 AvoidBinPacking =

2107 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||

2108 (Style.isJavaScript() && EndsInComma) ||

2109 (State.Line->MustBeDeclaration && !BinPackDeclaration) ||

2110 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||

2111 (Style.ExperimentalAutoDetectBinPacking &&

2113 (!BinPackInconclusiveFunctions && Current.is(PPK_Inconclusive))));

2114

2115 if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen &&

2116 Style.ObjCBreakBeforeNestedBlockParam) {

2117 if (Style.ColumnLimit) {

2118

2119

2122 BreakBeforeParameter = true;

2123 }

2124 } else {

2125

2126

2128 Tok && Tok != Current.MatchingParen; Tok = Tok->Next) {

2129 if (Tok->MustBreakBefore ||

2130 (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) {

2131 BreakBeforeParameter = true;

2132 break;

2133 }

2134 }

2135 }

2136 }

2137

2138 if (Style.isJavaScript() && EndsInComma)

2139 BreakBeforeParameter = true;

2140 }

2141

2142

2143

2144 bool NoLineBreak =

2145 Current.Children.empty() &&

2146 Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&

2147 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||

2148 (Current.is(TT_TemplateOpener) &&

2149 CurrentState.ContainsUnwrappedBuilder));

2150 State.Stack.push_back(

2151 ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));

2152 auto &NewState = State.Stack.back();

2153 NewState.NestedBlockIndent = NestedBlockIndent;

2154 NewState.BreakBeforeParameter = BreakBeforeParameter;

2155 NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);

2156

2157 if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&

2158 Current.is(tok::l_paren)) {

2159

2161 while (next) {

2162 if (next->is(TT_LambdaLSquare)) {

2163 NewState.HasMultipleNestedBlocks = true;

2164 break;

2165 }

2166 next = next->Next;

2167 }

2168 }

2169

2170 NewState.IsInsideObjCArrayLiteral = Current.is(TT_ArrayInitializerLSquare) &&

2171 Current.Previous &&

2172 Current.Previous->is(tok::at);

2173}

2174

2175void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {

2176 const FormatToken &Current = *State.NextToken;

2177 if (!Current.closesScope())

2178 return;

2179

2180

2181

2182 if (State.Stack.size() > 1 &&

2183 (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||

2184 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||

2185 State.NextToken->is(TT_TemplateCloser) ||

2186 State.NextToken->is(TT_TableGenListCloser) ||

2187 (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {

2188 State.Stack.pop_back();

2189 }

2190

2191 auto &CurrentState = State.Stack.back();

2192

2193

2194

2195

2196

2197

2198

2199

2200

2201

2202

2203 if (CurrentState.BreakBeforeParameter && Current.MatchingParen &&

2204 Current.MatchingParen->Previous) {

2205 const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous;

2206 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&

2207 CurrentScopeOpener.MatchingParen) {

2208 int NecessarySpaceInLine =

2210 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;

2211 if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <=

2212 Style.ColumnLimit) {

2213 CurrentState.BreakBeforeParameter = false;

2214 }

2215 }

2216 }

2217

2218 if (Current.is(tok::r_square)) {

2219

2220 const FormatToken *NextNonComment = Current.getNextNonComment();

2221 if (NextNonComment && NextNonComment->isNot(tok::l_square))

2222 CurrentState.StartOfArraySubscripts = 0;

2223 }

2224}

2225

2226void ContinuationIndenter::moveStateToNewBlock(LineState &State, bool NewLine) {

2227 if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&

2228 State.NextToken->is(TT_LambdaLBrace) &&

2229 !State.Line->MightBeFunctionDecl) {

2230 const auto Indent = Style.IndentWidth * Style.BraceWrapping.IndentBraces;

2231 State.Stack.back().NestedBlockIndent = State.FirstIndent + Indent;

2232 }

2233 unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;

2234

2235 unsigned NewIndent =

2236 NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)

2237 ? Style.ObjCBlockIndentWidth

2238 : Style.IndentWidth);

2239

2240

2241

2242

2243

2244

2245 bool NoLineBreak = Style.BraceWrapping.BeforeLambdaBody && !NewLine &&

2246 State.NextToken->is(TT_LambdaLBrace);

2247

2248 State.Stack.push_back(ParenState(State.NextToken, NewIndent,

2249 State.Stack.back().LastSpace,

2250 true, NoLineBreak));

2251 State.Stack.back().NestedBlockIndent = NestedBlockIndent;

2252 State.Stack.back().BreakBeforeParameter = true;

2253}

2254

2258 size_t LastNewlinePos = Text.find_last_of("\n");

2259 if (LastNewlinePos == StringRef::npos) {

2260 return StartColumn +

2262 } else {

2264 0, TabWidth, Encoding);

2265 }

2266}

2267

2268unsigned ContinuationIndenter::reformatRawStringLiteral(

2269 const FormatToken &Current, LineState &State,

2270 const FormatStyle &RawStringStyle, bool DryRun, bool Newline) {

2271 unsigned StartColumn = State.Column - Current.ColumnWidth;

2273 StringRef NewDelimiter =

2275 if (NewDelimiter.empty())

2276 NewDelimiter = OldDelimiter;

2277

2278

2279 unsigned OldPrefixSize = 3 + OldDelimiter.size();

2280 unsigned OldSuffixSize = 2 + OldDelimiter.size();

2281

2282

2283 std::string RawText = std::string(

2284 Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize));

2285 if (NewDelimiter != OldDelimiter) {

2286

2287

2288 std::string CanonicalDelimiterSuffix = (")" + NewDelimiter + "\"").str();

2289 if (StringRef(RawText).contains(CanonicalDelimiterSuffix))

2290 NewDelimiter = OldDelimiter;

2291 }

2292

2293 unsigned NewPrefixSize = 3 + NewDelimiter.size();

2294 unsigned NewSuffixSize = 2 + NewDelimiter.size();

2295

2296

2297 unsigned FirstStartColumn = StartColumn + NewPrefixSize;

2298

2299

2300

2301

2302

2303

2304

2305

2306

2307

2308 bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] == '\n';

2309

2310

2311

2312

2313

2314

2315

2316

2317

2318

2319

2320

2321

2322

2323

2324

2325

2326

2327

2328

2329

2330 unsigned CurrentIndent =

2331 (!Newline && Current.Next && Current.Next->is(tok::r_paren))

2332 ? State.Stack.back().NestedBlockIndent

2333 : State.Stack.back().Indent.Total;

2334 unsigned NextStartColumn = ContentStartsOnNewline

2335 ? CurrentIndent + Style.IndentWidth

2336 : FirstStartColumn;

2337

2338

2339

2340

2341

2342

2343

2344

2345

2346 unsigned LastStartColumn =

2347 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;

2348

2349 std::pair<tooling::Replacements, unsigned> Fixes = internal::reformat(

2350 RawStringStyle, RawText, {tooling::Range(0, RawText.size())},

2351 FirstStartColumn, NextStartColumn, LastStartColumn, "",

2352 nullptr);

2353

2355 if (!NewCode)

2356 return addMultilineToken(Current, State);

2357 if (!DryRun) {

2358 if (NewDelimiter != OldDelimiter) {

2359

2360

2361 SourceLocation PrefixDelimiterStart =

2362 Current.Tok.getLocation().getLocWithOffset(2);

2363 auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(

2364 SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));

2365 if (PrefixErr) {

2366 llvm::errs()

2367 << "Failed to update the prefix delimiter of a raw string: "

2368 << llvm::toString(std::move(PrefixErr)) << "\n";

2369 }

2370

2371

2372 SourceLocation SuffixDelimiterStart =

2373 Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -

2374 1 - OldDelimiter.size());

2375 auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(

2376 SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));

2377 if (SuffixErr) {

2378 llvm::errs()

2379 << "Failed to update the suffix delimiter of a raw string: "

2380 << llvm::toString(std::move(SuffixErr)) << "\n";

2381 }

2382 }

2383 SourceLocation OriginLoc =

2384 Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);

2385 for (const tooling::Replacement &Fix : Fixes.first) {

2386 auto Err = Whitespaces.addReplacement(tooling::Replacement(

2387 SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),

2388 Fix.getLength(), Fix.getReplacementText()));

2389 if (Err) {

2390 llvm::errs() << "Failed to reformat raw string: "

2391 << llvm::toString(std::move(Err)) << "\n";

2392 }

2393 }

2394 }

2396 *NewCode, FirstStartColumn, Style.TabWidth, Encoding);

2397 State.Column = RawLastLineEndColumn + NewSuffixSize;

2398

2399

2400

2401 unsigned PrefixExcessCharacters =

2402 StartColumn + NewPrefixSize > Style.ColumnLimit

2403 ? StartColumn + NewPrefixSize - Style.ColumnLimit

2404 : 0;

2406 ContentStartsOnNewline || (NewCode->find('\n') != std:🧵:npos);

2408

2409 for (ParenState &Paren : State.Stack)

2410 Paren.BreakBeforeParameter = true;

2411 }

2412 return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;

2413}

2414

2415unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current,

2417

2418 for (ParenState &Paren : State.Stack)

2419 Paren.BreakBeforeParameter = true;

2420

2421 unsigned ColumnsUsed = State.Column;

2422

2423

2424 State.Column = Current.LastLineColumnWidth;

2425

2427 return Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit(State));

2428 return 0;

2429}

2430

2431unsigned ContinuationIndenter::handleEndOfLine(const FormatToken &Current,

2433 bool AllowBreak, bool Newline) {

2434 unsigned Penalty = 0;

2435

2436

2437 auto RawStringStyle = getRawStringStyle(Current, State);

2438 if (RawStringStyle && !Current.Finalized) {

2439 Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,

2440 Newline);

2441 } else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {

2442

2443

2444 Penalty = addMultilineToken(Current, State);

2446

2447 LineState OriginalState = State;

2448

2449

2450

2451 bool Strict = false;

2452

2453

2454 bool Exceeded = false;

2455 std::tie(Penalty, Exceeded) = breakProtrudingToken(

2456 Current, State, AllowBreak, true, Strict);

2457 if (Exceeded) {

2458

2459

2460 LineState StrictState = OriginalState;

2461 unsigned StrictPenalty =

2462 breakProtrudingToken(Current, StrictState, AllowBreak,

2463 true, true)

2464 .first;

2465 Strict = StrictPenalty <= Penalty;

2466 if (Strict) {

2467 Penalty = StrictPenalty;

2468 State = StrictState;

2469 }

2470 }

2471 if (!DryRun) {

2472

2473

2474 breakProtrudingToken(Current, OriginalState, AllowBreak, false,

2475 Strict);

2476 }

2477 }

2479 unsigned ExcessCharacters = State.Column - getColumnLimit(State);

2480 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;

2481 }

2482 return Penalty;

2483}

2484

2485

2486

2488

2489 auto Tok = Current.getPreviousNonComment();

2490 if (Tok || Tok->isNot(tok::l_paren))

2491 return "";

2492 Tok = Tok->getPreviousNonComment();

2493 if (Tok)

2494 return "";

2495 if (Tok->is(TT_TemplateCloser)) {

2496 Tok = Tok->MatchingParen;

2497 if (Tok)

2498 Tok = Tok->getPreviousNonComment();

2499 }

2500 if (Tok || Tok->isNot(tok::identifier))

2501 return "";

2502 return Tok->TokenText;

2503}

2504

2505std::optional

2506ContinuationIndenter::getRawStringStyle(const FormatToken &Current,

2507 const LineState &State) {

2508 if (!Current.isStringLiteral())

2509 return std::nullopt;

2511 if (!Delimiter)

2512 return std::nullopt;

2513 auto RawStringStyle = RawStringFormats.getDelimiterStyle(*Delimiter);

2514 if (!RawStringStyle && Delimiter->empty()) {

2515 RawStringStyle = RawStringFormats.getEnclosingFunctionStyle(

2517 }

2518 if (!RawStringStyle)

2519 return std::nullopt;

2520 RawStringStyle->ColumnLimit = getColumnLimit(State);

2521 return RawStringStyle;

2522}

2523

2524std::unique_ptr

2525ContinuationIndenter::createBreakableToken(const FormatToken &Current,

2526 LineState &State, bool AllowBreak) {

2527 unsigned StartColumn = State.Column - Current.ColumnWidth;

2528 if (Current.isStringLiteral()) {

2529

2530

2531 if (Style.isJson() || Style.isJavaScript() || !Style.BreakStringLiterals ||

2532 !AllowBreak) {

2533 return nullptr;

2534 }

2535

2536

2537

2538

2539

2540

2542 return nullptr;

2543

2544

2545 if (Current.IsUnterminatedLiteral)

2546 return nullptr;

2547

2548

2549 if (State.Stack.back().IsInsideObjCArrayLiteral)

2550 return nullptr;

2551

2552

2553

2554

2555

2556 if (Style.isVerilog() && Current.Previous &&

2557 Current.Previous->isOneOf(tok::kw_export, Keywords.kw_import)) {

2558 return nullptr;

2559 }

2560 StringRef Text = Current.TokenText;

2561

2562

2563

2564

2565

2567 ? 0

2569

2570 if (Style.isVerilog() || Style.isJava() || Style.isJavaScript() ||

2571 Style.isCSharp()) {

2573 if (Style.isJavaScript() && Text.starts_with("'") &&

2574 Text.ends_with("'")) {

2576 } else if (Style.isCSharp() && Text.starts_with("@\"") &&

2577 Text.ends_with("\"")) {

2579 } else if (Text.starts_with("\"") && Text.ends_with("\"")) {

2581 } else {

2582 return nullptr;

2583 }

2584 return std::make_unique(

2585 Current, QuoteStyle,

2588 }

2589

2590 StringRef Prefix;

2591 StringRef Postfix;

2592

2593

2594

2595

2596 if ((Text.ends_with(Postfix = "\"") &&

2597 (Text.starts_with(Prefix = "@\"") || Text.starts_with(Prefix = "\"") ||

2598 Text.starts_with(Prefix = "u\"") ||

2599 Text.starts_with(Prefix = "U\"") ||

2600 Text.starts_with(Prefix = "u8\"") ||

2601 Text.starts_with(Prefix = "L\""))) ||

2602 (Text.starts_with(Prefix = "_T(\"") &&

2603 Text.ends_with(Postfix = "\")"))) {

2604 return std::make_unique(

2606 State.Line->InPPDirective, Encoding, Style);

2607 }

2608 } else if (Current.is(TT_BlockComment)) {

2609 if (Style.ReflowComments == FormatStyle::RCS_Never ||

2610

2611

2612

2614 return nullptr;

2615 }

2616 return std::make_unique(

2617 Current, StartColumn, Current.OriginalColumn, !Current.Previous,

2618 State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());

2619 } else if (Current.is(TT_LineComment) &&

2620 (!Current.Previous ||

2621 Current.Previous->isNot(TT_ImplicitStringLiteral))) {

2622 bool RegularComments = [&]() {

2623 for (const FormatToken *T = &Current; T && T->is(TT_LineComment);

2624 T = T->Next) {

2625 if (!(T->TokenText.starts_with("//") || T->TokenText.starts_with("#")))

2626 return false;

2627 }

2628 return true;

2629 }();

2630 if (Style.ReflowComments == FormatStyle::RCS_Never ||

2631 CommentPragmasRegex.match(Current.TokenText.substr(2)) ||

2633 return nullptr;

2634 }

2635 return std::make_unique(

2636 Current, StartColumn, false, Encoding, Style);

2637 }

2638 return nullptr;

2639}

2640

2641std::pair<unsigned, bool>

2642ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,

2643 LineState &State, bool AllowBreak,

2644 bool DryRun, bool Strict) {

2645 std::unique_ptr Token =

2646 createBreakableToken(Current, State, AllowBreak);

2647 if (!Token)

2648 return {0, false};

2649 assert(Token->getLineCount() > 0);

2651 if (Current.is(TT_LineComment)) {

2652

2653 ColumnLimit = Style.ColumnLimit;

2654 }

2655 if (ColumnLimit == 0) {

2656

2657

2658 ColumnLimit = std::numeric_limits<decltype(ColumnLimit)>::max();

2659 }

2660 if (Current.UnbreakableTailLength >= ColumnLimit)

2661 return {0, false};

2662

2663

2664 unsigned StartColumn = State.Column - Current.ColumnWidth;

2665 unsigned NewBreakPenalty = Current.isStringLiteral()

2666 ? Style.PenaltyBreakString

2667 : Style.PenaltyBreakComment;

2668

2669

2670 bool Exceeded = false;

2671

2672 bool BreakInserted = Token->introducesBreakBeforeToken();

2673

2674

2675 bool NewBreakBefore = false;

2676

2677

2678

2679 bool Reflow = false;

2680

2681

2682 unsigned TailOffset = 0;

2683

2684 unsigned ContentStartColumn =

2685 Token->getContentStartColumn(0, false);

2686

2687 unsigned RemainingTokenColumns =

2688 Token->getRemainingLength(0, TailOffset, ContentStartColumn);

2689

2690 if (!DryRun)

2691 Token->adaptStartOfLine(0, Whitespaces);

2692

2693 unsigned ContentIndent = 0;

2694 unsigned Penalty = 0;

2695 LLVM_DEBUG(llvm::dbgs() << "Breaking protruding token at column "

2696 << StartColumn << ".\n");

2697 for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();

2698 LineIndex != EndIndex; ++LineIndex) {

2699 LLVM_DEBUG(llvm::dbgs()

2700 << " Line: " << LineIndex << " (Reflow: " << Reflow << ")\n");

2701 NewBreakBefore = false;

2702

2703

2704

2705 bool TryReflow = Reflow;

2706

2707 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {

2708 LLVM_DEBUG(llvm::dbgs() << " Over limit, need: "

2709 << (ContentStartColumn + RemainingTokenColumns)

2710 << ", space: " << ColumnLimit

2711 << ", reflown prefix: " << ContentStartColumn

2712 << ", offset in line: " << TailOffset << "\n");

2713

2714

2715

2716

2718 Token->getSplit(LineIndex, TailOffset, ColumnLimit,

2719 ContentStartColumn, CommentPragmasRegex);

2720 if (Split.first == StringRef::npos) {

2721

2722

2723 if (LineIndex < EndIndex - 1) {

2724

2725

2726 Penalty += Style.PenaltyExcessCharacter *

2727 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);

2728 }

2729 LLVM_DEBUG(llvm::dbgs() << " No break opportunity.\n");

2730 break;

2731 }

2732 assert(Split.first != 0);

2733

2734 if (Token->supportsReflow()) {

2735

2736

2737

2738

2739

2740

2741

2742

2743

2744

2745

2746

2747

2748

2749

2750

2751

2752

2753

2754 unsigned ToSplitColumns = Token->getRangeLength(

2755 LineIndex, TailOffset, Split.first, ContentStartColumn);

2756 LLVM_DEBUG(llvm::dbgs() << " ToSplit: " << ToSplitColumns << "\n");

2757

2759 LineIndex, TailOffset + Split.first + Split.second, ColumnLimit,

2760 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);

2761

2762

2763 unsigned ToNextSplitColumns = 0;

2764 if (NextSplit.first == StringRef::npos) {

2765 ToNextSplitColumns = Token->getRemainingLength(LineIndex, TailOffset,

2766 ContentStartColumn);

2767 } else {

2768 ToNextSplitColumns = Token->getRangeLength(

2769 LineIndex, TailOffset,

2770 Split.first + Split.second + NextSplit.first, ContentStartColumn);

2771 }

2772

2773

2774 ToNextSplitColumns =

2775 Token->getLengthAfterCompression(ToNextSplitColumns, Split);

2776 LLVM_DEBUG(llvm::dbgs()

2777 << " ContentStartColumn: " << ContentStartColumn << "\n");

2778 LLVM_DEBUG(llvm::dbgs()

2779 << " ToNextSplit: " << ToNextSplitColumns << "\n");

2780

2781

2782 bool ContinueOnLine =

2783 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;

2784 unsigned ExcessCharactersPenalty = 0;

2785 if (!ContinueOnLine && !Strict) {

2786

2787

2788 ExcessCharactersPenalty =

2789 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *

2790 Style.PenaltyExcessCharacter;

2791 LLVM_DEBUG(llvm::dbgs()

2792 << " Penalty excess: " << ExcessCharactersPenalty

2793 << "\n break : " << NewBreakPenalty << "\n");

2794 if (ExcessCharactersPenalty < NewBreakPenalty) {

2795 Exceeded = true;

2796 ContinueOnLine = true;

2797 }

2798 }

2799 if (ContinueOnLine) {

2800 LLVM_DEBUG(llvm::dbgs() << " Continuing on line...\n");

2801

2802

2803 TryReflow = true;

2804 if (!DryRun) {

2805 Token->compressWhitespace(LineIndex, TailOffset, Split,

2806 Whitespaces);

2807 }

2808

2809 ContentStartColumn += ToSplitColumns + 1;

2810 Penalty += ExcessCharactersPenalty;

2811 TailOffset += Split.first + Split.second;

2812 RemainingTokenColumns = Token->getRemainingLength(

2813 LineIndex, TailOffset, ContentStartColumn);

2814 continue;

2815 }

2816 }

2817 LLVM_DEBUG(llvm::dbgs() << " Breaking...\n");

2818

2819

2820

2821 if (!Reflow)

2822 ContentIndent = Token->getContentIndent(LineIndex);

2823 LLVM_DEBUG(llvm::dbgs()

2824 << " ContentIndent: " << ContentIndent << "\n");

2825 ContentStartColumn = ContentIndent + Token->getContentStartColumn(

2826 LineIndex, true);

2827

2828 unsigned NewRemainingTokenColumns = Token->getRemainingLength(

2829 LineIndex, TailOffset + Split.first + Split.second,

2830 ContentStartColumn);

2831 if (NewRemainingTokenColumns == 0) {

2832

2833 ContentIndent = 0;

2834 ContentStartColumn =

2835 Token->getContentStartColumn(LineIndex, true);

2836 NewRemainingTokenColumns = Token->getRemainingLength(

2837 LineIndex, TailOffset + Split.first + Split.second,

2838 ContentStartColumn);

2839 }

2840

2841

2842

2843

2844 if (NewRemainingTokenColumns >= RemainingTokenColumns) {

2845

2846 break;

2847 }

2848

2849 LLVM_DEBUG(llvm::dbgs() << " Breaking at: " << TailOffset + Split.first

2850 << ", " << Split.second << "\n");

2851 if (!DryRun) {

2852 Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,

2853 Whitespaces);

2854 }

2855

2856 Penalty += NewBreakPenalty;

2857 TailOffset += Split.first + Split.second;

2858 RemainingTokenColumns = NewRemainingTokenColumns;

2859 BreakInserted = true;

2860 NewBreakBefore = true;

2861 }

2862

2863

2864 if (LineIndex + 1 != EndIndex) {

2865 unsigned NextLineIndex = LineIndex + 1;

2866 if (NewBreakBefore) {

2867

2868

2869 TryReflow = true;

2870 }

2871 if (TryReflow) {

2872

2873

2874

2875

2876

2877

2878 Reflow = false;

2879

2880

2881

2882

2883

2884

2885 ContentStartColumn += RemainingTokenColumns + 1;

2886

2887

2888

2890 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);

2891 LLVM_DEBUG(llvm::dbgs()

2892 << " Size of reflown text: " << ContentStartColumn

2893 << "\n Potential reflow split: ");

2894 if (SplitBeforeNext.first != StringRef::npos) {

2895 LLVM_DEBUG(llvm::dbgs() << SplitBeforeNext.first << ", "

2896 << SplitBeforeNext.second << "\n");

2897 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;

2898

2899

2900 RemainingTokenColumns = Token->getRemainingLength(

2901 NextLineIndex, TailOffset, ContentStartColumn);

2902 Reflow = true;

2903 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {

2904 LLVM_DEBUG(llvm::dbgs()

2905 << " Over limit after reflow, need: "

2906 << (ContentStartColumn + RemainingTokenColumns)

2907 << ", space: " << ColumnLimit

2908 << ", reflown prefix: " << ContentStartColumn

2909 << ", offset in line: " << TailOffset << "\n");

2910

2911

2912

2913

2915 Token->getSplit(NextLineIndex, TailOffset, ColumnLimit,

2916 ContentStartColumn, CommentPragmasRegex);

2917 if (Split.first == StringRef::npos) {

2918 LLVM_DEBUG(llvm::dbgs() << " Did not find later break\n");

2919 Reflow = false;

2920 } else {

2921

2922

2923

2924 unsigned ToSplitColumns = Token->getRangeLength(

2925 NextLineIndex, TailOffset, Split.first, ContentStartColumn);

2926 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {

2927 LLVM_DEBUG(llvm::dbgs() << " Next split protrudes, need: "

2928 << (ContentStartColumn + ToSplitColumns)

2929 << ", space: " << ColumnLimit);

2930 unsigned ExcessCharactersPenalty =

2931 (ContentStartColumn + ToSplitColumns - ColumnLimit) *

2932 Style.PenaltyExcessCharacter;

2933 if (NewBreakPenalty < ExcessCharactersPenalty)

2934 Reflow = false;

2935 }

2936 }

2937 }

2938 } else {

2939 LLVM_DEBUG(llvm::dbgs() << "not found.\n");

2940 }

2941 }

2942 if (!Reflow) {

2943

2944

2945

2946 TailOffset = 0;

2947 ContentStartColumn =

2948 Token->getContentStartColumn(NextLineIndex, false);

2949 RemainingTokenColumns = Token->getRemainingLength(

2950 NextLineIndex, TailOffset, ContentStartColumn);

2951

2952 if (!DryRun)

2953 Token->adaptStartOfLine(NextLineIndex, Whitespaces);

2954 } else {

2955

2956

2957

2958

2959

2960

2961

2962

2963

2964

2965

2966

2967

2968 if (NewBreakBefore) {

2969 assert(Penalty >= NewBreakPenalty);

2970 Penalty -= NewBreakPenalty;

2971 }

2972 if (!DryRun)

2973 Token->reflow(NextLineIndex, Whitespaces);

2974 }

2975 }

2976 }

2977

2979 Token->getSplitAfterLastLine(TailOffset);

2980 if (SplitAfterLastLine.first != StringRef::npos) {

2981 LLVM_DEBUG(llvm::dbgs() << "Replacing whitespace after last line.\n");

2982

2983

2984

2985 Penalty += Style.PenaltyExcessCharacter *

2986 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);

2987

2988 if (!DryRun) {

2989 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,

2990 Whitespaces);

2991 }

2992 ContentStartColumn =

2993 Token->getContentStartColumn(Token->getLineCount() - 1, true);

2994 RemainingTokenColumns = Token->getRemainingLength(

2995 Token->getLineCount() - 1,

2996 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,

2997 ContentStartColumn);

2998 }

2999

3000 State.Column = ContentStartColumn + RemainingTokenColumns -

3001 Current.UnbreakableTailLength;

3002

3003 if (BreakInserted) {

3004 if (!DryRun)

3005 Token->updateAfterBroken(Whitespaces);

3006

3007

3008

3009

3010 if (Current.isNot(TT_LineComment))

3011 for (ParenState &Paren : State.Stack)

3012 Paren.BreakBeforeParameter = true;

3013

3014 if (Current.is(TT_BlockComment))

3015 State.NoContinuation = true;

3016

3017 State.Stack.back().LastSpace = StartColumn;

3018 }

3019

3020 Token->updateNextToken(State);

3021

3022 return {Penalty, Exceeded};

3023}

3024

3026

3027 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);

3028}

3029

3030bool ContinuationIndenter::nextIsMultilineString(const LineState &State) {

3031 const FormatToken &Current = *State.NextToken;

3032 if (!Current.isStringLiteral() || Current.is(TT_ImplicitStringLiteral))

3033 return false;

3034

3035

3036

3037 if (Current.TokenText.starts_with("R\""))

3038 return false;

3040 return true;

3041 if (Current.getNextNonComment() &&

3042 Current.getNextNonComment()->isStringLiteral()) {

3043 return true;

3044 }

3045 if (Style.ColumnLimit != 0 && Style.BreakStringLiterals &&

3047 Style.ColumnLimit) {

3048 return true;

3049 }

3050 return false;

3051}

3052

3053}

3054}

Declares BreakableToken, BreakableStringLiteral, BreakableComment, BreakableBlockComment and Breakabl...

This file implements an indenter that manages the indentation of continuations.

This file declares Format APIs to be used internally by the formatting library implementation.

This file contains the declaration of the FormatToken, a wrapper around Token with additional informa...

unsigned UnbreakableTailLength

The length of following tokens until the next natural split point, or the next token that can be brok...

unsigned ColumnWidth

The width of the non-whitespace parts of the token (or its first line for multi-line tokens) in colum...

int Newlines

The number of newlines immediately before the Token after formatting.

StringRef TokenText

The raw text of the token.

unsigned IsMultiline

Whether the token text contains newlines (escaped or not).

unsigned LongestObjCSelectorName

If this is the first ObjC selector name in an ObjC method definition or call, this contains the lengt...

FormatToken * Previous

The previous token in the unwrapped line.

FormatToken * Next

The next token in the unwrapped line.

Various functions to configurably format source code.

Defines and computes precedence levels for binary/ternary operators.

static bool contains(const std::set< tok::TokenKind > &Terminators, const Token &Tok)

Defines the SourceManager interface.

Defines the clang::TokenKind enum and support functions.

WhitespaceManager class manages whitespace around tokens and their replacements.

__DEVICE__ int max(int __a, int __b)

This class handles loading and caching of source files into memory.

SourceLocation getEnd() const

SourceLocation getBegin() const

Token - This structure provides full information about a lexed token.

bool is(tok::TokenKind K) const

is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....

std::pair< StringRef::size_type, unsigned > Split

Contains starting character index and length of split.

bool canBreak(const LineState &State)

Returns true, if a line break after State is allowed.

Definition ContinuationIndenter.cpp:337

unsigned addTokenToState(LineState &State, bool Newline, bool DryRun, unsigned ExtraSpaces=0)

Appends the next token to State and updates information necessary for indentation.

Definition ContinuationIndenter.cpp:712

unsigned getColumnLimit(const LineState &State) const

Get the column limit for this line.

Definition ContinuationIndenter.cpp:3025

LineState getInitialState(unsigned FirstIndent, unsigned FirstStartColumn, const AnnotatedLine *Line, bool DryRun)

Get the initial state, i.e.

Definition ContinuationIndenter.cpp:293

ContinuationIndenter(const FormatStyle &Style, const AdditionalKeywords &Keywords, const SourceManager &SourceMgr, WhitespaceManager &Whitespaces, encoding::Encoding Encoding, bool BinPackInconclusiveFunctions)

Constructs a ContinuationIndenter to format Line starting in column FirstIndent.

Definition ContinuationIndenter.cpp:282

bool mustBreak(const LineState &State)

Returns true, if a line break after State is mandatory.

Definition ContinuationIndenter.cpp:437

Manages the whitespaces around tokens and their replacements.

unsigned columnWidthWithTabs(StringRef Text, unsigned StartColumn, unsigned TabWidth, Encoding Encoding)

Returns the number of columns required to display the Text, starting from the StartColumn on a termin...

std::pair< tooling::Replacements, unsigned > reformat(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, unsigned FirstStartColumn, unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, FormattingAttemptStatus *Status)

Reformats the given Ranges in the code fragment Code.

static bool mustBreakBinaryOperation(const FormatToken &Current, const FormatStyle &Style)

Definition ContinuationIndenter.cpp:148

static unsigned getLastLineEndColumn(StringRef Text, unsigned StartColumn, unsigned TabWidth, encoding::Encoding Encoding)

Definition ContinuationIndenter.cpp:2255

static bool shouldUnindentNextOperator(const FormatToken &Tok)

Definition ContinuationIndenter.cpp:41

bool switchesFormatting(const FormatToken &Token)

Checks if Token switches formatting, like /* clang-format off *‍/.

static bool hasNestedBlockInlined(const FormatToken *Previous, const FormatToken &Current, const FormatStyle &Style)

Definition ContinuationIndenter.cpp:1688

static bool startsSegmentOfBuilderTypeCall(const FormatToken &Tok)

Definition ContinuationIndenter.cpp:127

static unsigned getLengthToNextOperator(const FormatToken &Tok)

Definition ContinuationIndenter.cpp:119

static bool isAlignableBinaryOperator(const FormatToken &Token)

Definition ContinuationIndenter.cpp:132

static unsigned getLengthToMatchingParen(const FormatToken &Tok, ArrayRef< ParenState > Stack)

Definition ContinuationIndenter.cpp:49

static bool shouldIndentWrappedSelectorName(const FormatStyle &Style, LineType LineType)

Definition ContinuationIndenter.cpp:34

bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style)

static std::optional< StringRef > getRawStringDelimiter(StringRef TokenText)

Definition ContinuationIndenter.cpp:170

static StringRef getCanonicalRawStringDelimiter(const FormatStyle &Style, FormatStyle::LanguageKind Language)

Definition ContinuationIndenter.cpp:196

FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language)

static bool startsNextOperand(const FormatToken &Current)

Definition ContinuationIndenter.cpp:141

static bool opensProtoMessageField(const FormatToken &LessTok, const FormatStyle &Style)

Definition ContinuationIndenter.cpp:157

static StringRef getEnclosingFunctionName(const FormatToken &Current)

Definition ContinuationIndenter.cpp:2487

@ LT_PreprocessorDirective

bool startsNextParameter(const FormatToken &Current, const FormatStyle &Style)

The JSON file list parser is used to communicate input to InstallAPI.

unsigned TabWidth

The number of columns used for tab stops.

std::vector< RawStringFormat > RawStringFormats

Defines hints for detecting supported languages code blocks in raw strings.

raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)

Language

The language for the input, used to select and validate the language standard and possible actions.

const FunctionProtoType * T

BinPackStyle ObjCBinPackProtocolList

Controls bin-packing Objective-C protocol conformance list items into as few lines as possible when t...

unsigned MaxEmptyLinesToKeep

The maximum number of consecutive empty lines to keep.

Encapsulates keywords that are context sensitive or for languages not properly supported by Clang's l...

See documentation of RawStringFormats.

std::vector< std::string > Delimiters

A list of raw string delimiters that match this language.

std::vector< std::string > EnclosingFunctions

A list of enclosing function names that match this language.

std::string BasedOnStyle

The style name on which this raw string format is based on. If not specified, the raw string format i...

LanguageKind Language

The language of this raw string.

A wrapper around a Token storing information about the whitespace characters preceding it.

unsigned NestingLevel

The nesting level of this token, i.e.

bool MacroParent

When macro expansion introduces nodes with children, those are marked as MacroParent.

unsigned StartsBinaryExpression

true if this token starts a binary expression, i.e.

unsigned OriginalColumn

The original 0-based column of this token, including expanded tabs.

unsigned CanBreakBefore

true if it is allowed to break before this token.

StringRef TokenText

The raw text of the token.

unsigned LongestObjCSelectorName

If this is the first ObjC selector name in an ObjC method definition or call, this contains the lengt...

unsigned LastNewlineOffset

The offset just past the last ' ' in this token's leading whitespace (relative to WhiteSpaceStart).

bool isNoneOf(Ts... Ks) const

FormatToken * Next

The next token in the unwrapped line.

unsigned IsMultiline

Whether the token text contains newlines (escaped or not).

unsigned NewlinesBefore

The number of newlines immediately before the Token.

unsigned SpacesRequiredBefore

The number of spaces that should be inserted before this token.

std::shared_ptr< TokenRole > Role

A token can have a special role that can carry extra information about the token's formatting.

unsigned MustBreakBefore

Whether there must be a line break before this token.

unsigned ColumnWidth

The width of the non-whitespace parts of the token (or its first line for multi-line tokens) in colum...

unsigned ObjCSelectorNameParts

If this is the first ObjC selector name in an ObjC method definition or call, this contains the numbe...

unsigned UnbreakableTailLength

The length of following tokens until the next natural split point, or the next token that can be brok...

bool is(tok::TokenKind Kind) const

unsigned TotalLength

The total length of the unwrapped line up to and including this token.

bool isOneOf(A K1, B K2) const

SourceRange WhitespaceRange

The range of the whitespace immediately preceding the Token.

FormatToken * MatchingParen

If this is a bracket, this points to the matching one.

FormatToken * Previous

The previous token in the unwrapped line.

Represents the spaces at the start of a line, keeping track of what the spaces are for.

IndentationAndAlignment operator+(unsigned Spaces) const

Adding indentation is more common than padding. So the operator does that.

Definition ContinuationIndenter.cpp:249

IndentationAndAlignment(unsigned Total, unsigned IndentedFrom)

Definition ContinuationIndenter.cpp:263

IndentationAndAlignment addPadding(unsigned Spaces) const

Add spaces for right-justifying the token.

Definition ContinuationIndenter.cpp:244

IndentationAndAlignment operator-(unsigned Spaces) const

Definition ContinuationIndenter.cpp:254

IndentationAndAlignment & operator+=(unsigned Spaces)

Definition ContinuationIndenter.cpp:258

bool operator<(const IndentationAndAlignment &Other) const

Definition ContinuationIndenter.cpp:270

unsigned IndentedFrom

The column that the position of the start of the line is calculated from.

The current state when indenting a unwrapped line.

const AnnotatedLine * Line

The line that is being formatted.

unsigned Column

The number of used columns in the current line.

SmallVector< ParenState > Stack

A stack keeping track of properties applying to parenthesis levels.

unsigned FirstIndent

The indent of the first token.

llvm::StringMap< FormatStyle > EnclosingFunctionStyle

std::optional< FormatStyle > getDelimiterStyle(StringRef Delimiter) const

Definition ContinuationIndenter.cpp:227

std::optional< FormatStyle > getEnclosingFunctionStyle(StringRef EnclosingFunction) const

Definition ContinuationIndenter.cpp:235

RawStringFormatStyleManager(const FormatStyle &CodeStyle)

Definition ContinuationIndenter.cpp:204

llvm::StringMap< FormatStyle > DelimiterStyle