21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/Debug.h"
24#include "llvm/Support/raw_os_ostream.h"
25#include "llvm/Support/raw_ostream.h"
29#define DEBUG_TYPE "format-parser"
36void printLine(llvm::raw_ostream &OS,
const UnwrappedLine &
Line,
37 StringRef Prefix =
"",
bool PrintText =
false) {
38 OS << Prefix <<
"Line(" <<
Line.Level <<
", FSC=" <<
Line.FirstStartColumn
39 <<
")" << (
Line.InPPDirective ?
" MACRO" :
"") <<
": ";
41 for (std::list<UnwrappedLineNode>::const_iterator I =
Line.Tokens.begin(),
42 E =
Line.Tokens.end();
48 OS << I->Tok->Tok.getName() <<
"["
49 <<
"T=" << (
unsigned)I->Tok->getType()
50 <<
", OC=" << I->Tok->OriginalColumn <<
", \"" << I->Tok->TokenText
52 for (
const auto *CI = I->Children.begin(), *CE = I->Children.end();
55 printLine(OS, *CI, (Prefix +
" ").str());
63[[maybe_unused]]
static void printDebugInfo(
const UnwrappedLine &
Line) {
64 printLine(llvm::dbgs(),
Line);
67class ScopedDeclarationState {
69 ScopedDeclarationState(UnwrappedLine &
Line, llvm::BitVector &Stack,
70 bool MustBeDeclaration)
72 Line.MustBeDeclaration = MustBeDeclaration;
73 Stack.push_back(MustBeDeclaration);
75 ~ScopedDeclarationState() {
78 Line.MustBeDeclaration = Stack.back();
80 Line.MustBeDeclaration =
true;
85 llvm::BitVector &Stack;
91 llvm::raw_os_ostream OS(Stream);
99 bool SwitchToPreprocessorLines =
false)
100 : Parser(Parser), OriginalLines(Parser.CurrentLines) {
101 if (SwitchToPreprocessorLines)
102 Parser.CurrentLines = &Parser.PreprocessorDirectives;
103 else if (!Parser.Line->Tokens.empty())
104 Parser.CurrentLines = &Parser.Line->Tokens.back().Children;
105 PreBlockLine = std::move(Parser.Line);
106 Parser.Line = std::make_unique<UnwrappedLine>();
107 Parser.Line->Level = PreBlockLine->Level;
108 Parser.Line->PPLevel = PreBlockLine->PPLevel;
109 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
110 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
111 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;
115 if (!Parser.Line->Tokens.empty())
116 Parser.addUnwrappedLine();
117 assert(Parser.Line->Tokens.empty());
118 Parser.Line = std::move(PreBlockLine);
119 if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
120 Parser.AtEndOfPPLine =
true;
121 Parser.CurrentLines = OriginalLines;
127 std::unique_ptr<UnwrappedLine> PreBlockLine;
134 const FormatStyle &Style,
unsigned &LineLevel)
136 Style.BraceWrapping.AfterControlStatement ==
137 FormatStyle::BWACS_Always,
138 Style.BraceWrapping.IndentBraces) {}
140 bool WrapBrace,
bool IndentBrace)
141 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
143 Parser->addUnwrappedLine();
151 unsigned OldLineLevel;
158 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
161 Style(Style), IsCpp(Style.
isCpp()),
163 CommentPragmasRegex(Style.CommentPragmas), Tokens(
nullptr),
164 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
165 IncludeGuard(getIncludeGuardState(Style.IndentPPDirectives)),
166 IncludeGuardToken(
nullptr), FirstStartColumn(FirstStartColumn),
167 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}
169void UnwrappedLineParser::reset() {
171 IncludeGuard = getIncludeGuardState(Style.IndentPPDirectives);
172 IncludeGuardToken =
nullptr;
174 CommentsBeforeNextToken.clear();
176 AtEndOfPPLine =
false;
177 IsDecltypeAutoFunction =
false;
178 PreprocessorDirectives.clear();
179 CurrentLines = &Lines;
180 DeclarationScopeStack.clear();
181 NestedTooDeep.clear();
182 NestedLambdas.clear();
184 Line->FirstStartColumn = FirstStartColumn;
186 if (!Unexpanded.empty())
188 Token->MacroCtx.reset();
189 CurrentExpandedLines.clear();
190 ExpandedLines.clear();
198 Line->FirstStartColumn = FirstStartColumn;
200 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
202 Tokens = &TokenSource;
210 if (IncludeGuard == IG_Found) {
211 for (
auto &Line : Lines)
212 if (Line.InPPDirective && Line.Level > 0)
218 pushToken(FormatTok);
223 if (!ExpandedLines.empty()) {
224 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
225 for (
const auto &Line : Lines) {
226 if (!Line.Tokens.empty()) {
227 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
228 if (it != ExpandedLines.end()) {
229 for (
const auto &Expanded : it->second) {
230 LLVM_DEBUG(printDebugInfo(Expanded));
231 Callback.consumeUnwrappedLine(Expanded);
236 LLVM_DEBUG(printDebugInfo(Line));
237 Callback.consumeUnwrappedLine(Line);
239 Callback.finishRun();
242 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
244 LLVM_DEBUG(printDebugInfo(Line));
245 Callback.consumeUnwrappedLine(Line);
247 Callback.finishRun();
249 while (!PPLevelBranchIndex.empty() &&
250 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
251 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
252 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
254 if (!PPLevelBranchIndex.empty()) {
255 ++PPLevelBranchIndex.back();
256 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
257 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
259 }
while (!PPLevelBranchIndex.empty());
262void UnwrappedLineParser::parseFile() {
265 bool MustBeDeclaration = !
Line->InPPDirective && !Style.isJavaScript();
266 ScopedDeclarationState DeclarationState(*
Line, DeclarationScopeStack,
268 if (Style.isTextProto() || (Style.isJson() && FormatTok->
IsFirst))
282 if (Style.isTextProto() && !CommentsBeforeNextToken.empty())
288void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
298 parseCSharpGenericTypeConstraint();
307void UnwrappedLineParser::parseCSharpAttribute() {
308 int UnpairedSquareBrackets = 1;
310 switch (FormatTok->Tok.getKind()) {
313 --UnpairedSquareBrackets;
314 if (UnpairedSquareBrackets == 0) {
320 ++UnpairedSquareBrackets;
330bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
331 if (!Lines.empty() && Lines.back().InPPDirective)
345bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
348 const bool InRequiresExpression =
349 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
350 const bool IsPrecededByCommentOrPPDirective =
351 !Style.RemoveBracesLLVM || precededByCommentOrPPDirective();
353 bool HasDoWhile =
false;
354 bool HasLabel =
false;
355 unsigned StatementCount = 0;
356 bool SwitchLabelEncountered =
false;
359 if (FormatTok->isAttribute()) {
361 if (FormatTok->is(tok::l_paren))
366 if (FormatTok->is(TT_MacroBlockBegin))
368 else if (FormatTok->is(TT_MacroBlockEnd))
371 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
372 &HasLabel, &StatementCount] {
373 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
374 HasDoWhile ?
nullptr : &HasDoWhile,
375 HasLabel ?
nullptr : &HasLabel);
377 assert(StatementCount > 0 &&
"StatementCount overflow!");
386 if (InRequiresExpression) {
387 FormatTok->setFinalizedType(TT_CompoundRequirementLBrace);
388 }
else if (FormatTok->Previous &&
389 FormatTok->Previous->ClosesRequiresClause) {
395 if (!InRequiresExpression && FormatTok->isNot(TT_MacroBlockBegin)) {
396 if (tryToParseBracedList())
398 FormatTok->setFinalizedType(TT_BlockLBrace);
402 assert(StatementCount > 0 &&
"StatementCount overflow!");
407 if (!Style.RemoveBracesLLVM || Line->InPPDirective ||
408 OpeningBrace->isNoneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
411 if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
412 HasDoWhile || IsPrecededByCommentOrPPDirective ||
413 precededByCommentOrPPDirective()) {
417 if (
Next->is(tok::comment) &&
Next->NewlinesBefore == 0)
420 *IfLeftBrace = IfLBrace;
426 case tok::kw_default: {
427 unsigned StoredPosition = Tokens->getPosition();
428 auto *
Next = Tokens->getNextNonComment();
429 FormatTok = Tokens->setPosition(StoredPosition);
430 if (
Next->isNoneOf(tok::colon, tok::arrow)) {
433 parseStructuralElement();
440 if (Style.Language == FormatStyle::LK_Proto || Style.isVerilog() ||
441 (Style.isJavaScript() && Line->MustBeDeclaration)) {
449 if (!SwitchLabelEncountered &&
450 (Style.IndentCaseLabels ||
451 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
452 (Line->InPPDirective && Line->Level == 1))) {
455 SwitchLabelEncountered =
true;
456 parseStructuralElement();
459 if (Style.isCSharp()) {
461 parseCSharpAttribute();
464 if (handleCppAttributes())
476void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
481 unsigned StoredPosition = Tokens->getPosition();
491 SmallVector<StackEntry, 8> LBraceStack;
492 assert(
Tok->is(tok::l_brace));
495 auto *NextTok = Tokens->getNextNonComment();
497 if (!Line->InMacroBody && !Style.isTableGen()) {
499 while (NextTok->is(tok::hash)) {
500 NextTok = Tokens->getNextToken();
501 if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))
504 NextTok = Tokens->getNextToken();
505 }
while (!NextTok->HasUnescapedNewline && NextTok->isNot(tok::eof));
507 while (NextTok->is(tok::comment))
508 NextTok = Tokens->getNextToken();
512 switch (
Tok->Tok.getKind()) {
514 if (Style.isJavaScript() && PrevTok) {
515 if (PrevTok->isOneOf(tok::colon, tok::less)) {
526 }
else if (PrevTok->is(tok::r_paren)) {
530 }
else if (Style.isJava() && PrevTok && PrevTok->is(tok::arrow)) {
535 LBraceStack.push_back({
Tok, PrevTok});
538 if (LBraceStack.empty())
540 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
541 bool ProbablyBracedList =
false;
542 if (Style.Language == FormatStyle::LK_Proto) {
543 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
544 }
else if (LBrace->isNot(TT_EnumLBrace)) {
547 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
548 NextTok->OriginalColumn == 0;
558 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
560 ProbablyBracedList = ProbablyBracedList ||
561 (Style.isJavaScript() &&
562 NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
565 ProbablyBracedList ||
566 (IsCpp && (PrevTok->Tok.isLiteral() ||
567 NextTok->isOneOf(tok::l_paren, tok::arrow)));
574 ProbablyBracedList ||
575 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
576 tok::r_paren, tok::r_square, tok::ellipsis);
581 ProbablyBracedList ||
582 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
583 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
587 ProbablyBracedList ||
588 (NextTok->is(tok::identifier) &&
589 PrevTok->isNoneOf(tok::semi, tok::r_brace, tok::l_brace));
591 ProbablyBracedList = ProbablyBracedList ||
592 (NextTok->is(tok::semi) &&
593 (!ExpectClassBody || LBraceStack.size() != 1));
596 ProbablyBracedList ||
597 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
599 if (!Style.isCSharp() && NextTok->is(tok::l_square)) {
602 NextTok = Tokens->getNextToken();
603 ProbablyBracedList = NextTok->isNot(tok::l_square);
607 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
608 !FormatTok->Previous && NextTok->is(tok::eof) &&
612 PrevTok->isNoneOf(tok::semi,
BK_Block, tok::colon)) {
613 ProbablyBracedList =
true;
617 Tok->setBlockKind(BlockKind);
618 LBrace->setBlockKind(BlockKind);
620 LBraceStack.pop_back();
622 case tok::identifier:
623 if (
Tok->isNot(TT_StatementMacro))
634 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
635 LBraceStack.back().Tok->setBlockKind(
BK_Block);
643 }
while (
Tok->isNot(tok::eof) && !LBraceStack.empty());
646 for (
const auto &Entry : LBraceStack)
650 FormatTok = Tokens->setPosition(StoredPosition);
654void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
655 if (
auto Prev = FormatTok->getPreviousNonComment();
656 Prev && Prev->is(tok::r_brace)) {
657 Prev->setFinalizedType(
Type);
664 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
667size_t UnwrappedLineParser::computePPHash()
const {
669 for (
const auto &i : PPStack) {
680bool UnwrappedLineParser::mightFitOnOneLine(
682 const auto ColumnLimit = Style.ColumnLimit;
683 if (ColumnLimit == 0)
686 auto &Tokens = ParsedLine.Tokens;
687 assert(!Tokens.empty());
689 const auto *LastToken = Tokens.back().Tok;
692 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
695 for (
const auto &Token : Tokens) {
697 auto &SavedToken = SavedTokens[Index++];
699 SavedToken.Tok->copyFrom(*Token.Tok);
700 SavedToken.Children = std::move(Token.Children);
703 AnnotatedLine
Line(ParsedLine);
704 assert(Line.Last == LastToken);
706 TokenAnnotator Annotator(Style, Keywords);
707 Annotator.annotate(Line);
708 Annotator.calculateFormattingInformation(Line);
710 auto Length = LastToken->TotalLength;
712 assert(OpeningBrace != Tokens.front().Tok);
713 if (
auto Prev = OpeningBrace->Previous;
714 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
715 Length -= ColumnLimit;
717 Length -= OpeningBrace->TokenText.size() + 1;
720 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
721 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
722 Length -= FirstToken->TokenText.size() + 1;
726 for (
auto &Token : Tokens) {
727 const auto &SavedToken = SavedTokens[Index++];
728 Token.Tok->copyFrom(*SavedToken.Tok);
729 Token.Children = std::move(SavedToken.Children);
730 delete SavedToken.Tok;
734 assert(!Line.InMacroBody);
735 assert(!Line.InPPDirective);
736 return Line.Level * Style.IndentWidth + Length <= ColumnLimit;
739FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
740 unsigned AddLevels,
bool MunchSemi,
743 bool UnindentWhitesmithsBraces) {
744 auto HandleVerilogBlockLabel = [
this]() {
746 if (Style.isVerilog() && FormatTok->is(tok::colon)) {
748 if (Keywords.isVerilogIdentifier(*FormatTok))
755 const bool VerilogHierarchy =
756 Style.isVerilog() && Keywords.isVerilogHierarchy(*FormatTok);
757 assert((FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
758 (Style.isVerilog() &&
759 (Keywords.isVerilogBegin(*FormatTok) || VerilogHierarchy))) &&
760 "'{' or macro block token expected");
762 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
763 auto Index = CurrentLines->size();
764 const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);
767 const bool IsWhitesmiths =
768 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
772 if (!VerilogHierarchy && AddLevels > 0 && IsWhitesmiths)
775 size_t PPStartHash = computePPHash();
777 const unsigned InitialLevel = Line->Level;
778 if (VerilogHierarchy) {
779 AddLevels += parseVerilogHierarchyHeader();
781 nextToken(AddLevels);
782 HandleVerilogBlockLabel();
786 if (Line->Level > 300)
789 if (MacroBlock && FormatTok->is(tok::l_paren))
792 size_t NbPreprocessorDirectives =
793 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
795 size_t OpeningLineIndex =
796 CurrentLines->empty()
798 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
803 if (UnindentWhitesmithsBraces)
806 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
812 Line->Level += AddLevels - (IsWhitesmiths ? 1 : 0);
815 const bool SimpleBlock = parseLevel(
Tok, IfKind, &IfLBrace);
820 if (MacroBlock ? FormatTok->isNot(TT_MacroBlockEnd)
821 : FormatTok->isNot(tok::r_brace)) {
822 Line->Level = InitialLevel;
823 FormatTok->setBlockKind(BK_Block);
827 if (FormatTok->is(tok::r_brace)) {
828 FormatTok->setBlockKind(BK_Block);
829 if (Tok->is(TT_NamespaceLBrace))
830 FormatTok->setFinalizedType(TT_NamespaceRBrace);
833 const bool IsFunctionRBrace =
834 FormatTok->is(tok::r_brace) &&
Tok->is(TT_FunctionLBrace);
836 auto RemoveBraces = [=]()
mutable {
839 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
840 assert(FormatTok->is(tok::r_brace));
841 const bool WrappedOpeningBrace = !Tok->Previous;
842 if (WrappedOpeningBrace && FollowedByComment)
844 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
845 if (KeepBraces && !HasRequiredIfBraces)
847 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
848 const FormatToken *Previous = Tokens->getPreviousToken();
850 if (Previous->is(tok::r_brace) && !Previous->Optional)
853 assert(!CurrentLines->empty());
854 auto &LastLine = CurrentLines->back();
855 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
857 if (
Tok->is(TT_ElseLBrace))
859 if (WrappedOpeningBrace) {
864 return mightFitOnOneLine((*CurrentLines)[Index],
Tok);
866 if (RemoveBraces()) {
867 Tok->MatchingParen = FormatTok;
868 FormatTok->MatchingParen =
Tok;
871 size_t PPEndHash = computePPHash();
874 nextToken(-AddLevels);
879 if (Style.RemoveSemicolon && IsFunctionRBrace) {
880 while (FormatTok->is(tok::semi)) {
881 FormatTok->Optional =
true;
886 HandleVerilogBlockLabel();
888 if (MacroBlock && FormatTok->is(tok::l_paren))
891 Line->Level = InitialLevel;
893 if (FormatTok->is(tok::kw_noexcept)) {
898 if (FormatTok->is(tok::arrow)) {
902 parseStructuralElement();
905 if (MunchSemi && FormatTok->is(tok::semi))
908 if (PPStartHash == PPEndHash) {
909 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
912 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
913 CurrentLines->size() - 1;
923 if (
Line.Tokens.size() < 4)
925 auto I =
Line.Tokens.begin();
926 if (I->Tok->TokenText !=
"goog")
929 if (I->Tok->isNot(tok::period))
932 if (I->Tok->TokenText !=
"scope")
935 return I->Tok->is(tok::l_paren);
944 if (
Line.Tokens.size() < 3)
946 auto I =
Line.Tokens.begin();
947 if (I->Tok->isNot(tok::l_paren))
953 return I->Tok->is(tok::l_paren);
959 bool IsJavaRecord =
false) {
961 return Style.BraceWrapping.AfterClass;
964 if (InitialToken.
is(TT_NamespaceMacro))
965 Kind = tok::kw_namespace;
967 const bool WrapRecordAllowed =
969 Style.AllowShortRecordOnASingleLine < FormatStyle::SRS_Empty ||
970 Style.BraceWrapping.SplitEmptyRecord;
973 case tok::kw_namespace:
974 return Style.BraceWrapping.AfterNamespace;
976 return Style.BraceWrapping.AfterClass && WrapRecordAllowed;
978 return Style.BraceWrapping.AfterUnion && WrapRecordAllowed;
980 return Style.BraceWrapping.AfterStruct && WrapRecordAllowed;
982 return Style.BraceWrapping.AfterEnum;
988void UnwrappedLineParser::parseChildBlock() {
989 assert(FormatTok->is(tok::l_brace));
990 FormatTok->setBlockKind(BK_Block);
994 bool SkipIndent = (Style.isJavaScript() &&
995 (isGoogScope(*
Line) || isIIFE(*
Line, Keywords)));
996 ScopedLineState LineState(*
this);
997 ScopedDeclarationState DeclarationState(*
Line, DeclarationScopeStack,
999 Line->Level += SkipIndent ? 0 : 1;
1000 parseLevel(OpeningBrace);
1001 flushComments(isOnNewLine(*FormatTok));
1002 Line->Level -= SkipIndent ? 0 : 1;
1007void UnwrappedLineParser::parsePPDirective() {
1008 assert(FormatTok->is(tok::hash) &&
"'#' expected");
1009 ScopedMacroState MacroState(*
Line, Tokens, FormatTok);
1013 if (!FormatTok->Tok.getIdentifierInfo()) {
1018 switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {
1019 case tok::pp_define:
1026 case tok::pp_ifndef:
1030 case tok::pp_elifdef:
1031 case tok::pp_elifndef:
1038 case tok::pp_pragma:
1042 case tok::pp_warning:
1044 if (!
eof() && Style.isCpp())
1045 FormatTok->setFinalizedType(TT_AfterPPDirective);
1053void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1054 size_t Line = CurrentLines->size();
1055 if (CurrentLines == &PreprocessorDirectives)
1056 Line += Lines.size();
1059 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1060 PPStack.push_back({PP_Unreachable,
Line});
1062 PPStack.push_back({PP_Conditional,
Line});
1066void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1068 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1069 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1070 PPLevelBranchIndex.push_back(0);
1071 PPLevelBranchCount.push_back(0);
1073 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1074 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1075 conditionalCompilationCondition(Unreachable ||
Skip);
1078void UnwrappedLineParser::conditionalCompilationAlternative() {
1079 if (!PPStack.empty())
1081 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1082 if (!PPChainBranchIndex.empty())
1083 ++PPChainBranchIndex.top();
1084 conditionalCompilationCondition(
1085 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1086 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1089void UnwrappedLineParser::conditionalCompilationEnd() {
1090 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1091 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1092 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1093 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1096 if (PPBranchLevel > -1)
1098 if (!PPChainBranchIndex.empty())
1099 PPChainBranchIndex.pop();
1100 if (!PPStack.empty())
1104void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1105 bool IfNDef = FormatTok->is(tok::pp_ifndef);
1107 bool Unreachable =
false;
1108 if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText ==
"0"))
1110 if (IfDef && !IfNDef && FormatTok->TokenText ==
"SWIG")
1112 conditionalCompilationStart(Unreachable);
1116 bool MaybeIncludeGuard = IfNDef;
1117 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1118 for (
auto &
Line : Lines) {
1119 if (
Line.Tokens.front().Tok->isNot(tok::comment)) {
1120 MaybeIncludeGuard =
false;
1121 IncludeGuard = IG_Rejected;
1129 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1130 IncludeGuard = IG_IfNdefed;
1131 IncludeGuardToken = IfCondition;
1135void UnwrappedLineParser::parsePPElse() {
1137 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1138 IncludeGuard = IG_Rejected;
1140 assert(PPBranchLevel >= -1);
1141 if (PPBranchLevel == -1)
1142 conditionalCompilationStart(
true);
1143 conditionalCompilationAlternative();
1149void UnwrappedLineParser::parsePPEndIf() {
1150 conditionalCompilationEnd();
1154void UnwrappedLineParser::parsePPDefine() {
1157 if (!FormatTok->Tok.getIdentifierInfo()) {
1158 IncludeGuard = IG_Rejected;
1159 IncludeGuardToken =
nullptr;
1164 bool MaybeIncludeGuard =
false;
1165 if (IncludeGuard == IG_IfNdefed &&
1166 IncludeGuardToken->TokenText == FormatTok->TokenText) {
1167 IncludeGuard = IG_Defined;
1168 IncludeGuardToken =
nullptr;
1169 for (
auto &
Line : Lines) {
1170 if (
Line.Tokens.front().Tok->isNoneOf(tok::comment, tok::hash)) {
1171 IncludeGuard = IG_Rejected;
1175 MaybeIncludeGuard = IncludeGuard == IG_Defined;
1183 FormatTok->Tok.setKind(tok::identifier);
1184 FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);
1188 if (MaybeIncludeGuard && !
eof())
1189 IncludeGuard = IG_Rejected;
1191 if (FormatTok->is(tok::l_paren) && !FormatTok->hasWhitespaceBefore())
1193 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
1194 Line->Level += PPBranchLevel + 1;
1198 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1199 assert((
int)
Line->PPLevel >= 0);
1204 Line->InMacroBody =
true;
1206 if (!Style.SkipMacroDefinitionBody) {
1216 for (
auto *Comment : CommentsBeforeNextToken)
1217 Comment->Finalized =
true;
1220 FormatTok->Finalized =
true;
1221 FormatTok = Tokens->getNextToken();
1227void UnwrappedLineParser::parsePPPragma() {
1228 Line->InPragmaDirective =
true;
1232void UnwrappedLineParser::parsePPUnknown() {
1235 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
1236 Line->Level += PPBranchLevel + 1;
1246 return Tok.isNoneOf(tok::semi, tok::l_brace,
1249 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1250 tok::less, tok::greater, tok::slash, tok::percent,
1251 tok::lessless, tok::greatergreater, tok::equal,
1252 tok::plusequal, tok::minusequal, tok::starequal,
1253 tok::slashequal, tok::percentequal, tok::ampequal,
1254 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1267 return FormatTok->
is(tok::identifier) &&
1282 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1293 tok::kw_if, tok::kw_else,
1295 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1297 tok::kw_switch, tok::kw_case,
1299 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1301 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1309 return Tok.isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1310 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1327 if (FuncName->
isNot(tok::identifier))
1335 Tok->isNoneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1339 if (
Next->isNot(tok::star) && !
Next->Tok.getIdentifierInfo())
1343 if (!
Tok ||
Tok->isNot(tok::r_paren))
1347 if (!
Tok ||
Tok->isNot(tok::identifier))
1350 return Tok->Previous &&
Tok->Previous->isOneOf(tok::l_paren, tok::comma);
1353bool UnwrappedLineParser::parseModuleDecl() {
1355 assert(FormatTok->is(Keywords.kw_module));
1357 if (Style.Language == FormatStyle::LK_C ||
1358 Style.Standard < FormatStyle::LS_Cpp20) {
1363 if (FormatTok->isNot(tok::identifier))
1366 for (nextToken(); FormatTok->isNoneOf(tok::semi, tok::eof); nextToken())
1367 if (FormatTok->is(tok::colon))
1368 FormatTok->setFinalizedType(TT_ModulePartitionColon);
1371 Line->IsModuleOrImportDecl =
true;
1376bool UnwrappedLineParser::parseImportDecl() {
1378 assert(FormatTok->is(Keywords.kw_import) &&
"'import' expected");
1380 if (Style.Language == FormatStyle::LK_C ||
1381 Style.Standard < FormatStyle::LS_Cpp20) {
1386 if (FormatTok->is(tok::colon)) {
1387 FormatTok->setFinalizedType(TT_ModulePartitionColon);
1390 if (FormatTok->isNoneOf(tok::identifier, tok::less, tok::string_literal))
1393 for (; FormatTok->isNoneOf(tok::semi, tok::eof); nextToken()) {
1395 if (FormatTok->is(tok::less)) {
1396 for (nextToken(); FormatTok->isNoneOf(tok::greater, tok::semi, tok::eof);
1400 FormatTok->setFinalizedType(TT_ImplicitStringLiteral);
1406 Line->IsModuleOrImportDecl =
true;
1418void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1424 CommentsBeforeNextToken.empty()
1425 ?
Next->NewlinesBefore == 0
1426 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1431 bool PreviousStartsTemplateExpr =
1433 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1436 bool HasAt = llvm::any_of(
Line->Tokens, [](UnwrappedLineNode &LineNode) {
1437 return LineNode.Tok->is(tok::at);
1442 if (
Next->is(tok::exclaim) && PreviousMustBeValue)
1443 return addUnwrappedLine();
1445 bool NextEndsTemplateExpr =
1446 Next->is(TT_TemplateString) &&
Next->TokenText.starts_with(
"}");
1447 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1448 (PreviousMustBeValue ||
1449 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1450 tok::minusminus))) {
1451 return addUnwrappedLine();
1453 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1455 return addUnwrappedLine();
1459void UnwrappedLineParser::parseStructuralElement(
1460 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1461 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1462 if (Style.isTableGen() && FormatTok->is(tok::pp_include)) {
1464 if (FormatTok->is(tok::string_literal))
1471 while (FormatTok->is(tok::l_square) && handleCppAttributes()) {
1473 }
else if (Style.isVerilog()) {
1475 while (FormatTok->is(tok::l_paren) &&
1476 Tokens->peekNextToken()->is(tok::star)) {
1479 skipVerilogQualifiers();
1481 if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
1482 Keywords.kw_unique0)) {
1486 if (Keywords.isVerilogStructuredProcedure(*FormatTok)) {
1487 parseForOrWhileLoop(
false);
1490 if (FormatTok->isOneOf(Keywords.kw_foreach, Keywords.kw_repeat)) {
1491 parseForOrWhileLoop();
1494 if (FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,
1495 Keywords.kw_assume, Keywords.kw_cover)) {
1496 parseIfThenElse(IfKind,
false,
true);
1502 if (FormatTok->isAccessSpecifierKeyword()) {
1503 if (Style.isJava() || Style.isJavaScript() || Style.isCSharp())
1506 parseAccessSpecifier();
1509 switch (FormatTok->Tok.getKind()) {
1514 bool DoNotFormat =
false;
1519 FormatTok->isOneOf(tok::kw_volatile, tok::kw_inline, tok::kw_goto)) {
1524 if (FormatTok->is(tok::l_brace)) {
1525 FormatTok->setFinalizedType(TT_InlineASMBrace);
1526 OpenType = tok::l_brace;
1527 CloseType = tok::r_brace;
1529 }
else if (FormatTok->is(tok::l_paren)) {
1530 OpenType = tok::l_paren;
1531 CloseType = tok::r_paren;
1532 FormatTok->setFinalizedType(TT_InlineASMParen);
1540 while (FormatTok && !
eof()) {
1541 if (FormatTok->is(OpenType)) {
1543 }
else if (FormatTok->is(CloseType)) {
1545 if (NestLevel < 1) {
1546 FormatTok->setFinalizedType(OpenTok->getType());
1552 FormatTok->Finalized =
true;
1558 case tok::kw_namespace:
1562 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1573 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1577 parseForOrWhileLoop();
1580 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1588 case tok::kw_switch:
1589 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1595 case tok::kw_default: {
1597 if (Style.isVerilog())
1599 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1605 if (FormatTok->is(tok::colon)) {
1606 FormatTok->setFinalizedType(TT_CaseLabelColon);
1610 if (FormatTok->is(tok::arrow)) {
1611 FormatTok->setFinalizedType(TT_CaseLabelArrow);
1612 Default->setFinalizedType(TT_SwitchExpressionLabel);
1621 if (Style.Language == FormatStyle::LK_Proto) {
1625 if (Style.isVerilog()) {
1630 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1639 if (FormatTok->is(tok::kw_case))
1644 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1650 case tok::kw_extern:
1651 if (Style.isVerilog()) {
1654 parseVerilogExtern();
1658 if (FormatTok->is(tok::string_literal)) {
1660 if (FormatTok->is(tok::l_brace)) {
1661 if (Style.BraceWrapping.AfterExternBlock)
1665 unsigned AddLevels =
1666 (Style.IndentExternBlock == FormatStyle::IEBS_Indent) ||
1667 (Style.BraceWrapping.AfterExternBlock &&
1668 Style.IndentExternBlock ==
1669 FormatStyle::IEBS_AfterExternBlock)
1672 parseBlock(
true, AddLevels);
1678 case tok::kw_export:
1681 if (FormatTok->is(tok::kw_namespace)) {
1685 if (FormatTok->is(tok::l_brace)) {
1686 parseCppExportBlock();
1689 if (FormatTok->is(Keywords.kw_module) && parseModuleDecl())
1691 if (FormatTok->is(Keywords.kw_import) && parseImportDecl())
1695 if (Style.isJavaScript()) {
1696 parseJavaScriptEs6ImportExport();
1699 if (Style.isVerilog()) {
1700 parseVerilogExtern();
1704 case tok::kw_inline:
1706 if (FormatTok->is(tok::kw_namespace)) {
1711 case tok::identifier:
1712 if (FormatTok->is(TT_ForEachMacro)) {
1713 parseForOrWhileLoop();
1716 if (FormatTok->is(TT_MacroBlockBegin)) {
1717 parseBlock(
false, 1u,
1721 if (FormatTok->is(Keywords.kw_import)) {
1722 if (IsCpp && parseImportDecl())
1724 if (Style.isJavaScript()) {
1725 parseJavaScriptEs6ImportExport();
1728 if (Style.Language == FormatStyle::LK_Proto) {
1730 if (FormatTok->is(tok::kw_public))
1732 if (FormatTok->isNot(tok::string_literal))
1735 if (FormatTok->is(tok::semi))
1740 if (Style.isVerilog()) {
1741 parseVerilogExtern();
1746 if (FormatTok->is(Keywords.kw_module) && parseModuleDecl())
1748 if (FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
1749 Keywords.kw_slots, Keywords.kw_qslots)) {
1751 if (FormatTok->is(tok::colon)) {
1757 if (FormatTok->is(TT_StatementMacro)) {
1758 parseStatementMacro();
1761 if (FormatTok->is(TT_NamespaceMacro)) {
1770 if (!Style.isJavaScript() && !Style.isVerilog() && !Style.isTableGen() &&
1771 Tokens->peekNextToken()->is(tok::colon) && !
Line->MustBeDeclaration) {
1773 if (!
Line->InMacroBody || CurrentLines->size() > 1)
1774 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1775 FormatTok->setFinalizedType(TT_GotoLabelColon);
1776 parseLabel(Style.IndentGotoLabels);
1781 if (Style.isJava() && FormatTok->is(Keywords.kw_record)) {
1782 parseRecord(
false,
true);
1792 bool SeenEqual =
false;
1793 for (
const bool InRequiresExpression =
1794 OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
1795 TT_CompoundRequirementLBrace);
1798 switch (FormatTok->Tok.getKind()) {
1801 if (FormatTok->is(tok::l_brace)) {
1806 if (Style.isJava() && FormatTok->is(Keywords.kw_interface)) {
1810 switch (
bool IsAutoRelease =
false; FormatTok->Tok.getObjCKeywordID()) {
1811 case tok::objc_public:
1812 case tok::objc_protected:
1813 case tok::objc_package:
1814 case tok::objc_private:
1815 return parseAccessSpecifier();
1816 case tok::objc_interface:
1817 case tok::objc_implementation:
1818 return parseObjCInterfaceOrImplementation();
1819 case tok::objc_protocol:
1820 if (parseObjCProtocol())
1825 case tok::objc_optional:
1826 case tok::objc_required:
1830 case tok::objc_autoreleasepool:
1831 IsAutoRelease =
true;
1833 case tok::objc_synchronized:
1835 if (!IsAutoRelease && FormatTok->is(tok::l_paren)) {
1839 if (FormatTok->is(tok::l_brace)) {
1840 if (Style.BraceWrapping.AfterControlStatement ==
1841 FormatStyle::BWACS_Always) {
1857 case tok::kw_requires: {
1859 bool ParsedClause = parseRequires(SeenEqual);
1880 if (!IsCpp && !Style.isVerilog()) {
1885 case tok::kw_typedef:
1887 if (FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
1888 Keywords.kw_CF_ENUM, Keywords.kw_CF_OPTIONS,
1889 Keywords.kw_CF_CLOSED_ENUM,
1890 Keywords.kw_NS_CLOSED_ENUM)) {
1895 if (Style.isVerilog()) {
1900 if (Style.isTableGen()) {
1907 case tok::kw_struct:
1909 if (parseStructLike())
1912 case tok::kw_decltype:
1914 if (FormatTok->is(tok::l_paren)) {
1916 if (FormatTok->Previous &&
1917 FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,
1919 Line->SeenDecltypeAuto =
true;
1926 if (Style.isJava() && FormatTok && FormatTok->is(tok::kw_class))
1928 if (Style.isJavaScript() && FormatTok &&
1929 FormatTok->Tok.getIdentifierInfo()) {
1942 case tok::string_literal:
1943 if (Style.isVerilog() && FormatTok->is(TT_VerilogProtected)) {
1944 FormatTok->Finalized =
true;
1951 case tok::l_paren: {
1958 Tokens->peekNextToken(
true),
1965 case tok::kw_operator:
1967 if (FormatTok->isBinaryOperator())
1971 const auto *Prev = FormatTok->getPreviousNonComment();
1973 if (Prev && Prev->is(tok::identifier))
1976 if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName(LangOpts)) {
1979 while (FormatTok->is(tok::star))
1983 if (FormatTok->is(tok::l_paren))
1986 if (FormatTok->is(tok::l_brace))
1991 if (InRequiresExpression)
1992 FormatTok->setFinalizedType(TT_BracedListLBrace);
1993 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1994 IsDecltypeAutoFunction =
Line->SeenDecltypeAuto;
1999 if (Style.isJava() &&
2000 Line->Tokens.front().Tok->is(Keywords.kw_synchronized)) {
2003 if (Style.BraceWrapping.AfterControlStatement ==
2004 FormatStyle::BWACS_Always) {
2007 }
else if (Style.BraceWrapping.AfterFunction) {
2011 FormatTok->setFinalizedType(TT_FunctionLBrace);
2013 IsDecltypeAutoFunction =
false;
2021 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
2027 if (Style.BraceWrapping.AfterFunction)
2031 case tok::identifier: {
2032 if (Style.isCSharp() && FormatTok->is(Keywords.kw_where) &&
2033 Line->MustBeDeclaration) {
2035 parseCSharpGenericTypeConstraint();
2038 if (FormatTok->is(TT_MacroBlockEnd)) {
2047 size_t TokenCount =
Line->Tokens.size();
2048 if (Style.isJavaScript() && FormatTok->is(Keywords.kw_function) &&
2051 Line->Tokens.front().Tok->isNot(Keywords.kw_async)))) {
2052 tryToParseJSFunction();
2055 if ((Style.isJavaScript() || Style.isJava()) &&
2056 FormatTok->is(Keywords.kw_interface)) {
2057 if (Style.isJavaScript()) {
2062 unsigned StoredPosition = Tokens->getPosition();
2064 FormatTok = Tokens->setPosition(StoredPosition);
2075 if (Style.isVerilog()) {
2076 if (FormatTok->is(Keywords.kw_table)) {
2077 parseVerilogTable();
2080 if (Keywords.isVerilogBegin(*FormatTok) ||
2081 Keywords.isVerilogHierarchy(*FormatTok)) {
2088 if (!IsCpp && FormatTok->is(Keywords.kw_interface)) {
2089 if (parseStructLike())
2094 if (IsCpp && FormatTok->is(TT_StatementMacro)) {
2095 parseStatementMacro();
2100 StringRef
Text = FormatTok->TokenText;
2107 if (Style.isJavaScript())
2110 auto OneTokenSoFar = [&]() {
2111 auto I =
Line->Tokens.begin(), E =
Line->Tokens.end();
2112 while (I != E && I->Tok->is(tok::comment))
2114 if (Style.isVerilog())
2115 while (I != E && I->Tok->is(tok::hash))
2117 return I != E && (++I == E);
2119 if (OneTokenSoFar()) {
2122 bool FunctionLike = FormatTok->is(tok::l_paren);
2126 bool FollowedByNewline =
2127 CommentsBeforeNextToken.empty()
2128 ? FormatTok->NewlinesBefore > 0
2129 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2131 if (FollowedByNewline &&
2132 (
Text.size() >= 5 ||
2133 (FunctionLike && FormatTok->isNot(tok::l_paren))) &&
2135 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2136 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2144 if ((Style.isJavaScript() || Style.isCSharp()) &&
2145 FormatTok->is(TT_FatArrow)) {
2146 tryToParseChildBlock();
2152 if (FormatTok->is(tok::l_brace)) {
2156 if (!Style.isJavaScript())
2157 FormatTok->setBlockKind(BK_BracedInit);
2160 if (Style.isTableGen() &&
2161 Line->Tokens.begin()->Tok->is(Keywords.kw_defset)) {
2162 FormatTok->setFinalizedType(TT_FunctionLBrace);
2163 parseBlock(
false, 1u,
2170 }
else if (Style.Language == FormatStyle::LK_Proto &&
2171 FormatTok->is(tok::less)) {
2173 parseBracedList(
true);
2180 if (Style.isCSharp() &&
2181 (Tokens->peekNextToken()->isAccessSpecifierKeyword() ||
2188 case tok::kw_switch:
2196 if (Style.Language == FormatStyle::LK_Proto) {
2201 if (Style.isVerilog()) {
2206 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
2213 case tok::kw_default:
2215 if (Style.isVerilog()) {
2216 if (FormatTok->is(tok::colon)) {
2220 if (FormatTok->is(Keywords.kw_clocking)) {
2226 parseVerilogCaseLabel();
2232 if (Style.isVerilog()) {
2233 parseVerilogCaseLabel();
2239 if (FormatTok->is(tok::l_brace))
2240 FormatTok->Previous->setFinalizedType(TT_TemplateCloser);
2249bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2250 assert(FormatTok->is(tok::l_brace));
2251 if (!Style.isCSharp())
2254 if (!FormatTok->Previous || FormatTok->Previous->isNot(tok::identifier))
2262 unsigned int StoredPosition = Tokens->getPosition();
2268 bool HasSpecialAccessor =
false;
2269 bool IsTrivialPropertyAccessor =
true;
2272 if (
const bool IsAccessorKeyword =
2273 Tok->
isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set);
2274 IsAccessorKeyword ||
Tok->isAccessSpecifierKeyword() ||
2275 Tok->
isOneOf(tok::l_square, tok::semi, Keywords.kw_internal)) {
2276 if (IsAccessorKeyword)
2277 HasSpecialAccessor =
true;
2278 else if (
Tok->
is(tok::l_square))
2280 Tok = Tokens->getNextToken();
2284 IsTrivialPropertyAccessor =
false;
2289 Tokens->setPosition(StoredPosition);
2295 Tokens->setPosition(StoredPosition);
2296 if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction)
2300 switch (FormatTok->Tok.getKind()) {
2303 if (FormatTok->is(tok::equal)) {
2304 while (!
eof() && FormatTok->isNot(tok::semi))
2317 if (FormatTok->is(TT_FatArrow)) {
2321 }
while (!
eof() && FormatTok->isNot(tok::semi));
2330 if (FormatTok->isOneOf(Keywords.kw_get, Keywords.kw_init,
2332 !IsTrivialPropertyAccessor) {
2344bool UnwrappedLineParser::tryToParseLambda() {
2345 assert(FormatTok->is(tok::l_square));
2351 if (!tryToParseLambdaIntroducer())
2355 bool InTemplateParameterList =
false;
2357 while (FormatTok->isNot(tok::l_brace)) {
2358 if (FormatTok->isTypeName(LangOpts) || FormatTok->isAttribute()) {
2362 switch (FormatTok->Tok.getKind()) {
2366 parseParens(TT_PointerOrReference);
2372 assert(FormatTok->Previous);
2373 if (FormatTok->Previous->is(tok::r_square))
2374 InTemplateParameterList =
true;
2379 case tok::kw_struct:
2381 case tok::kw_template:
2382 case tok::kw_typename:
2386 case tok::kw_constexpr:
2387 case tok::kw_consteval:
2390 case tok::identifier:
2391 case tok::numeric_constant:
2392 case tok::coloncolon:
2393 case tok::kw_mutable:
2394 case tok::kw_noexcept:
2395 case tok::kw_static:
2420 case tok::equalequal:
2421 case tok::exclaimequal:
2422 case tok::greaterequal:
2423 case tok::lessequal:
2429 if (Arrow || InTemplateParameterList) {
2438 case tok::kw_requires:
2439 parseRequiresClause();
2442 if (!InTemplateParameterList)
2451 FormatTok->setFinalizedType(TT_LambdaLBrace);
2452 LSquare.setFinalizedType(TT_LambdaLSquare);
2455 Arrow->setFinalizedType(TT_LambdaArrow);
2457 NestedLambdas.push_back(
Line->SeenDecltypeAuto);
2459 assert(!NestedLambdas.empty());
2460 NestedLambdas.pop_back();
2465bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2470 const auto *PrevPrev =
Previous->getPreviousNonComment();
2471 if (
Previous->is(tok::star) && PrevPrev && PrevPrev->isTypeName(LangOpts))
2479 if (!PrevPrev || PrevPrev->isNoneOf(tok::greater, tok::r_paren))
2483 Previous->isNoneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
2484 tok::kw_co_return)) {
2488 if (LeftSquare->isCppStructuredBinding(IsCpp))
2490 if (FormatTok->is(tok::l_square) ||
tok::isLiteral(FormatTok->Tok.getKind()))
2492 if (FormatTok->is(tok::r_square)) {
2494 if (
Next->is(tok::greater))
2501void UnwrappedLineParser::tryToParseJSFunction() {
2502 assert(FormatTok->is(Keywords.kw_function));
2503 if (FormatTok->is(Keywords.kw_async))
2509 if (FormatTok->is(tok::star)) {
2510 FormatTok->setFinalizedType(TT_OverloadedOperator);
2515 if (FormatTok->is(tok::identifier))
2518 if (FormatTok->isNot(tok::l_paren))
2524 if (FormatTok->is(tok::colon)) {
2530 if (FormatTok->is(tok::l_brace))
2531 tryToParseBracedList();
2533 while (FormatTok->isNoneOf(tok::l_brace, tok::semi) && !
eof())
2537 if (FormatTok->is(tok::semi))
2543bool UnwrappedLineParser::tryToParseBracedList() {
2544 if (FormatTok->is(BK_Unknown))
2545 calculateBraceTypes();
2546 assert(FormatTok->isNot(BK_Unknown));
2547 if (FormatTok->is(BK_Block))
2554bool UnwrappedLineParser::tryToParseChildBlock() {
2555 assert(Style.isJavaScript() || Style.isCSharp());
2556 assert(FormatTok->is(TT_FatArrow));
2561 if (FormatTok->isNot(tok::l_brace))
2567bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2568 assert(!IsAngleBracket || !IsEnum);
2569 bool HasError =
false;
2574 if (Style.isCSharp() && FormatTok->is(TT_FatArrow) &&
2575 tryToParseChildBlock()) {
2578 if (Style.isJavaScript()) {
2579 if (FormatTok->is(Keywords.kw_function)) {
2580 tryToParseJSFunction();
2583 if (FormatTok->is(tok::l_brace)) {
2585 if (tryToParseBracedList())
2590 if (FormatTok->is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2592 FormatTok->setBlockKind(BK_Block);
2593 if (!Style.AllowShortEnumsOnASingleLine)
2599 switch (FormatTok->Tok.getKind()) {
2601 if (Style.isCSharp())
2610 if (Style.isJavaScript()) {
2611 if (FormatTok->is(tok::l_brace))
2619 FormatTok->setBlockKind(BK_BracedInit);
2620 if (!IsAngleBracket) {
2621 auto *Prev = FormatTok->Previous;
2622 if (Prev && Prev->is(tok::greater))
2623 Prev->setFinalizedType(TT_TemplateCloser);
2631 parseBracedList(
true);
2638 if (Style.isJavaScript()) {
2649 if (IsEnum && !Style.AllowShortEnumsOnASingleLine)
2652 case tok::kw_requires:
2653 parseRequiresExpression();
2669bool UnwrappedLineParser::parseParens(TokenType StarAndAmpTokenType,
2671 assert(FormatTok->is(tok::l_paren) &&
"'(' expected.");
2672 auto *LParen = FormatTok;
2673 auto *Prev = FormatTok->Previous;
2674 bool SeenComma =
false;
2675 bool SeenEqual =
false;
2676 bool MightBeFoldExpr =
false;
2678 const bool MightBeStmtExpr = FormatTok->is(tok::l_brace);
2679 if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro))
2682 switch (FormatTok->Tok.getKind()) {
2684 if (parseParens(StarAndAmpTokenType, InMacroCall))
2686 if (Style.isJava() && FormatTok->is(tok::l_brace))
2689 case tok::r_paren: {
2690 auto *RParen = FormatTok;
2693 auto OptionalParens = [&] {
2694 if (Style.RemoveParentheses == FormatStyle::RPS_Leave ||
2695 MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall ||
2696 Line->InMacroBody || RParen->getPreviousNonComment() == LParen) {
2699 const bool DoubleParens =
2700 Prev->is(tok::l_paren) && FormatTok->is(tok::r_paren);
2702 const auto *PrevPrev = Prev->getPreviousNonComment();
2703 const bool Excluded =
2705 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2707 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2708 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2712 const bool CommaSeparated =
2713 Prev->isOneOf(tok::l_paren, tok::comma) &&
2714 FormatTok->isOneOf(tok::comma, tok::r_paren);
2715 if (CommaSeparated &&
2717 !Prev->endsSequence(tok::comma, tok::ellipsis) &&
2719 !(FormatTok->is(tok::comma) &&
2720 Tokens->peekNextToken()->is(tok::ellipsis))) {
2723 const bool ReturnParens =
2724 Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&
2725 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2726 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2727 Prev->isOneOf(tok::kw_return, tok::kw_co_return) &&
2728 FormatTok->is(tok::semi);
2734 if (OptionalParens()) {
2735 LParen->Optional =
true;
2736 RParen->Optional =
true;
2737 }
else if (Prev->is(TT_TypenameMacro)) {
2738 LParen->setFinalizedType(TT_TypeDeclarationParen);
2739 RParen->setFinalizedType(TT_TypeDeclarationParen);
2740 }
else if (Prev->is(tok::greater) && RParen->Previous == LParen) {
2741 Prev->setFinalizedType(TT_TemplateCloser);
2742 }
else if (FormatTok->is(tok::l_brace) && Prev->is(tok::amp) &&
2744 FormatTok->setBlockKind(BK_BracedInit);
2756 if (!tryToParseBracedList())
2761 if (FormatTok->is(tok::l_brace)) {
2771 MightBeFoldExpr =
true;
2776 if (Style.isCSharp() && FormatTok->is(TT_FatArrow))
2777 tryToParseChildBlock();
2782 if (Style.isJavaScript())
2787 case tok::identifier:
2788 if (Style.isJavaScript() && (FormatTok->is(Keywords.kw_function)))
2789 tryToParseJSFunction();
2793 case tok::kw_switch:
2799 case tok::kw_requires:
2800 parseRequiresExpression();
2805 if (StarAndAmpTokenType != TT_Unknown)
2806 FormatTok->setFinalizedType(StarAndAmpTokenType);
2818 assert(FormatTok->is(tok::l_square) &&
"'[' expected.");
2819 if (tryToParseLambda())
2823 switch (FormatTok->Tok.getKind()) {
2836 case tok::l_brace: {
2837 if (!tryToParseBracedList())
2844 if (FormatTok->is(tok::l_brace)) {
2856void UnwrappedLineParser::keepAncestorBraces() {
2857 if (!Style.RemoveBracesLLVM)
2860 const int MaxNestingLevels = 2;
2861 const int Size = NestedTooDeep.size();
2862 if (Size >= MaxNestingLevels)
2863 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2864 NestedTooDeep.push_back(
false);
2868 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2875void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2878 if (Style.InsertBraces && !
Line->InPPDirective && !
Line->Tokens.empty() &&
2879 PreprocessorDirectives.empty() && FormatTok->isNot(tok::semi)) {
2880 Tok = Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Never
2881 ? getLastNonComment(*
Line)
2884 if (
Tok->BraceCount < 0) {
2885 assert(
Tok->BraceCount == -1);
2888 Tok->BraceCount = -1;
2894 ++
Line->UnbracedBodyLevel;
2895 parseStructuralElement();
2896 --
Line->UnbracedBodyLevel;
2899 assert(!
Line->InPPDirective);
2901 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2903 Tok = L.Tokens.back().Tok;
2911 if (CheckEOF &&
eof())
2921 assert(LeftBrace->
is(tok::l_brace));
2929 assert(RightBrace->
is(tok::r_brace));
2937void UnwrappedLineParser::handleAttributes() {
2939 if (FormatTok->isAttribute())
2941 else if (FormatTok->is(tok::l_square))
2942 handleCppAttributes();
2945bool UnwrappedLineParser::handleCppAttributes() {
2947 assert(FormatTok->is(tok::l_square));
2948 if (!tryToParseSimpleAttribute())
2955bool UnwrappedLineParser::isBlockBegin(
const FormatToken &
Tok)
const {
2958 return Style.isVerilog() ? Keywords.isVerilogBegin(
Tok)
2959 :
Tok.
is(tok::l_brace);
2962FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2964 bool IsVerilogAssert) {
2965 assert((FormatTok->is(tok::kw_if) ||
2966 (Style.isVerilog() &&
2967 FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,
2968 Keywords.kw_assume, Keywords.kw_cover))) &&
2972 if (IsVerilogAssert) {
2974 if (FormatTok->is(Keywords.kw_verilogHash)) {
2976 if (FormatTok->is(tok::numeric_constant))
2978 }
else if (FormatTok->isOneOf(Keywords.kw_final, Keywords.kw_property,
2979 Keywords.kw_sequence)) {
2985 if (Style.isTableGen()) {
2986 while (!
eof() && FormatTok->isNot(Keywords.kw_then)) {
2993 if (FormatTok->is(tok::exclaim))
2996 bool KeepIfBraces =
true;
2997 if (FormatTok->is(tok::kw_consteval)) {
3000 KeepIfBraces = !Style.RemoveBracesLLVM || KeepBraces;
3001 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
3003 if (FormatTok->is(tok::l_paren)) {
3004 FormatTok->setFinalizedType(TT_ConditionLParen);
3010 if (IsVerilogAssert && FormatTok->is(tok::semi)) {
3016 bool NeedsUnwrappedLine =
false;
3017 keepAncestorBraces();
3020 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
3022 if (isBlockBegin(*FormatTok)) {
3023 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3024 IfLeftBrace = FormatTok;
3025 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3026 parseBlock(
false, 1u,
3027 true, KeepIfBraces, &IfBlockKind);
3028 setPreviousRBraceType(TT_ControlStatementRBrace);
3029 if (Style.BraceWrapping.BeforeElse)
3032 NeedsUnwrappedLine =
true;
3033 }
else if (IsVerilogAssert && FormatTok->is(tok::kw_else)) {
3036 parseUnbracedBody();
3039 if (Style.RemoveBracesLLVM) {
3040 assert(!NestedTooDeep.empty());
3041 KeepIfBraces = KeepIfBraces ||
3042 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
3043 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
3044 IfBlockKind == IfStmtKind::IfElseIf;
3047 bool KeepElseBraces = KeepIfBraces;
3049 IfStmtKind
Kind = IfStmtKind::IfOnly;
3051 if (FormatTok->is(tok::kw_else)) {
3052 if (Style.RemoveBracesLLVM) {
3053 NestedTooDeep.back() =
false;
3054 Kind = IfStmtKind::IfElse;
3058 if (isBlockBegin(*FormatTok)) {
3059 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
3060 FormatTok->setFinalizedType(TT_ElseLBrace);
3061 ElseLeftBrace = FormatTok;
3062 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3063 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
3065 parseBlock(
false, 1u,
3066 true, KeepElseBraces, &ElseBlockKind);
3067 setPreviousRBraceType(TT_ElseRBrace);
3068 if (FormatTok->is(tok::kw_else)) {
3069 KeepElseBraces = KeepElseBraces ||
3070 ElseBlockKind == IfStmtKind::IfOnly ||
3071 ElseBlockKind == IfStmtKind::IfElseIf;
3072 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
3073 KeepElseBraces =
true;
3074 assert(ElseLeftBrace->MatchingParen);
3078 }
else if (!IsVerilogAssert && FormatTok->is(tok::kw_if)) {
3081 const bool IsPrecededByComment =
Previous->is(tok::comment);
3082 if (IsPrecededByComment) {
3086 bool TooDeep =
true;
3087 if (Style.RemoveBracesLLVM) {
3088 Kind = IfStmtKind::IfElseIf;
3089 TooDeep = NestedTooDeep.pop_back_val();
3091 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
3092 if (Style.RemoveBracesLLVM)
3093 NestedTooDeep.push_back(TooDeep);
3094 if (IsPrecededByComment)
3097 parseUnbracedBody(
true);
3100 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
3101 if (NeedsUnwrappedLine)
3105 if (!Style.RemoveBracesLLVM)
3108 assert(!NestedTooDeep.empty());
3109 KeepElseBraces = KeepElseBraces ||
3110 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
3111 NestedTooDeep.back();
3113 NestedTooDeep.pop_back();
3115 if (!KeepIfBraces && !KeepElseBraces) {
3118 }
else if (IfLeftBrace) {
3119 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
3121 assert(IfRightBrace->MatchingParen == IfLeftBrace);
3122 assert(!IfLeftBrace->Optional);
3123 assert(!IfRightBrace->Optional);
3124 IfLeftBrace->MatchingParen =
nullptr;
3125 IfRightBrace->MatchingParen =
nullptr;
3135void UnwrappedLineParser::parseTryCatch() {
3136 assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
3138 bool NeedsUnwrappedLine =
false;
3139 bool HasCtorInitializer =
false;
3140 if (FormatTok->is(tok::colon)) {
3141 auto *Colon = FormatTok;
3144 if (FormatTok->is(tok::identifier)) {
3145 HasCtorInitializer =
true;
3146 Colon->setFinalizedType(TT_CtorInitializerColon);
3151 while (FormatTok->is(tok::comma))
3154 while (FormatTok->is(tok::identifier)) {
3156 if (FormatTok->is(tok::l_paren)) {
3158 }
else if (FormatTok->is(tok::l_brace)) {
3165 while (FormatTok->is(tok::comma))
3170 if (Style.isJava() && FormatTok->is(tok::l_paren))
3173 keepAncestorBraces();
3175 if (FormatTok->is(tok::l_brace)) {
3176 if (HasCtorInitializer)
3177 FormatTok->setFinalizedType(TT_FunctionLBrace);
3178 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3180 if (Style.BraceWrapping.BeforeCatch)
3183 NeedsUnwrappedLine =
true;
3184 }
else if (FormatTok->isNot(tok::kw_catch)) {
3190 parseStructuralElement();
3193 for (
bool SeenCatch =
false;;) {
3194 if (FormatTok->is(tok::at))
3196 if (FormatTok->isNoneOf(tok::kw_catch, Keywords.kw___except,
3197 tok::kw___finally, tok::objc_catch,
3198 tok::objc_finally) &&
3199 !((Style.isJava() || Style.isJavaScript()) &&
3200 FormatTok->is(Keywords.kw_finally))) {
3203 if (FormatTok->is(tok::kw_catch))
3206 while (FormatTok->isNot(tok::l_brace)) {
3207 if (FormatTok->is(tok::l_paren)) {
3211 if (FormatTok->isOneOf(tok::semi, tok::r_brace) ||
eof()) {
3212 if (Style.RemoveBracesLLVM)
3213 NestedTooDeep.pop_back();
3219 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3222 NeedsUnwrappedLine =
false;
3223 Line->MustBeDeclaration =
false;
3224 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3226 if (Style.BraceWrapping.BeforeCatch)
3229 NeedsUnwrappedLine =
true;
3232 if (Style.RemoveBracesLLVM)
3233 NestedTooDeep.pop_back();
3235 if (NeedsUnwrappedLine)
3239void UnwrappedLineParser::parseNamespaceOrExportBlock(
unsigned AddLevels) {
3240 bool ManageWhitesmithsBraces =
3241 AddLevels == 0u && Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
3245 if (ManageWhitesmithsBraces)
3250 parseBlock(
true, AddLevels,
true,
3251 true,
nullptr, ManageWhitesmithsBraces);
3253 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3255 if (ManageWhitesmithsBraces)
3259void UnwrappedLineParser::parseNamespace() {
3260 assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3261 "'namespace' expected");
3265 if (InitialToken.is(TT_NamespaceMacro)) {
3268 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3269 tok::l_square, tok::period, tok::l_paren) ||
3270 (Style.isCSharp() && FormatTok->is(tok::kw_union))) {
3271 if (FormatTok->is(tok::l_square))
3273 else if (FormatTok->is(tok::l_paren))
3279 if (FormatTok->is(tok::l_brace)) {
3280 FormatTok->setFinalizedType(TT_NamespaceLBrace);
3283 Tokens->peekNextToken()->is(tok::r_brace))) {
3287 unsigned AddLevels =
3288 Style.NamespaceIndentation == FormatStyle::NI_All ||
3289 (Style.NamespaceIndentation == FormatStyle::NI_Inner &&
3290 DeclarationScopeStack.size() > 1)
3293 parseNamespaceOrExportBlock(AddLevels);
3298void UnwrappedLineParser::parseCppExportBlock() {
3299 parseNamespaceOrExportBlock(Style.IndentExportBlock ? 1 : 0);
3302void UnwrappedLineParser::parseNew() {
3303 assert(FormatTok->is(tok::kw_new) &&
"'new' expected");
3306 if (Style.isCSharp()) {
3309 if (FormatTok->is(tok::l_paren))
3313 if (FormatTok->is(tok::l_brace))
3316 if (FormatTok->isOneOf(tok::semi, tok::comma))
3323 if (!Style.isJava())
3329 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3333 if (FormatTok->is(tok::l_paren)) {
3337 if (FormatTok->is(tok::l_brace))
3345void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3346 keepAncestorBraces();
3348 if (isBlockBegin(*FormatTok)) {
3349 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3351 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3352 parseBlock(
false, 1u,
3354 setPreviousRBraceType(TT_ControlStatementRBrace);
3356 assert(!NestedTooDeep.empty());
3357 if (!NestedTooDeep.back())
3363 parseUnbracedBody();
3367 NestedTooDeep.pop_back();
3370void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3371 assert((FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3372 (Style.isVerilog() &&
3373 FormatTok->isOneOf(Keywords.kw_always, Keywords.kw_always_comb,
3374 Keywords.kw_always_ff, Keywords.kw_always_latch,
3375 Keywords.kw_final, Keywords.kw_initial,
3376 Keywords.kw_foreach, Keywords.kw_forever,
3377 Keywords.kw_repeat))) &&
3378 "'for', 'while' or foreach macro expected");
3379 const bool KeepBraces = !Style.RemoveBracesLLVM ||
3380 FormatTok->isNoneOf(tok::kw_for, tok::kw_while);
3384 if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
3386 if (IsCpp && FormatTok->is(tok::kw_co_await))
3388 if (HasParens && FormatTok->is(tok::l_paren)) {
3392 if (Style.isVerilog())
3393 FormatTok->setFinalizedType(TT_ConditionLParen);
3397 if (Style.isVerilog()) {
3399 parseVerilogSensitivityList();
3400 }
else if (Style.AllowShortLoopsOnASingleLine && FormatTok->is(tok::semi) &&
3401 Tokens->getPreviousToken()->is(tok::r_paren)) {
3408 parseLoopBody(KeepBraces,
true);
3411void UnwrappedLineParser::parseDoWhile() {
3412 assert(FormatTok->is(tok::kw_do) &&
"'do' expected");
3415 parseLoopBody(
true, Style.BraceWrapping.BeforeWhile);
3418 if (FormatTok->isNot(tok::kw_while)) {
3423 FormatTok->setFinalizedType(TT_DoWhile);
3427 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths)
3431 parseStructuralElement();
3434void UnwrappedLineParser::parseLabel(
3435 FormatStyle::IndentGotoLabelStyle IndentGotoLabels) {
3436 const bool IsGotoLabel = FormatTok->is(TT_GotoLabelColon);
3438 unsigned OldLineLevel =
Line->Level;
3440 switch (IndentGotoLabels) {
3441 case FormatStyle::IGLS_NoIndent:
3444 case FormatStyle::IGLS_OuterIndent:
3445 if (
Line->Level > 1 || (!
Line->InPPDirective &&
Line->Level > 0))
3448 case FormatStyle::IGLS_HalfIndent:
3449 case FormatStyle::IGLS_InnerIndent:
3453 if (!IsGotoLabel && !Style.IndentCaseBlocks &&
3454 CommentsBeforeNextToken.empty() && FormatTok->is(tok::l_brace)) {
3455 CompoundStatementIndenter Indenter(
this,
Line->Level,
3456 Style.BraceWrapping.AfterCaseLabel,
3457 Style.BraceWrapping.IndentBraces);
3459 if (FormatTok->is(tok::kw_break)) {
3460 if (Style.BraceWrapping.AfterControlStatement ==
3461 FormatStyle::BWACS_Always) {
3463 if (!Style.IndentCaseBlocks &&
3464 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {
3468 parseStructuralElement();
3472 if (FormatTok->is(tok::semi))
3476 Line->Level = OldLineLevel;
3477 if (FormatTok->isNot(tok::l_brace)) {
3478 parseStructuralElement();
3483void UnwrappedLineParser::parseCaseLabel() {
3484 assert(FormatTok->is(tok::kw_case) &&
"'case' expected");
3485 auto *Case = FormatTok;
3490 if (FormatTok->is(tok::colon)) {
3491 FormatTok->setFinalizedType(TT_CaseLabelColon);
3494 if (Style.isJava() && FormatTok->is(tok::arrow)) {
3495 FormatTok->setFinalizedType(TT_CaseLabelArrow);
3496 Case->setFinalizedType(TT_SwitchExpressionLabel);
3503void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3504 assert(FormatTok->is(tok::kw_switch) &&
"'switch' expected");
3506 if (FormatTok->is(tok::l_paren))
3509 keepAncestorBraces();
3511 if (FormatTok->is(tok::l_brace)) {
3512 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3513 FormatTok->setFinalizedType(IsExpr ? TT_SwitchExpressionLBrace
3514 : TT_ControlStatementLBrace);
3519 setPreviousRBraceType(TT_ControlStatementRBrace);
3525 parseStructuralElement();
3529 if (Style.RemoveBracesLLVM)
3530 NestedTooDeep.pop_back();
3533void UnwrappedLineParser::parseAccessSpecifier() {
3536 if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
3539 if (FormatTok->is(tok::colon))
3547bool UnwrappedLineParser::parseRequires(
bool SeenEqual) {
3548 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3552 switch (Tokens->peekNextToken(
true)->Tok.getKind()) {
3555 parseRequiresExpression();
3562 parseRequiresClause();
3573 auto *PreviousNonComment = FormatTok->getPreviousNonComment();
3575 if (!PreviousNonComment ||
3576 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3579 parseRequiresClause();
3583 switch (PreviousNonComment->Tok.getKind()) {
3586 case tok::kw_noexcept:
3591 parseRequiresClause();
3600 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3601 if ((PrevPrev && PrevPrev->is(tok::kw_const)) || !SeenEqual) {
3602 parseRequiresClause();
3608 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3610 parseRequiresClause();
3614 parseRequiresExpression();
3624 unsigned StoredPosition = Tokens->getPosition();
3627 auto PeekNext = [&Lookahead, &NextToken,
this] {
3629 NextToken = Tokens->getNextToken();
3632 bool FoundType =
false;
3633 bool LastWasColonColon =
false;
3636 for (; Lookahead < 50; PeekNext()) {
3637 switch (NextToken->Tok.getKind()) {
3638 case tok::kw_volatile:
3641 if (OpenAngles == 0) {
3642 FormatTok = Tokens->setPosition(StoredPosition);
3643 parseRequiresExpression();
3651 case tok::coloncolon:
3652 LastWasColonColon =
true;
3654 case tok::kw_decltype:
3655 case tok::identifier:
3656 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3657 FormatTok = Tokens->setPosition(StoredPosition);
3658 parseRequiresExpression();
3662 LastWasColonColon =
false;
3671 if (NextToken->isTypeName(LangOpts)) {
3672 FormatTok = Tokens->setPosition(StoredPosition);
3673 parseRequiresExpression();
3680 FormatTok = Tokens->setPosition(StoredPosition);
3681 parseRequiresClause();
3690void UnwrappedLineParser::parseRequiresClause() {
3691 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3696 bool InRequiresExpression =
3697 !FormatTok->Previous ||
3698 FormatTok->Previous->is(TT_RequiresExpressionLBrace);
3700 FormatTok->setFinalizedType(InRequiresExpression
3701 ? TT_RequiresClauseInARequiresExpression
3702 : TT_RequiresClause);
3707 parseConstraintExpression();
3709 if (!InRequiresExpression && FormatTok->Previous)
3710 FormatTok->Previous->ClosesRequiresClause =
true;
3718void UnwrappedLineParser::parseRequiresExpression() {
3719 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3721 FormatTok->setFinalizedType(TT_RequiresExpression);
3724 if (FormatTok->is(tok::l_paren)) {
3725 FormatTok->setFinalizedType(TT_RequiresExpressionLParen);
3729 if (FormatTok->is(tok::l_brace)) {
3730 FormatTok->setFinalizedType(TT_RequiresExpressionLBrace);
3739void UnwrappedLineParser::parseConstraintExpression() {
3746 bool LambdaNextTimeAllowed =
true;
3756 bool TopLevelParensAllowed =
true;
3759 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3761 switch (FormatTok->Tok.getKind()) {
3762 case tok::kw_requires:
3763 parseRequiresExpression();
3767 if (!TopLevelParensAllowed)
3769 parseParens(TT_BinaryOperator);
3770 TopLevelParensAllowed =
false;
3774 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3781 case tok::kw_struct:
3791 FormatTok->setFinalizedType(TT_BinaryOperator);
3793 LambdaNextTimeAllowed =
true;
3794 TopLevelParensAllowed =
true;
3799 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3803 case tok::kw_sizeof:
3805 case tok::greaterequal:
3806 case tok::greatergreater:
3808 case tok::lessequal:
3810 case tok::equalequal:
3812 case tok::exclaimequal:
3817 LambdaNextTimeAllowed =
true;
3818 TopLevelParensAllowed =
true;
3823 case tok::numeric_constant:
3824 case tok::coloncolon:
3827 TopLevelParensAllowed =
false;
3832 case tok::kw_static_cast:
3833 case tok::kw_const_cast:
3834 case tok::kw_reinterpret_cast:
3835 case tok::kw_dynamic_cast:
3837 if (FormatTok->isNot(tok::less))
3841 parseBracedList(
true);
3845 if (!FormatTok->Tok.getIdentifierInfo()) {
3855 assert(FormatTok->Previous);
3856 switch (FormatTok->Previous->Tok.getKind()) {
3857 case tok::coloncolon:
3861 case tok::kw_requires:
3870 if (FormatTok->is(tok::less)) {
3872 parseBracedList(
true);
3874 TopLevelParensAllowed =
false;
3880bool UnwrappedLineParser::parseEnum() {
3884 if (FormatTok->is(tok::kw_enum))
3890 if (Style.isJavaScript() && FormatTok->isOneOf(tok::colon, tok::question))
3894 if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))
3899 if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))
3901 while (FormatTok->is(tok::l_square))
3902 if (!handleCppAttributes())
3906 while (FormatTok->Tok.getIdentifierInfo() ||
3907 FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
3908 tok::greater, tok::comma, tok::question,
3910 if (FormatTok->is(tok::colon))
3911 FormatTok->setFinalizedType(TT_EnumUnderlyingTypeColon);
3912 if (Style.isVerilog()) {
3913 FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);
3916 while (FormatTok->is(tok::l_square))
3922 if (FormatTok->is(tok::l_paren))
3924 if (FormatTok->is(tok::identifier)) {
3928 if (IsCpp && FormatTok->is(tok::identifier))
3934 if (FormatTok->isNot(tok::l_brace))
3936 FormatTok->setFinalizedType(TT_EnumLBrace);
3937 FormatTok->setBlockKind(BK_Block);
3939 if (Style.isJava()) {
3941 parseJavaEnumBody();
3944 if (Style.Language == FormatStyle::LK_Proto) {
3949 const bool ManageWhitesmithsBraces =
3950 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
3952 if (!Style.AllowShortEnumsOnASingleLine &&
3954 Tokens->peekNextToken()->is(tok::r_brace))) {
3959 if (ManageWhitesmithsBraces)
3964 if (!Style.AllowShortEnumsOnASingleLine) {
3966 if (!ManageWhitesmithsBraces)
3969 const auto OpeningLineIndex = CurrentLines->empty()
3970 ? UnwrappedLine::kInvalidIndex
3971 : CurrentLines->size() - 1;
3972 bool HasError = !parseBracedList(
false,
true);
3973 if (!Style.AllowShortEnumsOnASingleLine && !ManageWhitesmithsBraces)
3976 if (FormatTok->is(tok::semi))
3980 setPreviousRBraceType(TT_EnumRBrace);
3981 if (ManageWhitesmithsBraces)
3982 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
3990bool UnwrappedLineParser::parseStructLike() {
3995 if (Style.isJava() || Style.isJavaScript() || Style.isCSharp()) {
3996 if (FormatTok->is(tok::semi))
4007class ScopedTokenPosition {
4008 unsigned StoredPosition;
4009 FormatTokenSource *Tokens;
4012 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
4013 assert(Tokens &&
"Tokens expected to not be null");
4014 StoredPosition = Tokens->getPosition();
4017 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
4023bool UnwrappedLineParser::tryToParseSimpleAttribute() {
4024 ScopedTokenPosition AutoPosition(Tokens);
4032 if (
Tok->
is(tok::r_square))
4034 Tok = Tokens->getNextToken();
4036 if (
Tok->
is(tok::eof))
4038 Tok = Tokens->getNextToken();
4041 Tok = Tokens->getNextToken();
4042 if (
Tok->
is(tok::semi))
4047void UnwrappedLineParser::parseJavaEnumBody() {
4048 assert(FormatTok->is(tok::l_brace));
4054 unsigned StoredPosition = Tokens->getPosition();
4055 bool IsSimple =
true;
4058 if (
Tok->
is(tok::r_brace))
4066 Tok = Tokens->getNextToken();
4068 FormatTok = Tokens->setPosition(StoredPosition);
4085 if (FormatTok->is(tok::l_brace)) {
4087 parseBlock(
true, 1u,
4089 }
else if (FormatTok->is(tok::l_paren)) {
4091 }
else if (FormatTok->is(tok::comma)) {
4094 }
else if (FormatTok->is(tok::semi)) {
4098 }
else if (FormatTok->is(tok::r_brace)) {
4107 parseLevel(OpeningBrace);
4113void UnwrappedLineParser::parseRecord(
bool ParseAsExpr,
bool IsJavaRecord) {
4114 assert(!IsJavaRecord || FormatTok->is(Keywords.kw_record));
4119 IsJavaRecord && FormatTok->is(tok::identifier) ? FormatTok :
nullptr;
4120 bool IsDerived =
false;
4122 return Tok->
is(tok::identifier) &&
Tok->TokenText !=
Tok->TokenText.upper();
4126 bool JSPastExtendsOrImplements =
false;
4130 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
4131 tok::kw_alignas, tok::l_square) ||
4132 FormatTok->isAttribute() ||
4133 ((Style.isJava() || Style.isJavaScript()) &&
4134 FormatTok->isOneOf(tok::period, tok::comma))) {
4135 if (Style.isJavaScript() &&
4136 FormatTok->isOneOf(Keywords.kw_extends, Keywords.kw_implements)) {
4137 JSPastExtendsOrImplements =
true;
4142 if (FormatTok->is(tok::l_brace)) {
4143 tryToParseBracedList();
4147 if (FormatTok->is(tok::l_square) && handleCppAttributes())
4151 switch (FormatTok->Tok.getKind()) {
4154 if (IsJavaRecord || !IsNonMacroIdentifier(
Previous) ||
4156 Previous->Previous == &InitialToken) {
4160 case tok::coloncolon:
4164 if (JSPastExtendsOrImplements || ClassName ||
4175 auto IsListInitialization = [&] {
4176 if (!ClassName || IsDerived || JSPastExtendsOrImplements)
4178 assert(FormatTok->is(tok::l_brace));
4179 const auto *Prev = FormatTok->getPreviousNonComment();
4181 return Prev != ClassName && Prev->is(tok::identifier) &&
4182 Prev->isNot(Keywords.kw_final) && tryToParseBracedList();
4185 if (FormatTok->isOneOf(tok::colon, tok::less)) {
4186 int AngleNestingLevel = 0;
4188 if (FormatTok->is(tok::less))
4189 ++AngleNestingLevel;
4190 else if (FormatTok->is(tok::greater))
4191 --AngleNestingLevel;
4193 if (AngleNestingLevel == 0) {
4194 if (FormatTok->is(tok::colon)) {
4196 }
else if (!IsDerived && FormatTok->is(tok::identifier) &&
4197 FormatTok->Previous->is(tok::coloncolon)) {
4198 ClassName = FormatTok;
4199 }
else if (FormatTok->is(tok::l_paren) &&
4200 IsNonMacroIdentifier(FormatTok->Previous)) {
4204 if (FormatTok->is(tok::l_brace)) {
4205 if (AngleNestingLevel == 0 && IsListInitialization())
4207 calculateBraceTypes(
true);
4208 if (!tryToParseBracedList())
4211 if (FormatTok->is(tok::l_square)) {
4214 !
Previous->isTypeOrIdentifier(LangOpts))) {
4217 if (!tryToParseLambda())
4224 if (FormatTok->is(tok::semi))
4226 if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) {
4229 parseCSharpGenericTypeConstraint();
4236 auto GetBraceTypes =
4237 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4238 switch (RecordTok.Tok.getKind()) {
4240 return {TT_ClassLBrace, TT_ClassRBrace};
4241 case tok::kw_struct:
4242 return {TT_StructLBrace, TT_StructRBrace};
4244 return {TT_UnionLBrace, TT_UnionRBrace};
4247 return {TT_RecordLBrace, TT_RecordRBrace};
4250 if (FormatTok->is(tok::l_brace)) {
4251 if (IsListInitialization())
4254 ClassName->setFinalizedType(TT_ClassHeadName);
4255 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4256 FormatTok->setFinalizedType(OpenBraceType);
4261 Tokens->peekNextToken()->is(tok::r_brace),
4266 unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;
4267 parseBlock(
true, AddLevels,
false);
4269 setPreviousRBraceType(ClosingBraceType);
4276void UnwrappedLineParser::parseObjCMethod() {
4277 assert(FormatTok->isOneOf(tok::l_paren, tok::identifier) &&
4278 "'(' or identifier expected.");
4280 if (FormatTok->is(tok::semi)) {
4284 }
else if (FormatTok->is(tok::l_brace)) {
4285 if (Style.BraceWrapping.AfterFunction)
4296void UnwrappedLineParser::parseObjCProtocolList() {
4297 assert(FormatTok->is(tok::less) &&
"'<' expected.");
4301 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))
4303 }
while (!
eof() && FormatTok->isNot(tok::greater));
4307void UnwrappedLineParser::parseObjCUntilAtEnd() {
4309 if (FormatTok->is(tok::objc_end)) {
4314 if (FormatTok->is(tok::l_brace)) {
4318 }
else if (FormatTok->is(tok::r_brace)) {
4322 }
else if (FormatTok->isOneOf(tok::minus, tok::plus)) {
4324 if (FormatTok->isOneOf(tok::l_paren, tok::identifier))
4327 parseStructuralElement();
4332void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4333 assert(FormatTok->isOneOf(tok::objc_interface, tok::objc_implementation));
4339 if (FormatTok->is(tok::less))
4340 parseObjCLightweightGenerics();
4341 if (FormatTok->is(tok::colon)) {
4345 if (FormatTok->is(tok::less))
4346 parseObjCLightweightGenerics();
4347 }
else if (FormatTok->is(tok::l_paren)) {
4352 if (FormatTok->is(tok::less))
4353 parseObjCProtocolList();
4355 if (FormatTok->is(tok::l_brace)) {
4356 if (Style.BraceWrapping.AfterObjCDeclaration)
4365 parseObjCUntilAtEnd();
4368void UnwrappedLineParser::parseObjCLightweightGenerics() {
4369 assert(FormatTok->is(tok::less));
4377 unsigned NumOpenAngles = 1;
4381 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))
4383 if (FormatTok->is(tok::less)) {
4385 }
else if (FormatTok->is(tok::greater)) {
4386 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4389 }
while (!
eof() && NumOpenAngles != 0);
4395bool UnwrappedLineParser::parseObjCProtocol() {
4396 assert(FormatTok->is(tok::objc_protocol));
4399 if (FormatTok->is(tok::l_paren)) {
4411 if (FormatTok->is(tok::less))
4412 parseObjCProtocolList();
4415 if (FormatTok->is(tok::semi)) {
4422 parseObjCUntilAtEnd();
4426void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4427 bool IsImport = FormatTok->is(Keywords.kw_import);
4428 assert(IsImport || FormatTok->is(tok::kw_export));
4432 if (FormatTok->is(tok::kw_default))
4438 if (FormatTok->is(Keywords.kw_async))
4440 if (FormatTok->is(Keywords.kw_function)) {
4449 if (!IsImport && FormatTok->isNoneOf(tok::l_brace, tok::star) &&
4450 !FormatTok->isStringLiteral() &&
4451 !(FormatTok->is(Keywords.kw_type) &&
4452 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4457 if (FormatTok->is(tok::semi))
4459 if (
Line->Tokens.empty()) {
4464 if (FormatTok->is(tok::l_brace)) {
4465 FormatTok->setBlockKind(BK_Block);
4474void UnwrappedLineParser::parseStatementMacro() {
4476 if (FormatTok->is(tok::l_paren))
4478 if (FormatTok->is(tok::semi))
4483void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4486 if (FormatTok->isOneOf(tok::star, tok::period, tok::periodstar,
4487 tok::coloncolon, tok::hash) ||
4488 Keywords.isVerilogIdentifier(*FormatTok)) {
4490 }
else if (FormatTok->is(tok::l_square)) {
4498void UnwrappedLineParser::parseVerilogSensitivityList() {
4499 if (FormatTok->isNot(tok::at))
4503 if (FormatTok->is(tok::at))
4505 switch (FormatTok->Tok.getKind()) {
4513 parseVerilogHierarchyIdentifier();
4518unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4519 unsigned AddLevels = 0;
4521 if (FormatTok->is(Keywords.kw_clocking)) {
4523 if (Keywords.isVerilogIdentifier(*FormatTok))
4525 parseVerilogSensitivityList();
4526 if (FormatTok->is(tok::semi))
4528 }
else if (FormatTok->isOneOf(tok::kw_case, Keywords.kw_casex,
4529 Keywords.kw_casez, Keywords.kw_randcase,
4530 Keywords.kw_randsequence)) {
4531 if (Style.IndentCaseLabels)
4534 if (FormatTok->is(tok::l_paren)) {
4535 FormatTok->setFinalizedType(TT_ConditionLParen);
4538 if (FormatTok->isOneOf(Keywords.kw_inside, Keywords.kw_matches))
4547 if (FormatTok->is(tok::l_square)) {
4548 auto Prev = FormatTok->getPreviousNonComment();
4549 if (Prev && Keywords.isVerilogIdentifier(*Prev))
4550 Prev->setFinalizedType(TT_VerilogDimensionedTypeName);
4552 }
else if (Keywords.isVerilogIdentifier(*FormatTok) ||
4553 FormatTok->isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
4554 Keywords.kw_automatic, tok::kw_static)) {
4561 auto NewLine = [
this]() {
4563 Line->IsContinuation =
true;
4567 while (FormatTok->is(Keywords.kw_import)) {
4570 parseVerilogHierarchyIdentifier();
4571 if (FormatTok->is(tok::semi))
4576 if (FormatTok->is(Keywords.kw_verilogHash)) {
4579 if (FormatTok->is(tok::l_paren)) {
4580 FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
4584 if (FormatTok->is(tok::l_paren)) {
4586 FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
4591 if (FormatTok->is(Keywords.kw_extends)) {
4594 parseVerilogHierarchyIdentifier();
4595 if (FormatTok->is(tok::l_paren))
4598 if (FormatTok->is(Keywords.kw_implements)) {
4602 parseVerilogHierarchyIdentifier();
4603 }
while (FormatTok->is(tok::comma));
4607 if (FormatTok->is(tok::at)) {
4609 parseVerilogSensitivityList();
4612 if (FormatTok->is(tok::semi))
4620void UnwrappedLineParser::parseVerilogTable() {
4621 assert(FormatTok->is(Keywords.kw_table));
4625 auto InitialLevel =
Line->Level++;
4626 while (!
eof() && !Keywords.isVerilogEnd(*FormatTok)) {
4629 if (
Tok->
is(tok::semi))
4631 else if (
Tok->
isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4632 Tok->setFinalizedType(TT_VerilogTableItem);
4634 Line->Level = InitialLevel;
4639void UnwrappedLineParser::parseVerilogCaseLabel() {
4645 auto OrigLevel =
Line->Level;
4646 auto FirstLine = CurrentLines->size();
4647 if (
Line->Level == 0 || (
Line->InPPDirective &&
Line->Level <= 1))
4649 else if (!Style.IndentCaseBlocks && Keywords.isVerilogBegin(*FormatTok))
4651 parseStructuralElement();
4654 if (CurrentLines->size() > FirstLine)
4655 (*CurrentLines)[FirstLine].Level = OrigLevel;
4656 Line->Level = OrigLevel;
4659void UnwrappedLineParser::parseVerilogExtern() {
4661 FormatTok->isOneOf(tok::kw_extern, tok::kw_export, Keywords.kw_import));
4664 if (FormatTok->is(tok::string_literal))
4666 skipVerilogQualifiers();
4667 if (Keywords.isVerilogIdentifier(*FormatTok))
4669 if (FormatTok->is(tok::equal))
4671 if (Keywords.isVerilogHierarchy(*FormatTok))
4672 parseVerilogHierarchyHeader();
4675void UnwrappedLineParser::skipVerilogQualifiers() {
4676 while (FormatTok->isOneOf(tok::kw_protected, tok::kw_virtual, tok::kw_static,
4677 Keywords.kw_rand, Keywords.kw_context,
4678 Keywords.kw_pure, Keywords.kw_randc,
4679 Keywords.kw_local)) {
4684bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4685 for (
const auto &N :
Line.Tokens) {
4686 if (N.Tok->MacroCtx)
4688 for (
const UnwrappedLine &Child : N.Children)
4689 if (containsExpansion(Child))
4695void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4696 if (
Line->Tokens.empty())
4699 if (!parsingPPDirective()) {
4700 llvm::dbgs() <<
"Adding unwrapped line:\n";
4701 printDebugInfo(*
Line);
4709 bool ClosesWhitesmithsBlock =
4710 Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex &&
4711 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
4716 if (!parsingPPDirective() && !InExpansion && containsExpansion(*
Line)) {
4718 Reconstruct.emplace(
Line->Level, Unexpanded);
4719 Reconstruct->addLine(*
Line);
4724 CurrentExpandedLines.push_back(std::move(*
Line));
4726 if (Reconstruct->finished()) {
4727 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4728 assert(!Reconstructed.Tokens.empty() &&
4729 "Reconstructed must at least contain the macro identifier.");
4730 assert(!parsingPPDirective());
4732 llvm::dbgs() <<
"Adding unexpanded line:\n";
4733 printDebugInfo(Reconstructed);
4735 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4736 Lines.push_back(std::move(Reconstructed));
4737 CurrentExpandedLines.clear();
4738 Reconstruct.reset();
4743 assert(!Reconstruct || (CurrentLines != &Lines) || !PPStack.empty());
4744 CurrentLines->push_back(std::move(*
Line));
4746 Line->Tokens.clear();
4747 Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;
4748 Line->FirstStartColumn = 0;
4749 Line->IsContinuation =
false;
4750 Line->SeenDecltypeAuto =
false;
4751 Line->IsModuleOrImportDecl =
false;
4753 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4755 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4756 CurrentLines->append(
4757 std::make_move_iterator(PreprocessorDirectives.begin()),
4758 std::make_move_iterator(PreprocessorDirectives.end()));
4759 PreprocessorDirectives.clear();
4762 FormatTok->Previous =
nullptr;
4765bool UnwrappedLineParser::eof()
const {
return FormatTok->is(tok::eof); }
4767bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4768 return (
Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4769 FormatTok.NewlinesBefore > 0;
4777 const llvm::Regex &CommentPragmasRegex) {
4778 if (
Line.Tokens.empty() || Style.ReflowComments != FormatStyle::RCS_Always)
4781 StringRef IndentContent = FormatTok.
TokenText;
4782 if (FormatTok.
TokenText.starts_with(
"//") ||
4783 FormatTok.
TokenText.starts_with(
"/*")) {
4784 IndentContent = FormatTok.
TokenText.substr(2);
4786 if (CommentPragmasRegex.match(IndentContent))
4861 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4863 MinColumnToken = PreviousToken;
4866 PreviousToken = Node.
Tok;
4870 MinColumnToken = Node.
Tok;
4872 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4873 MinColumnToken = PreviousToken;
4879void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4880 bool JustComments =
Line->Tokens.empty();
4890 Tok->ContinuesLineCommentSection =
4891 continuesLineCommentSection(*
Tok, *
Line, Style, CommentPragmasRegex);
4892 if (isOnNewLine(*
Tok) && JustComments && !
Tok->ContinuesLineCommentSection)
4896 if (NewlineBeforeNext && JustComments)
4898 CommentsBeforeNextToken.clear();
4901void UnwrappedLineParser::nextToken(
int LevelDifference) {
4904 flushComments(isOnNewLine(*FormatTok));
4905 pushToken(FormatTok);
4907 if (!Style.isJavaScript())
4908 readToken(LevelDifference);
4910 readTokenWithJavaScriptASI();
4912 if (Style.isVerilog()) {
4919 if (Keywords.isVerilogEnd(*FormatTok))
4920 FormatTok->Tok.setKind(tok::r_brace);
4924void UnwrappedLineParser::distributeComments(
4944 if (Comments.empty())
4946 bool ShouldPushCommentsInCurrentLine =
true;
4947 bool HasTrailAlignedWithNextToken =
false;
4948 unsigned StartOfTrailAlignedWithNextToken = 0;
4951 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4953 HasTrailAlignedWithNextToken =
true;
4954 StartOfTrailAlignedWithNextToken = i;
4958 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4960 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4961 FormatTok->ContinuesLineCommentSection =
false;
4964 *FormatTok, *
Line, Style, CommentPragmasRegex);
4966 if (!FormatTok->ContinuesLineCommentSection &&
4967 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4968 ShouldPushCommentsInCurrentLine =
false;
4970 if (ShouldPushCommentsInCurrentLine)
4971 pushToken(FormatTok);
4973 CommentsBeforeNextToken.push_back(FormatTok);
4977void UnwrappedLineParser::readToken(
int LevelDifference) {
4979 bool PreviousWasComment =
false;
4980 bool FirstNonCommentOnLine =
false;
4982 FormatTok = Tokens->getNextToken();
4984 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4985 TT_ConflictAlternative)) {
4986 if (FormatTok->is(TT_ConflictStart))
4987 conditionalCompilationStart(
false);
4988 else if (FormatTok->is(TT_ConflictAlternative))
4989 conditionalCompilationAlternative();
4990 else if (FormatTok->is(TT_ConflictEnd))
4991 conditionalCompilationEnd();
4992 FormatTok = Tokens->getNextToken();
4993 FormatTok->MustBreakBefore =
true;
4994 FormatTok->MustBreakBeforeFinalized =
true;
4997 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4999 bool PreviousWasComment) {
5001 return Tok.HasUnescapedNewline ||
Tok.IsFirst;
5006 if (PreviousWasComment)
5007 return FirstNonCommentOnLine || IsFirstOnLine(
Tok);
5008 return IsFirstOnLine(
Tok);
5011 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
5012 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
5013 PreviousWasComment = FormatTok->is(tok::comment);
5015 while (!
Line->InPPDirective && FormatTok->is(tok::hash) &&
5016 FirstNonCommentOnLine) {
5019 const auto *
Next = Tokens->peekNextToken();
5020 if ((Style.isVerilog() && !Keywords.isVerilogPPDirective(*
Next)) ||
5021 (Style.isTableGen() &&
5022 Next->isNoneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,
5023 tok::pp_ifndef, tok::pp_endif))) {
5026 distributeComments(Comments, FormatTok);
5030 bool SwitchToPreprocessorLines = !
Line->Tokens.empty();
5031 ScopedLineState BlockState(*
this, SwitchToPreprocessorLines);
5032 assert((LevelDifference >= 0 ||
5033 static_cast<unsigned>(-LevelDifference) <=
Line->Level) &&
5034 "LevelDifference makes Line->Level negative");
5035 Line->Level += LevelDifference;
5039 if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
5040 PPBranchLevel > 0) {
5041 Line->Level += PPBranchLevel;
5043 assert(
Line->Level >=
Line->UnbracedBodyLevel);
5044 Line->Level -=
Line->UnbracedBodyLevel;
5045 flushComments(isOnNewLine(*FormatTok));
5046 const bool IsEndIf = Tokens->peekNextToken()->is(tok::pp_endif);
5048 PreviousWasComment = FormatTok->is(tok::comment);
5049 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
5050 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
5053 if (IsEndIf && IncludeGuard == IG_Defined && PPBranchLevel == -1 &&
5054 getIncludeGuardState(Style.IndentPPDirectives) == IG_Inited &&
5056 (PreviousWasComment &&
5057 Tokens->peekNextToken(
true)->is(tok::eof)))) {
5058 IncludeGuard = IG_Found;
5062 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
5063 !
Line->InPPDirective) {
5067 if (FormatTok->is(tok::identifier) &&
5068 Macros.defined(FormatTok->TokenText) &&
5070 !
Line->InPPDirective) {
5072 unsigned Position = Tokens->getPosition();
5076 auto PreCall = std::move(
Line);
5077 Line.reset(
new UnwrappedLine);
5078 bool OldInExpansion = InExpansion;
5081 auto Args = parseMacroCall();
5082 InExpansion = OldInExpansion;
5083 assert(
Line->Tokens.front().Tok == ID);
5085 auto UnexpandedLine = std::move(
Line);
5087 Line = std::move(PreCall);
5090 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
5092 llvm::dbgs() <<
"(";
5093 for (
const auto &Arg : Args.value())
5094 for (
const auto &T : Arg)
5095 llvm::dbgs() << T->TokenText <<
" ";
5096 llvm::dbgs() <<
")";
5098 llvm::dbgs() <<
"\n";
5100 if (
Macros.objectLike(
ID->TokenText) && Args &&
5101 !
Macros.hasArity(
ID->TokenText, Args->size())) {
5107 LLVM_DEBUG(llvm::dbgs()
5108 <<
"Macro \"" <<
ID->TokenText
5109 <<
"\" not overloaded for arity " << Args->size()
5110 <<
"or not function-like, using object-like overload.");
5112 UnexpandedLine->Tokens.resize(1);
5113 Tokens->setPosition(Position);
5115 assert(!Args &&
Macros.objectLike(
ID->TokenText));
5117 if ((!Args &&
Macros.objectLike(
ID->TokenText)) ||
5118 (Args &&
Macros.hasArity(
ID->TokenText, Args->size()))) {
5121 Unexpanded[
ID] = std::move(UnexpandedLine);
5123 Macros.expand(ID, std::move(Args));
5124 if (!Expansion.empty())
5125 FormatTok = Tokens->insertTokens(Expansion);
5128 llvm::dbgs() <<
"Expanded: ";
5129 for (
const auto &T : Expansion)
5130 llvm::dbgs() << T->TokenText <<
" ";
5131 llvm::dbgs() <<
"\n";
5135 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
5136 <<
"\", because it was used ";
5138 llvm::dbgs() <<
"with " << Args->size();
5140 llvm::dbgs() <<
"without";
5141 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
5143 Tokens->setPosition(Position);
5148 if (FormatTok->isNot(tok::comment)) {
5149 distributeComments(Comments, FormatTok);
5154 Comments.push_back(FormatTok);
5157 distributeComments(Comments,
nullptr);
5162template <
typename Iterator>
5163void pushTokens(Iterator Begin, Iterator End,
5165 for (
auto I = Begin; I != End; ++I) {
5166 Into.push_back(I->Tok);
5167 for (
const auto &Child : I->Children)
5168 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
5173std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
5174UnwrappedLineParser::parseMacroCall() {
5175 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
5176 assert(
Line->Tokens.empty());
5178 if (FormatTok->isNot(tok::l_paren))
5180 unsigned Position = Tokens->getPosition();
5184 auto ArgStart = std::prev(
Line->Tokens.end());
5188 switch (FormatTok->Tok.getKind()) {
5193 case tok::r_paren: {
5199 Args->push_back({});
5200 pushTokens(std::next(ArgStart),
Line->Tokens.end(), Args->back());
5209 Args->push_back({});
5210 pushTokens(std::next(ArgStart),
Line->Tokens.end(), Args->back());
5212 ArgStart = std::prev(
Line->Tokens.end());
5220 Line->Tokens.resize(1);
5221 Tokens->setPosition(Position);
5227 Line->Tokens.push_back(UnwrappedLineNode(
Tok));
5228 if (AtEndOfPPLine) {
5229 auto &
Tok = *
Line->Tokens.back().Tok;
5230 Tok.MustBreakBefore =
true;
5231 Tok.MustBreakBeforeFinalized =
true;
5232 Tok.FirstAfterPPLine =
true;
5233 AtEndOfPPLine =
false;
This file contains the main building blocks of macro support in clang-format.
static bool HasAttribute(const QualType &T)
This file implements a token annotator, i.e.
Defines the clang::TokenKind enum and support functions.
This file contains the declaration of the UnwrappedLineParser, which turns a stream of tokens into Un...
Implements an efficient mapping from strings to IdentifierInfo nodes.
Parser - This implements a parser for the C family of languages.
This class handles loading and caching of source files into memory.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isOneOf(Ts... Ks) const
bool isNot(tok::TokenKind K) const
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isLiteral(TokenKind K)
Return true if this is a "literal" kind, like a numeric constant, string, etc.
The JSON file list parser is used to communicate input to InstallAPI.
bool isLineComment(const FormatToken &FormatTok)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::vector< std::string > Macros
A list of macros of the form <definition>=<expansion> .
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Default
Set to the current date and time.
@ Type
The name was classified as a type.
bool continuesLineComment(const FormatToken &FormatTok, const FormatToken *Previous, const FormatToken *MinColumnToken)
@ Parens
New-expression has a C++98 paren-delimited initializer.
Encapsulates keywords that are context sensitive or for languages not properly supported by Clang's l...
IdentifierInfo * kw_instanceof
IdentifierInfo * kw_implements
IdentifierInfo * kw_override
IdentifierInfo * kw_await
IdentifierInfo * kw_extends
IdentifierInfo * kw_async
IdentifierInfo * kw_abstract
IdentifierInfo * kw_interface
IdentifierInfo * kw_function
IdentifierInfo * kw_yield
IdentifierInfo * kw_where
IdentifierInfo * kw_throws
IdentifierInfo * kw_import
IdentifierInfo * kw_finally
Represents a complete lambda introducer.