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

37}

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

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) {

104 if (End->Next->CanBreakBefore)

105 break;

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

107 continue;

108 if (End->Next->MatchingParen &&

109 End->Next->MatchingParen->isOneOf(

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

111 const ParenState *State = FindParenState(End->Next->MatchingParen);

112 if (State && State->BreakBeforeClosingBrace)

113 break;

114 }

115 }

116 return End->TotalLength - Tok.TotalLength + 1;

117}

118

121 return 0;

123}

124

125

126

129}

130

131

133

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

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

138}

139

140

145}

146

147

154}

155

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

159 return false;

164}

165

166

167

168

170 if (TokenText.size() < 5

171 || !TokenText.starts_with("R\"") || !TokenText.ends_with("\"")) {

172 return std::nullopt;

173 }

174

175

176

177

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

179 if (LParenPos == StringRef::npos)

180 return std::nullopt;

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

182

183

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

185 if (TokenText[RParenPos] != ')')

186 return std::nullopt;

187 if (!TokenText.substr(RParenPos + 1).starts_with(Delimiter))

188 return std::nullopt;

189 return Delimiter;

190}

191

192

193

194static StringRef

198 if (Format.Language == Language)

199 return StringRef(Format.CanonicalDelimiter);

200 return "";

201}

202

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

206 std::optional LanguageStyle =

208 if (!LanguageStyle) {

211 RawStringFormat.Language, &PredefinedStyle)) {

213 PredefinedStyle.Language = RawStringFormat.Language;

214 }

215 LanguageStyle = PredefinedStyle;

216 }

218 for (StringRef Delimiter : RawStringFormat.Delimiters)

220 for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions)

222 }

223}

224

225std::optional

229 return std::nullopt;

230 return It->second;

231}

232

233std::optional

235 StringRef EnclosingFunction) const {

238 return std::nullopt;

239 return It->second;

240}

241

247 bool BinPackInconclusiveFunctions)

248 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr),

249 Whitespaces(Whitespaces), Encoding(Encoding),

250 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),

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

252

254 unsigned FirstStartColumn,

256 bool DryRun) {

258 State.FirstIndent = FirstIndent;

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

260 State.Column = FirstStartColumn;

261 else

262 State.Column = FirstIndent;

263

264

265

269 State.Column = 0;

270 }

271 State.Line = Line;

272 State.NextToken = Line->First;

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

274 false,

275 false));

276 State.NoContinuation = false;

277 State.StartOfStringLiteral = 0;

278 State.NoLineBreak = false;

279 State.StartOfLineLevel = 0;

280 State.LowestLevelOnLine = 0;

281 State.IgnoreStackForComparison = false;

282

284

285

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

287 CurrentState.AvoidBinPacking = true;

288 CurrentState.BreakBeforeParameter = true;

289 CurrentState.AlignColons = false;

290 }

291

292

293 moveStateToNextToken(State, DryRun, false);

294 return State;

295}

296

298 const FormatToken &Current = *State.NextToken;

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

301 assert(&Previous == Current.Previous);

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

303 Current.closesBlockOrBlockTypeList(Style))) {

304 return false;

305 }

306

307

308 if (!Current.MustBreakBefore && Previous.is(tok::l_brace) &&

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

312 return false;

313 }

314

315

316

317

318

320 State.LowestLevelOnLine < State.StartOfLineLevel &&

321 State.LowestLevelOnLine < Current.NestingLevel) {

322 return false;

323 }

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

325 return false;

326

327

328

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

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

331 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks &&

333 return false;

334 }

335

336

337

338 if (Current.is(TT_FunctionDeclarationName)) {

340 State.Column < 6) {

341 return false;

342 }

343

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

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

347 return false;

348 }

349 }

350

351

352

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

354 Current.isBlockIndentedInitRBrace(Style)) {

355 return CurrentState.BreakBeforeClosingBrace;

356 }

357

358

359

360 if (!Current.isOneOf(TT_BinaryOperator, tok::comma) &&

361

362

363

365 Current.isNot(TT_LambdaLBrace)) &&

366 CurrentState.NoLineBreakInOperand) {

367 return false;

368 }

369

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

371 return false;

372

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

374 Previous.MatchingParen && Previous.MatchingParen->Previous &&

375 Previous.MatchingParen->Previous->MatchingParen &&

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

377

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

379 return true;

380 }

381

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

383}

384

386 const FormatToken &Current = *State.NextToken;

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

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

393 }

394 if (Current.MustBreakBefore ||

395 (Current.is(TT_InlineASMColon) &&

399 return true;

400 }

401 if (CurrentState.BreakBeforeClosingBrace &&

402 (Current.closesBlockOrBlockTypeList(Style) ||

403 (Current.is(tok::r_brace) &&

404 Current.isBlockIndentedInitRBrace(Style)))) {

405 return true;

406 }

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

408 return true;

411 Current.ObjCSelectorNameParts > 1 &&

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

413 return true;

414 }

415

416

417 if (CurrentState.IsCSharpGenericTypeConstraint &&

418 Previous.isNot(TT_CSharpGenericTypeConstraintComma)) {

419 return false;

420 }

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

423 State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() &&

424

425

426

427

428 (Previous.NestingLevel == 1 ||

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

433 Previous.is(TT_ConditionalExpr))) &&

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

435 !Current.isOneOf(tok::r_paren, tok::r_brace)) {

436 return true;

437 }

438 if (CurrentState.IsChainedConditional &&

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

443 return true;

444 }

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

446 (Previous.is(TT_ArrayInitializerLSquare) &&

447 Previous.ParameterCount > 1) ||

452 return true;

453 }

454

455 const FormatToken &BreakConstructorInitializersToken =

458 : Current;

459 if (BreakConstructorInitializersToken.is(TT_CtorInitializerColon) &&

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

462 CurrentState.BreakBeforeParameter) &&

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

465 Style.ColumnLimit > 0 || Current.NewlinesBefore > 0)) {

466 return true;

467 }

468

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

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

471 return true;

472 }

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

474 CurrentState.ObjCSelectorNameFound && CurrentState.BreakBeforeParameter &&

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

477 return true;

478 }

479

480 unsigned NewLineColumn = getNewLineColumn(State);

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

483 (State.Column > NewLineColumn ||

484 Current.NestingLevel < State.StartOfLineLevel)) {

485 return true;

486 }

487

489 (CurrentState.CallContinuation != 0 ||

490 CurrentState.BreakBeforeParameter) &&

491

492

493

494

495

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

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

498 return true;

499 }

500

501

502

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

504 Current.CanBreakBefore) {

505 return true;

506 }

507

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

509 return false;

510

513 Previous.is(tok::comma) || Current.NestingLevel < 2) &&

514 Previous.isOneOf(tok::kw_return, tok::lessless, tok::at,

516 Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&

517 nextIsMultilineString(State)) {

518 return true;

519 }

520

521

522

523

524 if (Previous.is(TT_BinaryOperator) && Current.CanBreakBefore) {

525 const auto PreviousPrecedence = Previous.getPrecedence();

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

528 const bool LHSIsBinaryExpr =

529 Previous.Previous && Previous.Previous->EndsBinaryExpression;

530 if (LHSIsBinaryExpr)

531 return true;

532

533

534

535

536

537

538

539

540

541 const bool IsComparison =

546 Previous.Previous->isNot(TT_BinaryOperator);

547 if (!IsComparison)

548 return true;

549 }

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

551 CurrentState.BreakBeforeParameter) {

552 return true;

553 }

554

555

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

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

558 return true;

559 }

560

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

562

563

564

565

566 if (Previous.ClosesTemplateDeclaration) {

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

570 break;

572 return true;

574 return false;

575 }

576 }

577 if (Current.is(TT_RequiresClause)) {

581 return false;

582 default:

583 return true;

584 }

585 }

588 Current.NewlinesBefore > 0);

589 }

590 if (Previous.is(TT_FunctionAnnotationRParen) &&

592 return true;

593 }

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

595 Current.isNot(TT_LeadingJavaAnnotation)) {

596 return true;

597 }

598 }

599

601 Previous.is(TT_JavaAnnotation)) {

602

603

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

605 "function"};

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

607 return true;

608 }

609

