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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

21#include "llvm/ADT/STLExtras.h"

22#include "llvm/ADT/StringRef.h"

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

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

25#include "llvm/Support/raw_ostream.h"

26

27#include

28

29#define DEBUG_TYPE "format-parser"

30

32namespace format {

33

34namespace {

35

36void printLine(llvm::raw_ostream &OS, const UnwrappedLine &Line,

37 StringRef Prefix = "", bool PrintText = false) {

38 OS << Prefix << "Line(" << Line.Level << ", FSC=" << Line.FirstStartColumn

39 << ")" << (Line.InPPDirective ? " MACRO" : "") << ": ";

40 bool NewLine = false;

41 for (std::list::const_iterator I = Line.Tokens.begin(),

42 E = Line.Tokens.end();

43 I != E; ++I) {

44 if (NewLine) {

45 OS << Prefix;

46 NewLine = false;

47 }

48 OS << I->Tok->Tok.getName() << "["

49 << "T=" << (unsigned)I->Tok->getType()

50 << ", OC=" << I->Tok->OriginalColumn << ", \"" << I->Tok->TokenText

51 << "\"] ";

52 for (const auto *CI = I->Children.begin(), *CE = I->Children.end();

53 CI != CE; ++CI) {

54 OS << "\n";

55 printLine(OS, *CI, (Prefix + " ").str());

56 NewLine = true;

57 }

58 }

59 if (!NewLine)

60 OS << "\n";

61}

62

63[[maybe_unused]] static void printDebugInfo(const UnwrappedLine &Line) {

64 printLine(llvm::dbgs(), Line);

65}

66

67class ScopedDeclarationState {

68public:

69 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,

70 bool MustBeDeclaration)

72 Line.MustBeDeclaration = MustBeDeclaration;

73 Stack.push_back(MustBeDeclaration);

74 }

75 ~ScopedDeclarationState() {

76 Stack.pop_back();

77 if (!Stack.empty())

78 Line.MustBeDeclaration = Stack.back();

79 else

80 Line.MustBeDeclaration = true;

81 }

82

83private:

84 UnwrappedLine &Line;

85 llvm::BitVector &Stack;

86};

87

88}

89

91 llvm::raw_os_ostream OS(Stream);

92 printLine(OS, Line);

93 return Stream;

94}

95

97public:

99 bool SwitchToPreprocessorLines = false)

100 : Parser(Parser), OriginalLines(Parser.CurrentLines) {

101 if (SwitchToPreprocessorLines)

102 Parser.CurrentLines = &Parser.PreprocessorDirectives;

103 else if (!Parser.Line->Tokens.empty())

104 Parser.CurrentLines = &Parser.Line->Tokens.back().Children;

105 PreBlockLine = std::move(Parser.Line);

106 Parser.Line = std::make_unique();

107 Parser.Line->Level = PreBlockLine->Level;

108 Parser.Line->PPLevel = PreBlockLine->PPLevel;

109 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;

110 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;

111 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;

112 }

113

115 if (!Parser.Line->Tokens.empty())

116 Parser.addUnwrappedLine();

117 assert(Parser.Line->Tokens.empty());

118 Parser.Line = std::move(PreBlockLine);

119 if (Parser.CurrentLines == &Parser.PreprocessorDirectives)

120 Parser.AtEndOfPPLine = true;

121 Parser.CurrentLines = OriginalLines;

122 }

123

124private:

126

127 std::unique_ptr PreBlockLine;

129};

130

132public:

134 const FormatStyle &Style, unsigned &LineLevel)

136 Style.BraceWrapping.AfterControlStatement ==

137 FormatStyle::BWACS_Always,

138 Style.BraceWrapping.IndentBraces) {}

140 bool WrapBrace, bool IndentBrace)

141 : LineLevel(LineLevel), OldLineLevel(LineLevel) {

142 if (WrapBrace)

143 Parser->addUnwrappedLine();

144 if (IndentBrace)

145 ++LineLevel;

146 }

148

149private:

150 unsigned &LineLevel;

151 unsigned OldLineLevel;

152};

153

155 SourceManager &SourceMgr, const FormatStyle &Style,

158 llvm::SpecificBumpPtrAllocator &Allocator,

160 : Line(new UnwrappedLine), AtEndOfPPLine(false), CurrentLines(&Lines),

161 Style(Style), IsCpp(Style.isCpp()),

163 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),

164 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),

165 IncludeGuard(getIncludeGuardState(Style.IndentPPDirectives)),

166 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),

167 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}

168

169void UnwrappedLineParser::reset() {

170 PPBranchLevel = -1;

171 IncludeGuard = getIncludeGuardState(Style.IndentPPDirectives);

172 IncludeGuardToken = nullptr;

174 CommentsBeforeNextToken.clear();

175 FormatTok = nullptr;

176 AtEndOfPPLine = false;

177 IsDecltypeAutoFunction = false;

178 PreprocessorDirectives.clear();

179 CurrentLines = &Lines;

180 DeclarationScopeStack.clear();

181 NestedTooDeep.clear();

182 NestedLambdas.clear();

183 PPStack.clear();

184 Line->FirstStartColumn = FirstStartColumn;

185

186 if (!Unexpanded.empty())

188 Token->MacroCtx.reset();

189 CurrentExpandedLines.clear();

190 ExpandedLines.clear();

191 Unexpanded.clear();

192 InExpansion = false;

193 Reconstruct.reset();

194}

195

198 Line->FirstStartColumn = FirstStartColumn;

199 do {

200 LLVM_DEBUG(llvm::dbgs() << "----\n");

201 reset();

202 Tokens = &TokenSource;

203 TokenSource.reset();

204

205 readToken();

206 parseFile();

207

208

209

210 if (IncludeGuard == IG_Found) {

211 for (auto &Line : Lines)

212 if (Line.InPPDirective && Line.Level > 0)

213 --Line.Level;

214 }

215

216

217 assert(eof());

218 pushToken(FormatTok);

219 addUnwrappedLine();

220

221

222

223 if (!ExpandedLines.empty()) {

224 LLVM_DEBUG(llvm::dbgs() << "Expanded lines:\n");

225 for (const auto &Line : Lines) {

226 if (!Line.Tokens.empty()) {

227 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);

228 if (it != ExpandedLines.end()) {

229 for (const auto &Expanded : it->second) {

230 LLVM_DEBUG(printDebugInfo(Expanded));

231 Callback.consumeUnwrappedLine(Expanded);

232 }

233 continue;

234 }

235 }

236 LLVM_DEBUG(printDebugInfo(Line));

237 Callback.consumeUnwrappedLine(Line);

238 }

239 Callback.finishRun();

240 }

241

242 LLVM_DEBUG(llvm::dbgs() << "Unwrapped lines:\n");

244 LLVM_DEBUG(printDebugInfo(Line));

245 Callback.consumeUnwrappedLine(Line);

246 }

247 Callback.finishRun();

248 Lines.clear();

249 while (!PPLevelBranchIndex.empty() &&

250 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {

251 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);

252 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);

253 }

254 if (!PPLevelBranchIndex.empty()) {

255 ++PPLevelBranchIndex.back();

256 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());

257 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());

258 }

259 } while (!PPLevelBranchIndex.empty());

260}

261

262void UnwrappedLineParser::parseFile() {

263

264

265 bool MustBeDeclaration = Line->InPPDirective && !Style.isJavaScript();

266 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,

267 MustBeDeclaration);

268 if (Style.isTextProto() || (Style.isJson() && FormatTok->IsFirst))

269 parseBracedList();

270 else

271 parseLevel();

272

273

274

275

276

277

278

279

280

281

282 if (Style.isTextProto() && !CommentsBeforeNextToken.empty())

283 addUnwrappedLine();

284 flushComments(true);

285 addUnwrappedLine();

286}

287

288void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {

289 do {

291 case tok::l_brace:

292 case tok:🚛

293 return;

294 default:

295 if (FormatTok->is(Keywords.kw_where)) {

296 addUnwrappedLine();

297 nextToken();

298 parseCSharpGenericTypeConstraint();

299 break;

300 }

301 nextToken();

302 break;

303 }

304 } while (!eof());

305}

306

307void UnwrappedLineParser::parseCSharpAttribute() {

308 int UnpairedSquareBrackets = 1;

309 do {

310 switch (FormatTok->Tok.getKind()) {

311 case tok::r_square:

312 nextToken();

313 --UnpairedSquareBrackets;

314 if (UnpairedSquareBrackets == 0) {

315 addUnwrappedLine();

316 return;

317 }

318 break;

319 case tok::l_square:

320 ++UnpairedSquareBrackets;

321 nextToken();

322 break;

323 default:

324 nextToken();

325 break;

326 }

327 } while (!eof());

328}

329

330bool UnwrappedLineParser::precededByCommentOrPPDirective() const {

331 if (!Lines.empty() && Lines.back().InPPDirective)

332 return true;

333

337}

338

339

340

341

342

343

344

345bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,

346 IfStmtKind *IfKind,

348 const bool InRequiresExpression =

349 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);

350 const bool IsPrecededByCommentOrPPDirective =

351 !Style.RemoveBracesLLVM || precededByCommentOrPPDirective();

353 bool HasDoWhile = false;

354 bool HasLabel = false;

355 unsigned StatementCount = 0;

356 bool SwitchLabelEncountered = false;

357

358 do {

359 if (FormatTok->isAttribute()) {

360 nextToken();

361 if (FormatTok->is(tok::l_paren))

362 parseParens();

363 continue;

364 }

366 if (FormatTok->is(TT_MacroBlockBegin))

367 Kind = tok::l_brace;

368 else if (FormatTok->is(TT_MacroBlockEnd))

369 Kind = tok::r_brace;

370

371 auto ParseDefault = [this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,

372 &HasLabel, &StatementCount] {

373 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,

374 HasDoWhile ? nullptr : &HasDoWhile,

375 HasLabel ? nullptr : &HasLabel);

376 ++StatementCount;

377 assert(StatementCount > 0 && "StatementCount overflow!");

378 };

379

380 switch (Kind) {

381 case tok::comment:

382 nextToken();

383 addUnwrappedLine();

384 break;

385 case tok::l_brace:

386 if (InRequiresExpression) {

387 FormatTok->setFinalizedType(TT_CompoundRequirementLBrace);

388 } else if (FormatTok->Previous &&

389 FormatTok->Previous->ClosesRequiresClause) {

390

391

392 ParseDefault();

393 continue;

394 }

395 if (!InRequiresExpression && FormatTok->isNot(TT_MacroBlockBegin)) {

396 if (tryToParseBracedList())

397 continue;

398 FormatTok->setFinalizedType(TT_BlockLBrace);

399 }

400 parseBlock();

401 ++StatementCount;

402 assert(StatementCount > 0 && "StatementCount overflow!");

403 addUnwrappedLine();

404 break;

405 case tok::r_brace:

406 if (OpeningBrace) {

407 if (!Style.RemoveBracesLLVM || Line->InPPDirective ||

408 OpeningBrace->isNoneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {

409 return false;

410 }

411 if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||

412 HasDoWhile || IsPrecededByCommentOrPPDirective ||

413 precededByCommentOrPPDirective()) {

414 return false;

415 }

417 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)

418 return false;

419 if (IfLeftBrace)

420 *IfLeftBrace = IfLBrace;

421 return true;

422 }

423 nextToken();

424 addUnwrappedLine();

425 break;

426 case tok::kw_default: {

427 unsigned StoredPosition = Tokens->getPosition();

428 auto *Next = Tokens->getNextNonComment();

429 FormatTok = Tokens->setPosition(StoredPosition);

430 if (Next->isNoneOf(tok::colon, tok::arrow)) {

431

432

433 parseStructuralElement();

434 break;

435 }

436

437 [[fallthrough]];

438 }

439 case tok::kw_case:

440 if (Style.Language == FormatStyle::LK_Proto || Style.isVerilog() ||

441 (Style.isJavaScript() && Line->MustBeDeclaration)) {

442

443

444

445

446 ParseDefault();

447 break;

448 }

449 if (!SwitchLabelEncountered &&

450 (Style.IndentCaseLabels ||

451 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||

452 (Line->InPPDirective && Line->Level == 1))) {

453 ++Line->Level;

454 }

455 SwitchLabelEncountered = true;

456 parseStructuralElement();

457 break;

458 case tok::l_square:

459 if (Style.isCSharp()) {

460 nextToken();

461 parseCSharpAttribute();

462 break;

463 }

464 if (handleCppAttributes())

465 break;

466 [[fallthrough]];

467 default:

468 ParseDefault();

469 break;

470 }

471 } while (!eof());

472

473 return false;

474}

475

476void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {

477

478

479

480

481 unsigned StoredPosition = Tokens->getPosition();

484

485

486

487 struct StackEntry {

490 };

491 SmallVector<StackEntry, 8> LBraceStack;

492 assert(Tok->is(tok::l_brace));

493

494 do {

495 auto *NextTok = Tokens->getNextNonComment();

496

497 if (!Line->InMacroBody && !Style.isTableGen()) {

498

499 while (NextTok->is(tok::hash)) {

500 NextTok = Tokens->getNextToken();

501 if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))

502 break;

503 do {

504 NextTok = Tokens->getNextToken();

505 } while (!NextTok->HasUnescapedNewline && NextTok->isNot(tok::eof));

506

507 while (NextTok->is(tok::comment))

508 NextTok = Tokens->getNextToken();

509 }

510 }

511

512 switch (Tok->Tok.getKind()) {

513 case tok::l_brace:

514 if (Style.isJavaScript() && PrevTok) {

515 if (PrevTok->isOneOf(tok::colon, tok::less)) {

516

517

518

519

520

521

522

523

524

526 } else if (PrevTok->is(tok::r_paren)) {

527

529 }

530 } else {

532 }

533 LBraceStack.push_back({Tok, PrevTok});

534 break;

535 case tok::r_brace:

536 if (LBraceStack.empty())

537 break;

538 if (auto *LBrace = LBraceStack.back().Tok; LBrace->is(BK_Unknown)) {

539 bool ProbablyBracedList = false;

540 if (Style.Language == FormatStyle::LK_Proto) {

541 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);

542 } else if (LBrace->isNot(TT_EnumLBrace)) {

543

544

545 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&

546 NextTok->OriginalColumn == 0;

547

548

549

550

551

552

553

554

555

556 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);

557

558 ProbablyBracedList = ProbablyBracedList ||

559 (Style.isJavaScript() &&

560 NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,

561 Keywords.kw_as));

562 ProbablyBracedList =

563 ProbablyBracedList ||

564 (IsCpp && (PrevTok->Tok.isLiteral() ||

565 NextTok->isOneOf(tok::l_paren, tok::arrow)));

566

567

568

569

570

571 ProbablyBracedList =

572 ProbablyBracedList ||

573 NextTok->isOneOf(tok::comma, tok::period, tok::colon,

574 tok::r_paren, tok::r_square, tok::ellipsis);

575

576

577

578 ProbablyBracedList =

579 ProbablyBracedList ||

580 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&

581 LBraceStack.back().PrevTok->isOneOf(tok::identifier,

582 tok::greater));

583

584 ProbablyBracedList =

585 ProbablyBracedList ||

586 (NextTok->is(tok::identifier) &&

587 PrevTok->isNoneOf(tok::semi, tok::r_brace, tok::l_brace));

588

589 ProbablyBracedList = ProbablyBracedList ||

590 (NextTok->is(tok::semi) &&

591 (!ExpectClassBody || LBraceStack.size() != 1));

592

593 ProbablyBracedList =

594 ProbablyBracedList ||

595 (NextTok->isBinaryOperator() && !NextIsObjCMethod);

596

597 if (!Style.isCSharp() && NextTok->is(tok::l_square)) {

598

599

600 NextTok = Tokens->getNextToken();

601 ProbablyBracedList = NextTok->isNot(tok::l_square);

602 }

603

604

605 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&

606 !FormatTok->Previous && NextTok->is(tok::eof) &&

607

608

609

610 PrevTok->isNoneOf(tok::semi, BK_Block, tok::colon)) {

611 ProbablyBracedList = true;

612 }

613 }

615 Tok->setBlockKind(BlockKind);

616 LBrace->setBlockKind(BlockKind);

617 }

618 LBraceStack.pop_back();

619 break;

620 case tok::identifier:

621 if (Tok->isNot(TT_StatementMacro))

622 break;

623 [[fallthrough]];

624 case tok::at:

625 case tok:🚛

626 case tok::kw_if:

627 case tok::kw_while:

628 case tok::kw_for:

629 case tok::kw_switch:

630 case tok::kw_try:

631 case tok::kw___try:

632 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(BK_Unknown))

633 LBraceStack.back().Tok->setBlockKind(BK_Block);

634 break;

635 default:

636 break;

637 }

638

639 PrevTok = Tok;

640 Tok = NextTok;

641 } while (Tok->isNot(tok::eof) && !LBraceStack.empty());

642

643

644 for (const auto &Entry : LBraceStack)

646 Entry.Tok->setBlockKind(BK_Block);

647

648 FormatTok = Tokens->setPosition(StoredPosition);

649}

650

651

652void UnwrappedLineParser::setPreviousRBraceType(TokenType Type) {

653 if (auto Prev = FormatTok->getPreviousNonComment();

654 Prev && Prev->is(tok::r_brace)) {

655 Prev->setFinalizedType(Type);

656 }

657}

658

659template

660static inline void hash_combine(std::size_t &seed, const T &v) {

661 std::hash hasher;

662 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);

663}

664

665size_t UnwrappedLineParser::computePPHash() const {

666 size_t h = 0;

667 for (const auto &i : PPStack) {

670 }

671 return h;

672}

673

674

675

676

677

678bool UnwrappedLineParser::mightFitOnOneLine(

680 const auto ColumnLimit = Style.ColumnLimit;

681 if (ColumnLimit == 0)

682 return true;

683

684 auto &Tokens = ParsedLine.Tokens;

685 assert(!Tokens.empty());

686

687 const auto *LastToken = Tokens.back().Tok;

688 assert(LastToken);

689

690 SmallVector SavedTokens(Tokens.size());

691

692 int Index = 0;

693 for (const auto &Token : Tokens) {

694 assert(Token.Tok);

695 auto &SavedToken = SavedTokens[Index++];

697 SavedToken.Tok->copyFrom(*Token.Tok);

698 SavedToken.Children = std::move(Token.Children);

699 }

700

701 AnnotatedLine Line(ParsedLine);

702 assert(Line.Last == LastToken);

703

704 TokenAnnotator Annotator(Style, Keywords);

705 Annotator.annotate(Line);

706 Annotator.calculateFormattingInformation(Line);

707

708 auto Length = LastToken->TotalLength;

709 if (OpeningBrace) {

710 assert(OpeningBrace != Tokens.front().Tok);

711 if (auto Prev = OpeningBrace->Previous;

712 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {

713 Length -= ColumnLimit;

714 }

715 Length -= OpeningBrace->TokenText.size() + 1;

716 }

717

718 if (const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {

719 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));

720 Length -= FirstToken->TokenText.size() + 1;

721 }

722

723 Index = 0;

724 for (auto &Token : Tokens) {

725 const auto &SavedToken = SavedTokens[Index++];

726 Token.Tok->copyFrom(*SavedToken.Tok);

727 Token.Children = std::move(SavedToken.Children);

728 delete SavedToken.Tok;

729 }

730

731

732 assert(!Line.InMacroBody);

733 assert(!Line.InPPDirective);

734 return Line.Level * Style.IndentWidth + Length <= ColumnLimit;

735}

