clang: lib/Format/UnwrappedLineParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/raw_os_ostream.h"
26#include "llvm/Support/raw_ostream.h"
27
28#include
29#include
30
31#define DEBUG_TYPE "format-parser"
32
34namespace format {
35
36namespace {
37
38void printLine(llvm::raw_ostream &OS, const UnwrappedLine &Line,
39 StringRef Prefix = "", bool PrintText = false) {
40 OS << Prefix << "Line(" << Line.Level << ", FSC=" << Line.FirstStartColumn
41 << ")" << (Line.InPPDirective ? " MACRO" : "") << ": ";
43 for (std::list::const_iterator I = Line.Tokens.begin(),
45 I != E; ++I) {
47 OS << Prefix;
49 }
50 OS << I->Tok->Tok.getName() << "["
51 << "T=" << (unsigned)I->Tok->getType()
52 << ", OC=" << I->Tok->OriginalColumn << ", \"" << I->Tok->TokenText
53 << "\"] ";
54 for (const auto *CI = I->Children.begin(), *CE = I->Children.end();
55 CI != CE; ++CI) {
56 OS << "\n";
57 printLine(OS, *CI, (Prefix + " ").str());
59 }
60 }
62 OS << "\n";
63}
64
65LLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line) {
66 printLine(llvm::dbgs(), Line);
67}
68
69class ScopedDeclarationState {
70public:
71 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
72 bool MustBeDeclaration)
73 : Line(Line), Stack(Stack) {
74 Line.MustBeDeclaration = MustBeDeclaration;
75 Stack.push_back(MustBeDeclaration);
76 }
77 ~ScopedDeclarationState() {
78 Stack.pop_back();
79 if (!Stack.empty())
80 Line.MustBeDeclaration = Stack.back();
81 else
82 Line.MustBeDeclaration = true;
83 }
84
85private:
86 UnwrappedLine &Line;
87 llvm::BitVector &Stack;
88};
89
90}
91
93 llvm::raw_os_ostream OS(Stream);
94 printLine(OS, Line);
95 return Stream;
96}
97
99public:
101 bool SwitchToPreprocessorLines = false)
103 if (SwitchToPreprocessorLines)
104 Parser.CurrentLines = &Parser.PreprocessorDirectives;
105 else if (.Line->Tokens.empty())
106 Parser.CurrentLines = &Parser.Line->Tokens.back().Children;
107 PreBlockLine = std::move(Parser.Line);
108 Parser.Line = std::make_unique();
109 Parser.Line->Level = PreBlockLine->Level;
110 Parser.Line->PPLevel = PreBlockLine->PPLevel;
111 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
112 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
113 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;
114 }
115
117 if (.Line->Tokens.empty())
118 Parser.addUnwrappedLine();
119 assert(Parser.Line->Tokens.empty());
120 Parser.Line = std::move(PreBlockLine);
121 if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
122 Parser.MustBreakBeforeNextToken = true;
123 Parser.CurrentLines = OriginalLines;
124 }
125
126private:
128
129 std::unique_ptr PreBlockLine;
131};
132
134public:
136 const FormatStyle &Style, unsigned &LineLevel)
138 Style.BraceWrapping.AfterControlStatement,
139 Style.BraceWrapping.IndentBraces) {}
141 bool WrapBrace, bool IndentBrace)
142 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
143 if (WrapBrace)
144 Parser->addUnwrappedLine();
145 if (IndentBrace)
146 ++LineLevel;
147 }
149
150private:
151 unsigned &LineLevel;
152 unsigned OldLineLevel;
153};
154
159 llvm::SpecificBumpPtrAllocator &Allocator,
162 CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()),
164 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
165 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
166 IncludeGuard(Style.IndentPPDirectives == FormatStyle::PPDIS_None
167 ? IG_Rejected
168 : IG_Inited),
169 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
170 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {
171 assert(IsCpp == LangOpts.CXXOperatorNames);
172}
173
174void UnwrappedLineParser::reset() {
175 PPBranchLevel = -1;
177 ? IG_Rejected
178 : IG_Inited;
179 IncludeGuardToken = nullptr;
181 CommentsBeforeNextToken.clear();
182 FormatTok = nullptr;
183 MustBreakBeforeNextToken = false;
184 IsDecltypeAutoFunction = false;
185 PreprocessorDirectives.clear();
186 CurrentLines = &Lines;
187 DeclarationScopeStack.clear();
188 NestedTooDeep.clear();
189 NestedLambdas.clear();
190 PPStack.clear();
191 Line->FirstStartColumn = FirstStartColumn;
192
193 if (!Unexpanded.empty())
195 Token->MacroCtx.reset();
196 CurrentExpandedLines.clear();
197 ExpandedLines.clear();
198 Unexpanded.clear();
199 InExpansion = false;
200 Reconstruct.reset();
201}
202
205 Line->FirstStartColumn = FirstStartColumn;
206 do {
207 LLVM_DEBUG(llvm::dbgs() << "----\n");
208 reset();
209 Tokens = &TokenSource;
210 TokenSource.reset();
211
212 readToken();
213 parseFile();
214
215
216
217 if (IncludeGuard == IG_Found) {
218 for (auto &Line : Lines)
219 if (Line.InPPDirective && Line.Level > 0)
220 --Line.Level;
221 }
222
223
224 assert(eof());
225 pushToken(FormatTok);
226 addUnwrappedLine();
227
228
229
230 if (!ExpandedLines.empty()) {
231 LLVM_DEBUG(llvm::dbgs() << "Expanded lines:\n");
232 for (const auto &Line : Lines) {
233 if (!Line.Tokens.empty()) {
234 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
235 if (it != ExpandedLines.end()) {
236 for (const auto &Expanded : it->second) {
237 LLVM_DEBUG(printDebugInfo(Expanded));
239 }
240 continue;
241 }
242 }
243 LLVM_DEBUG(printDebugInfo(Line));
245 }
247 }
248
249 LLVM_DEBUG(llvm::dbgs() << "Unwrapped lines:\n");
251 LLVM_DEBUG(printDebugInfo(Line));
253 }
255 Lines.clear();
256 while (!PPLevelBranchIndex.empty() &&
257 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
258 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
259 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
260 }
261 if (!PPLevelBranchIndex.empty()) {
262 ++PPLevelBranchIndex.back();
263 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
264 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
265 }
266 } while (!PPLevelBranchIndex.empty());
267}
268
269void UnwrappedLineParser::parseFile() {
270
271
272 bool MustBeDeclaration = !Line->InPPDirective && !Style.isJavaScript();
273 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
274 MustBeDeclaration);
276 parseBracedList();
277 else
278 parseLevel();
279
280
281
282
283
284
285
286
287
288
290 !CommentsBeforeNextToken.empty()) {
291 addUnwrappedLine();
292 }
293 flushComments(true);
294 addUnwrappedLine();
295}
296
297void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
298 do {
300 case tok::l_brace:
301 return;
302 default:
303 if (FormatTok->is(Keywords.kw_where)) {
304 addUnwrappedLine();
305 nextToken();
306 parseCSharpGenericTypeConstraint();
307 break;
308 }
309 nextToken();
310 break;
311 }
312 } while (!eof());
313}
314
315void UnwrappedLineParser::parseCSharpAttribute() {
316 int UnpairedSquareBrackets = 1;
317 do {
319 case tok::r_square:
320 nextToken();
321 --UnpairedSquareBrackets;
322 if (UnpairedSquareBrackets == 0) {
323 addUnwrappedLine();
324 return;
325 }
326 break;
327 case tok::l_square:
328 ++UnpairedSquareBrackets;
329 nextToken();
330 break;
331 default:
332 nextToken();
333 break;
334 }
335 } while (!eof());
336}
337
338bool UnwrappedLineParser::precededByCommentOrPPDirective() const {
339 if (!Lines.empty() && Lines.back().InPPDirective)
340 return true;
341
345}
346
347
348
349
350
351
352
353bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
354 IfStmtKind *IfKind,
355 FormatToken **IfLeftBrace) {
356 const bool InRequiresExpression =
357 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
358 const bool IsPrecededByCommentOrPPDirective =
360 FormatToken *IfLBrace = nullptr;
361 bool HasDoWhile = false;
362 bool HasLabel = false;
363 unsigned StatementCount = 0;
364 bool SwitchLabelEncountered = false;
365
366 do {
368 nextToken();
369 if (FormatTok->is(tok::l_paren))
370 parseParens();
371 continue;
372 }
374 if (FormatTok->is(TT_MacroBlockBegin))
375 Kind = tok::l_brace;
376 else if (FormatTok->is(TT_MacroBlockEnd))
377 Kind = tok::r_brace;
378
379 auto ParseDefault = [this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
380 &HasLabel, &StatementCount] {
381 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
382 HasDoWhile ? nullptr : &HasDoWhile,
383 HasLabel ? nullptr : &HasLabel);
384 ++StatementCount;
385 assert(StatementCount > 0 && "StatementCount overflow!");
386 };
387
388 switch (Kind) {
389 case tok::comment:
390 nextToken();
391 addUnwrappedLine();
392 break;
393 case tok::l_brace:
394 if (InRequiresExpression) {
396 } else if (FormatTok->Previous &&
398
399
400 ParseDefault();
401 continue;
402 }
403 if (!InRequiresExpression && FormatTok->isNot(TT_MacroBlockBegin)) {
404 if (tryToParseBracedList())
405 continue;
407 }
408 parseBlock();
409 ++StatementCount;
410 assert(StatementCount > 0 && "StatementCount overflow!");
411 addUnwrappedLine();
412 break;
413 case tok::r_brace:
414 if (OpeningBrace) {
416 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
417 return false;
418 }
419 if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
420 HasDoWhile || IsPrecededByCommentOrPPDirective ||
421 precededByCommentOrPPDirective()) {
422 return false;
423 }
424 const FormatToken *Next = Tokens->peekNextToken();
425 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
426 return false;
427 if (IfLeftBrace)
428 *IfLeftBrace = IfLBrace;
429 return true;
430 }
431 nextToken();
432 addUnwrappedLine();
433 break;
434 case tok::kw_default: {
435 unsigned StoredPosition = Tokens->getPosition();
437 FormatTok = Tokens->setPosition(StoredPosition);
438 if (!Next->isOneOf(tok::colon, tok::arrow)) {
439
440
441 parseStructuralElement();
442 break;
443 }
444
445 [[fallthrough]];
446 }
447 case tok::kw_case:
449 (Style.isJavaScript() && Line->MustBeDeclaration)) {
450
451
452
453
454 ParseDefault();
455 break;
456 }
457 if (!SwitchLabelEncountered &&
459 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
460 (Line->InPPDirective && Line->Level == 1))) {
461 ++Line->Level;
462 }
463 SwitchLabelEncountered = true;
464 parseStructuralElement();
465 break;
466 case tok::l_square:
468 nextToken();
469 parseCSharpAttribute();
470 break;
471 }
472 if (handleCppAttributes())
473 break;
474 [[fallthrough]];
475 default:
476 ParseDefault();
477 break;
478 }
479 } while (!eof());
480
481 return false;
482}
483
484void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
485
486
487
488
489 unsigned StoredPosition = Tokens->getPosition();
490 FormatToken *Tok = FormatTok;
491 const FormatToken *PrevTok = Tok->Previous;
492
493
494
495 struct StackEntry {
496 FormatToken *Tok;
497 const FormatToken *PrevTok;
498 };
499 SmallVector<StackEntry, 8> LBraceStack;
500 assert(Tok->is(tok::l_brace));
501
502 do {
504
505 if (!Line->InMacroBody && !Style.isTableGen()) {
506
507 while (NextTok->is(tok::hash)) {
509 if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))
510 break;
511 do {
513 } while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof));
514
515 while (NextTok->is(tok::comment))
517 }
518 }
519
520 switch (Tok->Tok.getKind()) {
521 case tok::l_brace:
523 if (PrevTok->isOneOf(tok::colon, tok::less)) {
524
525
526
527
528
529
530
531
532
534 } else if (PrevTok->is(tok::r_paren)) {
535
537 }
538 } else {
540 }
541 LBraceStack.push_back({Tok, PrevTok});
542 break;
543 case tok::r_brace:
544 if (LBraceStack.empty())
545 break;
546 if (auto *LBrace = LBraceStack.back().Tok; LBrace->is(BK_Unknown)) {
547 bool ProbablyBracedList = false;
549 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
550 } else if (LBrace->isNot(TT_EnumLBrace)) {
551
552
553 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
554 NextTok->OriginalColumn == 0;
555
556
557
558
559
560
561
562
563
564 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
565
566 ProbablyBracedList = ProbablyBracedList ||
568 NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
569 Keywords.kw_as));
570 ProbablyBracedList =
571 ProbablyBracedList ||
572 (IsCpp && (PrevTok->Tok.isLiteral() ||
573 NextTok->isOneOf(tok::l_paren, tok::arrow)));
574
575
576
577
578
579 ProbablyBracedList =
580 ProbablyBracedList ||
581 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
582 tok::r_paren, tok::r_square, tok::ellipsis);
583
584
585
586 ProbablyBracedList =
587 ProbablyBracedList ||
588 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
589 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
590 tok::greater));
591
592 ProbablyBracedList =
593 ProbablyBracedList ||
594 (NextTok->is(tok::identifier) &&
595 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
596
597 ProbablyBracedList = ProbablyBracedList ||
598 (NextTok->is(tok::semi) &&
599 (!ExpectClassBody || LBraceStack.size() != 1));
600
601 ProbablyBracedList =
602 ProbablyBracedList ||
603 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
604
605 if (!Style.isCSharp() && NextTok->is(tok::l_square)) {
606
607
609 ProbablyBracedList = NextTok->isNot(tok::l_square);
610 }
611
612
613 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
614 !FormatTok->Previous && NextTok->is(tok::eof) &&
615
616
617
618 !PrevTok->isOneOf(tok::semi, BK_Block, tok::colon)) {
619 ProbablyBracedList = true;
620 }
621 }
623 Tok->setBlockKind(BlockKind);
624 LBrace->setBlockKind(BlockKind);
625 }
626 LBraceStack.pop_back();
627 break;
628 case tok::identifier:
629 if (Tok->isNot(TT_StatementMacro))
630 break;
631 [[fallthrough]];
632 case tok::at:
633 case tok:🚛
634 case tok::kw_if:
635 case tok::kw_while:
636 case tok::kw_for:
637 case tok::kw_switch:
638 case tok::kw_try:
639 case tok::kw___try:
640 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(BK_Unknown))
641 LBraceStack.back().Tok->setBlockKind(BK_Block);
642 break;
643 default:
644 break;
645 }
646
647 PrevTok = Tok;
648 Tok = NextTok;
649 } while (Tok->isNot(tok::eof) && !LBraceStack.empty());
650
651
652 for (const auto &Entry : LBraceStack)
654 Entry.Tok->setBlockKind(BK_Block);
655
656 FormatTok = Tokens->setPosition(StoredPosition);
657}
658
659
660void UnwrappedLineParser::setPreviousRBraceType(TokenType Type) {
662 Prev && Prev->is(tok::r_brace)) {
664 }
665}
666
667template
669 std::hash hasher;
670 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
671}
672
673size_t UnwrappedLineParser::computePPHash() const {
674 size_t h = 0;
675 for (const auto &i : PPStack) {
678 }
679 return h;
680}
681
682
683
684
685
686bool UnwrappedLineParser::mightFitOnOneLine(
687 UnwrappedLine &ParsedLine, const FormatToken *OpeningBrace) const {
688 const auto ColumnLimit = Style.ColumnLimit;
689 if (ColumnLimit == 0)
690 return true;
691
692 auto &Tokens = ParsedLine.Tokens;
693 assert(!Tokens.empty());
694
695 const auto *LastToken = Tokens.back().Tok;
696 assert(LastToken);
697
698 SmallVector SavedTokens(Tokens.size());
699
700 int Index = 0;
701 for (const auto &Token : Tokens) {
702 assert(Token.Tok);
703 auto &SavedToken = SavedTokens[Index++];
704 SavedToken.Tok = new FormatToken;
705 SavedToken.Tok->copyFrom(*Token.Tok);
706 SavedToken.Children = std::move(Token.Children);
707 }
708
709 AnnotatedLine Line(ParsedLine);
710 assert(Line.Last == LastToken);
711
712 TokenAnnotator Annotator(Style, Keywords);
713 Annotator.annotate(Line);
714 Annotator.calculateFormattingInformation(Line);
715
716 auto Length = LastToken->TotalLength;
717 if (OpeningBrace) {
718 assert(OpeningBrace != Tokens.front().Tok);
719 if (auto Prev = OpeningBrace->Previous;
720 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
721 Length -= ColumnLimit;
722 }
723 Length -= OpeningBrace->TokenText.size() + 1;
724 }
725
726 if (const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
727 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
728 Length -= FirstToken->TokenText.size() + 1;
729 }
730
731 Index = 0;
732 for (auto &Token : Tokens) {
733 const auto &SavedToken = SavedTokens[Index++];
734 Token.Tok->copyFrom(*SavedToken.Tok);
735 Token.Children = std::move(SavedToken.Children);
736 delete SavedToken.Tok;
737 }
738
739
740 assert(!Line.InMacroBody);
741 assert(!Line.InPPDirective);
742 return Line.Level * Style.IndentWidth + Length <= ColumnLimit;
743}
744
745FormatToken *UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
746 unsigned AddLevels, bool MunchSemi,
747 bool KeepBraces,
748 IfStmtKind *IfKind,
749 bool UnindentWhitesmithsBraces) {
750 auto HandleVerilogBlockLabel = [this]() {
751
752 if (Style.isVerilog() && FormatTok->is(tok::colon)) {
753 nextToken();
755 nextToken();
756 }
757 };
758
759
760
761 const bool VerilogHierarchy =
763 assert((FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
765 (Keywords.isVerilogBegin(*FormatTok) || VerilogHierarchy))) &&
766 "'{' or macro block token expected");
767 FormatToken *Tok = FormatTok;
768 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
769 auto Index = CurrentLines->size();
770 const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);
772
773
774
775 if (!VerilogHierarchy && AddLevels > 0 &&
777 ++Line->Level;
778 }
779
780 size_t PPStartHash = computePPHash();
781
782 const unsigned InitialLevel = Line->Level;
783 if (VerilogHierarchy) {
784 AddLevels += parseVerilogHierarchyHeader();
785 } else {
786 nextToken(AddLevels);
787 HandleVerilogBlockLabel();
788 }
789
790
791 if (Line->Level > 300)
792 return nullptr;
793
794 if (MacroBlock && FormatTok->is(tok::l_paren))
795 parseParens();
796
797 size_t NbPreprocessorDirectives =
798 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
799 addUnwrappedLine();
800 size_t OpeningLineIndex =
801 CurrentLines->empty()
803 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
804
805
806
807
808 if (UnindentWhitesmithsBraces)
809 --Line->Level;
810
811 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
812 MustBeDeclaration);
814 Line->Level += AddLevels;
815
816 FormatToken *IfLBrace = nullptr;
817 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
818
819 if (eof())
820 return IfLBrace;
821
822 if (MacroBlock ? FormatTok->isNot(TT_MacroBlockEnd)
823 : FormatTok->isNot(tok::r_brace)) {
824 Line->Level = InitialLevel;
826 return IfLBrace;
827 }
828
829 if (FormatTok->is(tok::r_brace)) {
831 if (Tok->is(TT_NamespaceLBrace))
833 }
834
835 const bool IsFunctionRBrace =
836 FormatTok->is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
837
838 auto RemoveBraces = [=]() mutable {
839 if (!SimpleBlock)
840 return false;
841 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
842 assert(FormatTok->is(tok::r_brace));
843 const bool WrappedOpeningBrace = !Tok->Previous;
844 if (WrappedOpeningBrace && FollowedByComment)
845 return false;
846 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
847 if (KeepBraces && !HasRequiredIfBraces)
848 return false;
849 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
850 const FormatToken *Previous = Tokens->getPreviousToken();
853 return false;
854 }
855 assert(!CurrentLines->empty());
856 auto &LastLine = CurrentLines->back();
857 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
858 return false;
859 if (Tok->is(TT_ElseLBrace))
860 return true;
861 if (WrappedOpeningBrace) {
862 assert(Index > 0);
863 --Index;
864 Tok = nullptr;
865 }
866 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
867 };
868 if (RemoveBraces()) {
869 Tok->MatchingParen = FormatTok;
871 }
872
873 size_t PPEndHash = computePPHash();
874
875
876 nextToken(-AddLevels);
877
878
879
880
882 while (FormatTok->is(tok::semi)) {
884 nextToken();
885 }
886 }
887
888 HandleVerilogBlockLabel();
889
890 if (MacroBlock && FormatTok->is(tok::l_paren))
891 parseParens();
892
893 Line->Level = InitialLevel;
894
895 if (FormatTok->is(tok::kw_noexcept)) {
896
897 nextToken();
898 }
899
900 if (FormatTok->is(tok::arrow)) {
901
902
903 nextToken();
904 parseStructuralElement();
905 }
906
907 if (MunchSemi && FormatTok->is(tok::semi))
908 nextToken();
909
910 if (PPStartHash == PPEndHash) {
911 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
913
914 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
915 CurrentLines->size() - 1;
916 }
917 }
918
919 return IfLBrace;
920}
921
923
924
925 if (Line.Tokens.size() < 4)
926 return false;
927 auto I = Line.Tokens.begin();
928 if (I->Tok->TokenText != "goog")
929 return false;
930 ++I;
931 if (I->Tok->isNot(tok::period))
932 return false;
933 ++I;
934 if (I->Tok->TokenText != "scope")
935 return false;
936 ++I;
937 return I->Tok->is(tok::l_paren);
938}
939
942
943
944
945
946 if (Line.Tokens.size() < 3)
947 return false;
948 auto I = Line.Tokens.begin();
949 if (I->Tok->isNot(tok::l_paren))
950 return false;
951 ++I;
953 return false;
954 ++I;
955 return I->Tok->is(tok::l_paren);
956}
957
961 if (InitialToken.is(TT_NamespaceMacro))
962 Kind = tok::kw_namespace;
963
964 switch (Kind) {
965 case tok::kw_namespace:
967 case tok::kw_class:
969 case tok::kw_union:
971 case tok::kw_struct:
973 case tok::kw_enum:
975 default:
976 return false;
977 }
978}
979
980void UnwrappedLineParser::parseChildBlock() {
981 assert(FormatTok->is(tok::l_brace));
983 const FormatToken *OpeningBrace = FormatTok;
984 nextToken();
985 {
989 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
990 false);
991 Line->Level += SkipIndent ? 0 : 1;
992 parseLevel(OpeningBrace);
993 flushComments(isOnNewLine(*FormatTok));
994 Line->Level -= SkipIndent ? 0 : 1;
995 }
996 nextToken();
997}
998
999void UnwrappedLineParser::parsePPDirective() {
1000 assert(FormatTok->is(tok::hash) && "'#' expected");
1001 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
1002
1003 nextToken();
1004
1006 parsePPUnknown();
1007 return;
1008 }
1009
1011 case tok::pp_define:
1012 parsePPDefine();
1013 return;
1014 case tok::pp_if:
1015 parsePPIf(false);
1016 break;
1017 case tok::pp_ifdef:
1018 case tok::pp_ifndef:
1019 parsePPIf(true);
1020 break;
1021 case tok::pp_else:
1022 case tok::pp_elifdef:
1023 case tok::pp_elifndef:
1024 case tok::pp_elif:
1025 parsePPElse();
1026 break;
1027 case tok::pp_endif:
1028 parsePPEndIf();
1029 break;
1030 case tok::pp_pragma:
1031 parsePPPragma();
1032 break;
1033 case tok::pp_error:
1034 case tok::pp_warning:
1035 nextToken();
1036 if (!eof() && Style.isCpp())
1038 [[fallthrough]];
1039 default:
1040 parsePPUnknown();
1041 break;
1042 }
1043}
1044
1045void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) {
1046 size_t Line = CurrentLines->size();
1047 if (CurrentLines == &PreprocessorDirectives)
1048 Line += Lines.size();
1049
1050 if (Unreachable ||
1051 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1052 PPStack.push_back({PP_Unreachable, Line});
1053 } else {
1054 PPStack.push_back({PP_Conditional, Line});
1055 }
1056}
1057
1058void UnwrappedLineParser::conditionalCompilationStart(bool Unreachable) {
1059 ++PPBranchLevel;
1060 assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size());
1061 if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {
1062 PPLevelBranchIndex.push_back(0);
1063 PPLevelBranchCount.push_back(0);
1064 }
1065 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1066 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1067 conditionalCompilationCondition(Unreachable || Skip);
1068}
1069
1070void UnwrappedLineParser::conditionalCompilationAlternative() {
1071 if (!PPStack.empty())
1072 PPStack.pop_back();
1073 assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
1074 if (!PPChainBranchIndex.empty())
1075 ++PPChainBranchIndex.top();
1076 conditionalCompilationCondition(
1077 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1078 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1079}
1080
1081void UnwrappedLineParser::conditionalCompilationEnd() {
1082 assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
1083 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1084 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1085 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1086 }
1087
1088 if (PPBranchLevel > -1)
1089 --PPBranchLevel;
1090 if (!PPChainBranchIndex.empty())
1091 PPChainBranchIndex.pop();
1092 if (!PPStack.empty())
1093 PPStack.pop_back();
1094}
1095
1096void UnwrappedLineParser::parsePPIf(bool IfDef) {
1097 bool IfNDef = FormatTok->is(tok::pp_ifndef);
1098 nextToken();
1099 bool Unreachable = false;
1100 if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText == "0"))
1101 Unreachable = true;
1102 if (IfDef && !IfNDef && FormatTok->TokenText == "SWIG")
1103 Unreachable = true;
1104 conditionalCompilationStart(Unreachable);
1105 FormatToken *IfCondition = FormatTok;
1106
1107
1108 bool MaybeIncludeGuard = IfNDef;
1109 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1110 for (auto &Line : Lines) {
1111 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1112 MaybeIncludeGuard = false;
1113 IncludeGuard = IG_Rejected;
1114 break;
1115 }
1116 }
1117 }
1118 --PPBranchLevel;
1119 parsePPUnknown();
1120 ++PPBranchLevel;
1121 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1122 IncludeGuard = IG_IfNdefed;
1123 IncludeGuardToken = IfCondition;
1124 }
1125}
1126
1127void UnwrappedLineParser::parsePPElse() {
1128
1129 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1130 IncludeGuard = IG_Rejected;
1131
1132 assert(PPBranchLevel >= -1);
1133 if (PPBranchLevel == -1)
1134 conditionalCompilationStart(true);
1135 conditionalCompilationAlternative();
1136 --PPBranchLevel;
1137 parsePPUnknown();
1138 ++PPBranchLevel;
1139}
1140
1141void UnwrappedLineParser::parsePPEndIf() {
1142 conditionalCompilationEnd();
1143 parsePPUnknown();
1144
1145
1146 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1148 IncludeGuard = IG_Found;
1149 }
1150}
1151
1152void UnwrappedLineParser::parsePPDefine() {
1153 nextToken();
1154
1156 IncludeGuard = IG_Rejected;
1157 IncludeGuardToken = nullptr;
1158 parsePPUnknown();
1159 return;
1160 }
1161
1162 if (IncludeGuard == IG_IfNdefed &&
1164 IncludeGuard = IG_Defined;
1165 IncludeGuardToken = nullptr;
1166 for (auto &Line : Lines) {
1167 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1168 IncludeGuard = IG_Rejected;
1169 break;
1170 }
1171 }
1172 }
1173
1174
1175
1176
1177
1178
1179 FormatTok->Tok.setKind(tok::identifier);
1181 nextToken();
1182 if (FormatTok->Tok.getKind() == tok::l_paren &&
1184 parseParens();
1185 }
1187 Line->Level += PPBranchLevel + 1;
1188 addUnwrappedLine();
1189 ++Line->Level;
1190
1191 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1192 assert((int)Line->PPLevel >= 0);
1193 Line->InMacroBody = true;
1194
1196 while (!eof()) {
1198 FormatTok = Tokens->getNextToken();
1199 }
1200 addUnwrappedLine();
1201 return;
1202 }
1203
1204
1205
1206
1207
1208
1209 parseFile();
1210}
1211
1212void UnwrappedLineParser::parsePPPragma() {
1213 Line->InPragmaDirective = true;
1214 parsePPUnknown();
1215}
1216
1217void UnwrappedLineParser::parsePPUnknown() {
1218 while (!eof())
1219 nextToken();
1221 Line->Level += PPBranchLevel + 1;
1222 addUnwrappedLine();
1223}
1224
1225
1226
1227
1229
1230
1231 return !Tok.isOneOf(tok::semi, tok::l_brace,
1232
1233
1234 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1235 tok::less, tok::greater, tok::slash, tok::percent,
1236 tok::lessless, tok::greatergreater, tok::equal,
1237 tok::plusequal, tok::minusequal, tok::starequal,
1238 tok::slashequal, tok::percentequal, tok::ampequal,
1239 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1240 tok::lesslessequal,
1241
1242
1243
1244 tok::colon,
1245
1246 tok::kw_noexcept);
1247}
1248
1251
1252 return FormatTok->is(tok::identifier) &&
1258 Keywords.kw_let, Keywords.kw_var, tok::kw_const,
1262}
1263
1267 FormatTok->isOneOf(tok::kw_true, tok::kw_false) ||
1269}
1270
1271
1272
1275 return FormatTok->isOneOf(
1276 tok::kw_return, Keywords.kw_yield,
1277
1278 tok::kw_if, tok::kw_else,
1279
1280 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1281
1282 tok::kw_switch, tok::kw_case,
1283
1284 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.kw_finally,
1285
1286 tok::kw_const, tok::kw_class, Keywords.kw_var, Keywords.kw_let,
1288
1289 Keywords.kw_import, tok::kw_export);
1290}
1291
1292
1294 return Tok.isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1295 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1296 tok::identifier);
1297}
1298
1299
1300
1301
1302
1303
1304
1305
1308 assert(Tok);
1309 assert(Next);
1310 assert(FuncName);
1311
1312 if (FuncName->isNot(tok::identifier))
1313 return false;
1314
1316 if (!Prev || (Prev->isNot(tok::star) && (*Prev)))
1317 return false;
1318
1320 !Tok->isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1321 return false;
1322 }
1323
1324 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1325 return false;
1326
1328 if (!Tok || Tok->isNot(tok::r_paren))
1329 return false;
1330
1332 if (!Tok || Tok->isNot(tok::identifier))
1333 return false;
1334
1336}
1337
1338bool UnwrappedLineParser::parseModuleImport() {
1339 assert(FormatTok->is(Keywords.kw_import) && "'import' expected");
1340
1341 if (auto Token = Tokens->peekNextToken(true);
1343 ->isOneOf(tok::colon, tok::less, tok::string_literal)) {
1344 return false;
1345 }
1346
1347 nextToken();
1348 while (!eof()) {
1349 if (FormatTok->is(tok::colon)) {
1351 }
1352
1353 else if (FormatTok->is(tok::less)) {
1354 nextToken();
1355 while (!FormatTok->isOneOf(tok::semi, tok::greater, tok::eof)) {
1356
1357
1358 if (FormatTok->isNot(tok::comment) &&
1359 !FormatTok->TokenText.starts_with("//")) {
1361 }
1362 nextToken();
1363 }
1364 }
1365 if (FormatTok->is(tok::semi)) {
1366 nextToken();
1367 break;
1368 }
1369 nextToken();
1370 }
1371
1372 addUnwrappedLine();
1373 return true;
1374}
1375
1376
1377
1378
1379
1380
1381
1382
1383void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1384 FormatToken *Previous = FormatTok;
1385 readToken();
1386 FormatToken *Next = FormatTok;
1387
1388 bool IsOnSameLine =
1389 CommentsBeforeNextToken.empty()
1390 ? Next->NewlinesBefore == 0
1391 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1392 if (IsOnSameLine)
1393 return;
1394
1396 bool PreviousStartsTemplateExpr =
1397 Previous->is(TT_TemplateString) && Previous->TokenText.ends_with("${");
1398 if (PreviousMustBeValue || Previous->is(tok::r_paren)) {
1399
1400
1401 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1402 return LineNode.Tok->is(tok::at);
1403 });
1404 if (HasAt)
1405 return;
1406 }
1407 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1408 return addUnwrappedLine();
1410 bool NextEndsTemplateExpr =
1411 Next->is(TT_TemplateString) && Next->TokenText.starts_with("}");
1412 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1413 (PreviousMustBeValue ||
1414 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1415 tok::minusminus))) {
1416 return addUnwrappedLine();
1417 }
1418 if ((PreviousMustBeValue || Previous->is(tok::r_paren)) &&
1420 return addUnwrappedLine();
1421 }
1422}
1423
1424void UnwrappedLineParser::parseStructuralElement(
1425 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1426 FormatToken **IfLeftBrace, bool *HasDoWhile, bool *HasLabel) {
1428 FormatTok->is(tok::pp_include)) {
1429 nextToken();
1430 if (FormatTok->is(tok::string_literal))
1431 nextToken();
1432 addUnwrappedLine();
1433 return;
1434 }
1435
1436 if (IsCpp) {
1437 while (FormatTok->is(tok::l_square) && handleCppAttributes()) {
1438 }
1441 parseForOrWhileLoop(false);
1442 return;
1443 }
1445 parseForOrWhileLoop();
1446 return;
1447 }
1448 if (FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,
1450 parseIfThenElse(IfKind, false, true);
1451 return;
1452 }
1453
1454
1455 while (true) {
1458 nextToken();
1459 } else if (FormatTok->is(tok::l_paren) &&
1460 Tokens->peekNextToken()->is(tok::star)) {
1461 parseParens();
1462 } else {
1463 break;
1464 }
1465 }
1466 }
1467
1468
1472 nextToken();
1473 } else {
1474 parseAccessSpecifier();
1475 }
1476 return;
1477 }
1479 case tok::kw_asm:
1480 nextToken();
1481 if (FormatTok->is(tok::l_brace)) {
1483 nextToken();
1484 while (FormatTok && !eof()) {
1485 if (FormatTok->is(tok::r_brace)) {
1487 nextToken();
1488 addUnwrappedLine();
1489 break;
1490 }
1492 nextToken();
1493 }
1494 }
1495 break;
1496 case tok::kw_namespace:
1497 parseNamespace();
1498 return;
1499 case tok::kw_if: {
1500 if (Style.isJavaScript() && Line->MustBeDeclaration) {
1501
1502 break;
1503 }
1504 FormatToken *Tok = parseIfThenElse(IfKind);
1505 if (IfLeftBrace)
1506 *IfLeftBrace = Tok;
1507 return;
1508 }
1509 case tok::kw_for:
1510 case tok::kw_while:
1511 if (Style.isJavaScript() && Line->MustBeDeclaration) {
1512
1513 break;
1514 }
1515 parseForOrWhileLoop();
1516 return;
1517 case tok::kw_do:
1518 if (Style.isJavaScript() && Line->MustBeDeclaration) {
1519
1520 break;
1521 }
1522 parseDoWhile();
1523 if (HasDoWhile)
1524 *HasDoWhile = true;
1525 return;
1526 case tok::kw_switch:
1527 if (Style.isJavaScript() && Line->MustBeDeclaration) {
1528
1529 break;
1530 }
1531 parseSwitch(false);
1532 return;
1533 case tok::kw_default: {
1534
1536 break;
1537 if (Style.isJavaScript() && Line->MustBeDeclaration) {
1538
1539 break;
1540 }
1541 auto *Default = FormatTok;
1542 nextToken();
1543 if (FormatTok->is(tok::colon)) {
1545 parseLabel();
1546 return;
1547 }
1548 if (FormatTok->is(tok::arrow)) {
1550 Default->setFinalizedType(TT_SwitchExpressionLabel);
1551 parseLabel();
1552 return;
1553 }
1554
1555 break;
1556 }
1557 case tok::kw_case:
1558
1560 nextToken();
1561 return;
1562 }
1564 parseBlock();
1565 addUnwrappedLine();
1566 return;
1567 }
1568 if (Style.isJavaScript() && Line->MustBeDeclaration) {
1569
1570 nextToken();
1571 break;
1572 }
1573 parseCaseLabel();
1574 return;
1575 case tok::kw_goto:
1576 nextToken();
1577 if (FormatTok->is(tok::kw_case))
1578 nextToken();
1579 break;
1580 case tok::kw_try:
1581 case tok::kw___try:
1582 if (Style.isJavaScript() && Line->MustBeDeclaration) {
1583
1584 break;
1585 }
1586 parseTryCatch();
1587 return;
1588 case tok::kw_extern:
1589 nextToken();
1591
1592
1594 parseVerilogHierarchyHeader();
1595 return;
1596 }
1597 } else if (FormatTok->is(tok::string_literal)) {
1598 nextToken();
1599 if (FormatTok->is(tok::l_brace)) {
1601 addUnwrappedLine();
1602
1603
1604 unsigned AddLevels =
1609 ? 1u
1610 : 0u;
1611 parseBlock(true, AddLevels);
1612 addUnwrappedLine();
1613 return;
1614 }
1615 }
1616 break;
1617 case tok::kw_export:
1619 parseJavaScriptEs6ImportExport();
1620 return;
1621 }
1622 if (IsCpp) {
1623 nextToken();
1624 if (FormatTok->is(tok::kw_namespace)) {
1625 parseNamespace();
1626 return;
1627 }
1628 if (FormatTok->is(tok::l_brace)) {
1629 parseCppExportBlock();
1630 return;
1631 }
1632 if (FormatTok->is(Keywords.kw_import) && parseModuleImport())
1633 return;
1634 }
1635 break;
1636 case tok::kw_inline:
1637 nextToken();
1638 if (FormatTok->is(tok::kw_namespace)) {
1639 parseNamespace();
1640 return;
1641 }
1642 break;
1643 case tok::identifier:
1644 if (FormatTok->is(TT_ForEachMacro)) {
1645 parseForOrWhileLoop();
1646 return;
1647 }
1648 if (FormatTok->is(TT_MacroBlockBegin)) {
1649 parseBlock(false, 1u,
1650 false);
1651 return;
1652 }
1653 if (FormatTok->is(Keywords.kw_import)) {
1655 parseJavaScriptEs6ImportExport();
1656 return;
1657 }
1659 nextToken();
1660 if (FormatTok->is(tok::kw_public))
1661 nextToken();
1662 if (FormatTok->isNot(tok::string_literal))
1663 return;
1664 nextToken();
1665 if (FormatTok->is(tok::semi))
1666 nextToken();
1667 addUnwrappedLine();
1668 return;
1669 }
1670 if (IsCpp && parseModuleImport())
1671 return;
1672 }
1675 nextToken();
1676 if (FormatTok->is(tok::colon)) {
1677 nextToken();
1678 addUnwrappedLine();
1679 return;
1680 }
1681 }
1682 if (IsCpp && FormatTok->is(TT_StatementMacro)) {
1683 parseStatementMacro();
1684 return;
1685 }
1686 if (IsCpp && FormatTok->is(TT_NamespaceMacro)) {
1687 parseNamespace();
1688 return;
1689 }
1690
1691
1692
1693
1695 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1696 nextToken();
1697 if (!Line->InMacroBody || CurrentLines->size() > 1)
1698 Line->Tokens.begin()->Tok->MustBreakBefore = true;
1701 if (HasLabel)
1702 *HasLabel = true;
1703 return;
1704 }
1705
1706 break;
1707 default:
1708 break;
1709 }
1710
1711 for (const bool InRequiresExpression =
1712 OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
1713 TT_CompoundRequirementLBrace);
1714 !eof();) {
1716 if (auto *Next = Tokens->peekNextToken(true);
1717 Next && Next->isBinaryOperator()) {
1718 FormatTok->Tok.setKind(tok::identifier);
1719 }
1720 }
1723 case tok::at:
1724 nextToken();
1725 if (FormatTok->is(tok::l_brace)) {
1726 nextToken();
1727 parseBracedList();
1728 break;
1731 nextToken();
1732 break;
1733 }
1735 case tok::objc_public:
1736 case tok::objc_protected:
1737 case tok::objc_package:
1738 case tok::objc_private:
1739 return parseAccessSpecifier();
1740 case tok::objc_interface:
1741 case tok::objc_implementation:
1742 return parseObjCInterfaceOrImplementation();
1743 case tok::objc_protocol:
1744 if (parseObjCProtocol())
1745 return;
1746 break;
1747 case tok::objc_end:
1748 return;
1749 case tok::objc_optional:
1750 case tok::objc_required:
1751 nextToken();
1752 addUnwrappedLine();
1753 return;
1754 case tok::objc_autoreleasepool:
1755 nextToken();
1756 if (FormatTok->is(tok::l_brace)) {
1759 addUnwrappedLine();
1760 }
1761 parseBlock();
1762 }
1763 addUnwrappedLine();
1764 return;
1765 case tok::objc_synchronized:
1766 nextToken();
1767 if (FormatTok->is(tok::l_paren)) {
1768
1769 parseParens();
1770 }
1771 if (FormatTok->is(tok::l_brace)) {
1774 addUnwrappedLine();
1775 }
1776 parseBlock();
1777 }
1778 addUnwrappedLine();
1779 return;
1780 case tok::objc_try:
1781
1782
1783 parseTryCatch();
1784 return;
1785 default:
1786 break;
1787 }
1788 break;
1789 case tok::kw_requires: {
1790 if (IsCpp) {
1791 bool ParsedClause = parseRequires();
1792 if (ParsedClause)
1793 return;
1794 } else {
1795 nextToken();
1796 }
1797 break;
1798 }
1799 case tok::kw_enum:
1800
1801
1802 if (Previous && Previous->isOneOf(tok::less, tok::arrow, tok::comma)) {
1803 nextToken();
1804 break;
1805 }
1806
1807
1808
1809 if (!parseEnum())
1810 break;
1811
1812 if (!IsCpp && !Style.isVerilog()) {
1813 addUnwrappedLine();
1814 return;
1815 }
1816 break;
1817 case tok::kw_typedef:
1818 nextToken();
1823 parseEnum();
1824 }
1825 break;
1826 case tok::kw_class:
1828 parseBlock();
1829 addUnwrappedLine();
1830 return;
1831 }
1833
1834
1835 nextToken();
1836 break;
1837 }
1838 [[fallthrough]];
1839 case tok::kw_struct:
1840 case tok::kw_union:
1841 if (parseStructLike())
1842 return;
1843 break;
1844 case tok::kw_decltype:
1845 nextToken();
1846 if (FormatTok->is(tok::l_paren)) {
1847 parseParens();
1848 assert(FormatTok->Previous);
1850 tok::l_paren)) {
1851 Line->SeenDecltypeAuto = true;
1852 }
1853 }
1854 break;
1855 case tok::period:
1856 nextToken();
1857
1859 FormatTok->is(tok::kw_class)) {
1860 nextToken();
1861 }
1864
1865
1866 nextToken();
1867 }
1868 break;
1869 case tok:🚛
1870 nextToken();
1871 addUnwrappedLine();
1872 return;
1873 case tok::r_brace:
1874 addUnwrappedLine();
1875 return;
1876 case tok::l_paren: {
1877 parseParens();
1878
1879
1880 if (OpeningBrace || !IsCpp || || eof())
1881 break;
1883 Tokens->peekNextToken(true),
1885 addUnwrappedLine();
1886 return;
1887 }
1888 break;
1889 }
1890 case tok::kw_operator:
1891 nextToken();
1893 nextToken();
1894 break;
1895 case tok::caret:
1896 nextToken();
1897
1899 nextToken();
1900
1901 while (FormatTok->is(tok::star))
1902 nextToken();
1903 }
1904
1905 if (FormatTok->is(tok::l_paren))
1906 parseParens();
1907
1908 if (FormatTok->is(tok::l_brace))
1909 parseChildBlock();
1910 break;
1911 case tok::l_brace:
1912 if (InRequiresExpression)
1914 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1915 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1916
1917
1918
1919
1921 Line->Tokens.front().Tok->is(Keywords.kw_synchronized)) {
1922
1923
1926 addUnwrappedLine();
1927 }
1929 addUnwrappedLine();
1930 }
1933 parseBlock();
1934 IsDecltypeAutoFunction = false;
1935 addUnwrappedLine();
1936 return;
1937 }
1938
1939
1940 break;
1941 case tok::kw_try:
1942 if (Style.isJavaScript() && Line->MustBeDeclaration) {
1943
1944 nextToken();
1945 break;
1946 }
1947
1949 addUnwrappedLine();
1950 parseTryCatch();
1951 return;
1952 case tok::identifier: {
1954 Line->MustBeDeclaration) {
1955 addUnwrappedLine();
1956 parseCSharpGenericTypeConstraint();
1957 break;
1958 }
1959 if (FormatTok->is(TT_MacroBlockEnd)) {
1960 addUnwrappedLine();
1961 return;
1962 }
1963
1964
1965
1966
1967
1968 size_t TokenCount = Line->Tokens.size();
1970 (TokenCount > 1 ||
1971 (TokenCount == 1 &&
1972 Line->Tokens.front().Tok->isNot(Keywords.kw_async)))) {
1973 tryToParseJSFunction();
1974 break;
1975 }
1979
1980
1981
1982
1983 unsigned StoredPosition = Tokens->getPosition();
1984 FormatToken *Next = Tokens->getNextToken();
1985 FormatTok = Tokens->setPosition(StoredPosition);
1987 nextToken();
1988 break;
1989 }
1990 }
1991 parseRecord();
1992 addUnwrappedLine();
1993 return;
1994 }
1995
1997 if (FormatTok->is(Keywords.kw_table)) {
1998 parseVerilogTable();
1999 return;
2000 }
2003 parseBlock();
2004 addUnwrappedLine();
2005 return;
2006 }
2007 }
2008
2009 if (!IsCpp && FormatTok->is(Keywords.kw_interface)) {
2010 if (parseStructLike())
2011 return;
2012 break;
2013 }
2014
2015 if (IsCpp && FormatTok->is(TT_StatementMacro)) {
2016 parseStatementMacro();
2017 return;
2018 }
2019
2020
2022
2023 FormatToken *PreviousToken = FormatTok;
2024 nextToken();
2025
2026
2027
2029 break;
2030
2031 auto OneTokenSoFar = [&]() {
2032 auto I = Line->Tokens.begin(), E = Line->Tokens.end();
2033 while (I != E && I->Tok->is(tok::comment))
2034 ++I;
2036 while (I != E && I->Tok->is(tok::hash))
2037 ++I;
2038 return I != E && (++I == E);
2039 };
2040 if (OneTokenSoFar()) {
2041
2042
2043 bool FunctionLike = FormatTok->is(tok::l_paren);
2044 if (FunctionLike)
2045 parseParens();
2046
2047 bool FollowedByNewline =
2048 CommentsBeforeNextToken.empty()
2050 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2051
2052 if (FollowedByNewline &&
2053 (Text.size() >= 5 ||
2054 (FunctionLike && FormatTok->isNot(tok::l_paren))) &&
2056 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2057 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2058 addUnwrappedLine();
2059 return;
2060 }
2061 }
2062 break;
2063 }
2064 case tok::equal:
2066 FormatTok->is(TT_FatArrow)) {
2067 tryToParseChildBlock();
2068 break;
2069 }
2070
2071 nextToken();
2072 if (FormatTok->is(tok::l_brace)) {
2073
2074
2075
2078
2079
2081 Line->Tokens.begin()->Tok->is(Keywords.kw_defset)) {
2083 parseBlock(false, 1u,
2084 false);
2085 addUnwrappedLine();
2086 break;
2087 }
2088 nextToken();
2089 parseBracedList();
2091 FormatTok->is(tok::less)) {
2092 nextToken();
2093 parseBracedList(true);
2094 }
2095 break;
2096 case tok::l_square:
2097 parseSquare();
2098 break;
2099 case tok::kw_new:
2100 parseNew();
2101 break;
2102 case tok::kw_switch:
2104 parseSwitch(true);
2105 else
2106 nextToken();
2107 break;
2108 case tok::kw_case:
2109
2111 nextToken();
2112 return;
2113 }
2114
2116 parseBlock();
2117 addUnwrappedLine();
2118 return;
2119 }
2120 if (Style.isJavaScript() && Line->MustBeDeclaration) {
2121
2122 nextToken();
2123 break;
2124 }
2125 parseCaseLabel();
2126 break;
2127 case tok::kw_default:
2128 nextToken();
2130 if (FormatTok->is(tok::colon)) {
2131
2132 break;
2133 }
2135
2136 parseBlock();
2137 addUnwrappedLine();
2138 return;
2139 }
2140 parseVerilogCaseLabel();
2141 return;
2142 }
2143 break;
2144 case tok::colon:
2145 nextToken();
2147 parseVerilogCaseLabel();
2148 return;
2149 }
2150 break;
2151 case tok::greater:
2152 nextToken();
2153 if (FormatTok->is(tok::l_brace))
2155 break;
2156 default:
2157 nextToken();
2158 break;
2159 }
2160 }
2161}
2162
2163bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2164 assert(FormatTok->is(tok::l_brace));
2166 return false;
2167
2169 return false;
2170
2171
2172
2173
2174
2175
2176 unsigned int StoredPosition = Tokens->getPosition();
2177 FormatToken *Tok = Tokens->getNextToken();
2178
2179
2180
2181
2182 bool HasSpecialAccessor = false;
2183 bool IsTrivialPropertyAccessor = true;
2184 bool HasAttribute = false;
2185 while (!eof()) {
2186 if (const bool IsAccessorKeyword =
2188 IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||
2189 Tok->isOneOf(tok::l_square, tok::semi, Keywords.kw_internal)) {
2190 if (IsAccessorKeyword)
2191 HasSpecialAccessor = true;
2192 else if (Tok->is(tok::l_square))
2193 HasAttribute = true;
2194 Tok = Tokens->getNextToken();
2195 continue;
2196 }
2197 if (Tok->isNot(tok::r_brace))
2198 IsTrivialPropertyAccessor = false;
2199 break;
2200 }
2201
2202 if (!HasSpecialAccessor || HasAttribute) {
2203 Tokens->setPosition(StoredPosition);
2204 return false;
2205 }
2206
2207
2208
2209 Tokens->setPosition(StoredPosition);
2211 addUnwrappedLine();
2212 nextToken();
2213 do {
2215 case tok::r_brace:
2216 nextToken();
2217 if (FormatTok->is(tok::equal)) {
2218 while (!eof() && FormatTok->isNot(tok::semi))
2219 nextToken();
2220 nextToken();
2221 }
2222 addUnwrappedLine();
2223 return true;
2224 case tok::l_brace:
2225 ++Line->Level;
2226 parseBlock(true);
2227 addUnwrappedLine();
2228 --Line->Level;
2229 break;
2230 case tok::equal:
2231 if (FormatTok->is(TT_FatArrow)) {
2232 ++Line->Level;
2233 do {
2234 nextToken();
2235 } while (!eof() && FormatTok->isNot(tok::semi));
2236 nextToken();
2237 addUnwrappedLine();
2238 --Line->Level;
2239 break;
2240 }
2241 nextToken();
2242 break;
2243 default:
2246 !IsTrivialPropertyAccessor) {
2247
2248 addUnwrappedLine();
2249 }
2250 nextToken();
2251 }
2252 } while (!eof());
2253
2254
2255 return true;
2256}
2257
2258bool UnwrappedLineParser::tryToParseLambda() {
2259 assert(FormatTok->is(tok::l_square));
2260 if (!IsCpp) {
2261 nextToken();
2262 return false;
2263 }
2264 FormatToken &LSquare = *FormatTok;
2265 if (!tryToParseLambdaIntroducer())
2266 return false;
2267
2268 bool SeenArrow = false;
2269 bool InTemplateParameterList = false;
2270
2271 while (FormatTok->isNot(tok::l_brace)) {
2273 nextToken();
2274 continue;
2275 }
2277 case tok::l_brace:
2278 break;
2279 case tok::l_paren:
2280 parseParens(TT_PointerOrReference);
2281 break;
2282 case tok::l_square:
2283 parseSquare();
2284 break;
2285 case tok::less:
2286 assert(FormatTok->Previous);
2287 if (FormatTok->Previous->is(tok::r_square))
2288 InTemplateParameterList = true;
2289 nextToken();
2290 break;
2291 case tok::kw_auto:
2292 case tok::kw_class:
2293 case tok::kw_struct:
2294 case tok::kw_union:
2295 case tok::kw_template:
2296 case tok::kw_typename:
2297 case tok::amp:
2298 case tok:⭐
2299 case tok::kw_const:
2300 case tok::kw_constexpr:
2301 case tok::kw_consteval:
2302 case tok::comma:
2303 case tok::greater:
2304 case tok::identifier:
2305 case tok::numeric_constant:
2306 case tok::coloncolon:
2307 case tok::kw_mutable:
2308 case tok::kw_noexcept:
2309 case tok::kw_static:
2310 nextToken();
2311 break;
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323 case tok:➕
2324 case tok:➖
2325 case tok::exclaim:
2326 case tok::tilde:
2327 case tok::slash:
2328 case tok::percent:
2329 case tok::lessless:
2330 case tok::pipe:
2331 case tok::pipepipe:
2332 case tok::ampamp:
2333 case tok::caret:
2334 case tok::equalequal:
2335 case tok::exclaimequal:
2336 case tok::greaterequal:
2337 case tok::lessequal:
2338 case tok::question:
2339 case tok::colon:
2340 case tok::ellipsis:
2341 case tok::kw_true:
2342 case tok::kw_false:
2343 if (SeenArrow || InTemplateParameterList) {
2344 nextToken();
2345 break;
2346 }
2347 return true;
2348 case tok::arrow:
2349
2350
2351
2353 SeenArrow = true;
2354 nextToken();
2355 break;
2356 case tok::kw_requires: {
2357 auto *RequiresToken = FormatTok;
2358 nextToken();
2359 parseRequiresClause(RequiresToken);
2360 break;
2361 }
2362 case tok::equal:
2363 if (!InTemplateParameterList)
2364 return true;
2365 nextToken();
2366 break;
2367 default:
2368 return true;
2369 }
2370 }
2371
2373 LSquare.setFinalizedType(TT_LambdaLSquare);
2374
2375 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2376 parseChildBlock();
2377 assert(!NestedLambdas.empty());
2378 NestedLambdas.pop_back();
2379
2380 return true;
2381}
2382
2383bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2385 const FormatToken *LeftSquare = FormatTok;
2386 nextToken();
2388 ->isOneOf(tok::kw_return, tok::kw_co_await,
2389 tok::kw_co_yield, tok::kw_co_return)) ||
2390 Previous->closesScope())) ||
2391 LeftSquare->isCppStructuredBinding(IsCpp)) {
2392 return false;
2393 }
2395 return false;
2396 if (FormatTok->is(tok::r_square)) {
2397 const FormatToken *Next = Tokens->peekNextToken(true);
2398 if (Next->is(tok::greater))
2399 return false;
2400 }
2401 parseSquare(true);
2402 return true;
2403}
2404
2405void UnwrappedLineParser::tryToParseJSFunction() {
2407 if (FormatTok->is(Keywords.kw_async))
2408 nextToken();
2409
2410 nextToken();
2411
2412
2413 if (FormatTok->is(tok::star)) {
2415 nextToken();
2416 }
2417
2418
2419 if (FormatTok->is(tok::identifier))
2420 nextToken();
2421
2422 if (FormatTok->isNot(tok::l_paren))
2423 return;
2424
2425
2426 parseParens();
2427
2428 if (FormatTok->is(tok::colon)) {
2429
2430 nextToken();
2431
2432
2433
2434 if (FormatTok->is(tok::l_brace))
2435 tryToParseBracedList();
2436 else
2437 while (!FormatTok->isOneOf(tok::l_brace, tok::semi) && !eof())
2438 nextToken();
2439 }
2440
2441 if (FormatTok->is(tok::semi))
2442 return;
2443
2444 parseChildBlock();
2445}
2446
2447bool UnwrappedLineParser::tryToParseBracedList() {
2449 calculateBraceTypes();
2452 return false;
2453 nextToken();
2454 parseBracedList();
2455 return true;
2456}
2457
2458bool UnwrappedLineParser::tryToParseChildBlock() {
2460 assert(FormatTok->is(TT_FatArrow));
2461
2462
2463
2464 nextToken();
2465 if (FormatTok->isNot(tok::l_brace))
2466 return false;
2467 parseChildBlock();
2468 return true;
2469}
2470
2471bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) {
2472 assert(!IsAngleBracket || !IsEnum);
2473 bool HasError = false;
2474
2475
2476
2477 do {
2478 if (Style.isCSharp() && FormatTok->is(TT_FatArrow) &&
2479 tryToParseChildBlock()) {
2480 continue;
2481 }
2484 tryToParseJSFunction();
2485 continue;
2486 }
2487 if (FormatTok->is(tok::l_brace)) {
2488
2489 if (tryToParseBracedList())
2490 continue;
2491 parseChildBlock();
2492 }
2493 }
2494 if (FormatTok->is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2495 if (IsEnum) {
2498 addUnwrappedLine();
2499 }
2500 nextToken();
2501 return !HasError;
2502 }
2504 case tok::l_square:
2506 parseSquare();
2507 else
2508 tryToParseLambda();
2509 break;
2510 case tok::l_paren:
2511 parseParens();
2512
2513
2515 if (FormatTok->is(tok::l_brace))
2516 parseChildBlock();
2517 break;
2518 }
2519 break;
2520 case tok::l_brace:
2521
2522
2524 if (!IsAngleBracket) {
2525 auto *Prev = FormatTok->Previous;
2526 if (Prev && Prev->is(tok::greater))
2528 }
2529 nextToken();
2530 parseBracedList();
2531 break;
2532 case tok::less:
2533 nextToken();
2534 if (IsAngleBracket)
2535 parseBracedList(true);
2536 break;
2537 case tok:🚛
2538
2539
2540
2541
2543 nextToken();
2544 break;
2545 }
2546 HasError = true;
2547 if (!IsEnum)
2548 return false;
2549 nextToken();
2550 break;
2551 case tok::comma:
2552 nextToken();
2554 addUnwrappedLine();
2555 break;
2556 default:
2557 nextToken();
2558 break;
2559 }
2560 } while (!eof());
2561 return false;
2562}
2563
2564
2565
2566
2567
2568
2569bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) {
2570 assert(FormatTok->is(tok::l_paren) && "'(' expected.");
2571 auto *LeftParen = FormatTok;
2572 bool SeenComma = false;
2573 bool SeenEqual = false;
2574 bool MightBeFoldExpr = false;
2575 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2576 nextToken();
2577 do {
2579 case tok::l_paren:
2580 if (parseParens(AmpAmpTokenType))
2581 SeenEqual = true;
2583 parseChildBlock();
2584 break;
2585 case tok::r_paren: {
2586 auto *Prev = LeftParen->Previous;
2587 if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
2589 const auto *Next = Tokens->peekNextToken();
2590 const bool DoubleParens =
2591 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2592 const bool CommaSeparated =
2593 !DoubleParens && Prev && Prev->isOneOf(tok::l_paren, tok::comma) &&
2594 Next && Next->isOneOf(tok::comma, tok::r_paren);
2595 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() : nullptr;
2596 const bool Excluded =
2597 PrevPrev &&
2598 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2599 SeenComma ||
2600 (SeenEqual &&
2601 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2602 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2603 const bool ReturnParens =
2605 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2606 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2607 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2608 Next->is(tok::semi);
2609 if ((DoubleParens && !Excluded) || (CommaSeparated && !SeenComma) ||
2610 ReturnParens) {
2611 LeftParen->Optional = true;
2613 }
2614 }
2615 if (Prev) {
2616 if (Prev->is(TT_TypenameMacro)) {
2617 LeftParen->setFinalizedType(TT_TypeDeclarationParen);
2619 } else if (Prev->is(tok::greater) && FormatTok->Previous == LeftParen) {
2620 Prev->setFinalizedType(TT_TemplateCloser);
2621 }
2622 }
2623 nextToken();
2624 return SeenEqual;
2625 }
2626 case tok::r_brace:
2627
2628 return SeenEqual;
2629 case tok::l_square:
2630 tryToParseLambda();
2631 break;
2632 case tok::l_brace:
2633 if (!tryToParseBracedList())
2634 parseChildBlock();
2635 break;
2636 case tok::at:
2637 nextToken();
2638 if (FormatTok->is(tok::l_brace)) {
2639 nextToken();
2640 parseBracedList();
2641 }
2642 break;
2643 case tok::comma:
2644 SeenComma = true;
2645 nextToken();
2646 break;
2647 case tok::ellipsis:
2648 MightBeFoldExpr = true;
2649 nextToken();
2650 break;
2651 case tok::equal:
2652 SeenEqual = true;
2653 if (Style.isCSharp() && FormatTok->is(TT_FatArrow))
2654 tryToParseChildBlock();
2655 else
2656 nextToken();
2657 break;
2658 case tok::kw_class:
2660 parseRecord(true);
2661 else
2662 nextToken();
2663 break;
2664 case tok::identifier:
2666 tryToParseJSFunction();
2667 else
2668 nextToken();
2669 break;
2670 case tok::kw_switch:
2672 parseSwitch(true);
2673 else
2674 nextToken();
2675 break;
2676 case tok::kw_requires: {
2677 auto RequiresToken = FormatTok;
2678 nextToken();
2679 parseRequiresExpression(RequiresToken);
2680 break;
2681 }
2682 case tok::ampamp:
2683 if (AmpAmpTokenType != TT_Unknown)
2685 [[fallthrough]];
2686 default:
2687 nextToken();
2688 break;
2689 }
2690 } while (!eof());
2691 return SeenEqual;
2692}
2693
2694void UnwrappedLineParser::parseSquare(bool LambdaIntroducer) {
2695 if (!LambdaIntroducer) {
2696 assert(FormatTok->is(tok::l_square) && "'[' expected.");
2697 if (tryToParseLambda())
2698 return;
2699 }
2700 do {
2702 case tok::l_paren:
2703 parseParens();
2704 break;
2705 case tok::r_square:
2706 nextToken();
2707 return;
2708 case tok::r_brace:
2709
2710 return;
2711 case tok::l_square:
2712 parseSquare();
2713 break;
2714 case tok::l_brace: {
2715 if (!tryToParseBracedList())
2716 parseChildBlock();
2717 break;
2718 }
2719 case tok::at:
2720 case tok::colon:
2721 nextToken();
2722 if (FormatTok->is(tok::l_brace)) {
2723 nextToken();
2724 parseBracedList();
2725 }
2726 break;
2727 default:
2728 nextToken();
2729 break;
2730 }
2731 } while (!eof());
2732}
2733
2734void UnwrappedLineParser::keepAncestorBraces() {
2736 return;
2737
2738 const int MaxNestingLevels = 2;
2739 const int Size = NestedTooDeep.size();
2740 if (Size >= MaxNestingLevels)
2741 NestedTooDeep[Size - MaxNestingLevels] = true;
2742 NestedTooDeep.push_back(false);
2743}
2744
2746 for (const auto &Token : llvm::reverse(Line.Tokens))
2748 return Token.Tok;
2749
2750 return nullptr;
2751}
2752
2753void UnwrappedLineParser::parseUnbracedBody(bool CheckEOF) {
2754 FormatToken *Tok = nullptr;
2755
2756 if (Style.InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2757 PreprocessorDirectives.empty() && FormatTok->isNot(tok::semi)) {
2760 : Line->Tokens.back().Tok;
2761 assert(Tok);
2762 if (Tok->BraceCount < 0) {
2763 assert(Tok->BraceCount == -1);
2764 Tok = nullptr;
2765 } else {
2766 Tok->BraceCount = -1;
2767 }
2768 }
2769
2770 addUnwrappedLine();
2771 ++Line->Level;
2772 ++Line->UnbracedBodyLevel;
2773 parseStructuralElement();
2774 --Line->UnbracedBodyLevel;
2775
2776 if (Tok) {
2777 assert(!Line->InPPDirective);
2778 Tok = nullptr;
2779 for (const auto &L : llvm::reverse(*CurrentLines)) {
2781 Tok = L.Tokens.back().Tok;
2782 break;
2783 }
2784 }
2785 assert(Tok);
2786 ++Tok->BraceCount;
2787 }
2788
2789 if (CheckEOF && eof())
2790 addUnwrappedLine();
2791
2792 --Line->Level;
2793}
2794
2796 if (!LeftBrace)
2797 return;
2798
2799 assert(LeftBrace->is(tok::l_brace));
2800
2802 if (!RightBrace) {
2803 assert(!LeftBrace->Optional);
2804 return;
2805 }
2806
2807 assert(RightBrace->is(tok::r_brace));
2810
2812 RightBrace->Optional = true;
2813}
2814
2815void UnwrappedLineParser::handleAttributes() {
2816
2818 nextToken();
2819 else if (FormatTok->is(tok::l_square))
2820 handleCppAttributes();
2821}
2822
2823bool UnwrappedLineParser::handleCppAttributes() {
2824
2825 assert(FormatTok->is(tok::l_square));
2826 if (!tryToParseSimpleAttribute())
2827 return false;
2828 parseSquare();
2829 return true;
2830}
2831
2832
2833bool UnwrappedLineParser::isBlockBegin(const FormatToken &Tok) const {
2834
2835
2837 : Tok.is(tok::l_brace);
2838}
2839
2840FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2841 bool KeepBraces,
2842 bool IsVerilogAssert) {
2843 assert((FormatTok->is(tok::kw_if) ||
2847 "'if' expected");
2848 nextToken();
2849
2850 if (IsVerilogAssert) {
2851
2853 nextToken();
2854 if (FormatTok->is(tok::numeric_constant))
2855 nextToken();
2858 nextToken();
2859 }
2860 }
2861
2862
2864 while (!eof() && FormatTok->isNot(Keywords.kw_then)) {
2865
2866 nextToken();
2867 }
2868 }
2869
2870
2871 if (FormatTok->is(tok::exclaim))
2872 nextToken();
2873
2874 bool KeepIfBraces = true;
2875 if (FormatTok->is(tok::kw_consteval)) {
2876 nextToken();
2877 } else {
2879 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
2880 nextToken();
2881 if (FormatTok->is(tok::l_paren)) {
2883 parseParens();
2884 }
2885 }
2886 handleAttributes();
2887
2888 if (IsVerilogAssert && FormatTok->is(tok::semi)) {
2889 nextToken();
2890 addUnwrappedLine();
2891 return nullptr;
2892 }
2893
2894 bool NeedsUnwrappedLine = false;
2895 keepAncestorBraces();
2896
2897 FormatToken *IfLeftBrace = nullptr;
2898 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2899
2900 if (isBlockBegin(*FormatTok)) {
2902 IfLeftBrace = FormatTok;
2904 parseBlock(false, 1u,
2905 true, KeepIfBraces, &IfBlockKind);
2906 setPreviousRBraceType(TT_ControlStatementRBrace);
2908 addUnwrappedLine();
2909 else
2910 NeedsUnwrappedLine = true;
2911 } else if (IsVerilogAssert && FormatTok->is(tok::kw_else)) {
2912 addUnwrappedLine();
2913 } else {
2914 parseUnbracedBody();
2915 }
2916
2918 assert(!NestedTooDeep.empty());
2919 KeepIfBraces = KeepIfBraces ||
2920 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2921 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2922 IfBlockKind == IfStmtKind::IfElseIf;
2923 }
2924
2925 bool KeepElseBraces = KeepIfBraces;
2926 FormatToken *ElseLeftBrace = nullptr;
2927 IfStmtKind Kind = IfStmtKind::IfOnly;
2928
2929 if (FormatTok->is(tok::kw_else)) {
2931 NestedTooDeep.back() = false;
2932 Kind = IfStmtKind::IfElse;
2933 }
2934 nextToken();
2935 handleAttributes();
2936 if (isBlockBegin(*FormatTok)) {
2937 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2939 ElseLeftBrace = FormatTok;
2941 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2942 FormatToken *IfLBrace =
2943 parseBlock(false, 1u,
2944 true, KeepElseBraces, &ElseBlockKind);
2945 setPreviousRBraceType(TT_ElseRBrace);
2946 if (FormatTok->is(tok::kw_else)) {
2947 KeepElseBraces = KeepElseBraces ||
2948 ElseBlockKind == IfStmtKind::IfOnly ||
2949 ElseBlockKind == IfStmtKind::IfElseIf;
2950 } else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2951 KeepElseBraces = true;
2952 assert(ElseLeftBrace->MatchingParen);
2954 }
2955 addUnwrappedLine();
2956 } else if (!IsVerilogAssert && FormatTok->is(tok::kw_if)) {
2957 const FormatToken *Previous = Tokens->getPreviousToken();
2959 const bool IsPrecededByComment = Previous->is(tok::comment);
2960 if (IsPrecededByComment) {
2961 addUnwrappedLine();
2962 ++Line->Level;
2963 }
2964 bool TooDeep = true;
2966 Kind = IfStmtKind::IfElseIf;
2967 TooDeep = NestedTooDeep.pop_back_val();
2968 }
2969 ElseLeftBrace = parseIfThenElse(nullptr, KeepIfBraces);
2971 NestedTooDeep.push_back(TooDeep);
2972 if (IsPrecededByComment)
2973 --Line->Level;
2974 } else {
2975 parseUnbracedBody(true);
2976 }
2977 } else {
2978 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2979 if (NeedsUnwrappedLine)
2980 addUnwrappedLine();
2981 }
2982
2984 return nullptr;
2985
2986 assert(!NestedTooDeep.empty());
2987 KeepElseBraces = KeepElseBraces ||
2988 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2989 NestedTooDeep.back();
2990
2991 NestedTooDeep.pop_back();
2992
2993 if (!KeepIfBraces && !KeepElseBraces) {
2996 } else if (IfLeftBrace) {
2997 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2998 if (IfRightBrace) {
2999 assert(IfRightBrace->MatchingParen == IfLeftBrace);
3000 assert(!IfLeftBrace->Optional);
3001 assert(!IfRightBrace->Optional);
3002 IfLeftBrace->MatchingParen = nullptr;
3003 IfRightBrace->MatchingParen = nullptr;
3004 }
3005 }
3006
3007 if (IfKind)
3008 *IfKind = Kind;
3009
3010 return IfLeftBrace;
3011}
3012
3013void UnwrappedLineParser::parseTryCatch() {
3014 assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) && "'try' expected");
3015 nextToken();
3016 bool NeedsUnwrappedLine = false;
3017 bool HasCtorInitializer = false;
3018 if (FormatTok->is(tok::colon)) {
3019 auto *Colon = FormatTok;
3020
3021 nextToken();
3022 if (FormatTok->is(tok::identifier)) {
3023 HasCtorInitializer = true;
3024 Colon->setFinalizedType(TT_CtorInitializerColon);
3025 }
3026
3027
3028
3029 while (FormatTok->is(tok::comma))
3030 nextToken();
3031
3032 while (FormatTok->is(tok::identifier)) {
3033 nextToken();
3034 if (FormatTok->is(tok::l_paren)) {
3035 parseParens();
3036 } else if (FormatTok->is(tok::l_brace)) {
3037 nextToken();
3038 parseBracedList();
3039 }
3040
3041
3042
3043 while (FormatTok->is(tok::comma))
3044 nextToken();
3045 }
3046 }
3047
3049 parseParens();
3050
3051 keepAncestorBraces();
3052
3053 if (FormatTok->is(tok::l_brace)) {
3054 if (HasCtorInitializer)
3057 parseBlock();
3059 addUnwrappedLine();
3060 else
3061 NeedsUnwrappedLine = true;
3062 } else if (FormatTok->isNot(tok::kw_catch)) {
3063
3064
3065
3066 addUnwrappedLine();
3067 ++Line->Level;
3068 parseStructuralElement();
3069 --Line->Level;
3070 }
3071 while (true) {
3072 if (FormatTok->is(tok::at))
3073 nextToken();
3075 tok::kw___finally) ||
3080 break;
3081 }
3082 nextToken();
3083 while (FormatTok->isNot(tok::l_brace)) {
3084 if (FormatTok->is(tok::l_paren)) {
3085 parseParens();
3086 continue;
3087 }
3088 if (FormatTok->isOneOf(tok::semi, tok::r_brace, tok::eof)) {
3090 NestedTooDeep.pop_back();
3091 return;
3092 }
3093 nextToken();
3094 }
3095 NeedsUnwrappedLine = false;
3096 Line->MustBeDeclaration = false;
3098 parseBlock();
3100 addUnwrappedLine();
3101 else
3102 NeedsUnwrappedLine = true;
3103 }
3104
3106 NestedTooDeep.pop_back();
3107
3108 if (NeedsUnwrappedLine)
3109 addUnwrappedLine();
3110}
3111
3112void UnwrappedLineParser::parseNamespaceOrExportBlock(unsigned AddLevels) {
3113 bool ManageWhitesmithsBraces =
3115
3116
3117
3118 if (ManageWhitesmithsBraces)
3119 ++Line->Level;
3120
3121
3122
3123 parseBlock(true, AddLevels, true,
3124 true, nullptr, ManageWhitesmithsBraces);
3125
3126 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3127
3128 if (ManageWhitesmithsBraces)
3129 --Line->Level;
3130}
3131
3132void UnwrappedLineParser::parseNamespace() {
3133 assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3134 "'namespace' expected");
3135
3136 const FormatToken &InitialToken = *FormatTok;
3137 nextToken();
3138 if (InitialToken.is(TT_NamespaceMacro)) {
3139 parseParens();
3140 } else {
3141 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3142 tok::l_square, tok::period, tok::l_paren) ||
3143 (Style.isCSharp() && FormatTok->is(tok::kw_union))) {
3144 if (FormatTok->is(tok::l_square))
3145 parseSquare();
3146 else if (FormatTok->is(tok::l_paren))
3147 parseParens();
3148 else
3149 nextToken();
3150 }
3151 }
3152 if (FormatTok->is(tok::l_brace)) {
3154
3156 addUnwrappedLine();
3157
3158 unsigned AddLevels =
3161 DeclarationScopeStack.size() > 1)
3162 ? 1u
3163 : 0u;
3164 parseNamespaceOrExportBlock(AddLevels);
3165 }
3166
3167}
3168
3169void UnwrappedLineParser::parseCppExportBlock() {
3170 parseNamespaceOrExportBlock(Style.IndentExportBlock ? 1 : 0);
3171}
3172
3173void UnwrappedLineParser::parseNew() {
3174 assert(FormatTok->is(tok::kw_new) && "'new' expected");
3175 nextToken();
3176
3178 do {
3179
3180 if (FormatTok->is(tok::l_paren))
3181 parseParens();
3182
3183
3184 if (FormatTok->is(tok::l_brace))
3185 parseBracedList();
3186
3187 if (FormatTok->isOneOf(tok::semi, tok::comma))
3188 return;
3189
3190 nextToken();
3191 } while (!eof());
3192 }
3193
3195 return;
3196
3197
3198 do {
3199
3200 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3201 return;
3202
3203
3204 if (FormatTok->is(tok::l_paren)) {
3205 parseParens();
3206
3207
3208 if (FormatTok->is(tok::l_brace))
3209 parseChildBlock();
3210 return;
3211 }
3212 nextToken();
3213 } while (!eof());
3214}
3215
3216void UnwrappedLineParser::parseLoopBody(bool KeepBraces, bool WrapRightBrace) {
3217 keepAncestorBraces();
3218
3219 if (isBlockBegin(*FormatTok)) {
3221 FormatToken *LeftBrace = FormatTok;
3223 parseBlock(false, 1u,
3224 true, KeepBraces);
3225 setPreviousRBraceType(TT_ControlStatementRBrace);
3226 if (!KeepBraces) {
3227 assert(!NestedTooDeep.empty());
3228 if (!NestedTooDeep.back())
3230 }
3231 if (WrapRightBrace)
3232 addUnwrappedLine();
3233 } else {
3234 parseUnbracedBody();
3235 }
3236
3237 if (!KeepBraces)
3238 NestedTooDeep.pop_back();
3239}
3240
3241void UnwrappedLineParser::parseForOrWhileLoop(bool HasParens) {
3242 assert((FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3249 "'for', 'while' or foreach macro expected");
3251 !FormatTok->isOneOf(tok::kw_for, tok::kw_while);
3252
3253 nextToken();
3254
3256 nextToken();
3257 if (IsCpp && FormatTok->is(tok::kw_co_await))
3258 nextToken();
3259 if (HasParens && FormatTok->is(tok::l_paren)) {
3260
3261
3262
3265 parseParens();
3266 }
3267
3269
3270 parseVerilogSensitivityList();
3272 Tokens->getPreviousToken()->is(tok::r_paren)) {
3273 nextToken();
3274 addUnwrappedLine();
3275 return;
3276 }
3277
3278 handleAttributes();
3279 parseLoopBody(KeepBraces, true);
3280}
3281
3282void UnwrappedLineParser::parseDoWhile() {
3283 assert(FormatTok->is(tok::kw_do) && "'do' expected");
3284 nextToken();
3285
3287
3288
3289 if (FormatTok->isNot(tok::kw_while)) {
3290 addUnwrappedLine();
3291 return;
3292 }
3293
3295
3296
3297
3299 ++Line->Level;
3300
3301 nextToken();
3302 parseStructuralElement();
3303}
3304
3305void UnwrappedLineParser::parseLabel(bool LeftAlignLabel) {
3306 nextToken();
3307 unsigned OldLineLevel = Line->Level;
3308
3309 if (LeftAlignLabel)
3310 Line->Level = 0;
3311 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3312 --Line->Level;
3313
3314 if (!Style.IndentCaseBlocks && CommentsBeforeNextToken.empty() &&
3315 FormatTok->is(tok::l_brace)) {
3316
3320 parseBlock();
3321 if (FormatTok->is(tok::kw_break)) {
3324 addUnwrappedLine();
3327 ++Line->Level;
3328 }
3329 }
3330 parseStructuralElement();
3331 }
3332 addUnwrappedLine();
3333 } else {
3334 if (FormatTok->is(tok::semi))
3335 nextToken();
3336 addUnwrappedLine();
3337 }
3338 Line->Level = OldLineLevel;
3339 if (FormatTok->isNot(tok::l_brace)) {
3340 parseStructuralElement();
3341 addUnwrappedLine();
3342 }
3343}
3344
3345void UnwrappedLineParser::parseCaseLabel() {
3346 assert(FormatTok->is(tok::kw_case) && "'case' expected");
3347 auto *Case = FormatTok;
3348
3349
3350 do {
3351 nextToken();
3352 if (FormatTok->is(tok::colon)) {
3354 break;
3355 }
3358 Case->setFinalizedType(TT_SwitchExpressionLabel);
3359 break;
3360 }
3361 } while (!eof());
3362 parseLabel();
3363}
3364
3365void UnwrappedLineParser::parseSwitch(bool IsExpr) {
3366 assert(FormatTok->is(tok::kw_switch) && "'switch' expected");
3367 nextToken();
3368 if (FormatTok->is(tok::l_paren))
3369 parseParens();
3370
3371 keepAncestorBraces();
3372
3373 if (FormatTok->is(tok::l_brace)) {
3375 FormatTok->setFinalizedType(IsExpr ? TT_SwitchExpressionLBrace
3376 : TT_ControlStatementLBrace);
3377 if (IsExpr)
3378 parseChildBlock();
3379 else
3380 parseBlock();
3381 setPreviousRBraceType(TT_ControlStatementRBrace);
3382 if (!IsExpr)
3383 addUnwrappedLine();
3384 } else {
3385 addUnwrappedLine();
3386 ++Line->Level;
3387 parseStructuralElement();
3388 --Line->Level;
3389 }
3390
3392 NestedTooDeep.pop_back();
3393}
3394
3395
3397 switch (Kind) {
3398 case tok::ampamp:
3399 case tok::ampequal:
3400 case tok::arrow:
3401 case tok::caret:
3402 case tok::caretequal:
3403 case tok::comma:
3404 case tok::ellipsis:
3405 case tok::equal:
3406 case tok::equalequal:
3407 case tok::exclaim:
3408 case tok::exclaimequal:
3409 case tok::greater:
3410 case tok::greaterequal:
3411 case tok::greatergreater:
3412 case tok::greatergreaterequal:
3413 case tok::l_paren:
3414 case tok::l_square:
3415 case tok::less:
3416 case tok::lessequal:
3417 case tok::lessless:
3418 case tok::lesslessequal:
3419 case tok:➖
3420 case tok::minusequal:
3421 case tok::minusminus:
3422 case tok::percent:
3423 case tok::percentequal:
3424 case tok::period:
3425 case tok::pipe:
3426 case tok::pipeequal:
3427 case tok::pipepipe:
3428 case tok:➕
3429 case tok::plusequal:
3430 case tok::plusplus:
3431 case tok::question:
3432 case tok::r_brace:
3433 case tok::r_paren:
3434 case tok::r_square:
3435 case tok:🚛
3436 case tok::slash:
3437 case tok::slashequal:
3438 case tok:⭐
3439 case tok::starequal:
3440 return true;
3441 default:
3442 return false;
3443 }
3444}
3445
3446void UnwrappedLineParser::parseAccessSpecifier() {
3447 FormatToken *AccessSpecifierCandidate = FormatTok;
3448 nextToken();
3449
3451 nextToken();
3452
3453 if (FormatTok->is(tok::colon)) {
3454 nextToken();
3455 addUnwrappedLine();
3456 } else if (FormatTok->isNot(tok::coloncolon) &&
3458
3459 addUnwrappedLine();
3460 } else if (AccessSpecifierCandidate) {
3461
3462 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3463 }
3464}
3465
3466
3467
3468
3469bool UnwrappedLineParser::parseRequires() {
3470 assert(FormatTok->is(tok::kw_requires) && "'requires' expected");
3471 auto RequiresToken = FormatTok;
3472
3473
3474
3475 nextToken();
3476
3478 case tok::l_brace:
3479
3480 parseRequiresExpression(RequiresToken);
3481 return false;
3482 case tok::l_paren:
3483
3484 break;
3485 default:
3486
3487 parseRequiresClause(RequiresToken);
3488 return true;
3489 }
3490
3491
3492
3493
3494
3495
3496
3497
3498 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3499
3500 if (!PreviousNonComment ||
3501 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3502
3503
3504 parseRequiresClause(RequiresToken);
3505 return true;
3506 }
3507
3508 switch (PreviousNonComment->Tok.getKind()) {
3509 case tok::greater:
3510 case tok::r_paren:
3511 case tok::kw_noexcept:
3512 case tok::kw_const:
3513 case tok::amp:
3514
3515 parseRequiresClause(RequiresToken);
3516 return true;
3517 case tok::ampamp: {
3518
3519
3520
3521
3522
3523
3524 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3525 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3526 parseRequiresClause(RequiresToken);
3527 return true;
3528 }
3529 break;
3530 }
3531 default:
3532 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3533
3534 parseRequiresClause(RequiresToken);
3535 return true;
3536 }
3537
3538 parseRequiresExpression(RequiresToken);
3539 return false;
3540 }
3541
3542
3543
3544
3545
3546
3547
3548 unsigned StoredPosition = Tokens->getPosition();
3549 FormatToken *NextToken = Tokens->getNextToken();
3550 int Lookahead = 0;
3551 auto PeekNext = [&Lookahead, &NextToken, this] {
3552 ++Lookahead;
3553 NextToken = Tokens->getNextToken();
3554 };
3555
3556 bool FoundType = false;
3557 bool LastWasColonColon = false;
3558 int OpenAngles = 0;
3559
3560 for (; Lookahead < 50; PeekNext()) {
3561 switch (NextToken->Tok.getKind()) {
3562 case tok::kw_volatile:
3563 case tok::kw_const:
3564 case tok::comma:
3565 if (OpenAngles == 0) {
3566 FormatTok = Tokens->setPosition(StoredPosition);
3567 parseRequiresExpression(RequiresToken);
3568 return false;
3569 }
3570 break;
3571 case tok::eof:
3572
3573 Lookahead = 50;
3574 break;
3575 case tok::coloncolon:
3576 LastWasColonColon = true;
3577 break;
3578 case tok::kw_decltype:
3579 case tok::identifier:
3580 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3581 FormatTok = Tokens->setPosition(StoredPosition);
3582 parseRequiresExpression(RequiresToken);
3583 return false;
3584 }
3585 FoundType = true;
3586 LastWasColonColon = false;
3587 break;
3588 case tok::less:
3589 ++OpenAngles;
3590 break;
3591 case tok::greater:
3592 --OpenAngles;
3593 break;
3594 default:
3595 if (NextToken->isTypeName(LangOpts)) {
3596 FormatTok = Tokens->setPosition(StoredPosition);
3597 parseRequiresExpression(RequiresToken);
3598 return false;
3599 }
3600 break;
3601 }
3602 }
3603
3604 FormatTok = Tokens->setPosition(StoredPosition);
3605 parseRequiresClause(RequiresToken);
3606 return true;
3607}
3608
3609
3610
3611
3612
3613
3614
3615
3616void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3618 assert(RequiresToken->is(tok::kw_requires) && "'requires' expected");
3619
3620
3621
3622
3623 bool InRequiresExpression =
3624 !RequiresToken->Previous ||
3625 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3626
3627 RequiresToken->setFinalizedType(InRequiresExpression
3628 ? TT_RequiresClauseInARequiresExpression
3629 : TT_RequiresClause);
3630
3631
3632
3633 parseConstraintExpression();
3634
3635 if (!InRequiresExpression)
3637}
3638
3639
3640
3641
3642
3643
3644
3645
3646void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3648 assert(RequiresToken->is(tok::kw_requires) && "'requires' expected");
3649
3650 RequiresToken->setFinalizedType(TT_RequiresExpression);
3651
3652 if (FormatTok->is(tok::l_paren)) {
3654 parseParens();
3655 }
3656
3657 if (FormatTok->is(tok::l_brace)) {
3659 parseChildBlock();
3660 }
3661}
3662
3663
3664
3665
3666
3667void UnwrappedLineParser::parseConstraintExpression() {
3668
3669
3670
3671
3672
3673
3674 bool LambdaNextTimeAllowed = true;
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684 bool TopLevelParensAllowed = true;
3685
3686 do {
3687 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed, false);
3688
3690 case tok::kw_requires: {
3691 auto RequiresToken = FormatTok;
3692 nextToken();
3693 parseRequiresExpression(RequiresToken);
3694 break;
3695 }
3696
3697 case tok::l_paren:
3698 if (!TopLevelParensAllowed)
3699 return;
3700 parseParens(TT_BinaryOperator);
3701 TopLevelParensAllowed = false;
3702 break;
3703
3704 case tok::l_square:
3705 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3706 return;
3707 break;
3708
3709 case tok::kw_const:
3710 case tok:🚛
3711 case tok::kw_class:
3712 case tok::kw_struct:
3713 case tok::kw_union:
3714 return;
3715
3716 case tok::l_brace:
3717
3718 return;
3719
3720 case tok::ampamp:
3721 case tok::pipepipe:
3723 nextToken();
3724 LambdaNextTimeAllowed = true;
3725 TopLevelParensAllowed = true;
3726 break;
3727
3728 case tok::comma:
3729 case tok::comment:
3730 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3731 nextToken();
3732 break;
3733
3734 case tok::kw_sizeof:
3735 case tok::greater:
3736 case tok::greaterequal:
3737 case tok::greatergreater:
3738 case tok::less:
3739 case tok::lessequal:
3740 case tok::lessless:
3741 case tok::equalequal:
3742 case tok::exclaim:
3743 case tok::exclaimequal:
3744 case tok:➕
3745 case tok:➖
3746 case tok:⭐
3747 case tok::slash:
3748 LambdaNextTimeAllowed = true;
3749 TopLevelParensAllowed = true;
3750
3751 nextToken();
3752 break;
3753
3754 case tok::numeric_constant:
3755 case tok::coloncolon:
3756 case tok::kw_true:
3757 case tok::kw_false:
3758 TopLevelParensAllowed = false;
3759
3760 nextToken();
3761 break;
3762
3763 case tok::kw_static_cast:
3764 case tok::kw_const_cast:
3765 case tok::kw_reinterpret_cast:
3766 case tok::kw_dynamic_cast:
3767 nextToken();
3768 if (FormatTok->isNot(tok::less))
3769 return;
3770
3771 nextToken();
3772 parseBracedList(true);
3773 break;
3774
3775 default:
3777
3778
3779 return;
3780 }
3781
3782
3783
3784
3785
3786 assert(FormatTok->Previous);
3788 case tok::coloncolon:
3789 case tok::ampamp:
3790 case tok::pipepipe:
3791 case tok::exclaim:
3792 case tok::kw_requires:
3793 case tok::equal:
3794 break;
3795 default:
3796 return;
3797 }
3798
3799
3800 nextToken();
3801 if (FormatTok->is(tok::less)) {
3802 nextToken();
3803 parseBracedList(true);
3804 }
3805 TopLevelParensAllowed = false;
3806 break;
3807 }
3808 } while (!eof());
3809}
3810
3811bool UnwrappedLineParser::parseEnum() {
3812 const FormatToken &InitialToken = *FormatTok;
3813
3814
3815 if (FormatTok->is(tok::kw_enum))
3816 nextToken();
3817
3818
3819
3820
3821 if (Style.isJavaScript() && FormatTok->isOneOf(tok::colon, tok::question))
3822 return false;
3823
3824
3826 return false;
3827
3828 if (IsCpp) {
3829
3830 if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))
3831 nextToken();
3832 while (FormatTok->is(tok::l_square))
3833 if (!handleCppAttributes())
3834 return false;
3835 }
3836
3838 FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
3839 tok::greater, tok::comma, tok::question,
3840 tok::l_square)) {
3843 nextToken();
3844
3845 while (FormatTok->is(tok::l_square))
3846 parseSquare();
3847 } else {
3848 nextToken();
3849 }
3850
3851 if (FormatTok->is(tok::l_paren))
3852 parseParens();
3853 if (FormatTok->is(tok::identifier)) {
3854 nextToken();
3855
3856
3857 if (IsCpp && FormatTok->is(tok::identifier))
3858 return false;
3859 }
3860 }
3861
3862
3863 if (FormatTok->isNot(tok::l_brace))
3864 return true;
3867
3869
3870 parseJavaEnumBody();
3871 return true;
3872 }
3874 parseBlock(true);
3875 return true;
3876 }
3877
3880 addUnwrappedLine();
3881 }
3882
3883 nextToken();
3885 addUnwrappedLine();
3886 Line->Level += 1;
3887 }
3888 bool HasError = !parseBracedList(false, true);
3890 Line->Level -= 1;
3891 if (HasError) {
3892 if (FormatTok->is(tok::semi))
3893 nextToken();
3894 addUnwrappedLine();
3895 }
3896 setPreviousRBraceType(TT_EnumRBrace);
3897 return true;
3898
3899
3900
3901
3902}
3903
3904bool UnwrappedLineParser::parseStructLike() {
3905
3906
3907 parseRecord();
3908
3911 if (FormatTok->is(tok::semi))
3912 nextToken();
3913 addUnwrappedLine();
3914 return true;
3915 }
3916 return false;
3917}
3918
3919namespace {
3920
3921
3922class ScopedTokenPosition {
3923 unsigned StoredPosition;
3924 FormatTokenSource *Tokens;
3925
3926public:
3927 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3928 assert(Tokens && "Tokens expected to not be null");
3929 StoredPosition = Tokens->getPosition();
3930 }
3931
3932 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3933};
3934}
3935
3936
3937
3938bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3939 ScopedTokenPosition AutoPosition(Tokens);
3940 FormatToken *Tok = Tokens->getNextToken();
3941
3942 if (Tok->isNot(tok::l_square))
3943 return false;
3944
3945
3946 while (Tok->isNot(tok::eof)) {
3947 if (Tok->is(tok::r_square))
3948 break;
3949 Tok = Tokens->getNextToken();
3950 }
3951 if (Tok->is(tok::eof))
3952 return false;
3953 Tok = Tokens->getNextToken();
3954 if (Tok->isNot(tok::r_square))
3955 return false;
3956 Tok = Tokens->getNextToken();
3957 if (Tok->is(tok::semi))
3958 return false;
3959 return true;
3960}
3961
3962void UnwrappedLineParser::parseJavaEnumBody() {
3963 assert(FormatTok->is(tok::l_brace));
3964 const FormatToken *OpeningBrace = FormatTok;
3965
3966
3967
3968
3969 unsigned StoredPosition = Tokens->getPosition();
3970 bool IsSimple = true;
3971 FormatToken *Tok = Tokens->getNextToken();
3972 while (Tok->isNot(tok::eof)) {
3973 if (Tok->is(tok::r_brace))
3974 break;
3975 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3976 IsSimple = false;
3977 break;
3978 }
3979
3980
3981 Tok = Tokens->getNextToken();
3982 }
3983 FormatTok = Tokens->setPosition(StoredPosition);
3984
3985 if (IsSimple) {
3986 nextToken();
3987 parseBracedList();
3988 addUnwrappedLine();
3989 return;
3990 }
3991
3992
3993
3994 nextToken();
3995 addUnwrappedLine();
3996 ++Line->Level;
3997
3998
3999 while (!eof()) {
4000 if (FormatTok->is(tok::l_brace)) {
4001
4002 parseBlock(true, 1u,
4003 false);
4004 } else if (FormatTok->is(tok::l_paren)) {
4005 parseParens();
4006 } else if (FormatTok->is(tok::comma)) {
4007 nextToken();
4008 addUnwrappedLine();
4009 } else if (FormatTok->is(tok::semi)) {
4010 nextToken();
4011 addUnwrappedLine();
4012 break;
4013 } else if (FormatTok->is(tok::r_brace)) {
4014 addUnwrappedLine();
4015 break;
4016 } else {
4017 nextToken();
4018 }
4019 }
4020
4021
4022 parseLevel(OpeningBrace);
4023 nextToken();
4024 --Line->Level;
4025 addUnwrappedLine();
4026}
4027
4028void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
4029 const FormatToken &InitialToken = *FormatTok;
4030 nextToken();
4031
4032 const FormatToken *ClassName = nullptr;
4033 bool IsDerived = false;
4034 auto IsNonMacroIdentifier = [](const FormatToken *Tok) {
4035 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
4036 };
4037
4038
4039 bool JSPastExtendsOrImplements = false;
4040
4041
4042
4043 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
4044 tok::kw_alignas, tok::l_square) ||
4047 FormatTok->isOneOf(tok::period, tok::comma))) {
4050 JSPastExtendsOrImplements = true;
4051
4052
4053
4054 nextToken();
4055 if (FormatTok->is(tok::l_brace)) {
4056 tryToParseBracedList();
4057 continue;
4058 }
4059 }
4060 if (FormatTok->is(tok::l_square) && handleCppAttributes())
4061 continue;
4062 const auto *Previous = FormatTok;
4063 nextToken();
4065 case tok::l_paren:
4066
4067 if (!IsNonMacroIdentifier(Previous) ||
4068
4069 Previous->Previous == &InitialToken) {
4070 parseParens();
4071 }
4072 break;
4073 case tok::coloncolon:
4074 case tok::hashhash:
4075 break;
4076 default:
4077 if (!JSPastExtendsOrImplements && !ClassName &&
4078 Previous->is(tok::identifier) && Previous->isNot(TT_AttributeMacro)) {
4080 }
4081 }
4082 }
4083
4084 auto IsListInitialization = [&] {
4085 if (!ClassName || IsDerived || JSPastExtendsOrImplements)
4086 return false;
4087 assert(FormatTok->is(tok::l_brace));
4089 assert(Prev);
4090 return Prev != ClassName && Prev->is(tok::identifier) &&
4091 Prev->isNot(Keywords.kw_final) && tryToParseBracedList();
4092 };
4093
4094 if (FormatTok->isOneOf(tok::colon, tok::less)) {
4095 int AngleNestingLevel = 0;
4096 do {
4097 if (FormatTok->is(tok::less))
4098 ++AngleNestingLevel;
4099 else if (FormatTok->is(tok::greater))
4100 --AngleNestingLevel;
4101
4102 if (AngleNestingLevel == 0) {
4103 if (FormatTok->is(tok::colon)) {
4104 IsDerived = true;
4105 } else if (FormatTok->is(tok::identifier) &&
4106 FormatTok->Previous->is(tok::coloncolon)) {
4107 ClassName = FormatTok;
4108 } else if (FormatTok->is(tok::l_paren) &&
4109 IsNonMacroIdentifier(FormatTok->Previous)) {
4110 break;
4111 }
4112 }
4113 if (FormatTok->is(tok::l_brace)) {
4114 if (AngleNestingLevel == 0 && IsListInitialization())
4115 return;
4116 calculateBraceTypes(true);
4117 if (!tryToParseBracedList())
4118 break;
4119 }
4120 if (FormatTok->is(tok::l_square)) {
4123 ->isTypeOrIdentifier(LangOpts))) {
4124
4125
4126 if (!tryToParseLambda())
4127 continue;
4128 } else {
4129 parseSquare();
4130 continue;
4131 }
4132 }
4133 if (FormatTok->is(tok::semi))
4134 return;
4136 addUnwrappedLine();
4137 nextToken();
4138 parseCSharpGenericTypeConstraint();
4139 break;
4140 }
4141 nextToken();
4142 } while (!eof());
4143 }
4144
4145 auto GetBraceTypes =
4146 [](const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4147 switch (RecordTok.Tok.getKind()) {
4148 case tok::kw_class:
4149 return {TT_ClassLBrace, TT_ClassRBrace};
4150 case tok::kw_struct:
4151 return {TT_StructLBrace, TT_StructRBrace};
4152 case tok::kw_union:
4153 return {TT_UnionLBrace, TT_UnionRBrace};
4154 default:
4155
4156 return {TT_RecordLBrace, TT_RecordRBrace};
4157 }
4158 };
4159 if (FormatTok->is(tok::l_brace)) {
4160 if (IsListInitialization())
4161 return;
4162 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4164 if (ParseAsExpr) {
4165 parseChildBlock();
4166 } else {
4168 addUnwrappedLine();
4169
4171 parseBlock(true, AddLevels, false);
4172 }
4173 setPreviousRBraceType(ClosingBraceType);
4174 }
4175
4176
4177
4178}
4179
4180void UnwrappedLineParser::parseObjCMethod() {
4181 assert(FormatTok->isOneOf(tok::l_paren, tok::identifier) &&
4182 "'(' or identifier expected.");
4183 do {
4184 if (FormatTok->is(tok::semi)) {
4185 nextToken();
4186 addUnwrappedLine();
4187 return;
4188 } else if (FormatTok->is(tok::l_brace)) {
4190 addUnwrappedLine();
4191 parseBlock();
4192 addUnwrappedLine();
4193 return;
4194 } else {
4195 nextToken();
4196 }
4197 } while (!eof());
4198}
4199
4200void UnwrappedLineParser::parseObjCProtocolList() {
4201 assert(FormatTok->is(tok::less) && "'<' expected.");
4202 do {
4203 nextToken();
4204
4205 if (FormatTok->isOneOf(tok::semi, tok::l_brace) ||
4207 return;
4208 }
4209 } while (!eof() && FormatTok->isNot(tok::greater));
4210 nextToken();
4211}
4212
4213void UnwrappedLineParser::parseObjCUntilAtEnd() {
4214 do {
4216 nextToken();
4217 addUnwrappedLine();
4218 break;
4219 }
4220 if (FormatTok->is(tok::l_brace)) {
4221 parseBlock();
4222
4223 addUnwrappedLine();
4224 } else if (FormatTok->is(tok::r_brace)) {
4225
4226 nextToken();
4227 addUnwrappedLine();
4228 } else if (FormatTok->isOneOf(tok::minus, tok::plus)) {
4229 nextToken();
4230 parseObjCMethod();
4231 } else {
4232 parseStructuralElement();
4233 }
4234 } while (!eof());
4235}
4236
4237void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4240 nextToken();
4241 nextToken();
4242
4243
4244
4245 if (FormatTok->is(tok::less))
4246 parseObjCLightweightGenerics();
4247 if (FormatTok->is(tok::colon)) {
4248 nextToken();
4249 nextToken();
4250
4251 if (FormatTok->is(tok::less))
4252 parseObjCLightweightGenerics();
4253 } else if (FormatTok->is(tok::l_paren)) {
4254
4255 parseParens();
4256 }
4257
4258 if (FormatTok->is(tok::less))
4259 parseObjCProtocolList();
4260
4261 if (FormatTok->is(tok::l_brace)) {
4263 addUnwrappedLine();
4264 parseBlock(true);
4265 }
4266
4267
4268
4269 addUnwrappedLine();
4270
4271 parseObjCUntilAtEnd();
4272}
4273
4274void UnwrappedLineParser::parseObjCLightweightGenerics() {
4275 assert(FormatTok->is(tok::less));
4276
4277
4278
4279
4280
4281
4282
4283 unsigned NumOpenAngles = 1;
4284 do {
4285 nextToken();
4286
4287 if (FormatTok->isOneOf(tok::semi, tok::l_brace) ||
4289 break;
4290 }
4291 if (FormatTok->is(tok::less)) {
4292 ++NumOpenAngles;
4293 } else if (FormatTok->is(tok::greater)) {
4294 assert(NumOpenAngles > 0 && "'>' makes NumOpenAngles negative");
4295 --NumOpenAngles;
4296 }
4297 } while (!eof() && NumOpenAngles != 0);
4298 nextToken();
4299}
4300
4301
4302
4303bool UnwrappedLineParser::parseObjCProtocol() {
4305 nextToken();
4306
4307 if (FormatTok->is(tok::l_paren)) {
4308
4309 return false;
4310 }
4311
4312
4313
4314
4315
4316
4317 nextToken();
4318
4319 if (FormatTok->is(tok::less))
4320 parseObjCProtocolList();
4321
4322
4323 if (FormatTok->is(tok::semi)) {
4324 nextToken();
4325 addUnwrappedLine();
4326 return true;
4327 }
4328
4329 addUnwrappedLine();
4330 parseObjCUntilAtEnd();
4331 return true;
4332}
4333
4334void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4335 bool IsImport = FormatTok->is(Keywords.kw_import);
4336 assert(IsImport || FormatTok->is(tok::kw_export));
4337 nextToken();
4338
4339
4340 if (FormatTok->is(tok::kw_default))
4341 nextToken();
4342
4343
4344
4345
4346 if (FormatTok->is(Keywords.kw_async))
4347 nextToken();
4349 nextToken();
4350 return;
4351 }
4352
4353
4354
4355
4356
4357 if (!IsImport && !FormatTok->isOneOf(tok::l_brace, tok::star) &&
4359 !(FormatTok->is(Keywords.kw_type) &&
4360 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4361 return;
4362 }
4363
4364 while (!eof()) {
4365 if (FormatTok->is(tok::semi))
4366 return;
4367 if (Line->Tokens.empty()) {
4368
4369
4370 return;
4371 }
4372 if (FormatTok->is(tok::l_brace)) {
4374 nextToken();
4375 parseBracedList();
4376 } else {
4377 nextToken();
4378 }
4379 }
4380}
4381
4382void UnwrappedLineParser::parseStatementMacro() {
4383 nextToken();
4384 if (FormatTok->is(tok::l_paren))
4385 parseParens();
4386 if (FormatTok->is(tok::semi))
4387 nextToken();
4388 addUnwrappedLine();
4389}
4390
4391void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4392
4393 while (true) {
4394 if (FormatTok->isOneOf(tok::star, tok::period, tok::periodstar,
4395 tok::coloncolon, tok::hash) ||
4397 nextToken();
4398 } else if (FormatTok->is(tok::l_square)) {
4399 parseSquare();
4400 } else {
4401 break;
4402 }
4403 }
4404}
4405
4406void UnwrappedLineParser::parseVerilogSensitivityList() {
4407 if (FormatTok->isNot(tok::at))
4408 return;
4409 nextToken();
4410
4411 if (FormatTok->is(tok::at))
4412 nextToken();
4414 case tok:⭐
4415 nextToken();
4416 break;
4417 case tok::l_paren:
4418 parseParens();
4419 break;
4420 default:
4421 parseVerilogHierarchyIdentifier();
4422 break;
4423 }
4424}
4425
4426unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4427 unsigned AddLevels = 0;
4428
4430 nextToken();
4432 nextToken();
4433 parseVerilogSensitivityList();
4434 if (FormatTok->is(tok::semi))
4435 nextToken();
4436 } else if (FormatTok->isOneOf(tok::kw_case, Keywords.kw_casex,
4440 AddLevels++;
4441 nextToken();
4442 if (FormatTok->is(tok::l_paren)) {
4444 parseParens();
4445 }
4447 nextToken();
4448
4449 } else {
4450
4451 nextToken();
4452
4453
4454 while (true) {
4455 if (FormatTok->is(tok::l_square)) {
4459 parseSquare();
4461 FormatTok->isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
4463 nextToken();
4464 } else {
4465 break;
4466 }
4467 }
4468
4469 auto NewLine = [this]() {
4470 addUnwrappedLine();
4471 Line->IsContinuation = true;
4472 };
4473
4474
4475 while (FormatTok->is(Keywords.kw_import)) {
4477 nextToken();
4478 parseVerilogHierarchyIdentifier();
4479 if (FormatTok->is(tok::semi))
4480 nextToken();
4481 }
4482
4483
4486 nextToken();
4487 if (FormatTok->is(tok::l_paren)) {
4489 parseParens();
4490 }
4491 }
4492 if (FormatTok->is(tok::l_paren)) {
4495 parseParens();
4496 }
4497
4498
4501 nextToken();
4502 parseVerilogHierarchyIdentifier();
4503 if (FormatTok->is(tok::l_paren))
4504 parseParens();
4505 }
4508 do {
4509 nextToken();
4510 parseVerilogHierarchyIdentifier();
4511 } while (FormatTok->is(tok::comma));
4512 }
4513
4514
4515 if (FormatTok->is(tok::at)) {
4517 parseVerilogSensitivityList();
4518 }
4519
4520 if (FormatTok->is(tok::semi))
4521 nextToken(1);
4522 addUnwrappedLine();
4523 }
4524
4525 return AddLevels;
4526}
4527
4528void UnwrappedLineParser::parseVerilogTable() {
4529 assert(FormatTok->is(Keywords.kw_table));
4530 nextToken(1);
4531 addUnwrappedLine();
4532
4533 auto InitialLevel = Line->Level++;
4534 while (!eof() && !Keywords.isVerilogEnd(*FormatTok)) {
4535 FormatToken *Tok = FormatTok;
4536 nextToken();
4537 if (Tok->is(tok::semi))
4538 addUnwrappedLine();
4539 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4540 Tok->setFinalizedType(TT_VerilogTableItem);
4541 }
4542 Line->Level = InitialLevel;
4543 nextToken(-1);
4544 addUnwrappedLine();
4545}
4546
4547void UnwrappedLineParser::parseVerilogCaseLabel() {
4548
4549
4550
4551
4552
4553 auto OrigLevel = Line->Level;
4554 auto FirstLine = CurrentLines->size();
4555 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4556 ++Line->Level;
4558 --Line->Level;
4559 parseStructuralElement();
4560
4561
4562 if (CurrentLines->size() > FirstLine)
4563 (*CurrentLines)[FirstLine].Level = OrigLevel;
4564 Line->Level = OrigLevel;
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 =
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.size() > 0);
4627 CurrentLines->push_back(std::move(*Line));
4628 }
4629 Line->Tokens.clear();
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) {
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
4751 if (Node.Tok->NewlinesBefore > 0)
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();
4763 for (FormatToken *Tok : CommentsBeforeNextToken) {
4764
4765
4766
4767
4768
4769
4770
4771
4772 Tok->ContinuesLineCommentSection =
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);
4788 FormatToken *Previous = FormatTok;
4790 readToken(LevelDifference);
4791 else
4792 readTokenWithJavaScriptASI();
4793 FormatTok->Previous = Previous;
4795
4796
4797
4798
4799
4800
4802 FormatTok->Tok.setKind(tok::r_brace);
4803 }
4804}
4805
4806void UnwrappedLineParser::distributeComments(
4807 const ArrayRef<FormatToken *> &Comments, const FormatToken *NextTok) {
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) {
4841 FormatToken *FormatTok = Comments[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) {
4860 SmallVector<FormatToken *, 1> Comments;
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,
4880 const FormatToken &Tok,
4881 bool PreviousWasComment) {
4882 auto IsFirstOnLine = [](const FormatToken &Tok) {
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) &&
4900 FirstNonCommentOnLine) {
4901 distributeComments(Comments, FormatTok);
4902 Comments.clear();
4903
4904
4905 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4906 ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
4907 assert((LevelDifference >= 0 ||
4908 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4909 "LevelDifference makes Line->Level negative");
4910 Line->Level += LevelDifference;
4911
4912
4913
4915 PPBranchLevel > 0) {
4916 Line->Level += PPBranchLevel;
4917 }
4918 assert(Line->Level >= Line->UnbracedBodyLevel);
4919 Line->Level -= Line->UnbracedBodyLevel;
4920 flushComments(isOnNewLine(*FormatTok));
4921 parsePPDirective();
4922 PreviousWasComment = FormatTok->is(tok::comment);
4923 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4924 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4925 }
4926
4927 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4928 !Line->InPPDirective) {
4929 continue;
4930 }
4931
4932 if (FormatTok->is(tok::identifier) &&
4933 Macros.defined(FormatTok->TokenText) &&
4934
4935 !Line->InPPDirective) {
4936 FormatToken *ID = FormatTok;
4937 unsigned Position = Tokens->getPosition();
4938
4939
4940
4941 auto PreCall = std::move(Line);
4942 Line.reset(new UnwrappedLine);
4943 bool OldInExpansion = InExpansion;
4944 InExpansion = true;
4945
4946 auto Args = parseMacroCall();
4947 InExpansion = OldInExpansion;
4948 assert(Line->Tokens.front().Tok == ID);
4949
4950 auto UnexpandedLine = std::move(Line);
4951
4952 Line = std::move(PreCall);
4953
4954 LLVM_DEBUG({
4955 llvm::dbgs() << "Macro call: " << ID->TokenText << "(";
4956 if (Args) {
4957 llvm::dbgs() << "(";
4958 for (const auto &Arg : Args.value())
4959 for (const auto &T : Arg)
4960 llvm::dbgs() << T->TokenText << " ";
4961 llvm::dbgs() << ")";
4962 }
4963 llvm::dbgs() << "\n";
4964 });
4965 if (Macros.objectLike(ID->TokenText) && Args &&
4966 !Macros.hasArity(ID->TokenText, Args->size())) {
4967
4968
4969
4970
4971
4972 LLVM_DEBUG(llvm::dbgs()
4973 << "Macro \"" << ID->TokenText
4974 << "\" not overloaded for arity " << Args->size()
4975 << "or not function-like, using object-like overload.");
4976 Args.reset();
4977 UnexpandedLine->Tokens.resize(1);
4978 Tokens->setPosition(Position);
4979 nextToken();
4980 assert(!Args && Macros.objectLike(ID->TokenText));
4981 }
4982 if ((!Args && Macros.objectLike(ID->TokenText)) ||
4983 (Args && Macros.hasArity(ID->TokenText, Args->size()))) {
4984
4985
4986 Unexpanded[ID] = std::move(UnexpandedLine);
4987 SmallVector<FormatToken *, 8> Expansion =
4988 Macros.expand(ID, std::move(Args));
4989 if (!Expansion.empty())
4990 FormatTok = Tokens->insertTokens(Expansion);
4991
4992 LLVM_DEBUG({
4993 llvm::dbgs() << "Expanded: ";
4994 for (const auto &T : Expansion)
4995 llvm::dbgs() << T->TokenText << " ";
4996 llvm::dbgs() << "\n";
4997 });
4998 } else {
4999 LLVM_DEBUG({
5000 llvm::dbgs() << "Did not expand macro \"" << ID->TokenText
5001 << "\", because it was used ";
5002 if (Args)
5003 llvm::dbgs() << "with " << Args->size();
5004 else
5005 llvm::dbgs() << "without";
5006 llvm::dbgs() << " arguments, which doesn't match any definition.\n";
5007 });
5008 Tokens->setPosition(Position);
5009 FormatTok = ID;
5010 }
5011 }
5012
5013 if (FormatTok->isNot(tok::comment)) {
5014 distributeComments(Comments, FormatTok);
5015 Comments.clear();
5016 return;
5017 }
5018
5019 Comments.push_back(FormatTok);
5020 } while (!eof());
5021
5022 distributeComments(Comments, nullptr);
5023 Comments.clear();
5024}
5025
5026namespace {
5027template
5028void pushTokens(Iterator Begin, Iterator End,
5029 SmallVectorImpl<FormatToken *> &Into) {
5030 for (auto I = Begin; I != End; ++I) {
5031 Into.push_back(I->Tok);
5032 for (const auto &Child : I->Children)
5033 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
5034 }
5035}
5036}
5037
5038std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
5039UnwrappedLineParser::parseMacroCall() {
5040 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
5041 assert(Line->Tokens.empty());
5042 nextToken();
5043 if (FormatTok->isNot(tok::l_paren))
5044 return Args;
5045 unsigned Position = Tokens->getPosition();
5046 FormatToken *Tok = FormatTok;
5047 nextToken();
5048 Args.emplace();
5049 auto ArgStart = std::prev(Line->Tokens.end());
5050
5052 do {
5053 switch (FormatTok->Tok.getKind()) {
5054 case tok::l_paren:
5056 nextToken();
5057 break;
5058 case tok::r_paren: {
5061 nextToken();
5062 break;
5063 }
5064 Args->push_back({});
5065 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5066 nextToken();
5067 return Args;
5068 }
5069 case tok::comma: {
5071 nextToken();
5072 break;
5073 }
5074 Args->push_back({});
5075 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5076 nextToken();
5077 ArgStart = std::prev(Line->Tokens.end());
5078 break;
5079 }
5080 default:
5081 nextToken();
5082 break;
5083 }
5084 } while (!eof());
5085 Line->Tokens.resize(1);
5086 Tokens->setPosition(Position);
5087 FormatTok = Tok;
5088 return {};
5089}
5090
5091void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5092 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5093 if (MustBreakBeforeNextToken) {
5094 Line->Tokens.back().Tok->MustBreakBefore = true;
5095 Line->Tokens.back().Tok->MustBreakBeforeFinalized = true;
5096 MustBreakBeforeNextToken = false;
5097 }
5098}
5099
5100}
5101}
enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind
This file contains FormatTokenLexer, which tokenizes a source file into a token stream suitable for C...
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...
This file contains the main building blocks of macro support in clang-format.
This file implements a token annotator, i.e.
Defines the clang::TokenKind enum and support functions.
ContinuationIndenter * Indenter
This file contains the declaration of the UnwrappedLineParser, which turns a stream of tokens into Un...
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
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 isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
void setKind(tok::TokenKind K)
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
tok::TokenKind getKind() const
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
void setIdentifierInfo(IdentifierInfo *II)
CompoundStatementIndenter(UnwrappedLineParser *Parser, const FormatStyle &Style, unsigned &LineLevel)
~CompoundStatementIndenter()
CompoundStatementIndenter(UnwrappedLineParser *Parser, unsigned &LineLevel, bool WrapBrace, bool IndentBrace)
virtual FormatToken * peekNextToken(bool SkipComment=false)=0
virtual unsigned getPosition()=0
FormatToken * getNextNonComment()
virtual FormatToken * getPreviousToken()=0
virtual FormatToken * setPosition(unsigned Position)=0
virtual FormatToken * getNextToken()=0
bool objectLike(StringRef Name) const
Returns whetherh there is an object-like overload, i.e.
SmallVector< FormatToken *, 8 > expand(FormatToken *ID, std::optional< ArgsList > OptionalArgs) const
Returns the expanded stream of format tokens for ID, where each element in Args is a positional argum...
bool hasArity(StringRef Name, unsigned Arity) const
Returns whether macro Name provides an overload with the given arity.
bool defined(StringRef Name) const
Returns whether any macro Name is defined, regardless of overloads.
ScopedLineState(UnwrappedLineParser &Parser, bool SwitchToPreprocessorLines=false)
Interface for users of the UnwrappedLineParser to receive the parsed lines.
virtual void finishRun()=0
virtual void consumeUnwrappedLine(const UnwrappedLine &Line)=0
friend class ScopedLineState
friend class CompoundStatementIndenter
UnwrappedLineParser(SourceManager &SourceMgr, const FormatStyle &Style, const AdditionalKeywords &Keywords, unsigned FirstStartColumn, ArrayRef< FormatToken * > Tokens, UnwrappedLineConsumer &Callback, llvm::SpecificBumpPtrAllocator< FormatToken > &Allocator, IdentifierTable &IdentTable)
static bool isCOperatorFollowingVar(tok::TokenKind Kind)
static void hash_combine(std::size_t &seed, const T &v)
static bool mustBeJSIdentOrValue(const AdditionalKeywords &Keywords, const FormatToken *FormatTok)
std::ostream & operator<<(std::ostream &Stream, const UnwrappedLine &Line)
bool continuesLineComment(const FormatToken &FormatTok, const FormatToken *Previous, const FormatToken *MinColumnToken)
static bool tokenCanStartNewLine(const FormatToken &Tok)
static bool continuesLineCommentSection(const FormatToken &FormatTok, const UnwrappedLine &Line, const FormatStyle &Style, const llvm::Regex &CommentPragmasRegex)
static bool isC78Type(const FormatToken &Tok)
bool isLineComment(const FormatToken &FormatTok)
static bool isJSDeclOrStmt(const AdditionalKeywords &Keywords, const FormatToken *FormatTok)
static bool ShouldBreakBeforeBrace(const FormatStyle &Style, const FormatToken &InitialToken)
LangOptions getFormattingLangOpts(const FormatStyle &Style=getLLVMStyle())
Returns the LangOpts that the formatter expects you to set.
static void markOptionalBraces(FormatToken *LeftBrace)
static bool mustBeJSIdent(const AdditionalKeywords &Keywords, const FormatToken *FormatTok)
static bool isIIFE(const UnwrappedLine &Line, const AdditionalKeywords &Keywords)
static bool isC78ParameterDecl(const FormatToken *Tok, const FormatToken *Next, const FormatToken *FuncName)
static bool isGoogScope(const UnwrappedLine &Line)
static FormatToken * getLastNonComment(const UnwrappedLine &Line)
TokenType
Determines the semantic type of a syntactic token, e.g.
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.
const FunctionProtoType * T
@ 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...
bool isVerilogEnd(const FormatToken &Tok) const
Returns whether Tok is a Verilog keyword that closes a block.
IdentifierInfo * kw_foreach
IdentifierInfo * kw_forever
IdentifierInfo * kw_signals
IdentifierInfo * kw_inside
IdentifierInfo * kw_CF_ENUM
IdentifierInfo * kw_synchronized
IdentifierInfo * kw_randcase
IdentifierInfo * kw_randsequence
IdentifierInfo * kw_always_ff
IdentifierInfo * kw_always_latch
IdentifierInfo * kw_final
IdentifierInfo * kw_assert
bool isVerilogBegin(const FormatToken &Tok) const
Returns whether Tok is a Verilog keyword that opens a block.
IdentifierInfo * kw_initial
IdentifierInfo * kw_priority
IdentifierInfo * kw_qsignals
IdentifierInfo * kw_cover
IdentifierInfo * kw_assume
bool isVerilogStructuredProcedure(const FormatToken &Tok) const
Returns whether Tok is a Verilog keyword that starts a structured procedure like 'always'.
IdentifierInfo * kw_CF_OPTIONS
IdentifierInfo * kw_defset
IdentifierInfo * kw_unique0
IdentifierInfo * kw_interface
IdentifierInfo * kw_yield
IdentifierInfo * kw_CF_CLOSED_ENUM
IdentifierInfo * kw_slots
IdentifierInfo * kw_import
IdentifierInfo * kw_casex
IdentifierInfo * kw_repeat
IdentifierInfo * kw_where
IdentifierInfo * kw_automatic
IdentifierInfo * kw_finally
IdentifierInfo * kw_NS_CLOSED_ENUM
bool isVerilogHierarchy(const FormatToken &Tok) const
Returns whether Tok is a Verilog keyword that opens a module, etc.
IdentifierInfo * kw_async
IdentifierInfo * kw_always_comb
IdentifierInfo * kw_internal
IdentifierInfo * kw_sequence
bool isVerilogPPDirective(const FormatToken &Tok) const
Returns whether Tok is a Verilog preprocessor directive.
IdentifierInfo * kw_casez
IdentifierInfo * kw_throws
IdentifierInfo * kw_NS_ENUM
IdentifierInfo * kw_override
IdentifierInfo * kw___except
IdentifierInfo * kw_table
IdentifierInfo * kw_NS_OPTIONS
IdentifierInfo * kw_abstract
IdentifierInfo * kw_internal_ident_after_define
IdentifierInfo * kw_await
IdentifierInfo * kw_implements
IdentifierInfo * kw_always
IdentifierInfo * kw_verilogHash
IdentifierInfo * kw_instanceof
IdentifierInfo * kw_matches
IdentifierInfo * kw_qslots
IdentifierInfo * kw_function
bool isVerilogIdentifier(const FormatToken &Tok) const
IdentifierInfo * kw_clocking
IdentifierInfo * kw_unique
IdentifierInfo * kw_extends
IdentifierInfo * kw_property
bool AfterClass
Wrap class definitions.
bool AfterCaseLabel
Wrap case labels.
bool AfterStruct
Wrap struct definitions.
bool AfterUnion
Wrap union definitions.
bool AfterEnum
Wrap enum definitions.
bool IndentBraces
Indent the wrapped braces themselves.
bool AfterObjCDeclaration
Wrap ObjC definitions (interfaces, implementations...).
bool BeforeElse
Wrap before else.
bool AfterNamespace
Wrap namespace definitions.
bool BeforeWhile
Wrap before while.
BraceWrappingAfterControlStatementStyle AfterControlStatement
Wrap control statements (if/for/while/switch/..).
bool AfterFunction
Wrap function definitions.
bool BeforeCatch
Wrap before catch.
bool AfterExternBlock
Wrap extern blocks.
The FormatStyle is used to configure the formatting to follow specific guidelines.
@ LK_Java
Should be used for Java.
@ LK_TableGen
Should be used for TableGen code.
@ LK_Proto
Should be used for Protocol Buffers (https://developers.google.com/protocol-buffers/).
@ LK_TextProto
Should be used for Protocol Buffer messages in text format (https://developers.google....
unsigned IndentWidth
The number of columns to use for indentation.
bool IndentCaseLabels
Indent case labels one level from the switch statement.
PPDirectiveIndentStyle IndentPPDirectives
The preprocessor directive indenting style to use.
bool RemoveSemicolon
Remove semicolons after the closing braces of functions and constructors/destructors.
bool IndentExportBlock
If true, clang-format will indent the body of an export { ... } block.
@ RCS_Always
Apply indentation rules and reflow long comments into new lines, trying to obey the ColumnLimit.
@ IEBS_AfterExternBlock
Backwards compatible with AfterExternBlock's indenting.
@ IEBS_Indent
Indents extern blocks.
bool IndentCaseBlocks
Indent case label blocks one level from the case label.
bool InsertBraces
Insert braces after control statements (if, else, for, do, and while) in C++ unless the control state...
RemoveParenthesesStyle RemoveParentheses
Remove redundant parentheses.
LanguageKind Language
Language, this format style is targeted at.
bool RemoveBracesLLVM
Remove optional braces of control statements (if, else, for, and while) in C++ according to the LLVM ...
@ PPDIS_BeforeHash
Indents directives before the hash.
@ PPDIS_None
Does not indent any directives.
bool AllowShortLoopsOnASingleLine
If true, while (true) continue; can be put on a single line.
bool AllowShortEnumsOnASingleLine
Allow short enums on a single line.
NamespaceIndentationKind NamespaceIndentation
The indentation used for namespaces.
BraceBreakingStyle BreakBeforeBraces
The brace breaking style to use.
@ BWACS_Always
Always wrap braces after a control statement.
@ BWACS_Never
Never wrap braces after a control statement.
@ BS_Whitesmiths
Like Allman but always indent braces and line up code with braces.
ReflowCommentsStyle ReflowComments
Comment reformatting style.
bool isJavaScript() const
bool IndentGotoLabels
Indent goto labels.
BraceWrappingFlags BraceWrapping
Control of individual brace wrapping cases.
@ RPS_Leave
Do not remove parentheses.
@ RPS_ReturnStatement
Also remove parentheses enclosing the expression in a return/co_return statement.
bool SkipMacroDefinitionBody
Do not format macro definition body.
@ NI_All
Indent in all namespaces.
@ NI_Inner
Indent only in inner namespaces (nested in other namespaces).
bool IndentAccessModifiers
Specify whether access modifiers should have their own indentation level.
IndentExternBlockStyle IndentExternBlock
IndentExternBlockStyle is the type of indenting of extern blocks.
unsigned ColumnLimit
The column limit.
A wrapper around a Token storing information about the whitespace characters preceding it.
bool Optional
Is optional and can be removed.
bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const
bool isTypeName(const LangOptions &LangOpts) const
bool isCppAlternativeOperatorKeyword() const
StringRef TokenText
The raw text of the token.
FormatToken * getPreviousNonComment() const
Returns the previous token ignoring comments.
unsigned Finalized
If true, this token has been fully formatted (indented and potentially re-formatted inside),...
unsigned NewlinesBefore
The number of newlines immediately before the Token.
void setBlockKind(BraceBlockKind BBK)
bool isStringLiteral() const
bool isBinaryOperator() const
bool is(tok::TokenKind Kind) const
bool hasWhitespaceBefore() const
Returns true if the range of whitespace immediately preceding the Token is not empty.
bool isOneOf(A K1, B K2) const
unsigned ClosesRequiresClause
true if this is the last token within requires clause.
bool isAccessSpecifierKeyword() const
FormatToken * MatchingParen
If this is a bracket, this points to the matching one.
FormatToken * Previous
The previous token in the unwrapped line.
bool endsSequence(A K1, Ts... Tokens) const
true if this token ends a sequence with the given tokens in order, following the Previous pointers,...
void setFinalizedType(TokenType T)
Sets the type and also the finalized flag.
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