610 if (Current.is(TT_FunctionDeclarationName) &&

611 !State.Line->ReturnTypeWrapped &&

612

615

616

618 CurrentState.BreakBeforeParameter) {

619 return true;

620 }

621

622

623

624

627 !Current.isOneOf(tok::r_brace, tok::comment)) {

628 return true;

629 }

630

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

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

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

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

635 return true;

636 }

637

639 return true;

640

641 if (State.NoContinuation)

642 return true;

643

644 return false;

645}

646

648 bool DryRun,

649 unsigned ExtraSpaces) {

650 const FormatToken &Current = *State.NextToken;

651 assert(State.NextToken->Previous);

653

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

655 State.NoContinuation = false;

656

657 if (Current.is(TT_ImplicitStringLiteral) &&

658 (Previous.Tok.getIdentifierInfo() ||

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

660 tok::pp_not_keyword)) {

661 unsigned EndColumn =

663 if (Current.LastNewlineOffset != 0) {

664

665

666 State.Column = EndColumn;

667 } else {

668 unsigned StartColumn =

670 assert(EndColumn >= StartColumn);

671 State.Column += EndColumn - StartColumn;

672 }

673 moveStateToNextToken(State, DryRun, false);

674 return 0;

675 }

676

677 unsigned Penalty = 0;

678 if (Newline)

679 Penalty = addTokenOnNewLine(State, DryRun);

680 else

681 addTokenOnCurrentLine(State, DryRun, ExtraSpaces);

682

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

684}

685

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

687 unsigned ExtraSpaces) {

689 assert(State.NextToken->Previous);

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

692

693 bool DisallowLineBreaksOnThisLine =

695

696

697

698

699

700 Style.isCpp() && [&] {

701

702 if (Previous.is(TT_BlockComment) && Current.SpacesRequiredBefore == 0)

703 return false;

704 const auto *PrevNonComment = Current.getPreviousNonComment();

705 if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren))

706 return false;

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

708 return false;

709 auto BlockParameterCount = PrevNonComment->BlockParameterCount;

710 if (BlockParameterCount == 0)

711 return false;

712

713

714 if (BlockParameterCount > 1)

715 return true;

716

717

718 if (!PrevNonComment->Role)

719 return false;

720 auto Comma = PrevNonComment->Role->lastComma();

721 if (!Comma)

722 return false;

723 auto Next = Comma->getNextNonComment();

724 return Next &&

725 !Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);

726 }();

727

728 if (DisallowLineBreaksOnThisLine)

729 State.NoLineBreak = true;

730

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

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

733 CurrentState.VariablePos == 0 &&

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

736 CurrentState.VariablePos = State.Column;

737

738 const FormatToken *Tok = &Previous;

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

740 CurrentState.VariablePos -= Tok->ColumnWidth;

741 if (Tok->SpacesRequiredBefore != 0)

742 break;

743 Tok = Tok->Previous;

744 }

745 if (Previous.PartOfMultiVariableDeclStmt)

746 CurrentState.LastSpace = CurrentState.VariablePos;

747 }

748

749 unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;

750

751

752 int PPColumnCorrection = 0;

754 Previous.is(tok::hash) && State.FirstIndent > 0 &&

755 &Previous == State.Line->First &&

758 Spaces += State.FirstIndent;

759

760

761

762

763

765 PPColumnCorrection = -1;

766 }

767

768 if (!DryRun) {

770 State.Column + Spaces + PPColumnCorrection,

771 false, State.Line->InMacroBody);

772 }

773

774

775

777 Current.is(TT_InheritanceColon)) {

778 CurrentState.NoLineBreak = true;

779 }

781 Previous.is(TT_InheritanceColon)) {

782 CurrentState.NoLineBreak = true;

783 }

784

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

786 unsigned MinIndent = std::max(

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

789 if (Current.LongestObjCSelectorName == 0)

790 CurrentState.AlignColons = false;

791 else if (MinIndent + Current.LongestObjCSelectorName > FirstColonPos)

792 CurrentState.ColonPos = MinIndent + Current.LongestObjCSelectorName;

793 else

794 CurrentState.ColonPos = FirstColonPos;

795 }

796

797

798

799

800

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

802 auto IsStartOfBracedList = [&]() {

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

805 };

806 if (!Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&

807 !IsStartOfBracedList()) {

808 return false;

809 }

810 if (!Tok.Previous)

811 return true;

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

814 return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,

815 tok::kw_switch) &&

817 };

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

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

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

821 };

822 auto IsInTemplateString = [this](const FormatToken &Tok) {

824 return false;

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

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

827 return true;

828 if (Prev->opensScope() ||

829 (Prev->is(TT_TemplateString) && Prev->closesScope())) {

830 break;

831 }

832 }

833 return false;

834 };

835

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

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

838 const auto &Tok =

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

840 if (!Tok.FakeLParens.empty() && Tok.FakeLParens.back() > prec::Unknown)

841 return false;

842

843

844

845

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

847 return true;

848 if (Tok.is(TT_UnaryOperator) ||

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

851 return true;

852 }

853 const auto *Previous = Tok.Previous;

854 if (Previous || (Previous->isOneOf(TT_FunctionDeclarationLParen,

855 TT_LambdaDefinitionLParen) &&

856 !IsFunctionCallParen(*Previous))) {

857 return true;

858 }

859 if (IsOpeningBracket(Tok) || IsInTemplateString(Tok))

860 return true;

861 const auto *Next = Tok.Next;

862 return !Next || Next->isMemberAccess() ||

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

864 };

867 IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) &&

868

869

870

871

872

873

874

875

876

877

878 !StartsSimpleOneArgList(Current)) {

879 CurrentState.NoLineBreak = true;

880 }

881

883 CurrentState.NoLineBreak = true;

884

885

886

887

888

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

891 Previous.isNot(TT_ObjCMethodExpr) && Previous.isNot(TT_RequiresClause) &&

892 Previous.isNot(TT_TableGenDAGArgOpener) &&

893 Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&

894 !(Current.MacroParent && Previous.MacroParent) &&

895 (Current.isNot(TT_LineComment) ||

897 !IsInTemplateString(Current)) {

898 CurrentState.Indent = State.Column + Spaces;

899 CurrentState.IsAligned = true;

900 }

902 CurrentState.NoLineBreak = true;

904 CurrentState.NoLineBreak = true;

905

907 State.Column > getNewLineColumn(State)) {

908 CurrentState.ContainsUnwrappedBuilder = true;

909 }

910

912 CurrentState.NoLineBreak = true;

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

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

916

917

918

919

920

921

922 CurrentState.NoLineBreak = true;

923 }

924

925

926

927

928

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

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

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

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

933 P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&

937 bool BreakBeforeOperator =

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

939 (P->is(TT_BinaryOperator) &&

942

943

944

945 bool HasTwoOperands = P->OperatorIndex == 0 && P->NextOperator &&

946 P->isNot(TT_ConditionalExpr);

947 if ((!BreakBeforeOperator &&

948 !(HasTwoOperands &&

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

951 CurrentState.NoLineBreakInOperand = true;

952 }

953 }

954

955 State.Column += Spaces;

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

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

959

960

961 CurrentState.LastSpace = State.Column;

962 CurrentState.NestedBlockIndent = State.Column;

963 } else if (!Current.isOneOf(tok::comment, tok::caret) &&

965 Previous.isNot(TT_OverloadedOperator)) ||

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

967 CurrentState.LastSpace = State.Column;

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

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

972 CurrentState.Indent = State.Column;

973 CurrentState.LastSpace = State.Column;

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

975 CurrentState.LastSpace = State.Column;

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

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

980 Current.StartsBinaryExpression)) {

981

982

984 CurrentState.LastSpace = State.Column;

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

986 CurrentState.Indent = State.Column;

987 CurrentState.LastSpace = State.Column;

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

989 CurrentState.ColonPos = State.Column;

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

991

992

993

994

995

996 if (Previous.MatchingParen) {

997 const FormatToken *Next = Previous.MatchingParen->getNextNonComment();

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

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

1000 CurrentState.LastSpace = State.Column;

1001 }

1002 }

1003 }

1004}

1005

1006unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,