736

737FormatToken *UnwrappedLineParser::parseBlock(bool MustBeDeclaration,

738 unsigned AddLevels, bool MunchSemi,

739 bool KeepBraces,

740 IfStmtKind *IfKind,

741 bool UnindentWhitesmithsBraces) {

742 auto HandleVerilogBlockLabel = [this]() {

743

744 if (Style.isVerilog() && FormatTok->is(tok::colon)) {

745 nextToken();

746 if (Keywords.isVerilogIdentifier(*FormatTok))

747 nextToken();

748 }

749 };

750

751

752

753 const bool VerilogHierarchy =

754 Style.isVerilog() && Keywords.isVerilogHierarchy(*FormatTok);

755 assert((FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) ||

756 (Style.isVerilog() &&

757 (Keywords.isVerilogBegin(*FormatTok) || VerilogHierarchy))) &&

758 "'{' or macro block token expected");

760 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);

761 auto Index = CurrentLines->size();

762 const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);

763 FormatTok->setBlockKind(BK_Block);

764

765

766

767 if (!VerilogHierarchy && AddLevels > 0 &&

768 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {

769 ++Line->Level;

770 }

771

772 size_t PPStartHash = computePPHash();

773

774 const unsigned InitialLevel = Line->Level;

775 if (VerilogHierarchy) {

776 AddLevels += parseVerilogHierarchyHeader();

777 } else {

778 nextToken(AddLevels);

779 HandleVerilogBlockLabel();

780 }

781

782

783 if (Line->Level > 300)

784 return nullptr;

785

786 if (MacroBlock && FormatTok->is(tok::l_paren))

787 parseParens();

788

789 size_t NbPreprocessorDirectives =

790 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;

791 addUnwrappedLine();

792 size_t OpeningLineIndex =

793 CurrentLines->empty()

795 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);

796

797

798

799

800 if (UnindentWhitesmithsBraces)

801 --Line->Level;

802

803 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,

804 MustBeDeclaration);

805 if (AddLevels > 0u && Style.BreakBeforeBraces != FormatStyle::BS_Whitesmiths)

806 Line->Level += AddLevels;

807

809 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);

810

811 if (eof())

812 return IfLBrace;

813

814 if (MacroBlock ? FormatTok->isNot(TT_MacroBlockEnd)

815 : FormatTok->isNot(tok::r_brace)) {

816 Line->Level = InitialLevel;

817 FormatTok->setBlockKind(BK_Block);

818 return IfLBrace;

819 }

820

821 if (FormatTok->is(tok::r_brace)) {

822 FormatTok->setBlockKind(BK_Block);

823 if (Tok->is(TT_NamespaceLBrace))

824 FormatTok->setFinalizedType(TT_NamespaceRBrace);

825 }

826

827 const bool IsFunctionRBrace =

828 FormatTok->is(tok::r_brace) && Tok->is(TT_FunctionLBrace);

829

830 auto RemoveBraces = [=]() mutable {

831 if (!SimpleBlock)

832 return false;

833 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));

834 assert(FormatTok->is(tok::r_brace));

835 const bool WrappedOpeningBrace = !Tok->Previous;

836 if (WrappedOpeningBrace && FollowedByComment)

837 return false;

838 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;

839 if (KeepBraces && !HasRequiredIfBraces)

840 return false;

841 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {

842 const FormatToken *Previous = Tokens->getPreviousToken();

843 assert(Previous);

844 if (Previous->is(tok::r_brace) && !Previous->Optional)

845 return false;

846 }

847 assert(!CurrentLines->empty());

848 auto &LastLine = CurrentLines->back();

849 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))

850 return false;

851 if (Tok->is(TT_ElseLBrace))

852 return true;

853 if (WrappedOpeningBrace) {

854 assert(Index > 0);

855 --Index;

856 Tok = nullptr;

857 }

858 return mightFitOnOneLine((*CurrentLines)[Index], Tok);

859 };

860 if (RemoveBraces()) {

861 Tok->MatchingParen = FormatTok;

862 FormatTok->MatchingParen = Tok;

863 }

864

865 size_t PPEndHash = computePPHash();

866

867

868 nextToken(-AddLevels);

869

870

871

872

873 if (Style.RemoveSemicolon && IsFunctionRBrace) {

874 while (FormatTok->is(tok::semi)) {

875 FormatTok->Optional = true;

876 nextToken();

877 }

878 }

879

880 HandleVerilogBlockLabel();

881

882 if (MacroBlock && FormatTok->is(tok::l_paren))

883 parseParens();

884

885 Line->Level = InitialLevel;

886

887 if (FormatTok->is(tok::kw_noexcept)) {

888

889 nextToken();

890 }

891

892 if (FormatTok->is(tok::arrow)) {

893

894

895 nextToken();

896 parseStructuralElement();

897 }

898

899 if (MunchSemi && FormatTok->is(tok::semi))

900 nextToken();

901

902 if (PPStartHash == PPEndHash) {

903 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;

905

906 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =

907 CurrentLines->size() - 1;

908 }

909 }

910

911 return IfLBrace;

912}

913

915

916

917 if (Line.Tokens.size() < 4)

918 return false;

919 auto I = Line.Tokens.begin();

920 if (I->Tok->TokenText != "goog")

921 return false;

922 ++I;

923 if (I->Tok->isNot(tok::period))

924 return false;

925 ++I;

926 if (I->Tok->TokenText != "scope")

927 return false;

928 ++I;

929 return I->Tok->is(tok::l_paren);

930}

931

934

935

936

937

938 if (Line.Tokens.size() < 3)

939 return false;

940 auto I = Line.Tokens.begin();

941 if (I->Tok->isNot(tok::l_paren))

942 return false;

943 ++I;

945 return false;

946 ++I;

947 return I->Tok->is(tok::l_paren);

948}

949

952 const bool IsJavaRecord) {

953 if (IsJavaRecord)

954 return Style.BraceWrapping.AfterClass;

955

957 if (InitialToken.is(TT_NamespaceMacro))

958 Kind = tok::kw_namespace;

959

960 switch (Kind) {

961 case tok::kw_namespace:

962 return Style.BraceWrapping.AfterNamespace;

963 case tok::kw_class:

964 return Style.BraceWrapping.AfterClass;

965 case tok::kw_union:

966 return Style.BraceWrapping.AfterUnion;

967 case tok::kw_struct:

968 return Style.BraceWrapping.AfterStruct;

969 case tok::kw_enum:

970 return Style.BraceWrapping.AfterEnum;

971 default:

972 return false;

973 }

974}

975

976void UnwrappedLineParser::parseChildBlock() {

977 assert(FormatTok->is(tok::l_brace));

978 FormatTok->setBlockKind(BK_Block);

979 const FormatToken *OpeningBrace = FormatTok;

980 nextToken();

981 {

982 bool SkipIndent = (Style.isJavaScript() &&

983 (isGoogScope(*Line) || isIIFE(*Line, Keywords)));

984 ScopedLineState LineState(*this);

985 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,

986 false);

987 Line->Level += SkipIndent ? 0 : 1;

988 parseLevel(OpeningBrace);

989 flushComments(isOnNewLine(*FormatTok));

990 Line->Level -= SkipIndent ? 0 : 1;

991 }

992 nextToken();

993}

994

995void UnwrappedLineParser::parsePPDirective() {

996 assert(FormatTok->is(tok::hash) && "'#' expected");

997 ScopedMacroState MacroState(*Line, Tokens, FormatTok);

998

999 nextToken();

1000

1001 if (!FormatTok->Tok.getIdentifierInfo()) {

1002 parsePPUnknown();

1003 return;

1004 }

1005

1006 switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {

1007 case tok::pp_define:

1008 parsePPDefine();

1009 return;

1010 case tok::pp_if:

1011 parsePPIf(false);

1012 break;

1013 case tok::pp_ifdef:

1014 case tok::pp_ifndef:

1015 parsePPIf(true);

1016 break;

1017 case tok::pp_else:

1018 case tok::pp_elifdef:

1019 case tok::pp_elifndef:

1020 case tok::pp_elif:

1021 parsePPElse();

1022 break;

1023 case tok::pp_endif:

1024 parsePPEndIf();

1025 break;

1026 case tok::pp_pragma:

1027 parsePPPragma();

1028 break;

1029 case tok::pp_error:

1030 case tok::pp_warning:

1031 nextToken();

1032 if (eof() && Style.isCpp())

1033 FormatTok->setFinalizedType(TT_AfterPPDirective);

1034 [[fallthrough]];

1035 default:

1036 parsePPUnknown();

1037 break;

1038 }

1039}

1040

1041void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) {

1042 size_t Line = CurrentLines->size();

1043 if (CurrentLines == &PreprocessorDirectives)

1044 Line += Lines.size();

1045

1046 if (Unreachable ||

1047 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {

1048 PPStack.push_back({PP_Unreachable, Line});

1049 } else {

1050 PPStack.push_back({PP_Conditional, Line});

1051 }

1052}

1053

1054void UnwrappedLineParser::conditionalCompilationStart(bool Unreachable) {

1055 ++PPBranchLevel;

1056 assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size());

1057 if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {

1058 PPLevelBranchIndex.push_back(0);

1059 PPLevelBranchCount.push_back(0);

1060 }

1061 PPChainBranchIndex.push(Unreachable ? -1 : 0);

1062 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;

1063 conditionalCompilationCondition(Unreachable || Skip);

1064}

1065

1066void UnwrappedLineParser::conditionalCompilationAlternative() {

1067 if (!PPStack.empty())

1068 PPStack.pop_back();

1069 assert(PPBranchLevel < (int)PPLevelBranchIndex.size());

1070 if (!PPChainBranchIndex.empty())

1071 ++PPChainBranchIndex.top();

1072 conditionalCompilationCondition(

1073 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&

1074 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());

1075}

1076

1077void UnwrappedLineParser::conditionalCompilationEnd() {

1078 assert(PPBranchLevel < (int)PPLevelBranchIndex.size());

1079 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {

1080 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])

1081 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;

1082 }

1083

1084 if (PPBranchLevel > -1)

1085 --PPBranchLevel;

1086 if (!PPChainBranchIndex.empty())

1087 PPChainBranchIndex.pop();

1088 if (!PPStack.empty())

1089 PPStack.pop_back();

1090}

1091

1092void UnwrappedLineParser::parsePPIf(bool IfDef) {

1093 bool IfNDef = FormatTok->is(tok::pp_ifndef);

1094 nextToken();

1095 bool Unreachable = false;

1096 if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText == "0"))

1097 Unreachable = true;

1098 if (IfDef && !IfNDef && FormatTok->TokenText == "SWIG")

1099 Unreachable = true;

1100 conditionalCompilationStart(Unreachable);

1102

1103

1104 bool MaybeIncludeGuard = IfNDef;

1105 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {

1106 for (auto &Line : Lines) {

1107 if (Line.Tokens.front().Tok->isNot(tok::comment)) {

1108 MaybeIncludeGuard = false;

1109 IncludeGuard = IG_Rejected;

1110 break;

1111 }

1112 }

1113 }

1114 --PPBranchLevel;

1115 parsePPUnknown();

1116 ++PPBranchLevel;

1117 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {

1118 IncludeGuard = IG_IfNdefed;

1119 IncludeGuardToken = IfCondition;

1120 }

1121}

1122

1123void UnwrappedLineParser::parsePPElse() {

1124

1125 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)

1126 IncludeGuard = IG_Rejected;

1127

1128 assert(PPBranchLevel >= -1);

1129 if (PPBranchLevel == -1)

1130 conditionalCompilationStart(true);

1131 conditionalCompilationAlternative();

1132 --PPBranchLevel;

1133 parsePPUnknown();

1134 ++PPBranchLevel;

1135}

1136

1137void UnwrappedLineParser::parsePPEndIf() {

1138 conditionalCompilationEnd();

1139 parsePPUnknown();

1140

1141

1142 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&

1143 getIncludeGuardState(Style.IndentPPDirectives) == IG_Inited) {

1144 IncludeGuard = IG_Found;

1145 }

1146}

1147

1148void UnwrappedLineParser::parsePPDefine() {

1149 nextToken();

1150

1151 if (!FormatTok->Tok.getIdentifierInfo()) {

1152 IncludeGuard = IG_Rejected;

1153 IncludeGuardToken = nullptr;

1154 parsePPUnknown();

1155 return;

1156 }

1157

1158 bool MaybeIncludeGuard = false;

1159 if (IncludeGuard == IG_IfNdefed &&

1160 IncludeGuardToken->TokenText == FormatTok->TokenText) {

1161 IncludeGuard = IG_Defined;

1162 IncludeGuardToken = nullptr;

1163 for (auto &Line : Lines) {

1164 if (Line.Tokens.front().Tok->isNoneOf(tok::comment, tok::hash)) {

1165 IncludeGuard = IG_Rejected;

1166 break;

1167 }

1168 }

1169 MaybeIncludeGuard = IncludeGuard == IG_Defined;

1170 }

1171

1172

1173

1174

1175

1176

1177 FormatTok->Tok.setKind(tok::identifier);

1178 FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);

1179 nextToken();

1180

1181

1182 if (MaybeIncludeGuard && eof())

1183 IncludeGuard = IG_Rejected;

1184

1185 if (FormatTok->is(tok::l_paren) && !FormatTok->hasWhitespaceBefore())

1186 parseParens();

1187 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)

1188 Line->Level += PPBranchLevel + 1;

1189 addUnwrappedLine();

1190 ++Line->Level;

1191

1192 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);

1193 assert((int)Line->PPLevel >= 0);

1194

1195 if (eof())

1196 return;

1197

1198 Line->InMacroBody = true;

1199

1200 if (!Style.SkipMacroDefinitionBody) {

1201

1202

1203

1204

1205

1206 parseFile();

1207 return;

1208 }

1209

1210 for (auto *Comment : CommentsBeforeNextToken)

1211 Comment->Finalized = true;

1212

1213 do {

1214 FormatTok->Finalized = true;

1215 FormatTok = Tokens->getNextToken();

1216 } while (eof());

1217

1218 addUnwrappedLine();

1219}

1220

1221void UnwrappedLineParser::parsePPPragma() {

1222 Line->InPragmaDirective = true;

1223 parsePPUnknown();

1224}

1225

1226void UnwrappedLineParser::parsePPUnknown() {

1227 while (eof())

1228 nextToken();

1229 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)

1230 Line->Level += PPBranchLevel + 1;

1231 addUnwrappedLine();

1232}

1233

1234

1235

1236

1238

1239

1240 return Tok.isNoneOf(tok::semi, tok::l_brace,

1241

1242

1243 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,

1244 tok::less, tok::greater, tok::slash, tok::percent,

1245 tok::lessless, tok::greatergreater, tok::equal,

1246 tok::plusequal, tok::minusequal, tok::starequal,

1247 tok::slashequal, tok::percentequal, tok::ampequal,

1248 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,

1249 tok::lesslessequal,

1250

1251

1252

1253 tok::colon,

1254

1255 tok::kw_noexcept);

1256}

1257

1260

1261 return FormatTok->is(tok::identifier) &&

1267 Keywords.kw_let, Keywords.kw_var, tok::kw_const,

1271}

1272

1276 FormatTok->isOneOf(tok::kw_true, tok::kw_false) ||

1278}

1279

1280

1281

1284 return FormatTok->isOneOf(

1285 tok::kw_return, Keywords.kw_yield,

1286

1287 tok::kw_if, tok::kw_else,

1288

1289 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,

1290

1291 tok::kw_switch, tok::kw_case,

1292

1293 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.kw_finally,

1294

1295 tok::kw_const, tok::kw_class, Keywords.kw_var, Keywords.kw_let,

1297

1298 Keywords.kw_import, tok::kw_export);

1299}

1300

1301

1303 return Tok.isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,

1304 tok::kw_unsigned, tok::kw_float, tok::kw_double,

1305 tok::identifier);

1306}

1307

1308

1309

1310

1311

1312

1313

1314

1317 assert(Tok);

1318 assert(Next);

1319 assert(FuncName);

1320

1321 if (FuncName->isNot(tok::identifier))

1322 return false;

1323

1325 if (!Prev || (Prev->isNot(tok::star) && isC78Type(*Prev)))

1326 return false;

1327

1329 Tok->isNoneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {

1330 return false;

1331 }

1332

1333 if (Next->isNot(tok::star) && Next->Tok.getIdentifierInfo())

1334 return false;

1335

1336 Tok = Tok->Previous;

1337 if (Tok || Tok->isNot(tok::r_paren))

1338 return false;

1339

1340 Tok = Tok->Previous;

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

1342 return false;

1343

1344 return Tok->Previous && Tok->Previous->isOneOf(tok::l_paren, tok::comma);

1345}

1346

1347bool UnwrappedLineParser::parseModuleImport() {

1348 assert(FormatTok->is(Keywords.kw_import) && "'import' expected");

1349

1350 if (auto Token = Tokens->peekNextToken(true);

1352 Token->isNoneOf(tok::colon, tok::less, tok::string_literal)) {

1353 return false;

1354 }

1355

1356 nextToken();

1357 while (!eof()) {

1358 if (FormatTok->is(tok::colon)) {

1359 FormatTok->setFinalizedType(TT_ModulePartitionColon);

1360 }

1361

1362 else if (FormatTok->is(tok::less)) {

1363 nextToken();

1364 while (FormatTok->isNoneOf(tok::semi, tok::greater) && eof()) {

1365

1366

1367 if (FormatTok->isNot(tok::comment) &&

1368 !FormatTok->TokenText.starts_with("//")) {

1369 FormatTok->setFinalizedType(TT_ImplicitStringLiteral);

1370 }

1371 nextToken();

1372 }

1373 }

1374 if (FormatTok->is(tok::semi)) {

1375 nextToken();

1376 break;

1377 }

1378 nextToken();

1379 }

1380

1381 addUnwrappedLine();

1382 return true;

1383}

1384

1385

1386

1387

1388

1389

1390

1391

1392void UnwrappedLineParser::readTokenWithJavaScriptASI() {

1394 readToken();

1396

1397 bool IsOnSameLine =

1398 CommentsBeforeNextToken.empty()

1399 ? Next->NewlinesBefore == 0

1400 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;

1401 if (IsOnSameLine)

1402 return;

1403

1405 bool PreviousStartsTemplateExpr =

1406 Previous->is(TT_TemplateString) && Previous->TokenText.ends_with("${");

1407 if (PreviousMustBeValue || Previous->is(tok::r_paren)) {

1408

1409

1410 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {

1411 return LineNode.Tok->is(tok::at);

1412 });

1413 if (HasAt)

1414 return;

1415 }