1007 bool DryRun) {

1008 FormatToken &Current = *State.NextToken;

1009 assert(State.NextToken->Previous);

1010 const FormatToken &Previous = *State.NextToken->Previous;

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

1012

1013

1014

1015 unsigned Penalty = 0;

1016

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

1018 const FormatToken *NextNonComment = Previous.getNextNonComment();

1019 if (!NextNonComment)

1020 NextNonComment = &Current;

1021

1022

1023 if (!CurrentState.ContainsLineBreak)

1024 Penalty += 15;

1025 CurrentState.ContainsLineBreak = true;

1026

1027 Penalty += State.NextToken->SplitPenalty;

1028

1029

1030

1031

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

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

1034 CurrentState.BreakBeforeParameter)) {

1036 }

1037

1038 State.Column = getNewLineColumn(State);

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1050

1051

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

1053 Penalty +=

1055 }

1056

1057

1058

1059

1060

1061

1062

1063

1064

1065

1066

1067 if (Current.isNot(TT_LambdaArrow) &&

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

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

1071 CurrentState.NestedBlockIndent = State.Column;

1072 }

1073

1074 if (NextNonComment->isMemberAccess()) {

1075 if (CurrentState.CallContinuation == 0)

1076 CurrentState.CallContinuation = State.Column;

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

1078 if (!CurrentState.ObjCSelectorNameFound) {

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

1080 CurrentState.AlignColons = false;

1081 } else {

1082 CurrentState.ColonPos =

1084 ? std::max(CurrentState.Indent,

1086 : CurrentState.Indent) +

1088 NextNonComment->ColumnWidth);

1089 }

1090 } else if (CurrentState.AlignColons &&

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

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

1093 }

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

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

1096

1097

1098

1099

1100

1101

1102

1103

1104

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

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

1107 std::max(CurrentState.LastSpace, CurrentState.Indent) +

1109 }

1110 }

1111

1112 if ((PreviousNonComment &&

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

1114 !CurrentState.AvoidBinPacking) ||

1115 Previous.is(TT_BinaryOperator)) {

1116 CurrentState.BreakBeforeParameter = false;

1117 }

1118 if (PreviousNonComment &&

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

1120 PreviousNonComment->ClosesRequiresClause) &&

1121 Current.NestingLevel == 0) {

1122 CurrentState.BreakBeforeParameter = false;

1123 }

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

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

1126 CurrentState.BreakBeforeParameter = true;

1127 }

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

1129 CurrentState.BreakBeforeParameter = false;

1130

1131 if (!DryRun) {

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

1134

1135

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

1137

1138

1139

1140 MaxEmptyLinesToKeep = 1;

1141 }

1142 unsigned Newlines =

1143 std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));

1144 bool ContinuePPDirective =

1145 State.Line->InPPDirective && State.Line->Type != LT_ImportStatement;

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

1147 CurrentState.IsAligned, ContinuePPDirective);

1148 }

1149

1150 if (!Current.isTrailingComment())

1151 CurrentState.LastSpace = State.Column;

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

1153

1154

1155

1156 CurrentState.LastSpace += 3;

1157 }

1158

1159 State.StartOfLineLevel = Current.NestingLevel;

1160 State.LowestLevelOnLine = Current.NestingLevel;

1161

1162

1163

1164 bool NestedBlockSpecialCase =

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

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

1169

1170 NestedBlockSpecialCase =

1171 NestedBlockSpecialCase ||

1172 (Current.MatchingParen &&

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

1174 if (!NestedBlockSpecialCase) {

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

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

1178

1179

1180

1181

1182

1183

1184

1185

1186

1187

1188

1189

1190

1191

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

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

1194 return PState.Tok != nullptr;

1195 });

1196 };

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

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

1199 };

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

1201 auto LevelContainingLambdaIt =

1202 FindCurrentLevel(MaybeIncrement(LambdaLevelIt));

1203 ParentLevelIt = MaybeIncrement(LevelContainingLambdaIt);

1204 }

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

1206 I->BreakBeforeParameter = true;

1207 }

1208

1209 if (PreviousNonComment &&

1210 !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&

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

1212 !PreviousNonComment->ClosesRequiresClause) ||

1213 Current.NestingLevel != 0) &&

1214 !PreviousNonComment->isOneOf(

1215 TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,

1216 TT_LeadingJavaAnnotation) &&

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

1218

1219

1221 Current.isNot(TT_LambdaLBrace))) {

1222 CurrentState.BreakBeforeParameter = true;

1223 }

1224

1225

1226

1227 if (PreviousNonComment &&

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

1230 CurrentState.BreakBeforeClosingBrace = true;

1231 }

1232

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

1234 CurrentState.BreakBeforeClosingParen =

1236 }

1237

1238 if (CurrentState.AvoidBinPacking) {

1239

1240

1241

1242

1243 bool PreviousIsBreakingCtorInitializerColon =

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

1246 bool AllowAllConstructorInitializersOnNextLine =

1249 if (!(Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||

1250 PreviousIsBreakingCtorInitializerColon) ||

1252 State.Line->MustBeDeclaration) ||

1254 !State.Line->MustBeDeclaration) ||

1255 (!AllowAllConstructorInitializersOnNextLine &&

1256 PreviousIsBreakingCtorInitializerColon) ||

1257 Previous.is(TT_DictLiteral)) {

1258 CurrentState.BreakBeforeParameter = true;

1259 }

1260

1261

1262

1263

1264 if (PreviousIsBreakingCtorInitializerColon &&

1265 AllowAllConstructorInitializersOnNextLine) {

1266 CurrentState.BreakBeforeParameter = false;

1267 }

1268 }

1269

1271 CurrentState.BreakBeforeParameter = true;

1272

1273 return Penalty;

1274}

1275

1276unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {

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

1278 return 0;

1279

1280 FormatToken &Current = *State.NextToken;

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

1282

1283 if (CurrentState.IsCSharpGenericTypeConstraint &&

1284 Current.isNot(TT_CSharpGenericTypeConstraint)) {

1285 return CurrentState.ColonPos + 2;

1286 }

1287

1288 const FormatToken &Previous = *Current.Previous;

1289

1290 unsigned ContinuationIndent =

1291 std::max(CurrentState.LastSpace, CurrentState.Indent) +

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

1294 const FormatToken *NextNonComment = Previous.getNextNonComment();

1295 if (!NextNonComment)

1296 NextNonComment = &Current;

1297

1298

1301 return std::max(CurrentState.LastSpace,

1303 }

1304

1305

1306

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

1309 return State.FirstIndent;

1310 }

1311

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

1314 return (Style.IndentWidth * State.Line->First->IndentLevel) +

1316 }

1317

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

1320 if (Current.NestingLevel == 0 ||

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

1323 return State.FirstIndent;

1324 }

1325 return CurrentState.Indent;

1326 }

1327 if (Current.is(TT_LambdaArrow) &&

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

1329 tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {

1330 return ContinuationIndent;

1331 }

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

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

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

1335 if (Current.closesBlockOrBlockTypeList(Style))

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

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

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

1339 return State.FirstIndent;

1340 }

1341

1342

1343

1344

1345

1346

1347

1348

1349

1350

1351

1352

1353

1354

1355

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

1357 (!Current.Next ||

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

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

1360 }

1361

1362

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

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

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

1366 }

1368 (Current.is(tok::r_paren) ||

1369 (Current.is(tok::r_brace) && Current.MatchingParen &&

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

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

1373 }

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

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

1376

1377

1378

1379

1380

1381

1382

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

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

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

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

1387 return CurrentState.Indent;

1388 }

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

1390 State.StartOfStringLiteral != 0) {

1391 return State.StartOfStringLiteral - 1;

1392 }

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

1394 return State.StartOfStringLiteral;

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

1396 return CurrentState.FirstLessLess;

1397 if (NextNonComment->isMemberAccess()) {

1398 if (CurrentState.CallContinuation == 0)

1399 return ContinuationIndent;

1400 return CurrentState.CallContinuation;

1401 }

1402 if (CurrentState.QuestionColumn != 0 &&

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

1404 NextNonComment->is(TT_ConditionalExpr)) ||

1405 Previous.is(TT_ConditionalExpr))) {

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

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

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

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

1411 !CurrentState.IsWrappedConditional) {

1412

1413

1414

1415

1416 unsigned Indent = CurrentState.Indent;

1420 Indent -= 2;

1421 return Indent;

1422 }

1423 return CurrentState.QuestionColumn;

1424 }

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

1426 return CurrentState.VariablePos;