1416 if (Next->is(tok::exclaim) && PreviousMustBeValue)

1417 return addUnwrappedLine();

1419 bool NextEndsTemplateExpr =

1420 Next->is(TT_TemplateString) && Next->TokenText.starts_with("}");

1421 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&

1422 (PreviousMustBeValue ||

1423 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,

1424 tok::minusminus))) {

1425 return addUnwrappedLine();

1426 }

1427 if ((PreviousMustBeValue || Previous->is(tok::r_paren)) &&

1429 return addUnwrappedLine();

1430 }

1431}

1432

1433void UnwrappedLineParser::parseStructuralElement(

1434 const FormatToken *OpeningBrace, IfStmtKind *IfKind,

1435 FormatToken **IfLeftBrace, bool *HasDoWhile, bool *HasLabel) {

1436 if (Style.isTableGen() && FormatTok->is(tok::pp_include)) {

1437 nextToken();

1438 if (FormatTok->is(tok::string_literal))

1439 nextToken();

1440 addUnwrappedLine();

1441 return;

1442 }

1443

1444 if (IsCpp) {

1445 while (FormatTok->is(tok::l_square) && handleCppAttributes()) {

1446 }

1447 } else if (Style.isVerilog()) {

1448 if (Keywords.isVerilogStructuredProcedure(*FormatTok)) {

1449 parseForOrWhileLoop(false);

1450 return;

1451 }

1452 if (FormatTok->isOneOf(Keywords.kw_foreach, Keywords.kw_repeat)) {

1453 parseForOrWhileLoop();

1454 return;

1455 }

1456 if (FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,

1457 Keywords.kw_assume, Keywords.kw_cover)) {

1458 parseIfThenElse(IfKind, false, true);

1459 return;

1460 }

1461

1462

1463 while (true) {

1464 if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,

1465 Keywords.kw_unique0)) {

1466 nextToken();

1467 } else if (FormatTok->is(tok::l_paren) &&

1468 Tokens->peekNextToken()->is(tok::star)) {

1469 parseParens();

1470 } else {

1471 break;

1472 }

1473 }

1474 }

1475

1476

1477 if (FormatTok->isAccessSpecifierKeyword()) {

1478 if (Style.isJava() || Style.isJavaScript() || Style.isCSharp())

1479 nextToken();

1480 else

1481 parseAccessSpecifier();

1482 return;

1483 }

1484 switch (FormatTok->Tok.getKind()) {

1485 case tok::kw_asm:

1486 nextToken();

1487 if (FormatTok->is(tok::l_brace)) {

1488 FormatTok->setFinalizedType(TT_InlineASMBrace);

1489 nextToken();

1490 while (FormatTok && eof()) {

1491 if (FormatTok->is(tok::r_brace)) {

1492 FormatTok->setFinalizedType(TT_InlineASMBrace);

1493 nextToken();

1494 addUnwrappedLine();

1495 break;

1496 }

1497 FormatTok->Finalized = true;

1498 nextToken();

1499 }

1500 }

1501 break;

1502 case tok::kw_namespace:

1503 parseNamespace();

1504 return;

1505 case tok::kw_if: {

1506 if (Style.isJavaScript() && Line->MustBeDeclaration) {

1507

1508 break;

1509 }

1511 if (IfLeftBrace)

1512 *IfLeftBrace = Tok;

1513 return;

1514 }

1515 case tok::kw_for:

1516 case tok::kw_while:

1517 if (Style.isJavaScript() && Line->MustBeDeclaration) {

1518

1519 break;

1520 }

1521 parseForOrWhileLoop();

1522 return;

1523 case tok::kw_do:

1524 if (Style.isJavaScript() && Line->MustBeDeclaration) {

1525

1526 break;

1527 }

1528 parseDoWhile();

1529 if (HasDoWhile)

1530 *HasDoWhile = true;

1531 return;

1532 case tok::kw_switch:

1533 if (Style.isJavaScript() && Line->MustBeDeclaration) {

1534

1535 break;

1536 }

1537 parseSwitch(false);

1538 return;

1539 case tok::kw_default: {

1540

1541 if (Style.isVerilog())

1542 break;

1543 if (Style.isJavaScript() && Line->MustBeDeclaration) {

1544

1545 break;

1546 }

1547 auto *Default = FormatTok;

1548 nextToken();

1549 if (FormatTok->is(tok::colon)) {

1550 FormatTok->setFinalizedType(TT_CaseLabelColon);

1551 parseLabel();

1552 return;

1553 }

1554 if (FormatTok->is(tok::arrow)) {

1555 FormatTok->setFinalizedType(TT_CaseLabelArrow);

1556 Default->setFinalizedType(TT_SwitchExpressionLabel);

1557 parseLabel();

1558 return;

1559 }

1560

1561 break;

1562 }

1563 case tok::kw_case:

1564

1565 if (Style.Language == FormatStyle::LK_Proto) {

1566 nextToken();

1567 return;

1568 }

1569 if (Style.isVerilog()) {

1570 parseBlock();

1571 addUnwrappedLine();

1572 return;

1573 }

1574 if (Style.isJavaScript() && Line->MustBeDeclaration) {

1575

1576 nextToken();

1577 break;

1578 }

1579 parseCaseLabel();

1580 return;

1581 case tok::kw_goto:

1582 nextToken();

1583 if (FormatTok->is(tok::kw_case))

1584 nextToken();

1585 break;

1586 case tok::kw_try:

1587 case tok::kw___try:

1588 if (Style.isJavaScript() && Line->MustBeDeclaration) {

1589

1590 break;

1591 }

1592 parseTryCatch();

1593 return;

1594 case tok::kw_extern:

1595 if (Style.isVerilog()) {

1596

1597

1598 parseVerilogExtern();

1599 return;

1600 }

1601 nextToken();

1602 if (FormatTok->is(tok::string_literal)) {

1603 nextToken();

1604 if (FormatTok->is(tok::l_brace)) {

1605 if (Style.BraceWrapping.AfterExternBlock)

1606 addUnwrappedLine();

1607

1608

1609 unsigned AddLevels =

1610 (Style.IndentExternBlock == FormatStyle::IEBS_Indent) ||

1611 (Style.BraceWrapping.AfterExternBlock &&

1612 Style.IndentExternBlock ==

1613 FormatStyle::IEBS_AfterExternBlock)

1614 ? 1u

1615 : 0u;

1616 parseBlock(true, AddLevels);

1617 addUnwrappedLine();

1618 return;

1619 }

1620 }

1621 break;

1622 case tok::kw_export:

1623 if (Style.isJavaScript()) {

1624 parseJavaScriptEs6ImportExport();

1625 return;

1626 }

1627 if (Style.isVerilog()) {

1628 parseVerilogExtern();

1629 return;

1630 }

1631 if (IsCpp) {

1632 nextToken();

1633 if (FormatTok->is(tok::kw_namespace)) {

1634 parseNamespace();

1635 return;

1636 }

1637 if (FormatTok->is(tok::l_brace)) {

1638 parseCppExportBlock();

1639 return;

1640 }

1641 if (FormatTok->is(Keywords.kw_import) && parseModuleImport())

1642 return;

1643 }

1644 break;

1645 case tok::kw_inline:

1646 nextToken();

1647 if (FormatTok->is(tok::kw_namespace)) {

1648 parseNamespace();

1649 return;

1650 }

1651 break;

1652 case tok::identifier:

1653 if (FormatTok->is(TT_ForEachMacro)) {

1654 parseForOrWhileLoop();

1655 return;

1656 }

1657 if (FormatTok->is(TT_MacroBlockBegin)) {

1658 parseBlock(false, 1u,

1659 false);

1660 return;

1661 }

1662 if (FormatTok->is(Keywords.kw_import)) {

1663 if (Style.isJavaScript()) {

1664 parseJavaScriptEs6ImportExport();

1665 return;

1666 }

1667 if (Style.Language == FormatStyle::LK_Proto) {

1668 nextToken();

1669 if (FormatTok->is(tok::kw_public))

1670 nextToken();

1671 if (FormatTok->isNot(tok::string_literal))

1672 return;

1673 nextToken();

1674 if (FormatTok->is(tok::semi))

1675 nextToken();

1676 addUnwrappedLine();

1677 return;

1678 }

1679 if (Style.isVerilog()) {

1680 parseVerilogExtern();

1681 return;

1682 }

1683 if (IsCpp && parseModuleImport())

1684 return;

1685 }

1686 if (IsCpp && FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,

1687 Keywords.kw_slots, Keywords.kw_qslots)) {

1688 nextToken();

1689 if (FormatTok->is(tok::colon)) {

1690 nextToken();

1691 addUnwrappedLine();

1692 return;

1693 }

1694 }

1695 if (IsCpp && FormatTok->is(TT_StatementMacro)) {

1696 parseStatementMacro();

1697 return;

1698 }

1699 if (IsCpp && FormatTok->is(TT_NamespaceMacro)) {

1700 parseNamespace();

1701 return;

1702 }

1703

1704

1705

1706

1707 if (!Style.isJavaScript() && !Style.isVerilog() && !Style.isTableGen() &&

1708 Tokens->peekNextToken()->is(tok::colon) && Line->MustBeDeclaration) {

1709 nextToken();

1710 if (Line->InMacroBody || CurrentLines->size() > 1)

1711 Line->Tokens.begin()->Tok->MustBreakBefore = true;

1712 FormatTok->setFinalizedType(TT_GotoLabelColon);

1713 parseLabel(!Style.IndentGotoLabels);

1714 if (HasLabel)

1715 *HasLabel = true;

1716 return;

1717 }

1718 if (Style.isJava() && FormatTok->is(Keywords.kw_record)) {

1719 parseRecord(false, true);

1720 addUnwrappedLine();

1721 return;

1722 }

1723

1724 break;

1725 default:

1726 break;

1727 }

1728

1729 bool SeenEqual = false;

1730 for (const bool InRequiresExpression =

1731 OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,

1732 TT_CompoundRequirementLBrace);

1733 eof();) {

1735 switch (FormatTok->Tok.getKind()) {

1736 case tok::at:

1737 nextToken();

1738 if (FormatTok->is(tok::l_brace)) {

1739 nextToken();

1740 parseBracedList();

1741 break;

1742 }

1743 if (Style.isJava() && FormatTok->is(Keywords.kw_interface)) {

1744 nextToken();

1745 break;

1746 }

1747 switch (bool IsAutoRelease = false; FormatTok->Tok.getObjCKeywordID()) {

1748 case tok::objc_public:

1749 case tok::objc_protected:

1750 case tok::objc_package:

1751 case tok::objc_private:

1752 return parseAccessSpecifier();

1753 case tok::objc_interface:

1754 case tok::objc_implementation:

1755 return parseObjCInterfaceOrImplementation();

1756 case tok::objc_protocol:

1757 if (parseObjCProtocol())

1758 return;

1759 break;

1760 case tok::objc_end:

1761 return;

1762 case tok::objc_optional:

1763 case tok::objc_required:

1764 nextToken();

1765 addUnwrappedLine();

1766 return;

1767 case tok::objc_autoreleasepool:

1768 IsAutoRelease = true;

1769 [[fallthrough]];

1770 case tok::objc_synchronized:

1771 nextToken();

1772 if (!IsAutoRelease && FormatTok->is(tok::l_paren)) {

1773

1774 parseParens();

1775 }

1776 if (FormatTok->is(tok::l_brace)) {

1777 if (Style.BraceWrapping.AfterControlStatement ==

1778 FormatStyle::BWACS_Always) {

1779 addUnwrappedLine();

1780 }

1781 parseBlock();

1782 }

1783 addUnwrappedLine();

1784 return;

1785 case tok::objc_try:

1786

1787

1788 parseTryCatch();

1789 return;

1790 default:

1791 break;

1792 }

1793 break;

1794 case tok::kw_requires: {

1795 if (IsCpp) {

1796 bool ParsedClause = parseRequires(SeenEqual);

1797 if (ParsedClause)

1798 return;

1799 } else {

1800 nextToken();

1801 }

1802 break;

1803 }

1804 case tok::kw_enum:

1805

1806

1807 if (Previous && Previous->isOneOf(tok::less, tok::arrow, tok::comma)) {

1808 nextToken();

1809 break;

1810 }

1811

1812

1813

1814 if (!parseEnum())

1815 break;

1816

1817 if (!IsCpp && !Style.isVerilog()) {

1818 addUnwrappedLine();

1819 return;

1820 }

1821 break;

1822 case tok::kw_typedef:

1823 nextToken();

1824 if (FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,

1825 Keywords.kw_CF_ENUM, Keywords.kw_CF_OPTIONS,

1826 Keywords.kw_CF_CLOSED_ENUM,

1827 Keywords.kw_NS_CLOSED_ENUM)) {

1828 parseEnum();

1829 }

1830 break;

1831 case tok::kw_class:

1832 if (Style.isVerilog()) {

1833 parseBlock();

1834 addUnwrappedLine();

1835 return;

1836 }

1837 if (Style.isTableGen()) {

1838

1839

1840 nextToken();

1841 break;

1842 }

1843 [[fallthrough]];

1844 case tok::kw_struct:

1845 case tok::kw_union:

1846 if (parseStructLike())

1847 return;

1848 break;

1849 case tok::kw_decltype:

1850 nextToken();

1851 if (FormatTok->is(tok::l_paren)) {

1852 parseParens();

1853 if (FormatTok->Previous &&

1854 FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,

1855 tok::l_paren)) {

1856 Line->SeenDecltypeAuto = true;

1857 }

1858 }

1859 break;

1860 case tok::period:

1861 nextToken();

1862

1863 if (Style.isJava() && FormatTok && FormatTok->is(tok::kw_class))

1864 nextToken();

1865 if (Style.isJavaScript() && FormatTok &&

1866 FormatTok->Tok.getIdentifierInfo()) {

1867

1868

1869 nextToken();

1870 }

1871 break;

1872 case tok:🚛

1873 nextToken();

1874 addUnwrappedLine();

1875 return;

1876 case tok::r_brace:

1877 addUnwrappedLine();

1878 return;

1879 case tok::l_paren: {

1880 parseParens();

1881

1882

1883 if (OpeningBrace || !IsCpp || Previous || eof())

1884 break;

1886 Tokens->peekNextToken(true),

1888 addUnwrappedLine();

1889 return;

1890 }

1891 break;

1892 }

1893 case tok::kw_operator:

1894 nextToken();

1895 if (FormatTok->isBinaryOperator())

1896 nextToken();

1897 break;

1898 case tok::caret: {

1899 const auto *Prev = FormatTok->getPreviousNonComment();

1900 nextToken();

1901 if (Prev && Prev->is(tok::identifier))

1902 break;

1903

1904 if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName(LangOpts)) {

1905 nextToken();

1906

1907 while (FormatTok->is(tok::star))

1908 nextToken();

1909 }

1910

1911 if (FormatTok->is(tok::l_paren))

1912 parseParens();

1913

1914 if (FormatTok->is(tok::l_brace))

1915 parseChildBlock();

1916 break;

1917 }

1918 case tok::l_brace:

1919 if (InRequiresExpression)

1920 FormatTok->setFinalizedType(TT_BracedListLBrace);

1921 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {

1922 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;

1923

1924

1925

1926

1927 if (Style.isJava() &&

1928 Line->Tokens.front().Tok->is(Keywords.kw_synchronized)) {

1929

1930

1931 if (Style.BraceWrapping.AfterControlStatement ==

1932 FormatStyle::BWACS_Always) {

1933 addUnwrappedLine();

1934 }

1935 } else if (Style.BraceWrapping.AfterFunction) {

1936 addUnwrappedLine();

1937 }

1939 FormatTok->setFinalizedType(TT_FunctionLBrace);

1940 parseBlock();

1941 IsDecltypeAutoFunction = false;

1942 addUnwrappedLine();

1943 return;

1944 }

1945

1946

1947 break;

1948 case tok::kw_try:

1949 if (Style.isJavaScript() && Line->MustBeDeclaration) {

1950

1951 nextToken();

1952 break;

1953 }

1954

1955 if (Style.BraceWrapping.AfterFunction)

1956 addUnwrappedLine();

1957 parseTryCatch();

1958 return;

1959 case tok::identifier: {

1960 if (Style.isCSharp() && FormatTok->is(Keywords.kw_where) &&

1961 Line->MustBeDeclaration) {

1962 addUnwrappedLine();

1963 parseCSharpGenericTypeConstraint();

1964 break;

1965 }

1966 if (FormatTok->is(TT_MacroBlockEnd)) {

1967 addUnwrappedLine();

1968 return;

1969 }

1970

1971

1972

1973

1974

1975 size_t TokenCount = Line->Tokens.size();

1976 if (Style.isJavaScript() && FormatTok->is(Keywords.kw_function) &&

1977 (TokenCount > 1 ||

1978 (TokenCount == 1 &&

1979 Line->Tokens.front().Tok->isNot(Keywords.kw_async)))) {

1980 tryToParseJSFunction();

1981 break;

1982 }

1983 if ((Style.isJavaScript() || Style.isJava()) &&

1984 FormatTok->is(Keywords.kw_interface)) {

1985 if (Style.isJavaScript()) {

1986

1987

1988

1989

1990 unsigned StoredPosition = Tokens->getPosition();

1992 FormatTok = Tokens->setPosition(StoredPosition);

1994 nextToken();

1995 break;

1996 }

1997 }

1998 parseRecord();

1999 addUnwrappedLine();

2000 return;

2001 }

2002

2003 if (Style.isVerilog()) {

2004 if (FormatTok->is(Keywords.kw_table)) {

2005 parseVerilogTable();

2006 return;

2007 }

2008 if (Keywords.isVerilogBegin(*FormatTok) ||

2009 Keywords.isVerilogHierarchy(*FormatTok)) {

2010 parseBlock();

2011 addUnwrappedLine();

2012 return;

2013 }

2014 }

2015

2016 if (!IsCpp && FormatTok->is(Keywords.kw_interface)) {

2017 if (parseStructLike())

2018 return;

2019 break;

2020 }

2021

2022 if (IsCpp && FormatTok->is(TT_StatementMacro)) {

2023 parseStatementMacro();

2024 return;

2025 }

2026

2027

2028 StringRef Text = FormatTok->TokenText;

2029

2031 nextToken();

2032

2033

2034

2035 if (Style.isJavaScript())

2036 break;

2037

2038 auto OneTokenSoFar = [&]() {

2039 auto I = Line->Tokens.begin(), E = Line->Tokens.end();

2040 while (I != E && I->Tok->is(tok::comment))

2041 ++I;

2042 if (Style.isVerilog())

2043 while (I != E && I->Tok->is(tok::hash))

2044 ++I;

2045 return I != E && (++I == E);

2046 };

2047 if (OneTokenSoFar()) {

2048

2049

2050 bool FunctionLike = FormatTok->is(tok::l_paren);

2051 if (FunctionLike)

2052 parseParens();

2053

2054 bool FollowedByNewline =

2055 CommentsBeforeNextToken.empty()

2056 ? FormatTok->NewlinesBefore > 0

2057 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;

2058

2059 if (FollowedByNewline &&

2060 (Text.size() >= 5 ||

2061 (FunctionLike && FormatTok->isNot(tok::l_paren))) &&

2063 if (PreviousToken->isNot(TT_UntouchableMacroFunc))

2064 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);

2065 addUnwrappedLine();

2066 return;

2067 }

2068 }

2069 break;

2070 }

2071 case tok::equal:

2072 if ((Style.isJavaScript() || Style.isCSharp()) &&

2073 FormatTok->is(TT_FatArrow)) {

2074 tryToParseChildBlock();

2075 break;

2076 }

2077

2078 SeenEqual = true;

2079 nextToken();

2080 if (FormatTok->is(tok::l_brace)) {

2081

2082

2083

2084 if (Style.isCSharp())

2085 FormatTok->setBlockKind(BK_BracedInit);

2086

2087

2088 if (Style.isTableGen() &&

2089 Line->Tokens.begin()->Tok->is(Keywords.kw_defset)) {

2090 FormatTok->setFinalizedType(TT_FunctionLBrace);

2091 parseBlock(false, 1u,

2092 false);

2093 addUnwrappedLine();

2094 break;

2095 }

2096 nextToken();

2097 parseBracedList();

2098 } else if (Style.Language == FormatStyle::LK_Proto &&

2099 FormatTok->is(tok::less)) {

2100 nextToken();

2101 parseBracedList(true);

2102 }

2103 break;

2104 case tok::l_square:

2105 parseSquare();

2106 break;

2107 case tok::kw_new:

2108 if (Style.isCSharp() &&

2109 (Tokens->peekNextToken()->isAccessSpecifierKeyword() ||

2111 nextToken();

2112 } else {

2113 parseNew();

2114 }

2115 break;

2116 case tok::kw_switch:

2117 if (Style.isJava())

2118 parseSwitch(true);

2119 else

2120 nextToken();

2121 break;

2122 case tok::kw_case:

2123

2124 if (Style.Language == FormatStyle::LK_Proto) {

2125 nextToken();

2126 return;

2127 }

2128

2129 if (Style.isVerilog()) {

2130 parseBlock();

2131 addUnwrappedLine();

2132 return;

2133 }

2134 if (Style.isJavaScript() && Line->MustBeDeclaration) {

2135

2136 nextToken();

2137 break;

2138 }

2139 parseCaseLabel();

2140 break;

2141 case tok::kw_default:

2142 nextToken();

2143 if (Style.isVerilog()) {

2144 if (FormatTok->is(tok::colon)) {

2145

2146 break;

2147 }

2148 if (FormatTok->is(Keywords.kw_clocking)) {

2149

2150 parseBlock();

2151 addUnwrappedLine();

2152 return;

2153 }

2154 parseVerilogCaseLabel();

2155 return;

2156 }

2157 break;

2158 case tok::colon:

2159 nextToken();

2160 if (Style.isVerilog()) {

2161 parseVerilogCaseLabel();

2162 return;

2163 }

2164 break;

2165 case tok::greater:

2166 nextToken();

2167 if (FormatTok->is(tok::l_brace))

2168 FormatTok->Previous->setFinalizedType(TT_TemplateCloser);

2169 break;

2170 default:

2171 nextToken();

2172 break;

2173 }

2174 }

2175}

2176

2177bool UnwrappedLineParser::tryToParsePropertyAccessor() {

2178 assert(FormatTok->is(tok::l_brace));

2179 if (!Style.isCSharp())

2180 return false;

2181

2182 if (!FormatTok->Previous || FormatTok->Previous->isNot(tok::identifier))

2183 return false;

2184

2185

2186

2187

2188

2189

2190 unsigned int StoredPosition = Tokens->getPosition();

2192

2193

2194

2195

2196 bool HasSpecialAccessor = false;

2197 bool IsTrivialPropertyAccessor = true;

2199 while (eof()) {

2200 if (const bool IsAccessorKeyword =

2201 Tok->isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set);

2202 IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||

2203 Tok->isOneOf(tok::l_square, tok::semi, Keywords.kw_internal)) {

2204 if (IsAccessorKeyword)

2205 HasSpecialAccessor = true;

2206 else if (Tok->is(tok::l_square))

2208 Tok = Tokens->getNextToken();

2209 continue;

2210 }

2211 if (Tok->isNot(tok::r_brace))

2212 IsTrivialPropertyAccessor = false;

2213 break;

2214 }

2215

2217 Tokens->setPosition(StoredPosition);

2218 return false;

2219 }

2220

2221

2222

2223 Tokens->setPosition(StoredPosition);

2224 if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction)

2225 addUnwrappedLine();

2226 nextToken();

2227 do {

2228 switch (FormatTok->Tok.getKind()) {

2229 case tok::r_brace:

2230 nextToken();

2231 if (FormatTok->is(tok::equal)) {

2232 while (eof() && FormatTok->isNot(tok::semi))

2233 nextToken();

2234 nextToken();

2235 }

2236 addUnwrappedLine();

2237 return true;

2238 case tok::l_brace:

2239 ++Line->Level;

2240 parseBlock(true);

2241 addUnwrappedLine();

2242 --Line->Level;

2243 break;

2244 case tok::equal:

2245 if (FormatTok->is(TT_FatArrow)) {

2246 ++Line->Level;

2247 do {

2248 nextToken();

2249 } while (eof() && FormatTok->isNot(tok::semi));

2250 nextToken();

2251 addUnwrappedLine();

2252 --Line->Level;

2253 break;

2254 }

2255 nextToken();

2256 break;

2257 default:

2258 if (FormatTok->isOneOf(Keywords.kw_get, Keywords.kw_init,

2259 Keywords.kw_set) &&

2260 !IsTrivialPropertyAccessor) {

2261

2262 addUnwrappedLine();

2263 }

2264 nextToken();

2265 }

2266 } while (eof());

2267

2268

2269 return true;

2270}

2271

2272bool UnwrappedLineParser::tryToParseLambda() {

2273 assert(FormatTok->is(tok::l_square));

2274 if (!IsCpp) {

2275 nextToken();

2276 return false;

2277 }

2279 if (!tryToParseLambdaIntroducer())

2280 return false;

2281

2283 bool InTemplateParameterList = false;

2284

2285 while (FormatTok->isNot(tok::l_brace)) {

2286 if (FormatTok->isTypeName(LangOpts) || FormatTok->isAttribute()) {

2287 nextToken();

2288 continue;

2289 }

2290 switch (FormatTok->Tok.getKind()) {

2291 case tok::l_brace:

2292 break;

2293 case tok::l_paren:

2294 parseParens(TT_PointerOrReference);

2295 break;

2296 case tok::l_square:

2297 parseSquare();

2298 break;

2299 case tok::less:

2300 assert(FormatTok->Previous);

2301 if (FormatTok->Previous->is(tok::r_square))

2302 InTemplateParameterList = true;

2303 nextToken();

2304 break;

2305 case tok::kw_auto:

2306 case tok::kw_class:

2307 case tok::kw_struct:

2308 case tok::kw_union:

2309 case tok::kw_template:

2310 case tok::kw_typename:

2311 case tok::amp:

2312 case tok:⭐

2313 case tok::kw_const:

2314 case tok::kw_constexpr:

2315 case tok::kw_consteval:

2316 case tok::comma:

2317 case tok::greater:

2318 case tok::identifier:

2319 case tok::numeric_constant:

2320 case tok::coloncolon:

2321 case tok::kw_mutable:

2322 case tok::kw_noexcept:

2323 case tok::kw_static:

2324 nextToken();

2325 break;

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2337 case tok:➕

2338 case tok:➖

2339 case tok::exclaim:

2340 case tok::tilde:

2341 case tok::slash:

2342 case tok::percent:

2343 case tok::lessless:

2344 case tok::pipe:

2345 case tok::pipepipe:

2346 case tok::ampamp:

2347 case tok::caret:

2348 case tok::equalequal:

2349 case tok::exclaimequal:

2350 case tok::greaterequal:

2351 case tok::lessequal:

2352 case tok::question:

2353 case tok::colon:

2354 case tok::ellipsis:

2355 case tok::kw_true:

2356 case tok::kw_false:

2357 if (Arrow || InTemplateParameterList) {

2358 nextToken();

2359 break;

2360 }

2361 return true;

2362 case tok::arrow:

2363 Arrow = FormatTok;

2364 nextToken();

2365 break;

2366 case tok::kw_requires:

2367 parseRequiresClause();

2368 break;

2369 case tok::equal:

2370 if (!InTemplateParameterList)

2371 return true;

2372 nextToken();

2373 break;

2374 default:

2375 return true;

2376 }

2377 }

2378

2379 FormatTok->setFinalizedType(TT_LambdaLBrace);

2380 LSquare.setFinalizedType(TT_LambdaLSquare);

2381

2382 if (Arrow)

2383 Arrow->setFinalizedType(TT_LambdaArrow);

2384

2385 NestedLambdas.push_back(Line->SeenDecltypeAuto);

2386 parseChildBlock();

2387 assert(!NestedLambdas.empty());

2388 NestedLambdas.pop_back();

2389

2390 return true;

2391}

2392

2393bool UnwrappedLineParser::tryToParseLambdaIntroducer() {

2395 const FormatToken *LeftSquare = FormatTok;

2396 nextToken();

2398 const auto *PrevPrev = Previous->getPreviousNonComment();

2399 if (Previous->is(tok::star) && PrevPrev && PrevPrev->isTypeName(LangOpts))

2400 return false;

2401 if (Previous->closesScope()) {

2402

2403 if (Previous->isNot(tok::r_paren))

2404 return false;

2405

2406

2407 if (!PrevPrev || PrevPrev->isNoneOf(tok::greater, tok::r_paren))

2408 return false;

2409 }

2411 Previous->isNoneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,

2412 tok::kw_co_return)) {

2413 return false;

2414 }

2415 }

2416 if (LeftSquare->isCppStructuredBinding(IsCpp))

2417 return false;

2418 if (FormatTok->is(tok::l_square) || tok::isLiteral(FormatTok->Tok.getKind()))

2419 return false;

2420 if (FormatTok->is(tok::r_square)) {

2421 const FormatToken *Next = Tokens->peekNextToken(true);

2422 if (Next->is(tok::greater))

2423 return false;

2424 }

2425 parseSquare(true);

2426 return true;

2427}

2428

2429void UnwrappedLineParser::tryToParseJSFunction() {

2430 assert(FormatTok->is(Keywords.kw_function));

2431 if (FormatTok->is(Keywords.kw_async))

2432 nextToken();

2433

2434 nextToken();

2435

2436

2437 if (FormatTok->is(tok::star)) {

2438 FormatTok->setFinalizedType(TT_OverloadedOperator);

2439 nextToken();

2440 }

2441

2442

2443 if (FormatTok->is(tok::identifier))

2444 nextToken();

2445

2446 if (FormatTok->isNot(tok::l_paren))

2447 return;

2448

2449

2450 parseParens();

2451

2452 if (FormatTok->is(tok::colon)) {

2453

2454 nextToken();

2455

2456

2457

2458 if (FormatTok->is(tok::l_brace))

2459 tryToParseBracedList();

2460 else

2461 while (FormatTok->isNoneOf(tok::l_brace, tok::semi) && eof())

2462 nextToken();

2463 }

2464

2465 if (FormatTok->is(tok::semi))

2466 return;

2467

2468 parseChildBlock();

2469}

2470

2471bool UnwrappedLineParser::tryToParseBracedList() {

2472 if (FormatTok->is(BK_Unknown))

2473 calculateBraceTypes();

2474 assert(FormatTok->isNot(BK_Unknown));

2475 if (FormatTok->is(BK_Block))

2476 return false;

2477 nextToken();

2478 parseBracedList();

2479 return true;

2480}

2481

2482bool UnwrappedLineParser::tryToParseChildBlock() {

2483 assert(Style.isJavaScript() || Style.isCSharp());

2484 assert(FormatTok->is(TT_FatArrow));

2485

2486

2487

2488 nextToken();

2489 if (FormatTok->isNot(tok::l_brace))

2490 return false;

2491 parseChildBlock();

2492 return true;

2493}

2494

2495bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) {

2496 assert(!IsAngleBracket || !IsEnum);

2497 bool HasError = false;

2498

2499

2500

2501 do {

2502 if (Style.isCSharp() && FormatTok->is(TT_FatArrow) &&

2503 tryToParseChildBlock()) {

2504 continue;

2505 }

2506 if (Style.isJavaScript()) {

2507 if (FormatTok->is(Keywords.kw_function)) {

2508 tryToParseJSFunction();

2509 continue;

2510 }

2511 if (FormatTok->is(tok::l_brace)) {

2512

2513 if (tryToParseBracedList())

2514 continue;

2515 parseChildBlock();

2516 }

2517 }

2518 if (FormatTok->is(IsAngleBracket ? tok::greater : tok::r_brace)) {

2519 if (IsEnum) {

2520 FormatTok->setBlockKind(BK_Block);

2521 if (!Style.AllowShortEnumsOnASingleLine)

2522 addUnwrappedLine();

2523 }

2524 nextToken();

2525 return !HasError;

2526 }

2527 switch (FormatTok->Tok.getKind()) {

2528 case tok::l_square:

2529 if (Style.isCSharp())

2530 parseSquare();

2531 else

2532 tryToParseLambda();

2533 break;

2534 case tok::l_paren:

2535 parseParens();

2536

2537

2538 if (Style.isJavaScript()) {

2539 if (FormatTok->is(tok::l_brace))

2540 parseChildBlock();

2541 break;

2542 }

2543 break;

2544 case tok::l_brace:

2545

2546

2547 FormatTok->setBlockKind(BK_BracedInit);

2548 if (!IsAngleBracket) {

2549 auto *Prev = FormatTok->Previous;

2550 if (Prev && Prev->is(tok::greater))

2551 Prev->setFinalizedType(TT_TemplateCloser);

2552 }

2553 nextToken();

2554 parseBracedList();

2555 break;

2556 case tok::less:

2557 nextToken();

2558 if (IsAngleBracket)

2559 parseBracedList(true);

2560 break;

2561 case tok:🚛

2562

2563

2564

2565

2566 if (Style.isJavaScript()) {

2567 nextToken();

2568 break;

2569 }

2570 HasError = true;

2571 if (!IsEnum)

2572 return false;

2573 nextToken();

2574 break;

2575 case tok::comma:

2576 nextToken();

2577 if (IsEnum && !Style.AllowShortEnumsOnASingleLine)

2578 addUnwrappedLine();

2579 break;

2580 case tok::kw_requires:

2581 parseRequiresExpression();

2582 break;

2583 default:

2584 nextToken();

2585 break;

2586 }

2587 } while (eof());

2588 return false;

2589}

2590

2591

2592

2593

2594

2595

2596bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType,

2597 bool InMacroCall) {

2598 assert(FormatTok->is(tok::l_paren) && "'(' expected.");

2599 auto *LParen = FormatTok;

2600 auto *Prev = FormatTok->Previous;

2601 bool SeenComma = false;

2602 bool SeenEqual = false;

2603 bool MightBeFoldExpr = false;

2604 nextToken();

2605 const bool MightBeStmtExpr = FormatTok->is(tok::l_brace);

2606 if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro))

2607 InMacroCall = true;

2608 do {

2609 switch (FormatTok->Tok.getKind()) {

2610 case tok::l_paren:

2611 if (parseParens(AmpAmpTokenType, InMacroCall))

2612 SeenEqual = true;

2613 if (Style.isJava() && FormatTok->is(tok::l_brace))

2614 parseChildBlock();

2615 break;

2616 case tok::r_paren: {

2617 auto *RParen = FormatTok;

2618 nextToken();

2619 if (Prev) {

2620 auto OptionalParens = [&] {

2621 if (MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall ||

2622 Line->InMacroBody ||

2623 Style.RemoveParentheses == FormatStyle::RPS_Leave ||

2624 RParen->getPreviousNonComment() == LParen) {

2625 return false;

2626 }

2627 const bool DoubleParens =

2628 Prev->is(tok::l_paren) && FormatTok->is(tok::r_paren);

2629 if (DoubleParens) {

2630 const auto *PrevPrev = Prev->getPreviousNonComment();

2631 const bool Excluded =

2632 PrevPrev &&

2633 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||

2634 (SeenEqual &&

2635 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||

2636 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));

2637 if (!Excluded)

2638 return true;

2639 } else {

2640 const bool CommaSeparated =

2641 Prev->isOneOf(tok::l_paren, tok::comma) &&

2642 FormatTok->isOneOf(tok::comma, tok::r_paren);

2643 if (CommaSeparated &&

2644

2645 !Prev->endsSequence(tok::comma, tok::ellipsis) &&

2646

2647 !(FormatTok->is(tok::comma) &&

2648 Tokens->peekNextToken()->is(tok::ellipsis))) {

2649 return true;

2650 }

2651 const bool ReturnParens =

2652 Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&

2653 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||

2654 (!NestedLambdas.empty() && !NestedLambdas.back())) &&

2655 Prev->isOneOf(tok::kw_return, tok::kw_co_return) &&

2656 FormatTok->is(tok::semi);

2657 if (ReturnParens)

2658 return true;

2659 }

2660 return false;

2661 };

2662 if (Prev->is(TT_TypenameMacro)) {

2663 LParen->setFinalizedType(TT_TypeDeclarationParen);

2664 RParen->setFinalizedType(TT_TypeDeclarationParen);

2665 } else if (Prev->is(tok::greater) && RParen->Previous == LParen) {

2666 Prev->setFinalizedType(TT_TemplateCloser);

2667 } else if (OptionalParens()) {

2668 LParen->Optional = true;

2669 RParen->Optional = true;

2670 }

2671 }

2672 return SeenEqual;

2673 }

2674 case tok::r_brace:

2675

2676 return SeenEqual;

2677 case tok::l_square:

2678 tryToParseLambda();

2679 break;

2680 case tok::l_brace:

2681 if (!tryToParseBracedList())

2682 parseChildBlock();

2683 break;

2684 case tok::at:

2685 nextToken();

2686 if (FormatTok->is(tok::l_brace)) {

2687 nextToken();

2688 parseBracedList();

2689 }

2690 break;

2691 case tok::comma:

2692 SeenComma = true;

2693 nextToken();

2694 break;

2695 case tok::ellipsis:

2696 MightBeFoldExpr = true;

2697 nextToken();

2698 break;

2699 case tok::equal:

2700 SeenEqual = true;

2701 if (Style.isCSharp() && FormatTok->is(TT_FatArrow))

2702 tryToParseChildBlock();

2703 else