1427 if (Current.is(TT_RequiresClause)) {

1429 return CurrentState.Indent + Style.IndentWidth;

1434 return CurrentState.Indent;

1435 default:

1436 break;

1437 }

1438 }

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

1440 TT_InheritanceComma)) {

1442 }

1443 if ((PreviousNonComment &&

1444 (PreviousNonComment->ClosesTemplateDeclaration ||

1445 PreviousNonComment->ClosesRequiresClause ||

1446 (PreviousNonComment->is(TT_AttributeMacro) &&

1447 Current.isNot(tok::l_paren)) ||

1448 PreviousNonComment->isOneOf(

1449 TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,

1450 TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||

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

1453 return std::max(CurrentState.LastSpace, CurrentState.Indent);

1454 }

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

1456 if (!CurrentState.ObjCSelectorNameFound) {

1457 unsigned MinIndent = CurrentState.Indent;

1459 MinIndent = std::max(MinIndent,

1461 }

1462

1463

1464

1465

1466

1467

1468

1469

1470

1471 return MinIndent +

1472 std::max(NextNonComment->LongestObjCSelectorName,

1473 NextNonComment->ColumnWidth) -

1474 NextNonComment->ColumnWidth;

1475 }

1476 if (!CurrentState.AlignColons)

1477 return CurrentState.Indent;

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

1479 return CurrentState.ColonPos - NextNonComment->ColumnWidth;

1480 return CurrentState.Indent;

1481 }

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

1483 return CurrentState.ColonPos;

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

1485 if (CurrentState.StartOfArraySubscripts != 0) {

1486 return CurrentState.StartOfArraySubscripts;

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

1488

1489 return CurrentState.Indent;

1490 }

1491 return ContinuationIndent;

1492 }

1493

1494

1495

1496 if (State.Line->InPragmaDirective) {

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

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

1500 }

1501

1502

1503

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

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

1506 return CurrentState.Indent;

1507 }

1508

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

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

1511 return ContinuationIndent;

1512 }

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

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

1515 return ContinuationIndent;

1516 }

1517 if (NextNonComment->is(TT_CtorInitializerComma))

1518 return CurrentState.Indent;

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

1521 return CurrentState.Indent;

1522 }

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

1525 return CurrentState.Indent;

1526 }

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

1528 Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&

1529 !Current.isBinaryOperator() &&

1530 !Current.isOneOf(tok::colon, tok::comment)) {

1531 return ContinuationIndent;

1532 }

1533 if (Current.is(TT_ProtoExtensionLSquare))

1534 return CurrentState.Indent;

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

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

1537 Current.SpacesRequiredBefore;

1538 }

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

1540 CurrentState.UnindentOperator) {

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

1542 NextNonComment->SpacesRequiredBefore;

1543 }

1544 if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&

1545 !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {

1546

1547

1549 }

1550 return CurrentState.Indent;

1551}

1552

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

1557 return true;

1558 if (Previous->ParameterCount > 1)

1559 return true;

1560

1561

1563}

1564

1565unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,

1566 bool DryRun, bool Newline) {

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

1568 const FormatToken &Current = *State.NextToken;

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

1570

1571 if (Current.is(TT_CSharpGenericTypeConstraint))

1572 CurrentState.IsCSharpGenericTypeConstraint = true;

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

1574 CurrentState.NoLineBreakInOperand = false;

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

1576 CurrentState.AvoidBinPacking = true;

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

1578 if (CurrentState.FirstLessLess == 0)

1579 CurrentState.FirstLessLess = State.Column;

1580 else

1581 CurrentState.LastOperatorWrapped = Newline;

1582 }

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

1584 CurrentState.LastOperatorWrapped = Newline;

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

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

1587 CurrentState.LastOperatorWrapped = Newline;

1588 }

1589 if (Current.is(TT_ArraySubscriptLSquare) &&

1590 CurrentState.StartOfArraySubscripts == 0) {

1591 CurrentState.StartOfArraySubscripts = State.Column;

1592 }

1593

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

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

1596 return false;

1597 if (Tok.MustBreakBefore)

1598 return true;

1599

1600 const FormatToken *Next = Tok.getNextNonComment();

1601 return Next && Next->MustBreakBefore;

1602 };

1603 if (IsWrappedConditional(Current))

1604 CurrentState.IsWrappedConditional = true;

1606 CurrentState.QuestionColumn = State.Column;

1608 const FormatToken *Previous = Current.Previous;

1612 CurrentState.QuestionColumn = State.Column;

1613 }

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

1615 Current.isNot(TT_PointerOrReference)) {

1616 State.LowestLevelOnLine =

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

1618 }

1619 if (Current.isMemberAccess())

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

1621 if (Current.is(TT_SelectorName))

1622 CurrentState.ObjCSelectorNameFound = true;

1623 if (Current.is(TT_CtorInitializerColon) &&

1625

1626

1627

1628

1629

1632 ? 0

1633 : 2);

1634 CurrentState.NestedBlockIndent = CurrentState.Indent;

1636 CurrentState.AvoidBinPacking = true;

1637 CurrentState.BreakBeforeParameter =

1641 } else {

1642 CurrentState.BreakBeforeParameter = false;

1643 }

1644 }

1645 if (Current.is(TT_CtorInitializerColon) &&

1647 CurrentState.Indent =

1649 CurrentState.NestedBlockIndent = CurrentState.Indent;

1651 CurrentState.AvoidBinPacking = true;

1652 else

1653 CurrentState.BreakBeforeParameter = false;

1654 }

1655 if (Current.is(TT_InheritanceColon)) {

1656 CurrentState.Indent =

1658 }

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

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

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

1662 CurrentState.LastSpace = State.Column;

1663 if (Current.is(TT_RequiresExpression) &&

1665 CurrentState.NestedBlockIndent = State.Column;

1666 }

1667

1668

1669 const FormatToken *Previous = Current.getPreviousNonComment();

1670

1671

1672

1673

1674

1675

1676

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

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

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

1680 !CurrentState.HasMultipleNestedBlocks) {

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

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

1683 PState.NoLineBreak = true;

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

1685 }

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

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

1688 Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))) {

1689 CurrentState.NestedBlockInlined =

1691 }

1692

1693 moveStatePastFakeLParens(State, Newline);

1694 moveStatePastScopeCloser(State);

1695

1696

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

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

1699 moveStatePastScopeOpener(State, Newline);

1700 moveStatePastFakeRParens(State);

1701

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

1703 State.StartOfStringLiteral = State.Column + 1;

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

1705 State.StartOfStringLiteral = State.Column + 1;

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

1707 State.StartOfStringLiteral == 0) {

1708 State.StartOfStringLiteral = State.Column + 1;

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

1710 State.StartOfStringLiteral = State.Column;

1711 } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&

1712 !Current.isStringLiteral()) {

1713 State.StartOfStringLiteral = 0;

1714 }

1715

1716 State.Column += Current.ColumnWidth;

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

1718

1719

1720

1721

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

1723 State.NextToken->MustBreakBefore &&

1726 CurrentState.Indent = State.FirstIndent;

1727 }

1728

1729 unsigned Penalty =

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

1731

1732 if (Current.Role)

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

1734

1735

1736

1737

1738

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

1741

1742 return Penalty;

1743}

1744

1745void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,

1746 bool Newline) {

1747 const FormatToken &Current = *State.NextToken;

1748 if (Current.FakeLParens.empty())

1749 return;

1750

1751 const FormatToken *Previous = Current.getPreviousNonComment();

1752

1753

1754

1755

1756 bool SkipFirstExtraIndent =

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

1762 Previous->is(TT_ObjCMethodExpr));

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

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

1765 ParenState NewParenState = CurrentState;

1766 NewParenState.Tok = nullptr;

1767 NewParenState.ContainsLineBreak = false;

1768 NewParenState.LastOperatorWrapped = true;

1769 NewParenState.IsChainedConditional = false;

1770 NewParenState.IsWrappedConditional = false;

1771 NewParenState.UnindentOperator = false;

1772 NewParenState.NoLineBreak =

1773 NewParenState.NoLineBreak || CurrentState.NoLineBreakInOperand;

1774

1775

1777 NewParenState.AvoidBinPacking = false;

1778

1779

1780

1781

1782 if (!Current.isTrailingComment() &&

1788 PrecedenceLevel > prec::Comma || Current.NestingLevel == 0) &&

1791 TT_TableGenDAGArgListCommaToBreak)))) {

1792 NewParenState.Indent = std::max(

1793 std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);

1794 }

1795

1796

1797

1798

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

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

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

1803 }

1804

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

1809 !Newline) {

1810

1811

1813 NewParenState.UnindentOperator = true;

1814

1816 NewParenState.IsAligned = true;

1817 }

1818

1819

1820

1821

1822

1823

1824

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

1828 Current.isNot(TT_UnaryOperator) &&

1830 NewParenState.StartOfFunctionCall = State.Column;

1831 }

1832

1833

1834

1835

1836

1837

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

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

1841 !CurrentState.IsWrappedConditional) {

1842 NewParenState.IsChainedConditional = true;

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

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

1846 !Current.isTrailingComment())) {

1848 }

1850 NewParenState.BreakBeforeParameter = false;

1851 State.Stack.push_back(NewParenState);

1852 SkipFirstExtraIndent = false;

1853 }

1854}

1855

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

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

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

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

1860

1861 break;

1862 }

1863 State.Stack.pop_back();

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

1865 }

1866

1868

1869

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

1871 }

1872}

1873

1874void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,

1875 bool Newline) {

1876 const FormatToken &Current = *State.NextToken;

1877 if (!Current.opensScope())

1878 return;

1879

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

1881

1882

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

1884 CurrentState.IsCSharpGenericTypeConstraint) {

1885 return;

1886 }

1887

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

1889 moveStateToNewBlock(State, Newline);

1890 return;

1891 }

1892

1893 unsigned NewIndent;

1894 unsigned LastSpace = CurrentState.LastSpace;

1895 bool AvoidBinPacking;

1896 bool BreakBeforeParameter = false;

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

1898 CurrentState.NestedBlockIndent);

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

1901 if (Current.opensBlockOrBlockTypeList(Style)) {

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

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

1905 NewIndent =

1908 } else {

1910 }

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

1912 bool EndsInComma = Current.MatchingParen &&

1913 Current.MatchingParen->Previous &&

1914 Current.MatchingParen->Previous->is(tok::comma);

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

1917 (NextNonComment && NextNonComment->isOneOf(

1918 TT_DesignatedInitializerPeriod,

1919 TT_DesignatedInitializerLSquare));

1920 BreakBeforeParameter = EndsInComma;

1921 if (Current.ParameterCount > 1)

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

1923 } else {

1924 NewIndent =

1926 std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);

1927

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

1930

1931

1932

1933

1934 const FormatToken *Next = Current.Next;

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

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

1937 }

1938

1939

1940

1941

1942

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

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

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

1946 }

1947

1948 bool EndsInComma =

1949 Current.MatchingParen &&

1950 Current.MatchingParen->getPreviousNonComment() &&

1951 Current.MatchingParen->getPreviousNonComment()->is(tok::comma);

1952

1953

1954

1955 bool ObjCBinPackProtocolList =

1959

1960 bool BinPackDeclaration =

1963 (State.Line->Type == LT_ObjCDecl && ObjCBinPackProtocolList);

1964

1965 bool GenericSelection =

1966 Current.getPreviousNonComment() &&

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

1968

1969 AvoidBinPacking =

1970 (CurrentState.IsCSharpGenericTypeConstraint) || GenericSelection ||

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

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

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

1977

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

1981

1982

1985 BreakBeforeParameter = true;

1986 }

1987 } else {

1988

1989

1990 for (const FormatToken *Tok = &Current;

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

1992 if (Tok->MustBreakBefore ||

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

1994 BreakBeforeParameter = true;

1995 break;

1996 }

1997 }

1998 }

1999 }

2000

2002 BreakBeforeParameter = true;

2003 }

2004

2005

2006

2007 bool NoLineBreak =

2008 Current.Children.empty() &&

2009 !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&

2010 (CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||

2011 (Current.is(TT_TemplateOpener) &&

2012 CurrentState.ContainsUnwrappedBuilder));

2013 State.Stack.push_back(

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

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

2016 NewState.NestedBlockIndent = NestedBlockIndent;

2017 NewState.BreakBeforeParameter = BreakBeforeParameter;

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

2019

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

2022

2023 FormatToken const *next = Current.Next;

2024 while (next) {

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

2026 NewState.HasMultipleNestedBlocks = true;

2027 break;

2028 }

2029 next = next->Next;

2030 }

2031 }

2032

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

2034 Current.Previous &&

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

2036}

2037

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

2039 const FormatToken &Current = *State.NextToken;

2040 if (!Current.closesScope())

2041 return;

2042

2043

2044

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

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

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

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

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

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

2051 State.Stack.pop_back();

2052 }

2053

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

2055

2056

2057

2058

2059

2060

2061

2062

2063

2064

2065

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

2067 Current.MatchingParen->Previous) {

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

2069 if (CurrentScopeOpener.is(TT_ObjCMethodExpr) &&

2070 CurrentScopeOpener.MatchingParen) {

2071 int NecessarySpaceInLine =

2073 CurrentScopeOpener.TotalLength - Current.TotalLength - 1;

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

2076 CurrentState.BreakBeforeParameter = false;

2077 }

2078 }

2079 }

2080

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

2082

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

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

2085 CurrentState.StartOfArraySubscripts = 0;

2086 }

2087}

2088

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

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

2092 !State.Line->MightBeFunctionDecl) {

2093 State.Stack.back().NestedBlockIndent = State.FirstIndent;

2094 }

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

2096

2097 unsigned NewIndent =

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

2101

2102

2103

2104

2105

2106

2108 State.NextToken->is(TT_LambdaLBrace);

2109

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

2111 State.Stack.back().LastSpace,

2112 true, NoLineBreak));

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

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

2115}

2116

2118 unsigned TabWidth,

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

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

2122 return StartColumn +

2124 } else {

2126 0, TabWidth, Encoding);

2127 }

2128}

2129

2130unsigned ContinuationIndenter::reformatRawStringLiteral(

2131 const FormatToken &Current, LineState &State,

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

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

2135 StringRef NewDelimiter =

2137 if (NewDelimiter.empty())

2138 NewDelimiter = OldDelimiter;

2139

2140

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

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

2143

2144

2145 std::string RawText = std::string(

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

2147 if (NewDelimiter != OldDelimiter) {

2148

2149

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

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

2152 NewDelimiter = OldDelimiter;

2153 }

2154

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

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

2157

2158

2159 unsigned FirstStartColumn = StartColumn + NewPrefixSize;

2160

2161

2162

2163

2164

2165

2166

2167

2168

2169

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

2171

2172

2173

2174

2175

2176

2177

2178

2179

2180

2181

2182

2183

2184

2185

2186

2187

2188

2189

2190

2191

2192 unsigned CurrentIndent =

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

2194 ? State.Stack.back().NestedBlockIndent

2195 : State.Stack.back().Indent;

2196 unsigned NextStartColumn = ContentStartsOnNewline

2198 : FirstStartColumn;

2199

2200

2201

2202

2203

2204

2205

2206

2207

2208 unsigned LastStartColumn =

2209 Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;

2210

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

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

2213 FirstStartColumn, NextStartColumn, LastStartColumn, "",

2214 nullptr);

2215

2217 tooling::Replacements NoFixes;

2218 if (!NewCode)

2219 return addMultilineToken(Current, State);

2220 if (!DryRun) {

2221 if (NewDelimiter != OldDelimiter) {

2222

2223

2224 SourceLocation PrefixDelimiterStart =

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

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

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

2228 if (PrefixErr) {

2229 llvm::errs()

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

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

2232 }

2233

2234

2235 SourceLocation SuffixDelimiterStart =

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

2237 1 - OldDelimiter.size());

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

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

2240 if (SuffixErr) {

2241 llvm::errs()

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

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

2244 }

2245 }

2246 SourceLocation OriginLoc =

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

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

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

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

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

2252 if (Err) {

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

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

2255 }

2256 }

2257 }

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

2260 State.Column = RawLastLineEndColumn + NewSuffixSize;

2261

2262

2263

2264 unsigned PrefixExcessCharacters =

2265 StartColumn + NewPrefixSize > Style.ColumnLimit

2266 ? StartColumn + NewPrefixSize - Style.ColumnLimit