2704 nextToken();

2705 break;

2706 case tok::kw_class:

2707 if (Style.isJavaScript())

2708 parseRecord(true);

2709 else

2710 nextToken();

2711 break;

2712 case tok::identifier:

2713 if (Style.isJavaScript() && (FormatTok->is(Keywords.kw_function)))

2714 tryToParseJSFunction();

2715 else

2716 nextToken();

2717 break;

2718 case tok::kw_switch:

2719 if (Style.isJava())

2720 parseSwitch(true);

2721 else

2722 nextToken();

2723 break;

2724 case tok::kw_requires:

2725 parseRequiresExpression();

2726 break;

2727 case tok::ampamp:

2728 if (AmpAmpTokenType != TT_Unknown)

2729 FormatTok->setFinalizedType(AmpAmpTokenType);

2730 [[fallthrough]];

2731 default:

2732 nextToken();

2733 break;

2734 }

2735 } while (eof());

2736 return SeenEqual;

2737}

2738

2739void UnwrappedLineParser::parseSquare(bool LambdaIntroducer) {

2741 assert(FormatTok->is(tok::l_square) && "'[' expected.");

2742 if (tryToParseLambda())

2743 return;

2744 }

2745 do {

2746 switch (FormatTok->Tok.getKind()) {

2747 case tok::l_paren:

2748 parseParens();

2749 break;

2750 case tok::r_square:

2751 nextToken();

2752 return;

2753 case tok::r_brace:

2754

2755 return;

2756 case tok::l_square:

2757 parseSquare();

2758 break;

2759 case tok::l_brace: {

2760 if (!tryToParseBracedList())

2761 parseChildBlock();

2762 break;

2763 }

2764 case tok::at:

2765 case tok::colon:

2766 nextToken();

2767 if (FormatTok->is(tok::l_brace)) {

2768 nextToken();

2769 parseBracedList();

2770 }

2771 break;

2772 default:

2773 nextToken();

2774 break;

2775 }

2776 } while (eof());

2777}

2778

2779void UnwrappedLineParser::keepAncestorBraces() {

2780 if (!Style.RemoveBracesLLVM)

2781 return;

2782

2783 const int MaxNestingLevels = 2;

2784 const int Size = NestedTooDeep.size();

2785 if (Size >= MaxNestingLevels)

2786 NestedTooDeep[Size - MaxNestingLevels] = true;

2787 NestedTooDeep.push_back(false);

2788}

2789

2791 for (const auto &Token : llvm::reverse(Line.Tokens))

2793 return Token.Tok;

2794

2795 return nullptr;

2796}

2797

2798void UnwrappedLineParser::parseUnbracedBody(bool CheckEOF) {

2800

2801 if (Style.InsertBraces && Line->InPPDirective && Line->Tokens.empty() &&

2802 PreprocessorDirectives.empty() && FormatTok->isNot(tok::semi)) {

2803 Tok = Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Never

2804 ? getLastNonComment(*Line)

2805 : Line->Tokens.back().Tok;

2806 assert(Tok);

2807 if (Tok->BraceCount < 0) {

2808 assert(Tok->BraceCount == -1);

2809 Tok = nullptr;

2810 } else {

2811 Tok->BraceCount = -1;

2812 }

2813 }

2814

2815 addUnwrappedLine();

2816 ++Line->Level;

2817 ++Line->UnbracedBodyLevel;

2818 parseStructuralElement();

2819 --Line->UnbracedBodyLevel;

2820

2821 if (Tok) {

2822 assert(Line->InPPDirective);

2823 Tok = nullptr;

2824 for (const auto &L : llvm::reverse(*CurrentLines)) {

2826 Tok = L.Tokens.back().Tok;

2827 break;

2828 }

2829 }

2830 assert(Tok);

2831 ++Tok->BraceCount;

2832 }

2833

2834 if (CheckEOF && eof())

2835 addUnwrappedLine();

2836

2837 --Line->Level;

2838}

2839

2841 if (!LeftBrace)

2842 return;

2843

2844 assert(LeftBrace->is(tok::l_brace));

2845

2847 if (!RightBrace) {

2848 assert(!LeftBrace->Optional);

2849 return;

2850 }

2851

2852 assert(RightBrace->is(tok::r_brace));

2855

2857 RightBrace->Optional = true;

2858}

2859

2860void UnwrappedLineParser::handleAttributes() {

2861

2862 if (FormatTok->isAttribute())

2863 nextToken();

2864 else if (FormatTok->is(tok::l_square))

2865 handleCppAttributes();

2866}

2867

2868bool UnwrappedLineParser::handleCppAttributes() {

2869

2870 assert(FormatTok->is(tok::l_square));

2871 if (!tryToParseSimpleAttribute())

2872 return false;

2873 parseSquare();

2874 return true;

2875}

2876

2877

2878bool UnwrappedLineParser::isBlockBegin(const FormatToken &Tok) const {

2879

2880

2881 return Style.isVerilog() ? Keywords.isVerilogBegin(Tok)

2882 : Tok.is(tok::l_brace);

2883}

2884

2885FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,

2886 bool KeepBraces,

2887 bool IsVerilogAssert) {

2888 assert((FormatTok->is(tok::kw_if) ||

2889 (Style.isVerilog() &&

2890 FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,

2891 Keywords.kw_assume, Keywords.kw_cover))) &&

2892 "'if' expected");

2893 nextToken();

2894

2895 if (IsVerilogAssert) {

2896

2897 if (FormatTok->is(Keywords.kw_verilogHash)) {

2898 nextToken();

2899 if (FormatTok->is(tok::numeric_constant))

2900 nextToken();

2901 } else if (FormatTok->isOneOf(Keywords.kw_final, Keywords.kw_property,

2902 Keywords.kw_sequence)) {

2903 nextToken();

2904 }

2905 }

2906

2907

2908 if (Style.isTableGen()) {

2909 while (eof() && FormatTok->isNot(Keywords.kw_then)) {

2910

2911 nextToken();

2912 }

2913 }

2914

2915

2916 if (FormatTok->is(tok::exclaim))

2917 nextToken();

2918

2919 bool KeepIfBraces = true;

2920 if (FormatTok->is(tok::kw_consteval)) {

2921 nextToken();

2922 } else {

2923 KeepIfBraces = !Style.RemoveBracesLLVM || KeepBraces;

2924 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))

2925 nextToken();

2926 if (FormatTok->is(tok::l_paren)) {

2927 FormatTok->setFinalizedType(TT_ConditionLParen);

2928 parseParens();

2929 }

2930 }

2931 handleAttributes();

2932

2933 if (IsVerilogAssert && FormatTok->is(tok::semi)) {

2934 nextToken();

2935 addUnwrappedLine();

2936 return nullptr;

2937 }

2938

2939 bool NeedsUnwrappedLine = false;

2940 keepAncestorBraces();

2941

2943 IfStmtKind IfBlockKind = IfStmtKind::NotIf;

2944

2945 if (isBlockBegin(*FormatTok)) {

2946 FormatTok->setFinalizedType(TT_ControlStatementLBrace);

2947 IfLeftBrace = FormatTok;

2948 CompoundStatementIndenter Indenter(this, Style, Line->Level);

2949 parseBlock(false, 1u,

2950 true, KeepIfBraces, &IfBlockKind);

2951 setPreviousRBraceType(TT_ControlStatementRBrace);

2952 if (Style.BraceWrapping.BeforeElse)

2953 addUnwrappedLine();

2954 else

2955 NeedsUnwrappedLine = true;

2956 } else if (IsVerilogAssert && FormatTok->is(tok::kw_else)) {

2957 addUnwrappedLine();

2958 } else {

2959 parseUnbracedBody();

2960 }

2961

2962 if (Style.RemoveBracesLLVM) {

2963 assert(!NestedTooDeep.empty());

2964 KeepIfBraces = KeepIfBraces ||

2965 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||

2966 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||

2967 IfBlockKind == IfStmtKind::IfElseIf;

2968 }

2969

2970 bool KeepElseBraces = KeepIfBraces;

2972 IfStmtKind Kind = IfStmtKind::IfOnly;

2973

2974 if (FormatTok->is(tok::kw_else)) {

2975 if (Style.RemoveBracesLLVM) {

2976 NestedTooDeep.back() = false;

2977 Kind = IfStmtKind::IfElse;

2978 }

2979 nextToken();

2980 handleAttributes();

2981 if (isBlockBegin(*FormatTok)) {

2982 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);

2983 FormatTok->setFinalizedType(TT_ElseLBrace);

2984 ElseLeftBrace = FormatTok;

2985 CompoundStatementIndenter Indenter(this, Style, Line->Level);

2986 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;

2988 parseBlock(false, 1u,

2989 true, KeepElseBraces, &ElseBlockKind);

2990 setPreviousRBraceType(TT_ElseRBrace);

2991 if (FormatTok->is(tok::kw_else)) {

2992 KeepElseBraces = KeepElseBraces ||

2993 ElseBlockKind == IfStmtKind::IfOnly ||

2994 ElseBlockKind == IfStmtKind::IfElseIf;

2995 } else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {

2996 KeepElseBraces = true;

2997 assert(ElseLeftBrace->MatchingParen);

2999 }

3000 addUnwrappedLine();

3001 } else if (!IsVerilogAssert && FormatTok->is(tok::kw_if)) {

3004 const bool IsPrecededByComment = Previous->is(tok::comment);

3005 if (IsPrecededByComment) {

3006 addUnwrappedLine();

3007 ++Line->Level;

3008 }

3009 bool TooDeep = true;

3010 if (Style.RemoveBracesLLVM) {

3011 Kind = IfStmtKind::IfElseIf;

3012 TooDeep = NestedTooDeep.pop_back_val();

3013 }

3014 ElseLeftBrace = parseIfThenElse(nullptr, KeepIfBraces);

3015 if (Style.RemoveBracesLLVM)

3016 NestedTooDeep.push_back(TooDeep);

3017 if (IsPrecededByComment)

3018 --Line->Level;

3019 } else {

3020 parseUnbracedBody(true);

3021 }

3022 } else {

3023 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;

3024 if (NeedsUnwrappedLine)

3025 addUnwrappedLine();

3026 }

3027

3028 if (!Style.RemoveBracesLLVM)

3029 return nullptr;

3030

3031 assert(!NestedTooDeep.empty());

3032 KeepElseBraces = KeepElseBraces ||

3033 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||

3034 NestedTooDeep.back();

3035

3036 NestedTooDeep.pop_back();

3037

3038 if (!KeepIfBraces && !KeepElseBraces) {

3041 } else if (IfLeftBrace) {

3042 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;

3043 if (IfRightBrace) {

3044 assert(IfRightBrace->MatchingParen == IfLeftBrace);

3045 assert(!IfLeftBrace->Optional);

3046 assert(!IfRightBrace->Optional);

3047 IfLeftBrace->MatchingParen = nullptr;

3048 IfRightBrace->MatchingParen = nullptr;

3049 }

3050 }

3051

3052 if (IfKind)

3053 *IfKind = Kind;

3054

3055 return IfLeftBrace;

3056}

3057

3058void UnwrappedLineParser::parseTryCatch() {

3059 assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) && "'try' expected");

3060 nextToken();

3061 bool NeedsUnwrappedLine = false;

3062 bool HasCtorInitializer = false;

3063 if (FormatTok->is(tok::colon)) {

3064 auto *Colon = FormatTok;

3065

3066 nextToken();

3067 if (FormatTok->is(tok::identifier)) {

3068 HasCtorInitializer = true;

3069 Colon->setFinalizedType(TT_CtorInitializerColon);

3070 }

3071

3072

3073

3074 while (FormatTok->is(tok::comma))

3075 nextToken();

3076

3077 while (FormatTok->is(tok::identifier)) {

3078 nextToken();

3079 if (FormatTok->is(tok::l_paren)) {

3080 parseParens();

3081 } else if (FormatTok->is(tok::l_brace)) {

3082 nextToken();

3083 parseBracedList();

3084 }

3085

3086

3087

3088 while (FormatTok->is(tok::comma))

3089 nextToken();

3090 }

3091 }

3092

3093 if (Style.isJava() && FormatTok->is(tok::l_paren))

3094 parseParens();

3095

3096 keepAncestorBraces();

3097

3098 if (FormatTok->is(tok::l_brace)) {

3099 if (HasCtorInitializer)

3100 FormatTok->setFinalizedType(TT_FunctionLBrace);

3101 CompoundStatementIndenter Indenter(this, Style, Line->Level);

3102 parseBlock();

3103 if (Style.BraceWrapping.BeforeCatch)

3104 addUnwrappedLine();

3105 else

3106 NeedsUnwrappedLine = true;

3107 } else if (FormatTok->isNot(tok::kw_catch)) {

3108

3109

3110

3111 addUnwrappedLine();

3112 ++Line->Level;

3113 parseStructuralElement();

3114 --Line->Level;

3115 }

3116 for (bool SeenCatch = false;;) {

3117 if (FormatTok->is(tok::at))

3118 nextToken();

3119 if (FormatTok->isNoneOf(tok::kw_catch, Keywords.kw___except,

3120 tok::kw___finally, tok::objc_catch,

3121 tok::objc_finally) &&

3122 !((Style.isJava() || Style.isJavaScript()) &&

3123 FormatTok->is(Keywords.kw_finally))) {

3124 break;

3125 }

3126 if (FormatTok->is(tok::kw_catch))

3127 SeenCatch = true;

3128 nextToken();

3129 while (FormatTok->isNot(tok::l_brace)) {

3130 if (FormatTok->is(tok::l_paren)) {

3131 parseParens();

3132 continue;

3133 }

3134 if (FormatTok->isOneOf(tok::semi, tok::r_brace) || eof()) {

3135 if (Style.RemoveBracesLLVM)

3136 NestedTooDeep.pop_back();

3137 return;

3138 }

3139 nextToken();

3140 }

3141 if (SeenCatch) {

3142 FormatTok->setFinalizedType(TT_ControlStatementLBrace);

3143 SeenCatch = false;

3144 }

3145 NeedsUnwrappedLine = false;

3146 Line->MustBeDeclaration = false;

3147 CompoundStatementIndenter Indenter(this, Style, Line->Level);

3148 parseBlock();

3149 if (Style.BraceWrapping.BeforeCatch)

3150 addUnwrappedLine();

3151 else

3152 NeedsUnwrappedLine = true;

3153 }

3154

3155 if (Style.RemoveBracesLLVM)

3156 NestedTooDeep.pop_back();

3157

3158 if (NeedsUnwrappedLine)

3159 addUnwrappedLine();

3160}

3161

3162void UnwrappedLineParser::parseNamespaceOrExportBlock(unsigned AddLevels) {

3163 bool ManageWhitesmithsBraces =

3164 AddLevels == 0u && Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;

3165

3166

3167

3168 if (ManageWhitesmithsBraces)

3169 ++Line->Level;

3170

3171

3172

3173 parseBlock(true, AddLevels, true,

3174 true, nullptr, ManageWhitesmithsBraces);

3175

3176 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);

3177

3178 if (ManageWhitesmithsBraces)

3179 --Line->Level;

3180}

3181

3182void UnwrappedLineParser::parseNamespace() {

3183 assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&

3184 "'namespace' expected");

3185

3186 const FormatToken &InitialToken = *FormatTok;

3187 nextToken();

3188 if (InitialToken.is(TT_NamespaceMacro)) {

3189 parseParens();

3190 } else {

3191 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,

3192 tok::l_square, tok::period, tok::l_paren) ||

3193 (Style.isCSharp() && FormatTok->is(tok::kw_union))) {

3194 if (FormatTok->is(tok::l_square))

3195 parseSquare();

3196 else if (FormatTok->is(tok::l_paren))

3197 parseParens();

3198 else

3199 nextToken();

3200 }

3201 }

3202 if (FormatTok->is(tok::l_brace)) {

3203 FormatTok->setFinalizedType(TT_NamespaceLBrace);

3204

3206 addUnwrappedLine();

3207

3208 unsigned AddLevels =

3209 Style.NamespaceIndentation == FormatStyle::NI_All ||

3210 (Style.NamespaceIndentation == FormatStyle::NI_Inner &&

3211 DeclarationScopeStack.size() > 1)

3212 ? 1u

3213 : 0u;

3214 parseNamespaceOrExportBlock(AddLevels);

3215 }

3216

3217}

3218

3219void UnwrappedLineParser::parseCppExportBlock() {

3220 parseNamespaceOrExportBlock(Style.IndentExportBlock ? 1 : 0);

3221}

3222

3223void UnwrappedLineParser::parseNew() {

3224 assert(FormatTok->is(tok::kw_new) && "'new' expected");

3225 nextToken();

3226

3227 if (Style.isCSharp()) {

3228 do {

3229

3230 if (FormatTok->is(tok::l_paren))

3231 parseParens();

3232

3233

3234 if (FormatTok->is(tok::l_brace))

3235 parseBracedList();

3236

3237 if (FormatTok->isOneOf(tok::semi, tok::comma))

3238 return;

3239

3240 nextToken();

3241 } while (eof());

3242 }

3243

3244 if (!Style.isJava())

3245 return;

3246

3247

3248 do {

3249

3250 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))

3251 return;

3252

3253

3254 if (FormatTok->is(tok::l_paren)) {

3255 parseParens();

3256

3257

3258 if (FormatTok->is(tok::l_brace))

3259 parseChildBlock();

3260 return;

3261 }

3262 nextToken();

3263 } while (eof());

3264}

3265

3266void UnwrappedLineParser::parseLoopBody(bool KeepBraces, bool WrapRightBrace) {

3267 keepAncestorBraces();

3268

3269 if (isBlockBegin(*FormatTok)) {

3270 FormatTok->setFinalizedType(TT_ControlStatementLBrace);

3272 CompoundStatementIndenter Indenter(this, Style, Line->Level);

3273 parseBlock(false, 1u,

3274 true, KeepBraces);

3275 setPreviousRBraceType(TT_ControlStatementRBrace);

3276 if (!KeepBraces) {

3277 assert(!NestedTooDeep.empty());

3278 if (!NestedTooDeep.back())

3280 }

3281 if (WrapRightBrace)

3282 addUnwrappedLine();

3283 } else {

3284 parseUnbracedBody();

3285 }

3286

3287 if (!KeepBraces)

3288 NestedTooDeep.pop_back();

3289}

3290

3291void UnwrappedLineParser::parseForOrWhileLoop(bool HasParens) {

3292 assert((FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||

3293 (Style.isVerilog() &&

3294 FormatTok->isOneOf(Keywords.kw_always, Keywords.kw_always_comb,

3295 Keywords.kw_always_ff, Keywords.kw_always_latch,

3296 Keywords.kw_final, Keywords.kw_initial,

3297 Keywords.kw_foreach, Keywords.kw_forever,

3298 Keywords.kw_repeat))) &&

3299 "'for', 'while' or foreach macro expected");

3300 const bool KeepBraces = !Style.RemoveBracesLLVM ||

3301 FormatTok->isNoneOf(tok::kw_for, tok::kw_while);

3302

3303 nextToken();

3304

3305 if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))