2267 : 0;

2268 bool IsMultiline =

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

2270 if (IsMultiline) {

2271

2272 for (ParenState &Paren : State.Stack)

2273 Paren.BreakBeforeParameter = true;

2274 }

2276}

2277

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

2279 LineState &State) {

2280

2281 for (ParenState &Paren : State.Stack)

2282 Paren.BreakBeforeParameter = true;

2283

2284 unsigned ColumnsUsed = State.Column;

2285

2286

2287 State.Column = Current.LastLineColumnWidth;

2288

2291 return 0;

2292}

2293

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

2295 LineState &State, bool DryRun,

2296 bool AllowBreak, bool Newline) {

2297 unsigned Penalty = 0;

2298

2299

2300 auto RawStringStyle = getRawStringStyle(Current, State);

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

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

2303 Newline);

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

2305

2306

2307 Penalty = addMultilineToken(Current, State);

2309

2310 LineState OriginalState = State;

2311

2312

2313

2314 bool Strict = false;

2315

2316

2317 bool Exceeded = false;

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

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

2320 if (Exceeded) {

2321

2322

2323 LineState StrictState = OriginalState;

2324 unsigned StrictPenalty =

2325 breakProtrudingToken(Current, StrictState, AllowBreak,

2326 true, true)

2327 .first;

2328 Strict = StrictPenalty <= Penalty;

2329 if (Strict) {

2330 Penalty = StrictPenalty;

2331 State = StrictState;

2332 }

2333 }

2334 if (!DryRun) {

2335

2336

2337 breakProtrudingToken(Current, OriginalState, AllowBreak, false,

2338 Strict);

2339 }

2340 }

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

2344 }

2345 return Penalty;

2346}

2347

2348

2349

2351

2353 if (!Tok || Tok->isNot(tok::l_paren))

2354 return "";

2356 if (!Tok)

2357 return "";

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

2360 if (Tok)

2362 }

2363 if (!Tok || Tok->isNot(tok::identifier))

2364 return "";

2366}

2367

2368std::optional

2369ContinuationIndenter::getRawStringStyle(const FormatToken &Current,

2370 const LineState &State) {

2371 if (!Current.isStringLiteral())

2372 return std::nullopt;

2374 if (!Delimiter)

2375 return std::nullopt;

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

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

2380 }

2381 if (!RawStringStyle)

2382 return std::nullopt;

2383 RawStringStyle->ColumnLimit = getColumnLimit(State);

2384 return RawStringStyle;

2385}

2386

2387std::unique_ptr

2388ContinuationIndenter::createBreakableToken(const FormatToken &Current,

2389 LineState &State, bool AllowBreak) {

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

2391 if (Current.isStringLiteral()) {

2392

2393

2395 !AllowBreak) {

2396 return nullptr;

2397 }

2398

2399

2400

2401

2402

2403

2405 return nullptr;

2406

2407

2408 if (Current.IsUnterminatedLiteral)

2409 return nullptr;

2410

2411

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

2413 return nullptr;

2414

2415

2416

2417

2418

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

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

2421 return nullptr;

2422 }

2423 StringRef Text = Current.TokenText;

2424

2425

2426

2427

2428

2429 unsigned UnbreakableTailLength = (State.NextToken && canBreak(State))

2430 ? 0

2431 : Current.UnbreakableTailLength;

2432

2437 Text.ends_with("'")) {

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

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

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

2444 } else {

2445 return nullptr;

2446 }

2447 return std::make_unique(

2448 Current, QuoteStyle,

2450 UnbreakableTailLength, State.Line->InPPDirective, Encoding, Style);

2451 }

2452

2453 StringRef Prefix;

2454 StringRef Postfix;

2455

2456

2457

2458

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

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

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

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

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

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

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

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

2467 return std::make_unique(

2468 Current, StartColumn, Prefix, Postfix, UnbreakableTailLength,

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

2470 }

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

2473

2474

2475

2477 return nullptr;

2478 }

2479 return std::make_unique(

2480 Current, StartColumn, Current.OriginalColumn, !Current.Previous,

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

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

2483 (!Current.Previous ||

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

2485 bool RegularComments = [&]() {

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

2487 T = T->Next) {

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

2489 return false;

2490 }

2491 return true;

2492 }();

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

2496 return nullptr;

2497 }

2498 return std::make_unique(

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

2500 }

2501 return nullptr;

2502}

2503

2504std::pair<unsigned, bool>

2505ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,

2506 LineState &State, bool AllowBreak,