3306 nextToken();

3307 if (IsCpp && FormatTok->is(tok::kw_co_await))

3308 nextToken();

3309 if (HasParens && FormatTok->is(tok::l_paren)) {

3310

3311

3312

3313 if (Style.isVerilog())

3314 FormatTok->setFinalizedType(TT_ConditionLParen);

3315 parseParens();

3316 }

3317

3318 if (Style.isVerilog()) {

3319

3320 parseVerilogSensitivityList();

3321 } else if (Style.AllowShortLoopsOnASingleLine && FormatTok->is(tok::semi) &&

3322 Tokens->getPreviousToken()->is(tok::r_paren)) {

3323 nextToken();

3324 addUnwrappedLine();

3325 return;

3326 }

3327

3328 handleAttributes();

3329 parseLoopBody(KeepBraces, true);

3330}

3331

3332void UnwrappedLineParser::parseDoWhile() {

3333 assert(FormatTok->is(tok::kw_do) && "'do' expected");

3334 nextToken();

3335

3336 parseLoopBody(true, Style.BraceWrapping.BeforeWhile);

3337

3338

3339 if (FormatTok->isNot(tok::kw_while)) {

3340 addUnwrappedLine();

3341 return;

3342 }

3343

3344 FormatTok->setFinalizedType(TT_DoWhile);

3345

3346

3347

3348 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths)

3349 ++Line->Level;

3350

3351 nextToken();

3352 parseStructuralElement();

3353}

3354

3355void UnwrappedLineParser::parseLabel(bool LeftAlignLabel) {

3356 nextToken();

3357 unsigned OldLineLevel = Line->Level;

3358

3359 if (LeftAlignLabel)

3360 Line->Level = 0;

3361 else if (Line->Level > 1 || (Line->InPPDirective && Line->Level > 0))

3362 --Line->Level;

3363

3364 if (!Style.IndentCaseBlocks && CommentsBeforeNextToken.empty() &&

3365 FormatTok->is(tok::l_brace)) {

3366

3367 CompoundStatementIndenter Indenter(this, Line->Level,

3368 Style.BraceWrapping.AfterCaseLabel,

3369 Style.BraceWrapping.IndentBraces);

3370 parseBlock();

3371 if (FormatTok->is(tok::kw_break)) {

3372 if (Style.BraceWrapping.AfterControlStatement ==

3373 FormatStyle::BWACS_Always) {

3374 addUnwrappedLine();

3375 if (!Style.IndentCaseBlocks &&

3376 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {

3377 ++Line->Level;

3378 }

3379 }

3380 parseStructuralElement();

3381 }

3382 addUnwrappedLine();

3383 } else {

3384 if (FormatTok->is(tok::semi))

3385 nextToken();

3386 addUnwrappedLine();

3387 }

3388 Line->Level = OldLineLevel;

3389 if (FormatTok->isNot(tok::l_brace)) {

3390 parseStructuralElement();

3391 addUnwrappedLine();

3392 }

3393}

3394

3395void UnwrappedLineParser::parseCaseLabel() {

3396 assert(FormatTok->is(tok::kw_case) && "'case' expected");

3397 auto *Case = FormatTok;

3398

3399

3400 do {

3401 nextToken();

3402 if (FormatTok->is(tok::colon)) {

3403 FormatTok->setFinalizedType(TT_CaseLabelColon);

3404 break;

3405 }

3406 if (Style.isJava() && FormatTok->is(tok::arrow)) {

3407 FormatTok->setFinalizedType(TT_CaseLabelArrow);

3408 Case->setFinalizedType(TT_SwitchExpressionLabel);

3409 break;

3410 }

3411 } while (eof());

3412 parseLabel();

3413}

3414

3415void UnwrappedLineParser::parseSwitch(bool IsExpr) {

3416 assert(FormatTok->is(tok::kw_switch) && "'switch' expected");

3417 nextToken();

3418 if (FormatTok->is(tok::l_paren))

3419 parseParens();

3420

3421 keepAncestorBraces();

3422

3423 if (FormatTok->is(tok::l_brace)) {

3424 CompoundStatementIndenter Indenter(this, Style, Line->Level);

3425 FormatTok->setFinalizedType(IsExpr ? TT_SwitchExpressionLBrace

3426 : TT_ControlStatementLBrace);

3427 if (IsExpr)

3428 parseChildBlock();

3429 else

3430 parseBlock();

3431 setPreviousRBraceType(TT_ControlStatementRBrace);

3432 if (!IsExpr)

3433 addUnwrappedLine();

3434 } else {

3435 addUnwrappedLine();

3436 ++Line->Level;

3437 parseStructuralElement();

3438 --Line->Level;

3439 }

3440

3441 if (Style.RemoveBracesLLVM)

3442 NestedTooDeep.pop_back();

3443}

3444

3445void UnwrappedLineParser::parseAccessSpecifier() {

3446 nextToken();

3447

3448 if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))

3449 nextToken();

3450

3451 if (FormatTok->is(tok::colon))

3452 nextToken();

3453 addUnwrappedLine();

3454}

3455

3456

3457

3458

3459bool UnwrappedLineParser::parseRequires(bool SeenEqual) {

3460 assert(FormatTok->is(tok::kw_requires) && "'requires' expected");

3461

3462

3463

3464 switch (Tokens->peekNextToken(true)->Tok.getKind()) {

3465 case tok::l_brace:

3466

3467 parseRequiresExpression();

3468 return false;

3469 case tok::l_paren:

3470

3471 break;

3472 default:

3473

3474 parseRequiresClause();

3475 return true;

3476 }

3477

3478

3479

3480

3481

3482

3483

3484

3485 auto *PreviousNonComment = FormatTok->getPreviousNonComment();

3486

3487 if (!PreviousNonComment ||

3488 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {

3489

3490

3491 parseRequiresClause();

3492 return true;

3493 }

3494

3495 switch (PreviousNonComment->Tok.getKind()) {

3496 case tok::greater:

3497 case tok::r_paren:

3498 case tok::kw_noexcept:

3499 case tok::kw_const:

3500 case tok:⭐

3501 case tok::amp:

3502

3503 parseRequiresClause();

3504 return true;

3505 case tok::ampamp: {

3506

3507

3508

3509

3510

3511

3512 auto PrevPrev = PreviousNonComment->getPreviousNonComment();

3513 if ((PrevPrev && PrevPrev->is(tok::kw_const)) || !SeenEqual) {

3514 parseRequiresClause();

3515 return true;

3516 }

3517 break;

3518 }

3519 default:

3520 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {

3521

3522 parseRequiresClause();

3523 return true;

3524 }

3525

3526 parseRequiresExpression();

3527 return false;

3528 }

3529

3530

3531

3532

3533

3534

3535

3536 unsigned StoredPosition = Tokens->getPosition();

3537 FormatToken *NextToken = Tokens->getNextToken();

3538 int Lookahead = 0;

3539 auto PeekNext = [&Lookahead, &NextToken, this] {

3540 ++Lookahead;

3541 NextToken = Tokens->getNextToken();

3542 };

3543

3544 bool FoundType = false;

3545 bool LastWasColonColon = false;

3546 int OpenAngles = 0;

3547

3548 for (; Lookahead < 50; PeekNext()) {

3549 switch (NextToken->Tok.getKind()) {

3550 case tok::kw_volatile:

3551 case tok::kw_const:

3552 case tok::comma:

3553 if (OpenAngles == 0) {

3554 FormatTok = Tokens->setPosition(StoredPosition);

3555 parseRequiresExpression();

3556 return false;

3557 }

3558 break;

3559 case tok::eof:

3560

3561 Lookahead = 50;

3562 break;

3563 case tok::coloncolon:

3564 LastWasColonColon = true;

3565 break;

3566 case tok::kw_decltype:

3567 case tok::identifier:

3568 if (FoundType && !LastWasColonColon && OpenAngles == 0) {

3569 FormatTok = Tokens->setPosition(StoredPosition);

3570 parseRequiresExpression();

3571 return false;

3572 }

3573 FoundType = true;

3574 LastWasColonColon = false;

3575 break;

3576 case tok::less:

3577 ++OpenAngles;

3578 break;

3579 case tok::greater:

3580 --OpenAngles;

3581 break;

3582 default:

3583 if (NextToken->isTypeName(LangOpts)) {

3584 FormatTok = Tokens->setPosition(StoredPosition);

3585 parseRequiresExpression();

3586 return false;

3587 }

3588 break;

3589 }

3590 }

3591

3592 FormatTok = Tokens->setPosition(StoredPosition);

3593 parseRequiresClause();

3594 return true;

3595}

3596

3597

3598

3599

3600

3601

3602void UnwrappedLineParser::parseRequiresClause() {

3603 assert(FormatTok->is(tok::kw_requires) && "'requires' expected");

3604

3605

3606

3607

3608 bool InRequiresExpression =

3609 !FormatTok->Previous ||

3610 FormatTok->Previous->is(TT_RequiresExpressionLBrace);

3611

3612 FormatTok->setFinalizedType(InRequiresExpression

3613 ? TT_RequiresClauseInARequiresExpression

3614 : TT_RequiresClause);

3615 nextToken();

3616

3617

3618

3619 parseConstraintExpression();

3620

3621 if (!InRequiresExpression && FormatTok->Previous)

3622 FormatTok->Previous->ClosesRequiresClause = true;

3623}

3624

3625

3626

3627

3628

3629

3630void UnwrappedLineParser::parseRequiresExpression() {

3631 assert(FormatTok->is(tok::kw_requires) && "'requires' expected");

3632

3633 FormatTok->setFinalizedType(TT_RequiresExpression);

3634 nextToken();

3635

3636 if (FormatTok->is(tok::l_paren)) {

3637 FormatTok->setFinalizedType(TT_RequiresExpressionLParen);

3638 parseParens();

3639 }

3640

3641 if (FormatTok->is(tok::l_brace)) {

3642 FormatTok->setFinalizedType(TT_RequiresExpressionLBrace);

3643 parseChildBlock();

3644 }

3645}

3646

3647

3648

3649

3650

3651void UnwrappedLineParser::parseConstraintExpression() {

3652

3653

3654

3655

3656

3657

3658 bool LambdaNextTimeAllowed = true;

3659

3660

3661

3662

3663

3664

3665

3666

3667

3668 bool TopLevelParensAllowed = true;

3669

3670 do {

3671 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed, false);

3672

3673 switch (FormatTok->Tok.getKind()) {

3674 case tok::kw_requires:

3675 parseRequiresExpression();

3676 break;

3677

3678 case tok::l_paren:

3679 if (!TopLevelParensAllowed)

3680 return;

3681 parseParens(TT_BinaryOperator);

3682 TopLevelParensAllowed = false;

3683 break;

3684

3685 case tok::l_square:

3686 if (!LambdaThisTimeAllowed || !tryToParseLambda())

3687 return;

3688 break;

3689

3690 case tok::kw_const:

3691 case tok:🚛

3692 case tok::kw_class:

3693 case tok::kw_struct:

3694 case tok::kw_union:

3695 return;

3696

3697 case tok::l_brace:

3698

3699 return;

3700

3701 case tok::ampamp:

3702 case tok::pipepipe:

3703 FormatTok->setFinalizedType(TT_BinaryOperator);

3704 nextToken();

3705 LambdaNextTimeAllowed = true;

3706 TopLevelParensAllowed = true;

3707 break;

3708

3709 case tok::comma:

3710 case tok::comment:

3711 LambdaNextTimeAllowed = LambdaThisTimeAllowed;

3712 nextToken();

3713 break;

3714

3715 case tok::kw_sizeof:

3716 case tok::greater:

3717 case tok::greaterequal:

3718 case tok::greatergreater:

3719 case tok::less:

3720 case tok::lessequal:

3721 case tok::lessless:

3722 case tok::equalequal:

3723 case tok::exclaim:

3724 case tok::exclaimequal:

3725 case tok:➕

3726 case tok:➖

3727 case tok:⭐

3728 case tok::slash:

3729 LambdaNextTimeAllowed = true;

3730 TopLevelParensAllowed = true;

3731

3732 nextToken();

3733 break;

3734

3735 case tok::numeric_constant:

3736 case tok::coloncolon:

3737 case tok::kw_true:

3738 case tok::kw_false:

3739 TopLevelParensAllowed = false;

3740

3741 nextToken();

3742 break;

3743

3744 case tok::kw_static_cast:

3745 case tok::kw_const_cast:

3746 case tok::kw_reinterpret_cast:

3747 case tok::kw_dynamic_cast:

3748 nextToken();

3749 if (FormatTok->isNot(tok::less))

3750 return;

3751

3752 nextToken();

3753 parseBracedList(true);

3754 break;

3755

3756 default:

3757 if (!FormatTok->Tok.getIdentifierInfo()) {

3758

3759

3760 return;

3761 }

3762

3763

3764

3765

3766

3767 assert(FormatTok->Previous);

3768 switch (FormatTok->Previous->Tok.getKind()) {

3769 case tok::coloncolon:

3770 case tok::ampamp:

3771 case tok::pipepipe:

3772 case tok::exclaim:

3773 case tok::kw_requires:

3774 case tok::equal:

3775 break;

3776 default:

3777 return;

3778 }

3779

3780

3781 nextToken();

3782 if (FormatTok->is(tok::less)) {

3783 nextToken();

3784 parseBracedList(true);

3785 }

3786 TopLevelParensAllowed = false;

3787 break;

3788 }

3789 } while (eof());

3790}

3791

3792bool UnwrappedLineParser::parseEnum() {

3793 const FormatToken &InitialToken = *FormatTok;

3794

3795

3796 if (FormatTok->is(tok::kw_enum))

3797 nextToken();

3798

3799

3800

3801

3802 if (Style.isJavaScript() && FormatTok->isOneOf(tok::colon, tok::question))

3803 return false;

3804

3805

3806 if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))

3807 return false;

3808

3809 if (IsCpp) {

3810

3811 if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))

3812 nextToken();

3813 while (FormatTok->is(tok::l_square))

3814 if (!handleCppAttributes())

3815 return false;

3816 }

3817

3818 while (FormatTok->Tok.getIdentifierInfo() ||

3819 FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,

3820 tok::greater, tok::comma, tok::question,

3821 tok::l_square)) {

3822 if (Style.isVerilog()) {

3823 FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);

3824 nextToken();

3825

3826 while (FormatTok->is(tok::l_square))

3827 parseSquare();

3828 } else {

3829 nextToken();

3830 }

3831

3832 if (FormatTok->is(tok::l_paren))

3833 parseParens();

3834 if (FormatTok->is(tok::identifier)) {

3835 nextToken();

3836

3837

3838 if (IsCpp && FormatTok->is(tok::identifier))

3839 return false;

3840 }

3841 }

3842

3843

3844 if (FormatTok->isNot(tok::l_brace))

3845 return true;

3846 FormatTok->setFinalizedType(TT_EnumLBrace);

3847 FormatTok->setBlockKind(BK_Block);

3848

3849 if (Style.isJava()) {

3850

3851 parseJavaEnumBody();

3852 return true;

3853 }

3854 if (Style.Language == FormatStyle::LK_Proto) {

3855 parseBlock(true);

3856 return true;

3857 }

3858

3859 if (!Style.AllowShortEnumsOnASingleLine &&

3861 addUnwrappedLine();

3862 }

3863

3864 nextToken();

3865 if (!Style.AllowShortEnumsOnASingleLine) {

3866 addUnwrappedLine();

3867 Line->Level += 1;

3868 }

3869 bool HasError = !parseBracedList(false, true);

3870 if (!Style.AllowShortEnumsOnASingleLine)

3871 Line->Level -= 1;

3872 if (HasError) {

3873 if (FormatTok->is(tok::semi))

3874 nextToken();

3875 addUnwrappedLine();

3876 }

3877 setPreviousRBraceType(TT_EnumRBrace);

3878 return true;

3879

3880

3881

3882

3883}

3884

3885bool UnwrappedLineParser::parseStructLike() {

3886

3887

3888 parseRecord();

3889

3890 if (Style.isJava() || Style.isJavaScript() || Style.isCSharp()) {

3891 if (FormatTok->is(tok::semi))

3892 nextToken();

3893 addUnwrappedLine();

3894 return true;

3895 }

3896 return false;

3897}

3898

3899namespace {

3900

3901

3902class ScopedTokenPosition {

3903 unsigned StoredPosition;

3904 FormatTokenSource *Tokens;

3905

3906public:

3907 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {

3908 assert(Tokens && "Tokens expected to not be null");

3909 StoredPosition = Tokens->getPosition();

3910 }

3911

3912 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }

3913};

3914}

3915

3916

3917

3918bool UnwrappedLineParser::tryToParseSimpleAttribute() {

3919 ScopedTokenPosition AutoPosition(Tokens);

3921

3922 if (Tok->isNot(tok::l_square))

3923 return false;

3924

3925

3926 while (Tok->isNot(tok::eof)) {

3927 if (Tok->is(tok::r_square))

3928 break;

3929 Tok = Tokens->getNextToken();

3930 }

3931 if (Tok->is(tok::eof))

3932 return false;

3933 Tok = Tokens->getNextToken();

3934 if (Tok->isNot(tok::r_square))

3935 return false;

3936 Tok = Tokens->getNextToken();

3937 if (Tok->is(tok::semi))

3938 return false;

3939 return true;

3940}

3941

3942void UnwrappedLineParser::parseJavaEnumBody() {

3943 assert(FormatTok->is(tok::l_brace));

3944 const FormatToken *OpeningBrace = FormatTok;

3945

3946

3947

3948

3949 unsigned StoredPosition = Tokens->getPosition();

3950 bool IsSimple = true;

3952 while (Tok->isNot(tok::eof)) {

3953 if (Tok->is(tok::r_brace))

3954 break;

3955 if (Tok->isOneOf(tok::l_brace, tok::semi)) {

3956 IsSimple = false;

3957 break;

3958 }

3959

3960

3961 Tok = Tokens->getNextToken();

3962 }

3963 FormatTok = Tokens->setPosition(StoredPosition);

3964

3965 if (IsSimple) {

3966 nextToken();

3967 parseBracedList();

3968 addUnwrappedLine();

3969 return;

3970 }

3971

3972

3973

3974 nextToken();

3975 addUnwrappedLine();

3976 ++Line->Level;

3977

3978

3979 while (eof()) {

3980 if (FormatTok->is(tok::l_brace)) {

3981

3982 parseBlock(true, 1u,

3983 false);

3984 } else if (FormatTok->is(tok::l_paren)) {

3985 parseParens();

3986 } else if (FormatTok->is(tok::comma)) {

3987 nextToken();

3988 addUnwrappedLine();

3989 } else if (FormatTok->is(tok::semi)) {

3990 nextToken();

3991 addUnwrappedLine();

3992 break;

3993 } else if (FormatTok->is(tok::r_brace)) {

3994 addUnwrappedLine();

3995 break;

3996 } else {

3997 nextToken();

3998 }

3999 }

4000

4001

4002 parseLevel(OpeningBrace);

4003 nextToken();

4004 --Line->Level;

4005 addUnwrappedLine();

4006}

4007

4008void UnwrappedLineParser::parseRecord(bool ParseAsExpr, bool IsJavaRecord) {

4009 assert(!IsJavaRecord || FormatTok->is(Keywords.kw_record));

4010 const FormatToken &InitialToken = *FormatTok;

4011 nextToken();

4012

4014 IsJavaRecord && FormatTok->is(tok::identifier) ? FormatTok : nullptr;

4015 bool IsDerived = false;

4016 auto IsNonMacroIdentifier = [](const FormatToken *Tok) {

4017 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();

4018 };

4019

4020

4021 bool JSPastExtendsOrImplements = false;

4022

4023

4024

4025 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,

4026 tok::kw_alignas, tok::l_square) ||

4027 FormatTok->isAttribute() ||

4028 ((Style.isJava() || Style.isJavaScript()) &&

4029 FormatTok->isOneOf(tok::period, tok::comma))) {

4030 if (Style.isJavaScript() &&

4031 FormatTok->isOneOf(Keywords.kw_extends, Keywords.kw_implements)) {

4032 JSPastExtendsOrImplements = true;

4033

4034

4035

4036 nextToken();

4037 if (FormatTok->is(tok::l_brace)) {

4038 tryToParseBracedList();

4039 continue;

4040 }

4041 }

4042 if (FormatTok->is(tok::l_square) && handleCppAttributes())

4043 continue;

4045 nextToken();

4046 switch (FormatTok->Tok.getKind()) {

4047 case tok::l_paren:

4048

4049 if (IsJavaRecord || !IsNonMacroIdentifier(Previous) ||

4050

4051 Previous->Previous == &InitialToken) {

4052 parseParens();

4053 }

4054 break;

4055 case tok::coloncolon:

4056 case tok::hashhash:

4057 break;

4058 default:

4059 if (JSPastExtendsOrImplements || ClassName ||

4060 Previous->isNot(tok::identifier) || Previous->is(TT_AttributeMacro)) {

4061 break;

4062 }

4066 }

4067 }

4068 }

4069

4070 auto IsListInitialization = [&] {

4071 if (!ClassName || IsDerived || JSPastExtendsOrImplements)

4072 return false;

4073 assert(FormatTok->is(tok::l_brace));

4074 const auto *Prev = FormatTok->getPreviousNonComment();

4075 assert(Prev);

4076 return Prev != ClassName && Prev->is(tok::identifier) &&

4077 Prev->isNot(Keywords.kw_final) && tryToParseBracedList();

4078 };

4079

4080 if (FormatTok->isOneOf(tok::colon, tok::less)) {

4081 int AngleNestingLevel = 0;

4082 do {

4083 if (FormatTok->is(tok::less))

4084 ++AngleNestingLevel;

4085 else if (FormatTok->is(tok::greater))

4086 --AngleNestingLevel;

4087

4088 if (AngleNestingLevel == 0) {

4089 if (FormatTok->is(tok::colon)) {

4090 IsDerived = true;

4091 } else if (!IsDerived && FormatTok->is(tok::identifier) &&

4092 FormatTok->Previous->is(tok::coloncolon)) {

4093 ClassName = FormatTok;

4094 } else if (FormatTok->is(tok::l_paren) &&

4095 IsNonMacroIdentifier(FormatTok->Previous)) {

4096 break;

4097 }

4098 }

4099 if (FormatTok->is(tok::l_brace)) {

4100 if (AngleNestingLevel == 0 && IsListInitialization())

4101 return;

4102 calculateBraceTypes(true);

4103 if (!tryToParseBracedList())

4104 break;

4105 }

4106 if (FormatTok->is(tok::l_square)) {

4109 Previous->isTypeOrIdentifier(LangOpts))) {

4110

4111

4112 if (!tryToParseLambda())

4113 continue;

4114 } else {

4115 parseSquare();

4116 continue;

4117 }

4118 }

4119 if (FormatTok->is(tok::semi))

4120 return;

4121 if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) {

4122 addUnwrappedLine();

4123 nextToken();

4124 parseCSharpGenericTypeConstraint();

4125 break;

4126 }

4127 nextToken();

4128 } while (eof());

4129 }

4130

4131 auto GetBraceTypes =

4132 [](const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {

4133 switch (RecordTok.Tok.getKind()) {

4134 case tok::kw_class:

4135 return {TT_ClassLBrace, TT_ClassRBrace};

4136 case tok::kw_struct:

4137 return {TT_StructLBrace, TT_StructRBrace};

4138 case tok::kw_union:

4139 return {TT_UnionLBrace, TT_UnionRBrace};

4140 default:

4141

4142 return {TT_RecordLBrace, TT_RecordRBrace};

4143 }

4144 };

4145 if (FormatTok->is(tok::l_brace)) {

4146 if (IsListInitialization())

4147 return;

4148 if (ClassName)

4149 ClassName->setFinalizedType(TT_ClassHeadName);

4150 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);

4151 FormatTok->setFinalizedType(OpenBraceType);

4152 if (ParseAsExpr) {

4153 parseChildBlock();

4154 } else {

4156 addUnwrappedLine();

4157

4158 unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;

4159 parseBlock(true, AddLevels, false);

4160 }

4161 setPreviousRBraceType(ClosingBraceType);

4162 }

4163

4164

4165

4166}

4167

4168void UnwrappedLineParser::parseObjCMethod() {

4169 assert(FormatTok->isOneOf(tok::l_paren, tok::identifier) &&

4170 "'(' or identifier expected.");

4171 do {

4172 if (FormatTok->is(tok::semi)) {

4173 nextToken();

4174 addUnwrappedLine();

4175 return;

4176 } else if (FormatTok->is(tok::l_brace)) {

4177 if (Style.BraceWrapping.AfterFunction)

4178 addUnwrappedLine();

4179 parseBlock();

4180 addUnwrappedLine();

4181 return;

4182 } else {

4183 nextToken();

4184 }

4185 } while (eof());

4186}

4187

4188void UnwrappedLineParser::parseObjCProtocolList() {

4189 assert(FormatTok->is(tok::less) && "'<' expected.");

4190 do {

4191 nextToken();

4192

4193 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))

4194 return;

4195 } while (eof() && FormatTok->isNot(tok::greater));

4196 nextToken();

4197}

4198

4199void UnwrappedLineParser::parseObjCUntilAtEnd() {

4200 do {

4201 if (FormatTok->is(tok::objc_end)) {

4202 nextToken();

4203 addUnwrappedLine();

4204 break;

4205 }

4206 if (FormatTok->is(tok::l_brace)) {

4207 parseBlock();

4208

4209 addUnwrappedLine();

4210 } else if (FormatTok->is(tok::r_brace)) {

4211

4212 nextToken();

4213 addUnwrappedLine();

4214 } else if (FormatTok->isOneOf(tok::minus, tok::plus)) {

4215 nextToken();

4216 parseObjCMethod();

4217 } else {

4218 parseStructuralElement();

4219 }

4220 } while (eof());

4221}

4222

4223void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {

4224 assert(FormatTok->isOneOf(tok::objc_interface, tok::objc_implementation));

4225 nextToken();

4226 nextToken();

4227

4228

4229

4230 if (FormatTok->is(tok::less))

4231 parseObjCLightweightGenerics();

4232 if (FormatTok->is(tok::colon)) {

4233 nextToken();

4234 nextToken();

4235

4236 if (FormatTok->is(tok::less))

4237 parseObjCLightweightGenerics();

4238 } else if (FormatTok->is(tok::l_paren)) {

4239

4240 parseParens();

4241 }

4242

4243 if (FormatTok->is(tok::less))

4244 parseObjCProtocolList();

4245

4246 if (FormatTok->is(tok::l_brace)) {

4247 if (Style.BraceWrapping.AfterObjCDeclaration)

4248 addUnwrappedLine();

4249 parseBlock(true);

4250 }

4251

4252

4253

4254 addUnwrappedLine();

4255

4256 parseObjCUntilAtEnd();

4257}

4258

4259void UnwrappedLineParser::parseObjCLightweightGenerics() {

4260 assert(FormatTok->is(tok::less));

4261

4262

4263

4264

4265

4266

4267

4268 unsigned NumOpenAngles = 1;

4269 do {

4270 nextToken();

4271

4272 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))

4273 break;

4274 if (FormatTok->is(tok::less)) {

4275 ++NumOpenAngles;

4276 } else if (FormatTok->is(tok::greater)) {

4277 assert(NumOpenAngles > 0 && "'>' makes NumOpenAngles negative");

4278 --NumOpenAngles;

4279 }

4280 } while (eof() && NumOpenAngles != 0);

4281 nextToken();

4282}

4283

4284

4285

4286bool UnwrappedLineParser::parseObjCProtocol() {

4287 assert(FormatTok->is(tok::objc_protocol));

4288 nextToken();

4289

4290 if (FormatTok->is(tok::l_paren)) {

4291

4292 return false;

4293 }

4294

4295

4296

4297

4298

4299

4300 nextToken();

4301

4302 if (FormatTok->is(tok::less))

4303 parseObjCProtocolList();

4304

4305

4306 if (FormatTok->is(tok::semi)) {

4307 nextToken();

4308 addUnwrappedLine();

4309 return true;

4310 }

4311

4312 addUnwrappedLine();

4313 parseObjCUntilAtEnd();

4314 return true;

4315}

4316

4317void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {

4318 bool IsImport = FormatTok->is(Keywords.kw_import);

4319 assert(IsImport || FormatTok->is(tok::kw_export));

4320 nextToken();

4321

4322

4323 if (FormatTok->is(tok::kw_default))

4324 nextToken();

4325

4326

4327

4328

4329 if (FormatTok->is(Keywords.kw_async))

4330 nextToken();

4331 if (FormatTok->is(Keywords.kw_function)) {

4332 nextToken();

4333 return;

4334 }

4335

4336

4337

4338

4339

4340 if (!IsImport && FormatTok->isNoneOf(tok::l_brace, tok::star) &&

4341 !FormatTok->isStringLiteral() &&

4342 !(FormatTok->is(Keywords.kw_type) &&

4343 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {

4344 return;

4345 }

4346

4347 while (eof()) {

4348 if (FormatTok->is(tok::semi))

4349 return;

4350 if (Line->Tokens.empty()) {

4351

4352

4353 return;

4354 }

4355 if (FormatTok->is(tok::l_brace)) {

4356 FormatTok->setBlockKind(BK_Block);

4357 nextToken();

4358 parseBracedList();

4359 } else {

4360 nextToken();

4361 }

4362 }

4363}

4364

4365void UnwrappedLineParser::parseStatementMacro() {

4366 nextToken();

4367 if (FormatTok->is(tok::l_paren))

4368 parseParens();

4369 if (FormatTok->is(tok::semi))

4370 nextToken();

4371 addUnwrappedLine();

4372}

4373

4374void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {

4375

4376 while (true) {

4377 if (FormatTok->isOneOf(tok::star, tok::period, tok::periodstar,

4378 tok::coloncolon, tok::hash) ||

4379 Keywords.isVerilogIdentifier(*FormatTok)) {

4380 nextToken();

4381 } else if (FormatTok->is(tok::l_square)) {

4382 parseSquare();

4383 } else {

4384 break;

4385 }

4386 }

4387}

4388

4389void UnwrappedLineParser::parseVerilogSensitivityList() {

4390 if (FormatTok->isNot(tok::at))

4391 return;

4392 nextToken();

4393

4394 if (FormatTok->is(tok::at))

4395 nextToken();

4396 switch (FormatTok->Tok.getKind()) {

4397 case tok:⭐

4398 nextToken();

4399 break;

4400 case tok::l_paren:

4401 parseParens();

4402 break;

4403 default:

4404 parseVerilogHierarchyIdentifier();

4405 break;

4406 }

4407}

4408

4409unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {

4410 unsigned AddLevels = 0;

4411

4412 if (FormatTok->is(Keywords.kw_clocking)) {

4413 nextToken();

4414 if (Keywords.isVerilogIdentifier(*FormatTok))

4415 nextToken();

4416 parseVerilogSensitivityList();

4417 if (FormatTok->is(tok::semi))

4418 nextToken();

4419 } else if (FormatTok->isOneOf(tok::kw_case, Keywords.kw_casex,

4420 Keywords.kw_casez, Keywords.kw_randcase,

4421 Keywords.kw_randsequence)) {

4422 if (Style.IndentCaseLabels)

4423 AddLevels++;

4424 nextToken();

4425 if (FormatTok->is(tok::l_paren)) {

4426 FormatTok->setFinalizedType(TT_ConditionLParen);

4427 parseParens();

4428 }

4429 if (FormatTok->isOneOf(Keywords.kw_inside, Keywords.kw_matches))

4430 nextToken();

4431

4432 } else {

4433

4434 nextToken();

4435

4436

4437 while (true) {

4438 if (FormatTok->is(tok::l_square)) {

4439 auto Prev = FormatTok->getPreviousNonComment();

4440 if (Prev && Keywords.isVerilogIdentifier(*Prev))

4441 Prev->setFinalizedType(TT_VerilogDimensionedTypeName);

4442 parseSquare();

4443 } else if (Keywords.isVerilogIdentifier(*FormatTok) ||

4444 FormatTok->isOneOf(tok::hash, tok::hashhash, tok::coloncolon,

4445 Keywords.kw_automatic, tok::kw_static)) {

4446 nextToken();

4447 } else {

4448 break;

4449 }

4450 }

4451

4452 auto NewLine = [this]() {

4453 addUnwrappedLine();

4454 Line->IsContinuation = true;

4455 };

4456

4457

4458 while (FormatTok->is(Keywords.kw_import)) {

4459 NewLine();

4460 nextToken();

4461 parseVerilogHierarchyIdentifier();

4462 if (FormatTok->is(tok::semi))

4463 nextToken();

4464 }

4465

4466

4467 if (FormatTok->is(Keywords.kw_verilogHash)) {

4468 NewLine();

4469 nextToken();

4470 if (FormatTok->is(tok::l_paren)) {

4471 FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);

4472 parseParens();

4473 }

4474 }

4475 if (FormatTok->is(tok::l_paren)) {

4476 NewLine();

4477 FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);

4478 parseParens();

4479 }

4480

4481

4482 if (FormatTok->is(Keywords.kw_extends)) {

4483 NewLine();

4484 nextToken();

4485 parseVerilogHierarchyIdentifier();

4486 if (FormatTok->is(tok::l_paren))

4487 parseParens();

4488 }

4489 if (FormatTok->is(Keywords.kw_implements)) {

4490 NewLine();

4491 do {

4492 nextToken();

4493 parseVerilogHierarchyIdentifier();

4494 } while (FormatTok->is(tok::comma));

4495 }

4496

4497

4498 if (FormatTok->is(tok::at)) {

4499 NewLine();

4500 parseVerilogSensitivityList();

4501 }

4502

4503 if (FormatTok->is(tok::semi))

4504 nextToken(1);

4505 addUnwrappedLine();

4506 }

4507

4508 return AddLevels;

4509}

4510

4511void UnwrappedLineParser::parseVerilogTable() {

4512 assert(FormatTok->is(Keywords.kw_table));

4513 nextToken(1);

4514 addUnwrappedLine();

4515

4516 auto InitialLevel = Line->Level++;

4517 while (eof() && !Keywords.isVerilogEnd(*FormatTok)) {

4519 nextToken();

4520 if (Tok->is(tok::semi))

4521 addUnwrappedLine();

4522 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))

4523 Tok->setFinalizedType(TT_VerilogTableItem);

4524 }

4525 Line->Level = InitialLevel;

4526 nextToken(-1);

4527 addUnwrappedLine();

4528}

4529

4530void UnwrappedLineParser::parseVerilogCaseLabel() {

4531

4532

4533

4534

4535

4536 auto OrigLevel = Line->Level;

4537 auto FirstLine = CurrentLines->size();

4538 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))

4539 ++Line->Level;

4540 else if (!Style.IndentCaseBlocks && Keywords.isVerilogBegin(*FormatTok))

4541 --Line->Level;

4542 parseStructuralElement();

4543

4544

4545 if (CurrentLines->size() > FirstLine)

4546 (*CurrentLines)[FirstLine].Level = OrigLevel;

4547 Line->Level = OrigLevel;

4548}

4549

4550void UnwrappedLineParser::parseVerilogExtern() {

4551 assert(

4552 FormatTok->isOneOf(tok::kw_extern, tok::kw_export, Keywords.kw_import));

4553 nextToken();

4554

4555 if (FormatTok->is(tok::string_literal))

4556 nextToken();

4557 if (FormatTok->isOneOf(Keywords.kw_context, Keywords.kw_pure))

4558 nextToken();

4559 if (Keywords.isVerilogIdentifier(*FormatTok))

4560 nextToken();

4561 if (FormatTok->is(tok::equal))

4562 nextToken();

4563 if (Keywords.isVerilogHierarchy(*FormatTok))

4564 parseVerilogHierarchyHeader();

4565}

4566

4567bool UnwrappedLineParser::containsExpansion(const UnwrappedLine &Line) const {

4568 for (const auto &N : Line.Tokens) {

4569 if (N.Tok->MacroCtx)

4570 return true;

4571 for (const UnwrappedLine &Child : N.Children)

4572 if (containsExpansion(Child))

4573 return true;

4574 }

4575 return false;

4576}

4577

4578void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {

4579 if (Line->Tokens.empty())

4580 return;

4581 LLVM_DEBUG({

4582 if (!parsingPPDirective()) {

4583 llvm::dbgs() << "Adding unwrapped line:\n";

4584 printDebugInfo(*Line);

4585 }

4586 });

4587

4588

4589

4590

4591

4592 bool ClosesWhitesmithsBlock =

4593 Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex &&

4594 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;

4595

4596

4597

4598

4599 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {

4600 if (!Reconstruct)

4601 Reconstruct.emplace(Line->Level, Unexpanded);

4602 Reconstruct->addLine(*Line);

4603

4604

4605

4606

4607 CurrentExpandedLines.push_back(std::move(*Line));

4608

4609 if (Reconstruct->finished()) {

4610 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();

4611 assert(!Reconstructed.Tokens.empty() &&

4612 "Reconstructed must at least contain the macro identifier.");

4613 assert(!parsingPPDirective());

4614 LLVM_DEBUG({

4615 llvm::dbgs() << "Adding unexpanded line:\n";

4616 printDebugInfo(Reconstructed);

4617 });

4618 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;

4619 Lines.push_back(std::move(Reconstructed));

4620 CurrentExpandedLines.clear();

4621 Reconstruct.reset();

4622 }

4623 } else {

4624

4625

4626 assert(!Reconstruct || (CurrentLines != &Lines) || !PPStack.empty());

4627 CurrentLines->push_back(std::move(*Line));

4628 }

4629 Line->Tokens.clear();

4630 Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;

4631 Line->FirstStartColumn = 0;

4632 Line->IsContinuation = false;

4633 Line->SeenDecltypeAuto = false;

4634

4635 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)