2507 bool DryRun, bool Strict) {

2508 std::unique_ptr Token =

2509 createBreakableToken(Current, State, AllowBreak);

2510 if (!Token)

2511 return {0, false};

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

2514 if (Current.is(TT_LineComment)) {

2515

2517 }

2518 if (ColumnLimit == 0) {

2519

2520

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

2522 }

2523 if (Current.UnbreakableTailLength >= ColumnLimit)

2524 return {0, false};

2525

2526

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

2528 unsigned NewBreakPenalty = Current.isStringLiteral()

2531

2532

2533 bool Exceeded = false;

2534

2535 bool BreakInserted = Token->introducesBreakBeforeToken();

2536

2537

2538 bool NewBreakBefore = false;

2539

2540

2541

2542 bool Reflow = false;

2543

2544

2545 unsigned TailOffset = 0;

2546

2547 unsigned ContentStartColumn =

2548 Token->getContentStartColumn(0, false);

2549

2550 unsigned RemainingTokenColumns =

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

2552

2553 if (!DryRun)

2554 Token->adaptStartOfLine(0, Whitespaces);

2555

2556 unsigned ContentIndent = 0;

2557 unsigned Penalty = 0;

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

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

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

2561 LineIndex != EndIndex; ++LineIndex) {

2562 LLVM_DEBUG(llvm::dbgs()

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

2564 NewBreakBefore = false;

2565

2566

2567

2568 bool TryReflow = Reflow;

2569

2570 while (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {

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

2572 << (ContentStartColumn + RemainingTokenColumns)

2573 << ", space: " << ColumnLimit

2574 << ", reflown prefix: " << ContentStartColumn

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

2576

2577

2578

2579

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

2582 ContentStartColumn, CommentPragmasRegex);

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

2584

2585

2586 if (LineIndex < EndIndex - 1) {

2587

2588

2590 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);

2591 }

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

2593 break;

2594 }

2595 assert(Split.first != 0);

2596

2597 if (Token->supportsReflow()) {

2598

2599

2600

2601

2602

2603

2604

2605

2606

2607

2608

2609

2610

2611

2612

2613

2614

2615

2616

2617 unsigned ToSplitColumns = Token->getRangeLength(

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

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

2620

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

2623 ContentStartColumn + ToSplitColumns + 1, CommentPragmasRegex);

2624

2625

2626 unsigned ToNextSplitColumns = 0;

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

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

2629 ContentStartColumn);

2630 } else {

2631 ToNextSplitColumns = Token->getRangeLength(

2632 LineIndex, TailOffset,

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

2634 }

2635

2636

2637 ToNextSplitColumns =

2638 Token->getLengthAfterCompression(ToNextSplitColumns, Split);

2639 LLVM_DEBUG(llvm::dbgs()

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

2641 LLVM_DEBUG(llvm::dbgs()

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

2643

2644

2645 bool ContinueOnLine =

2646 ContentStartColumn + ToNextSplitColumns <= ColumnLimit;

2647 unsigned ExcessCharactersPenalty = 0;

2648 if (!ContinueOnLine && !Strict) {

2649

2650

2651 ExcessCharactersPenalty =

2652 (ContentStartColumn + ToNextSplitColumns - ColumnLimit) *

2654 LLVM_DEBUG(llvm::dbgs()

2655 << " Penalty excess: " << ExcessCharactersPenalty

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

2657 if (ExcessCharactersPenalty < NewBreakPenalty) {

2658 Exceeded = true;

2659 ContinueOnLine = true;

2660 }

2661 }

2662 if (ContinueOnLine) {

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

2664

2665

2666 TryReflow = true;

2667 if (!DryRun) {

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

2669 Whitespaces);

2670 }

2671

2672 ContentStartColumn += ToSplitColumns + 1;

2673 Penalty += ExcessCharactersPenalty;

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

2675 RemainingTokenColumns = Token->getRemainingLength(

2676 LineIndex, TailOffset, ContentStartColumn);

2677 continue;

2678 }

2679 }

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

2681

2682

2683

2684 if (!Reflow)

2685 ContentIndent = Token->getContentIndent(LineIndex);

2686 LLVM_DEBUG(llvm::dbgs()

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

2688 ContentStartColumn = ContentIndent + Token->getContentStartColumn(

2689 LineIndex, true);

2690

2691 unsigned NewRemainingTokenColumns = Token->getRemainingLength(

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

2693 ContentStartColumn);

2694 if (NewRemainingTokenColumns == 0) {

2695

2696 ContentIndent = 0;

2697 ContentStartColumn =

2698 Token->getContentStartColumn(LineIndex, true);

2699 NewRemainingTokenColumns = Token->getRemainingLength(

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

2701 ContentStartColumn);

2702 }

2703

2704

2705

2706

2707 if (NewRemainingTokenColumns >= RemainingTokenColumns) {

2708

2709 break;

2710 }

2711

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

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

2714 if (!DryRun) {

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

2716 Whitespaces);

2717 }

2718

2719 Penalty += NewBreakPenalty;

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

2721 RemainingTokenColumns = NewRemainingTokenColumns;

2722 BreakInserted = true;

2723 NewBreakBefore = true;

2724 }

2725

2726

2727 if (LineIndex + 1 != EndIndex) {

2728 unsigned NextLineIndex = LineIndex + 1;

2729 if (NewBreakBefore) {

2730

2731

2732 TryReflow = true;

2733 }

2734 if (TryReflow) {

2735

2736

2737

2738

2739

2740

2741 Reflow = false;

2742

2743

2744

2745

2746

2747

2748 ContentStartColumn += RemainingTokenColumns + 1;

2749

2750

2751

2753 Token->getReflowSplit(NextLineIndex, CommentPragmasRegex);

2754 LLVM_DEBUG(llvm::dbgs()

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

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

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

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

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

2760 TailOffset = SplitBeforeNext.first + SplitBeforeNext.second;

2761

2762

2763 RemainingTokenColumns = Token->getRemainingLength(

2764 NextLineIndex, TailOffset, ContentStartColumn);

2765 Reflow = true;

2766 if (ContentStartColumn + RemainingTokenColumns > ColumnLimit) {

2767 LLVM_DEBUG(llvm::dbgs()

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

2769 << (ContentStartColumn + RemainingTokenColumns)

2770 << ", space: " << ColumnLimit

2771 << ", reflown prefix: " << ContentStartColumn

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

2773

2774

2775

2776

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

2779 ContentStartColumn, CommentPragmasRegex);

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

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

2782 Reflow = false;

2783 } else {

2784

2785

2786

2787 unsigned ToSplitColumns = Token->getRangeLength(

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

2789 if (ContentStartColumn + ToSplitColumns > ColumnLimit) {

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

2791 << (ContentStartColumn + ToSplitColumns)

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

2793 unsigned ExcessCharactersPenalty =

2794 (ContentStartColumn + ToSplitColumns - ColumnLimit) *

2796 if (NewBreakPenalty < ExcessCharactersPenalty)

2797 Reflow = false;

2798 }

2799 }

2800 }

2801 } else {

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

2803 }

2804 }

2805 if (!Reflow) {

2806

2807

2808

2809 TailOffset = 0;

2810 ContentStartColumn =

2811 Token->getContentStartColumn(NextLineIndex, false);

2812 RemainingTokenColumns = Token->getRemainingLength(

2813 NextLineIndex, TailOffset, ContentStartColumn);

2814

2815 if (!DryRun)

2816 Token->adaptStartOfLine(NextLineIndex, Whitespaces);

2817 } else {

2818

2819

2820

2821

2822

2823

2824

2825

2826

2827

2828

2829

2830

2831 if (NewBreakBefore) {

2832 assert(Penalty >= NewBreakPenalty);

2833 Penalty -= NewBreakPenalty;

2834 }

2835 if (!DryRun)

2836 Token->reflow(NextLineIndex, Whitespaces);

2837 }

2838 }

2839 }

2840

2842 Token->getSplitAfterLastLine(TailOffset);

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

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

2845

2846

2847

2849 (ContentStartColumn + RemainingTokenColumns - ColumnLimit);

2850

2851 if (!DryRun) {

2852 Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine,

2853 Whitespaces);

2854 }

2855 ContentStartColumn =

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

2857 RemainingTokenColumns = Token->getRemainingLength(

2858 Token->getLineCount() - 1,

2859 TailOffset + SplitAfterLastLine.first + SplitAfterLastLine.second,

2860 ContentStartColumn);

2861 }

2862

2863 State.Column = ContentStartColumn + RemainingTokenColumns -

2864 Current.UnbreakableTailLength;

2865

2866 if (BreakInserted) {

2867 if (!DryRun)

2868 Token->updateAfterBroken(Whitespaces);

2869

2870

2871

2872

2873 if (Current.isNot(TT_LineComment))

2874 for (ParenState &Paren : State.Stack)

2875 Paren.BreakBeforeParameter = true;

2876

2877 if (Current.is(TT_BlockComment))

2878 State.NoContinuation = true;

2879

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

2881 }

2882

2883 Token->updateNextToken(State);

2884

2885 return {Penalty, Exceeded};

2886}

2887

2889

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

2891}

2892

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

2894 const FormatToken &Current = *State.NextToken;

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

2896 return false;

2897

2898

2899

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

2901 return false;

2902 if (Current.IsMultiline)

2903 return true;

2904 if (Current.getNextNonComment() &&

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

2906 return true;

2907 }

2909 State.Column + Current.ColumnWidth + Current.UnbreakableTailLength >

2911 return true;

2912 }

2913 return false;

2914}

2915

2916}

2917}

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...

Various functions to configurably format source code.

Defines and computes precedence levels for binary/ternary operators.

Defines the SourceManager interface.

unsigned LongestObjCSelectorName

Defines the clang::TokenKind enum and support functions.

WhitespaceManager class manages whitespace around tokens and their replacements.

__DEVICE__ int max(int __a, int __b)

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

unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const

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

bool is(tok::TokenKind K) const

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

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.

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

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

unsigned getColumnLimit(const LineState &State) const

Get the column limit for this line.

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

Get the initial state, i.e.

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.

bool mustBreak(const LineState &State)

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

Manages the whitespaces around tokens and their replacements.

llvm::Error addReplacement(const tooling::Replacement &Replacement)

void replaceWhitespace(FormatToken &Tok, unsigned Newlines, unsigned Spaces, unsigned StartOfTokenColumn, bool IsAligned=false, bool InPPDirective=false)

Replaces the whitespace in front of Tok.

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)

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

static bool shouldUnindentNextOperator(const FormatToken &Tok)

FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language=FormatStyle::LanguageKind::LK_Cpp)

Returns a format style complying with the LLVM coding standards: http://llvm.org/docs/CodingStandards...

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)

static bool startsSegmentOfBuilderTypeCall(const FormatToken &Tok)

static unsigned getLengthToNextOperator(const FormatToken &Tok)

static bool isAlignableBinaryOperator(const FormatToken &Token)

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

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

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

Gets a predefined style for the specified language by name.

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

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

static bool startsNextOperand(const FormatToken &Current)

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

static StringRef getEnclosingFunctionName(const FormatToken &Current)

@ LT_PreprocessorDirective

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

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

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

Language

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

const FunctionProtoType * T

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

bool isVerilogBegin(const FormatToken &Tok) const

Returns whether Tok is a Verilog keyword that opens a block.

bool isVerilogEndOfLabel(const FormatToken &Tok) const

IdentifierInfo * kw_import

IdentifierInfo * kw_dollar

IdentifierInfo * kw_async

IdentifierInfo * kw_await

IdentifierInfo * kw_implements

IdentifierInfo * kw_function

IdentifierInfo * kw_extends

bool BeforeLambdaBody

Wrap lambda block.

The FormatStyle is used to configure the formatting to follow specific guidelines.

unsigned ContinuationIndentWidth

Indent width for line continuations.

bool AlwaysBreakBeforeMultilineStrings

This option is renamed to BreakAfterReturnType.

ReturnTypeBreakingStyle BreakAfterReturnType

The function declaration return type breaking style to use.

LanguageKind

Supported languages.