4636 --Line->Level;

4637 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {

4638 CurrentLines->append(

4639 std::make_move_iterator(PreprocessorDirectives.begin()),

4640 std::make_move_iterator(PreprocessorDirectives.end()));

4641 PreprocessorDirectives.clear();

4642 }

4643

4644 FormatTok->Previous = nullptr;

4645}

4646

4647bool UnwrappedLineParser::eof() const { return FormatTok->is(tok::eof); }

4648

4649bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) {

4650 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&

4651 FormatTok.NewlinesBefore > 0;

4652}

4653

4654

4655

4656static bool

4659 const llvm::Regex &CommentPragmasRegex) {

4660 if (Line.Tokens.empty() || Style.ReflowComments != FormatStyle::RCS_Always)

4661 return false;

4662

4663 StringRef IndentContent = FormatTok.TokenText;

4664 if (FormatTok.TokenText.starts_with("//") ||

4665 FormatTok.TokenText.starts_with("/*")) {

4666 IndentContent = FormatTok.TokenText.substr(2);

4667 }

4668 if (CommentPragmasRegex.match(IndentContent))

4669 return false;

4670

4671

4672

4673

4674

4675

4676

4677

4678

4679

4680

4681

4682

4683

4684

4685

4686

4687

4688

4689

4690

4691

4692

4693

4694

4695

4696

4697

4698

4699

4700

4701

4702

4703

4704

4705

4706

4707

4708

4709

4710

4711

4712

4713

4714

4715

4716

4717

4718

4719

4720

4721

4722

4723

4724

4725

4726

4727

4728

4729

4730

4731

4732

4733

4734

4735

4736

4737 const FormatToken *MinColumnToken = Line.Tokens.front().Tok;

4738

4739

4740

4741 const FormatToken *PreviousToken = nullptr;

4743 if (PreviousToken && PreviousToken->is(tok::l_brace) &&

4745 MinColumnToken = PreviousToken;

4746 break;

4747 }

4748 PreviousToken = Node.Tok;

4749

4750

4752 MinColumnToken = Node.Tok;

4753 }

4754 if (PreviousToken && PreviousToken->is(tok::l_brace))

4755 MinColumnToken = PreviousToken;

4756

4758 MinColumnToken);

4759}

4760

4761void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {

4762 bool JustComments = Line->Tokens.empty();

4764

4765

4766

4767

4768

4769

4770

4771

4772 Tok->ContinuesLineCommentSection =

4773 continuesLineCommentSection(*Tok, *Line, Style, CommentPragmasRegex);

4774 if (isOnNewLine(*Tok) && JustComments && Tok->ContinuesLineCommentSection)

4775 addUnwrappedLine();

4776 pushToken(Tok);

4777 }

4778 if (NewlineBeforeNext && JustComments)

4779 addUnwrappedLine();

4780 CommentsBeforeNextToken.clear();

4781}

4782

4783void UnwrappedLineParser::nextToken(int LevelDifference) {

4784 if (eof())

4785 return;

4786 flushComments(isOnNewLine(*FormatTok));

4787 pushToken(FormatTok);

4789 if (!Style.isJavaScript())

4790 readToken(LevelDifference);

4791 else

4792 readTokenWithJavaScriptASI();

4793 FormatTok->Previous = Previous;

4794 if (Style.isVerilog()) {

4795

4796

4797

4798

4799

4800

4801 if (Keywords.isVerilogEnd(*FormatTok))

4802 FormatTok->Tok.setKind(tok::r_brace);

4803 }

4804}

4805

4806void UnwrappedLineParser::distributeComments(

4808

4809

4810

4811

4812

4813

4814

4815

4816

4817

4818

4819

4820

4821

4822

4823

4824

4825

4826 if (Comments.empty())

4827 return;

4828 bool ShouldPushCommentsInCurrentLine = true;

4829 bool HasTrailAlignedWithNextToken = false;

4830 unsigned StartOfTrailAlignedWithNextToken = 0;

4831 if (NextTok) {

4832

4833 for (unsigned i = Comments.size() - 1; i > 0; --i) {

4834 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {

4835 HasTrailAlignedWithNextToken = true;

4836 StartOfTrailAlignedWithNextToken = i;

4837 }

4838 }

4839 }

4840 for (unsigned i = 0, e = Comments.size(); i < e; ++i) {

4842 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {

4843 FormatTok->ContinuesLineCommentSection = false;

4844 } else {

4846 *FormatTok, *Line, Style, CommentPragmasRegex);

4847 }

4848 if (!FormatTok->ContinuesLineCommentSection &&

4849 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {

4850 ShouldPushCommentsInCurrentLine = false;

4851 }

4852 if (ShouldPushCommentsInCurrentLine)

4853 pushToken(FormatTok);

4854 else

4855 CommentsBeforeNextToken.push_back(FormatTok);

4856 }

4857}

4858

4859void UnwrappedLineParser::readToken(int LevelDifference) {

4861 bool PreviousWasComment = false;

4862 bool FirstNonCommentOnLine = false;

4863 do {

4864 FormatTok = Tokens->getNextToken();

4865 assert(FormatTok);

4866 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,

4867 TT_ConflictAlternative)) {

4868 if (FormatTok->is(TT_ConflictStart))

4869 conditionalCompilationStart(false);

4870 else if (FormatTok->is(TT_ConflictAlternative))

4871 conditionalCompilationAlternative();

4872 else if (FormatTok->is(TT_ConflictEnd))

4873 conditionalCompilationEnd();

4874 FormatTok = Tokens->getNextToken();

4875 FormatTok->MustBreakBefore = true;

4876 FormatTok->MustBreakBeforeFinalized = true;

4877 }

4878

4879 auto IsFirstNonCommentOnLine = [](bool FirstNonCommentOnLine,

4881 bool PreviousWasComment) {

4883 return Tok.HasUnescapedNewline || Tok.IsFirst;

4884 };

4885

4886

4887

4888 if (PreviousWasComment)

4889 return FirstNonCommentOnLine || IsFirstOnLine(Tok);

4890 return IsFirstOnLine(Tok);

4891 };

4892

4893 FirstNonCommentOnLine = IsFirstNonCommentOnLine(

4894 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);

4895 PreviousWasComment = FormatTok->is(tok::comment);

4896

4897 while (Line->InPPDirective && FormatTok->is(tok::hash) &&

4898 FirstNonCommentOnLine) {

4899

4900

4901 const auto *Next = Tokens->peekNextToken();

4902 if ((Style.isVerilog() && !Keywords.isVerilogPPDirective(*Next)) ||

4903 (Style.isTableGen() &&

4904 Next->isNoneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,

4905 tok::pp_ifndef, tok::pp_endif))) {

4906 break;

4907 }

4908 distributeComments(Comments, FormatTok);

4909 Comments.clear();

4910

4911

4912 bool SwitchToPreprocessorLines = Line->Tokens.empty();

4913 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);

4914 assert((LevelDifference >= 0 ||

4915 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&

4916 "LevelDifference makes Line->Level negative");

4917 Line->Level += LevelDifference;

4918

4919

4920

4921 if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&

4922 PPBranchLevel > 0) {

4923 Line->Level += PPBranchLevel;

4924 }

4925 assert(Line->Level >= Line->UnbracedBodyLevel);

4926 Line->Level -= Line->UnbracedBodyLevel;

4927 flushComments(isOnNewLine(*FormatTok));

4928 parsePPDirective();

4929 PreviousWasComment = FormatTok->is(tok::comment);

4930 FirstNonCommentOnLine = IsFirstNonCommentOnLine(

4931 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);

4932 }

4933

4934 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&

4935 Line->InPPDirective) {

4936 continue;

4937 }

4938

4939 if (FormatTok->is(tok::identifier) &&

4940 Macros.defined(FormatTok->TokenText) &&

4941

4942 Line->InPPDirective) {

4944 unsigned Position = Tokens->getPosition();

4945

4946

4947

4948 auto PreCall = std::move(Line);

4949 Line.reset(new UnwrappedLine);

4950 bool OldInExpansion = InExpansion;

4951 InExpansion = true;

4952

4953 auto Args = parseMacroCall();

4954 InExpansion = OldInExpansion;

4955 assert(Line->Tokens.front().Tok == ID);

4956

4957 auto UnexpandedLine = std::move(Line);

4958

4959 Line = std::move(PreCall);

4960

4961 LLVM_DEBUG({

4962 llvm::dbgs() << "Macro call: " << ID->TokenText << "(";

4963 if (Args) {

4964 llvm::dbgs() << "(";

4965 for (const auto &Arg : Args.value())

4966 for (const auto &T : Arg)

4967 llvm::dbgs() << T->TokenText << " ";

4968 llvm::dbgs() << ")";

4969 }

4970 llvm::dbgs() << "\n";

4971 });

4972 if (Macros.objectLike(ID->TokenText) && Args &&

4973 Macros.hasArity(ID->TokenText, Args->size())) {

4974

4975

4976

4977

4978

4979 LLVM_DEBUG(llvm::dbgs()

4980 << "Macro \"" << ID->TokenText

4981 << "\" not overloaded for arity " << Args->size()

4982 << "or not function-like, using object-like overload.");

4983 Args.reset();

4984 UnexpandedLine->Tokens.resize(1);

4985 Tokens->setPosition(Position);

4986 nextToken();

4987 assert(!Args && Macros.objectLike(ID->TokenText));

4988 }

4989 if ((!Args && Macros.objectLike(ID->TokenText)) ||

4990 (Args && Macros.hasArity(ID->TokenText, Args->size()))) {

4991

4992

4993 Unexpanded[ID] = std::move(UnexpandedLine);

4995 Macros.expand(ID, std::move(Args));

4996 if (!Expansion.empty())

4997 FormatTok = Tokens->insertTokens(Expansion);

4998

4999 LLVM_DEBUG({

5000 llvm::dbgs() << "Expanded: ";

5001 for (const auto &T : Expansion)

5002 llvm::dbgs() << T->TokenText << " ";

5003 llvm::dbgs() << "\n";

5004 });

5005 } else {

5006 LLVM_DEBUG({

5007 llvm::dbgs() << "Did not expand macro \"" << ID->TokenText

5008 << "\", because it was used ";

5009 if (Args)

5010 llvm::dbgs() << "with " << Args->size();

5011 else

5012 llvm::dbgs() << "without";

5013 llvm::dbgs() << " arguments, which doesn't match any definition.\n";

5014 });

5015 Tokens->setPosition(Position);

5016 FormatTok = ID;

5017 }

5018 }

5019

5020 if (FormatTok->isNot(tok::comment)) {

5021 distributeComments(Comments, FormatTok);

5022 Comments.clear();

5023 return;

5024 }

5025

5026 Comments.push_back(FormatTok);

5027 } while (eof());

5028

5029 distributeComments(Comments, nullptr);

5030 Comments.clear();

5031}

5032

5033namespace {

5034template

5035void pushTokens(Iterator Begin, Iterator End,

5037 for (auto I = Begin; I != End; ++I) {

5038 Into.push_back(I->Tok);

5039 for (const auto &Child : I->Children)

5040 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);

5041 }

5042}

5043}

5044

5045std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>

5046UnwrappedLineParser::parseMacroCall() {

5047 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;

5048 assert(Line->Tokens.empty());

5049 nextToken();

5050 if (FormatTok->isNot(tok::l_paren))

5051 return Args;

5052 unsigned Position = Tokens->getPosition();

5054 nextToken();

5055 Args.emplace();

5056 auto ArgStart = std::prev(Line->Tokens.end());

5057

5059 do {

5060 switch (FormatTok->Tok.getKind()) {

5061 case tok::l_paren:

5063 nextToken();

5064 break;

5065 case tok::r_paren: {

5068 nextToken();

5069 break;

5070 }

5071 Args->push_back({});

5072 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());

5073 nextToken();

5074 return Args;

5075 }

5076 case tok::comma: {

5078 nextToken();

5079 break;

5080 }

5081 Args->push_back({});

5082 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());

5083 nextToken();

5084 ArgStart = std::prev(Line->Tokens.end());

5085 break;

5086 }

5087 default:

5088 nextToken();

5089 break;

5090 }

5091 } while (eof());

5092 Line->Tokens.resize(1);

5093 Tokens->setPosition(Position);

5094 FormatTok = Tok;

5095 return {};

5096}

5097

5098void UnwrappedLineParser::pushToken(FormatToken *Tok) {

5099 Line->Tokens.push_back(UnwrappedLineNode(Tok));

5100 if (AtEndOfPPLine) {

5101 auto &Tok = *Line->Tokens.back().Tok;

5102 Tok.MustBreakBefore = true;

5103 Tok.MustBreakBeforeFinalized = true;

5104 Tok.FirstAfterPPLine = true;

5105 AtEndOfPPLine = false;

5106 }

5107}

5108

5109}

5110}

This file defines the FormatTokenSource interface, which provides a token stream as well as the abili...

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

unsigned OriginalColumn

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

FormatToken * Previous

The previous token in the unwrapped line.

FormatToken * Next

The next token in the unwrapped line.

This file contains the main building blocks of macro support in clang-format.

static bool HasAttribute(const QualType &T)

This file implements a token annotator, i.e.

Defines the clang::TokenKind enum and support functions.

This file contains the declaration of the UnwrappedLineParser, which turns a stream of tokens into Un...

Implements an efficient mapping from strings to IdentifierInfo nodes.

Parser - This implements a parser for the C family of languages.

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

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

IdentifierInfo * getIdentifierInfo() const

bool isLiteral() const

Return true if this is a "literal", like a numeric constant, string, etc.

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

tok::TokenKind getKind() const

bool isOneOf(Ts... Ks) const

bool isNot(tok::TokenKind K) const

bool isNoneOf(Ts... Ks) const

CompoundStatementIndenter(UnwrappedLineParser *Parser, const FormatStyle &Style, unsigned &LineLevel)

Definition UnwrappedLineParser.cpp:133

~CompoundStatementIndenter()

Definition UnwrappedLineParser.cpp:147

CompoundStatementIndenter(UnwrappedLineParser *Parser, unsigned &LineLevel, bool WrapBrace, bool IndentBrace)

Definition UnwrappedLineParser.cpp:139

ScopedLineState(UnwrappedLineParser &Parser, bool SwitchToPreprocessorLines=false)

Definition UnwrappedLineParser.cpp:98

~ScopedLineState()

Definition UnwrappedLineParser.cpp:114

Interface for users of the UnwrappedLineParser to receive the parsed lines.

void parse()

Definition UnwrappedLineParser.cpp:196

UnwrappedLineParser(SourceManager &SourceMgr, const FormatStyle &Style, const AdditionalKeywords &Keywords, unsigned FirstStartColumn, ArrayRef< FormatToken * > Tokens, UnwrappedLineConsumer &Callback, llvm::SpecificBumpPtrAllocator< FormatToken > &Allocator, IdentifierTable &IdentTable)

Definition UnwrappedLineParser.cpp:154

static void hash_combine(std::size_t &seed, const T &v)

Definition UnwrappedLineParser.cpp:660

static bool mustBeJSIdentOrValue(const AdditionalKeywords &Keywords, const FormatToken *FormatTok)

Definition UnwrappedLineParser.cpp:1273

std::ostream & operator<<(std::ostream &Stream, const UnwrappedLine &Line)

Definition UnwrappedLineParser.cpp:90

static bool ShouldBreakBeforeBrace(const FormatStyle &Style, const FormatToken &InitialToken, const bool IsJavaRecord)

Definition UnwrappedLineParser.cpp:950

static bool tokenCanStartNewLine(const FormatToken &Tok)

Definition UnwrappedLineParser.cpp:1237

static bool continuesLineCommentSection(const FormatToken &FormatTok, const UnwrappedLine &Line, const FormatStyle &Style, const llvm::Regex &CommentPragmasRegex)

Definition UnwrappedLineParser.cpp:4657

static bool isC78Type(const FormatToken &Tok)

Definition UnwrappedLineParser.cpp:1302

static bool isJSDeclOrStmt(const AdditionalKeywords &Keywords, const FormatToken *FormatTok)

Definition UnwrappedLineParser.cpp:1282

static void markOptionalBraces(FormatToken *LeftBrace)

Definition UnwrappedLineParser.cpp:2840

static bool mustBeJSIdent(const AdditionalKeywords &Keywords, const FormatToken *FormatTok)

Definition UnwrappedLineParser.cpp:1258

static bool isIIFE(const UnwrappedLine &Line, const AdditionalKeywords &Keywords)

Definition UnwrappedLineParser.cpp:932

static bool isC78ParameterDecl(const FormatToken *Tok, const FormatToken *Next, const FormatToken *FuncName)

Definition UnwrappedLineParser.cpp:1315

static bool isGoogScope(const UnwrappedLine &Line)

Definition UnwrappedLineParser.cpp:914

static FormatToken * getLastNonComment(const UnwrappedLine &Line)

Definition UnwrappedLineParser.cpp:2790

TokenType

Determines the semantic type of a syntactic token, e.g.

LangOptions getFormattingLangOpts(const FormatStyle &Style)

TokenKind

Provides a simple uniform namespace for tokens from all C languages.

bool isLiteral(TokenKind K)

Return true if this is a "literal" kind, like a numeric constant, string, etc.

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

bool isLineComment(const FormatToken &FormatTok)

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

std::vector< std::string > Macros

A list of macros of the form = .

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

const FunctionProtoType * T

@ Type

The name was classified as a type.

bool continuesLineComment(const FormatToken &FormatTok, const FormatToken *Previous, const FormatToken *MinColumnToken)

@ Parens

New-expression has a C++98 paren-delimited initializer.

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

IdentifierInfo * kw_instanceof

IdentifierInfo * kw_implements

IdentifierInfo * kw_override

IdentifierInfo * kw_await

IdentifierInfo * kw_extends

IdentifierInfo * kw_async

IdentifierInfo * kw_abstract

IdentifierInfo * kw_interface

IdentifierInfo * kw_function

IdentifierInfo * kw_yield

IdentifierInfo * kw_where

IdentifierInfo * kw_throws

IdentifierInfo * kw_import

IdentifierInfo * kw_finally

Represents a complete lambda introducer.

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

bool Optional

Is optional and can be removed.

StringRef TokenText

The raw text of the token.

bool isNoneOf(Ts... Ks) const

unsigned NewlinesBefore

The number of newlines immediately before the Token.

bool is(tok::TokenKind Kind) const

bool isOneOf(A K1, B K2) const

unsigned IsFirst

Indicates that this is the first token of the file.

FormatToken * MatchingParen

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

FormatToken * Previous

The previous token in the unwrapped line.

An unwrapped line is a sequence of Token, that we would like to put on a single line if there was no ...

static const size_t kInvalidIndex