@ LK_Java

Should be used for Java.

@ LK_ObjC

Should be used for Objective-C, Objective-C++.

@ LK_Proto

Should be used for Protocol Buffers (https://developers.google.com/protocol-buffers/).

@ LK_TextProto

Should be used for Protocol Buffer messages in text format (https://developers.google....

bool Cpp11BracedListStyle

If true, format braced lists as best suited for C++11 braced lists.

BreakInheritanceListStyle BreakInheritanceList

The inheritance list style to use.

unsigned IndentWidth

The number of columns to use for indentation.

bool IndentRequiresClause

Indent the requires clause in a template.

std::vector< RawStringFormat > RawStringFormats

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

PPDirectiveIndentStyle IndentPPDirectives

The preprocessor directive indenting style to use.

@ BPPS_BinPack

Bin-pack parameters.

BinaryOperatorStyle BreakBeforeBinaryOperators

The way to wrap binary operators.

@ BPS_Auto

Automatically determine parameter bin-packing behavior.

@ BPS_Always

Always bin-pack parameters.

@ RCS_Never

Leave comments untouched.

@ BCIS_AfterColon

Break constructor initializers after the colon and commas.

@ BCIS_BeforeColon

Break constructor initializers before the colon and after the commas.

@ BCIS_BeforeComma

Break constructor initializers before the colon and commas, and align the commas with the colon.

BreakBeforeConceptDeclarationsStyle BreakBeforeConceptDeclarations

The concept declaration style to use.

BreakTemplateDeclarationsStyle BreakTemplateDeclarations

The template declaration breaking style to use.

@ BOS_None

Break after operators.

bool IndentWrappedFunctionNames

Indent if a function definition or declaration is wrapped after the type.

LanguageKind Language

Language, this format style is targeted at.

@ BAS_DontAlign

Don't align, instead use ContinuationIndentWidth, e.g.:

@ BAS_AlwaysBreak

Always break after an open bracket, if the parameters don't fit on a single line, e....

@ BAS_BlockIndent

Always break after an open bracket, if the parameters don't fit on a single line.

@ BBIAS_Always

Always break before inline ASM colon.

@ BBIAS_OnlyMultiline

Break before inline ASM colon if the line length is longer than column limit.

unsigned TabWidth

The number of columns used for tab stops.

@ PPDIS_AfterHash

Indents directives after the hash.

@ LBI_OuterScope

For statements within block scope, align lambda body relative to the indentation level of the outer s...

@ LBI_Signature

Align lambda body relative to the lambda signature.

unsigned PenaltyBreakFirstLessLess

The penalty for breaking before the first <<.

unsigned ObjCBlockIndentWidth

The number of characters to use for indentation of ObjC blocks.

std::optional< FormatStyle > GetLanguageStyle(LanguageKind Language) const

std::optional< unsigned > BracedInitializerIndentWidth

The number of columns to use to indent the contents of braced init lists.

bool ExperimentalAutoDetectBinPacking

If true, clang-format detects whether function calls and definitions are formatted with one parameter...

bool ObjCBreakBeforeNestedBlockParam

Break parameters list into lines when there is nested block parameters in a function call.

OperandAlignmentStyle AlignOperands

If true, horizontally align operands of binary and ternary expressions.

@ BTDS_No

Do not force break before declaration.

@ BTDS_Leave

Do not change the line breaking before the declaration.

BreakBinaryOperationsStyle BreakBinaryOperations

The break binary operations style to use.

BreakConstructorInitializersStyle BreakConstructorInitializers

The break constructor initializers style to use.

bool BreakStringLiterals

Allow breaking string literals when formatting.

@ PCIS_NextLineOnly

Put all constructor initializers on the next line if they fit.

@ PCIS_BinPack

Bin-pack constructor initializers.

@ PCIS_NextLine

Same as PCIS_CurrentLine except that if all constructor initializers do not fit on the current line,...

BraceBreakingStyle BreakBeforeBraces

The brace breaking style to use.

@ BILS_AfterColon

Break inheritance list after the colon and commas.

@ BILS_BeforeComma

Break inheritance list before the colon and commas, and align the commas with the colon.

unsigned PenaltyExcessCharacter

The penalty for each character outside of the column limit.

@ DAS_BreakElements

Break inside DAGArg after each list element but for the last.

unsigned ConstructorInitializerIndentWidth

This option is deprecated.

@ RCPS_OwnLineWithBrace

As with OwnLine, except, unless otherwise prohibited, place a following open brace (of a function def...

@ RCPS_OwnLine

Always put the requires clause on its own line (possibly followed by a semicolon).

@ RCPS_WithPreceding

Try to put the clause together with the preceding part of a declaration.

@ RCPS_SingleLine

Try to put everything in the same line if possible.

@ RCPS_WithFollowing

Try to put the requires clause together with the class or function declaration.

RequiresClausePositionStyle RequiresClausePosition

The position of the requires clause.

BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon

The inline ASM colon style to use.

@ BS_Whitesmiths

Like Allman but always indent braces and line up code with braces.

bool BinPackArguments

If false, a function call's arguments will either be all on the same line or will have one line each.

@ REI_Keyword

Align requires expression body relative to the requires keyword.

PackConstructorInitializersStyle PackConstructorInitializers

The pack constructor initializers style to use.

@ BBCDS_Allowed

Breaking between template declaration and concept is allowed.

@ BBCDS_Never

Keep the template declaration line together with concept.

@ BBCDS_Always

Always break before concept, putting it in the line after the template declaration.

ReflowCommentsStyle ReflowComments

Comment reformatting style.

bool AllowAllParametersOfDeclarationOnNextLine

This option is deprecated.

BracketAlignmentStyle AlignAfterOpenBracket

If true, horizontally aligns arguments after an open bracket.

BinPackParametersStyle BinPackParameters

The bin pack parameters style to use.

unsigned MaxEmptyLinesToKeep

The maximum number of consecutive empty lines to keep.

BinPackStyle ObjCBinPackProtocolList

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

bool isJavaScript() const

DAGArgStyle TableGenBreakInsideDAGArg

The styles of the line break inside the DAGArg in TableGen.

LambdaBodyIndentationKind LambdaBodyIndentation

The indentation style of lambda bodies.

@ BBO_Never

Don't break binary operations.

BraceWrappingFlags BraceWrapping

Control of individual brace wrapping cases.

unsigned PenaltyBreakString

The penalty for each line break introduced inside a string literal.

RequiresExpressionIndentationKind RequiresExpressionIndentation

The indentation used for requires expression bodies.

unsigned PenaltyIndentedWhitespace

Penalty for each character of whitespace indentation (counted relative to leading non-whitespace colu...

bool AllowAllArgumentsOnNextLine

If a function call or braced initializer list doesn't fit on a line, allow putting all arguments onto...

unsigned PenaltyBreakComment

The penalty for each line break introduced inside a comment.

@ RTBS_ExceptShortType

Same as Automatic above, except that there is no break after short return types.

@ RTBS_None

This is deprecated. See Automatic below.

UseTabStyle UseTab

The way to use tab characters in the resulting file.

@ OAS_AlignAfterOperator

Horizontally align operands of binary and ternary expressions.

@ OAS_DontAlign

Do not align operands of binary and ternary expressions.

bool BreakBeforeTernaryOperators

If true, ternary operators will be placed after line breaks.

unsigned ColumnLimit

The column limit.

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

unsigned NestingLevel

The nesting level of this token, i.e.

bool isMemberAccess() const

Returns true if this is a "." or "->" accessing a member.

StringRef TokenText

The raw text of the token.

FormatToken * getPreviousNonComment() const

Returns the previous token ignoring comments.

bool closesScope() const

Returns whether Tok is )]} or a closing > of a template or in protos.

bool is(tok::TokenKind Kind) const

unsigned TotalLength

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

bool isTrailingComment() const

FormatToken * NextOperator

If this is an operator (or "."/"->") in a sequence of operators with the same precedence,...

FormatToken * MatchingParen

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

FormatToken * Previous

The previous token in the unwrapped line.

The current state when indenting a unwrapped line.

llvm::StringMap< FormatStyle > EnclosingFunctionStyle

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

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

RawStringFormatStyleManager(const FormatStyle &CodeStyle)

llvm::StringMap< FormatStyle > DelimiterStyle