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->IsModuleOrImportDecl = PreBlockLine->IsModuleOrImportDecl;
112 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;
116 if (!Parser.Line->Tokens.empty())
117 Parser.addUnwrappedLine();
118 assert(Parser.Line->Tokens.empty());
119 Parser.Line = std::move(PreBlockLine);
120 if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
121 Parser.AtEndOfPPLine =
true;
122 Parser.CurrentLines = OriginalLines;
128 std::unique_ptr<UnwrappedLine> PreBlockLine;
135 const FormatStyle &Style,
unsigned &LineLevel)
137 Style.BraceWrapping.AfterControlStatement ==
138 FormatStyle::BWACS_Always,
139 Style.BraceWrapping.IndentBraces) {}
141 bool WrapBrace,
bool IndentBrace)
142 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
144 Parser->addUnwrappedLine();
152 unsigned OldLineLevel;
159 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
162 Style(Style), IsCpp(Style.
isCpp()),
164 CommentPragmasRegex(Style.CommentPragmas), Tokens(
nullptr),
165 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
166 IncludeGuard(getIncludeGuardState(Style.IndentPPDirectives)),
167 IncludeGuardToken(
nullptr), FirstStartColumn(FirstStartColumn),
168 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}
170void UnwrappedLineParser::reset() {
172 IncludeGuard = getIncludeGuardState(Style.IndentPPDirectives);
173 IncludeGuardToken =
nullptr;
175 CommentsBeforeNextToken.clear();
177 AtEndOfPPLine =
false;
178 IsDecltypeAutoFunction =
false;
179 PreprocessorDirectives.clear();
180 CurrentLines = &Lines;
181 DeclarationScopeStack.clear();
182 NestedTooDeep.clear();
183 NestedLambdas.clear();
185 Line->FirstStartColumn = FirstStartColumn;
187 if (!Unexpanded.empty())
189 Token->MacroCtx.reset();
190 CurrentExpandedLines.clear();
191 ExpandedLines.clear();
199 Line->FirstStartColumn = FirstStartColumn;
201 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
203 Tokens = &TokenSource;
211 if (IncludeGuard == IG_Found) {
212 for (
auto &Line : Lines)
213 if (Line.InPPDirective && Line.Level > 0)
219 pushToken(FormatTok);
224 if (!ExpandedLines.empty()) {
225 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
226 for (
const auto &Line : Lines) {
227 if (!Line.Tokens.empty()) {
228 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
229 if (it != ExpandedLines.end()) {
230 for (
const auto &Expanded : it->second) {
231 LLVM_DEBUG(printDebugInfo(Expanded));
232 Callback.consumeUnwrappedLine(Expanded);
237 LLVM_DEBUG(printDebugInfo(Line));
238 Callback.consumeUnwrappedLine(Line);
240 Callback.finishRun();
243 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
245 LLVM_DEBUG(printDebugInfo(Line));
246 Callback.consumeUnwrappedLine(Line);
248 Callback.finishRun();
250 while (!PPLevelBranchIndex.empty() &&
251 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
252 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
253 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
255 if (!PPLevelBranchIndex.empty()) {
256 ++PPLevelBranchIndex.back();
257 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
258 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
260 }
while (!PPLevelBranchIndex.empty());
263void UnwrappedLineParser::parseFile() {
266 bool MustBeDeclaration = !
Line->InPPDirective && !Style.isJavaScript();
267 ScopedDeclarationState DeclarationState(*
Line, DeclarationScopeStack,
269 if (Style.isTextProto() || (Style.isJson() && FormatTok->
IsFirst))
283 if (Style.isTextProto() && !CommentsBeforeNextToken.empty())
289void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
299 parseCSharpGenericTypeConstraint();
308void UnwrappedLineParser::parseCSharpAttribute() {
309 int UnpairedSquareBrackets = 1;
311 switch (FormatTok->Tok.getKind()) {
314 --UnpairedSquareBrackets;
315 if (UnpairedSquareBrackets == 0) {
321 ++UnpairedSquareBrackets;
331bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
332 if (!Lines.empty() && Lines.back().InPPDirective)
346bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
349 const bool InRequiresExpression =
350 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
351 const bool IsPrecededByCommentOrPPDirective =
352 !Style.RemoveBracesLLVM || precededByCommentOrPPDirective();
354 bool HasDoWhile =
false;
355 bool HasLabel =
false;
356 unsigned StatementCount = 0;
357 bool SwitchLabelEncountered =
false;
360 if (FormatTok->isAttribute()) {
362 if (FormatTok->is(tok::l_paren))
367 if (FormatTok->is(TT_MacroBlockBegin))
369 else if (FormatTok->is(TT_MacroBlockEnd))
372 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
373 &HasLabel, &StatementCount] {
374 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
375 HasDoWhile ?
nullptr : &HasDoWhile,
376 HasLabel ?
nullptr : &HasLabel);
378 assert(StatementCount > 0 &&
"StatementCount overflow!");
387 if (InRequiresExpression) {
388 FormatTok->setFinalizedType(TT_CompoundRequirementLBrace);
389 }
else if (FormatTok->Previous &&
390 FormatTok->Previous->ClosesRequiresClause) {
396 if (!InRequiresExpression && FormatTok->isNot(TT_MacroBlockBegin)) {
397 if (tryToParseBracedList())
399 FormatTok->setFinalizedType(TT_BlockLBrace);
403 assert(StatementCount > 0 &&
"StatementCount overflow!");
408 if (!Style.RemoveBracesLLVM || Line->InPPDirective ||
409 OpeningBrace->isNoneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
412 if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
413 HasDoWhile || IsPrecededByCommentOrPPDirective ||
414 precededByCommentOrPPDirective()) {
418 if (
Next->is(tok::comment) &&
Next->NewlinesBefore == 0)
421 *IfLeftBrace = IfLBrace;
427 case tok::kw_default: {
428 unsigned StoredPosition = Tokens->getPosition();
429 auto *
Next = Tokens->getNextNonComment();
430 FormatTok = Tokens->setPosition(StoredPosition);
431 if (
Next->isNoneOf(tok::colon, tok::arrow)) {
434 parseStructuralElement();
441 if (Style.Language == FormatStyle::LK_Proto || Style.isVerilog() ||
442 (Style.isJavaScript() && Line->MustBeDeclaration)) {
450 if (!SwitchLabelEncountered &&
451 (Style.IndentCaseLabels ||
452 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
453 (Line->InPPDirective && Line->Level == 1))) {
456 SwitchLabelEncountered =
true;
457 parseStructuralElement();
460 if (Style.isCSharp()) {
462 parseCSharpAttribute();
465 if (handleCppAttributes())
477void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
482 unsigned StoredPosition = Tokens->getPosition();
492 SmallVector<StackEntry, 8> LBraceStack;
493 assert(
Tok->is(tok::l_brace));
496 auto *NextTok = Tokens->getNextNonComment();
498 if (!Line->InMacroBody && !Style.isTableGen()) {
500 while (NextTok->is(tok::hash)) {
501 NextTok = Tokens->getNextToken();
502 if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))
505 NextTok = Tokens->getNextToken();
506 }
while (!NextTok->HasUnescapedNewline && NextTok->isNot(tok::eof));
508 while (NextTok->is(tok::comment))
509 NextTok = Tokens->getNextToken();
513 switch (
Tok->Tok.getKind()) {
515 if (Style.isJavaScript() && PrevTok) {
516 if (PrevTok->isOneOf(tok::colon, tok::less)) {
527 }
else if (PrevTok->is(tok::r_paren)) {
531 }
else if (Style.isJava() && PrevTok && PrevTok->is(tok::arrow)) {
536 LBraceStack.push_back({
Tok, PrevTok});
539 if (LBraceStack.empty())
541 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
542 bool ProbablyBracedList =
false;
543 if (Style.Language == FormatStyle::LK_Proto) {
544 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
545 }
else if (LBrace->isNot(TT_EnumLBrace)) {
548 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
549 NextTok->OriginalColumn == 0;
559 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
561 ProbablyBracedList = ProbablyBracedList ||
562 (Style.isJavaScript() &&
563 NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
566 ProbablyBracedList ||
567 (IsCpp && (PrevTok->Tok.isLiteral() ||
568 NextTok->isOneOf(tok::l_paren, tok::arrow)));
575 ProbablyBracedList ||
576 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
577 tok::r_paren, tok::r_square, tok::ellipsis);
582 ProbablyBracedList ||
583 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
584 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
588 ProbablyBracedList ||
589 (NextTok->is(tok::identifier) &&
590 PrevTok->isNoneOf(tok::semi, tok::r_brace, tok::l_brace));
592 ProbablyBracedList = ProbablyBracedList ||
593 (NextTok->is(tok::semi) &&
594 (!ExpectClassBody || LBraceStack.size() != 1));
597 ProbablyBracedList ||
598 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
600 if (!Style.isCSharp() && NextTok->is(tok::l_square)) {
603 NextTok = Tokens->getNextToken();
604 ProbablyBracedList = NextTok->isNot(tok::l_square);
608 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
609 !FormatTok->Previous && NextTok->is(tok::eof) &&
613 PrevTok->isNoneOf(tok::semi,
BK_Block, tok::colon)) {
614 ProbablyBracedList =
true;
618 Tok->setBlockKind(BlockKind);
619 LBrace->setBlockKind(BlockKind);
621 LBraceStack.pop_back();
623 case tok::identifier:
624 if (
Tok->isNot(TT_StatementMacro))
635 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
636 LBraceStack.back().Tok->setBlockKind(
BK_Block);
644 }
while (
Tok->isNot(tok::eof) && !LBraceStack.empty());
647 for (
const auto &Entry : LBraceStack)
651 FormatTok = Tokens->setPosition(StoredPosition);
655void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
656 if (
auto Prev = FormatTok->getPreviousNonComment();
657 Prev && Prev->is(tok::r_brace)) {
658 Prev->setFinalizedType(
Type);
665 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
668size_t UnwrappedLineParser::computePPHash()
const {
670 for (
const auto &i : PPStack) {
681bool UnwrappedLineParser::mightFitOnOneLine(
683 const auto ColumnLimit = Style.ColumnLimit;
684 if (ColumnLimit == 0)
687 auto &Tokens = ParsedLine.Tokens;
688 assert(!Tokens.empty());
690 const auto *LastToken = Tokens.back().Tok;
693 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
696 for (
const auto &Token : Tokens) {
698 auto &SavedToken = SavedTokens[Index++];
700 SavedToken.Tok->copyFrom(*Token.Tok);
701 SavedToken.Children = std::move(Token.Children);
704 AnnotatedLine
Line(ParsedLine);
705 assert(Line.Last == LastToken);
707 TokenAnnotator Annotator(Style, Keywords);
708 Annotator.annotate(Line);
709 Annotator.calculateFormattingInformation(Line);
711 auto Length = LastToken->TotalLength;
713 assert(OpeningBrace != Tokens.front().Tok);
714 if (
auto Prev = OpeningBrace->Previous;
715 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
716 Length -= ColumnLimit;
718 Length -= OpeningBrace->TokenText.size() + 1;
721 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
722 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
723 Length -= FirstToken->TokenText.size() + 1;
727 for (
auto &Token : Tokens) {
728 const auto &SavedToken = SavedTokens[Index++];
729 Token.Tok->copyFrom(*SavedToken.Tok);
730 Token.Children = std::move(SavedToken.Children);
731 delete SavedToken.Tok;
735 assert(!Line.InMacroBody);
736 assert(!Line.InPPDirective);
737 return Line.Level * Style.IndentWidth + Length <= ColumnLimit;
740FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
741 unsigned AddLevels,
bool MunchSemi,
744 bool UnindentWhitesmithsBraces) {
745 auto HandleVerilogBlockLabel = [
this]() {
747 if (Style.isVerilog() && FormatTok->is(tok::colon)) {
749 if (Keywords.isVerilogIdentifier(*FormatTok))
756 const bool VerilogHierarchy =
757 Style.isVerilog() && Keywords.isVerilogHierarchy(*FormatTok);
758 assert((FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
759 (Style.isVerilog() &&
760 (Keywords.isVerilogBegin(*FormatTok) || VerilogHierarchy))) &&
761 "'{' or macro block token expected");
763 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
764 auto Index = CurrentLines->size();
765 const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);
768 const bool IsWhitesmiths =
769 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
773 if (!VerilogHierarchy && AddLevels > 0 && IsWhitesmiths)
776 size_t PPStartHash = computePPHash();
778 const unsigned InitialLevel = Line->Level;
779 if (VerilogHierarchy) {
780 AddLevels += parseVerilogHierarchyHeader();
782 nextToken(AddLevels);
783 HandleVerilogBlockLabel();
787 if (Line->Level > 300)
790 if (MacroBlock && FormatTok->is(tok::l_paren))
793 size_t NbPreprocessorDirectives =
794 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
796 size_t OpeningLineIndex =
797 CurrentLines->empty()
799 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
804 if (UnindentWhitesmithsBraces)
807 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
813 Line->Level += AddLevels - (IsWhitesmiths ? 1 : 0);
816 const bool SimpleBlock = parseLevel(
Tok, IfKind, &IfLBrace);
821 if (MacroBlock ? FormatTok->isNot(TT_MacroBlockEnd)
822 : FormatTok->isNot(tok::r_brace)) {
823 Line->Level = InitialLevel;
824 FormatTok->setBlockKind(BK_Block);
828 if (FormatTok->is(tok::r_brace)) {
829 FormatTok->setBlockKind(BK_Block);
830 if (Tok->is(TT_NamespaceLBrace))
831 FormatTok->setFinalizedType(TT_NamespaceRBrace);
834 const bool IsFunctionRBrace =
835 FormatTok->is(tok::r_brace) &&
Tok->is(TT_FunctionLBrace);
837 auto RemoveBraces = [=]()
mutable {
840 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
841 assert(FormatTok->is(tok::r_brace));
842 const bool WrappedOpeningBrace = !Tok->Previous;
843 if (WrappedOpeningBrace && FollowedByComment)
845 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
846 if (KeepBraces && !HasRequiredIfBraces)
848 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
849 const FormatToken *Previous = Tokens->getPreviousToken();
851 if (Previous->is(tok::r_brace) && !Previous->Optional)
854 assert(!CurrentLines->empty());
855 auto &LastLine = CurrentLines->back();
856 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
858 if (
Tok->is(TT_ElseLBrace))
860 if (WrappedOpeningBrace) {
865 return mightFitOnOneLine((*CurrentLines)[Index],
Tok);
867 if (RemoveBraces()) {
868 Tok->MatchingParen = FormatTok;
869 FormatTok->MatchingParen =
Tok;
872 size_t PPEndHash = computePPHash();
875 nextToken(-AddLevels);
880 if (Style.RemoveSemicolon && IsFunctionRBrace) {
881 while (FormatTok->is(tok::semi)) {
882 FormatTok->Optional =
true;
887 HandleVerilogBlockLabel();
889 if (MacroBlock && FormatTok->is(tok::l_paren))
892 Line->Level = InitialLevel;
894 if (FormatTok->is(tok::kw_noexcept)) {
899 if (FormatTok->is(tok::arrow)) {
903 parseStructuralElement();
906 if (MunchSemi && FormatTok->is(tok::semi))
909 if (PPStartHash == PPEndHash) {
910 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
913 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
914 CurrentLines->size() - 1;
924 if (
Line.Tokens.size() < 4)
926 auto I =
Line.Tokens.begin();
927 if (I->Tok->TokenText !=
"goog")
930 if (I->Tok->isNot(tok::period))
933 if (I->Tok->TokenText !=
"scope")
936 return I->Tok->is(tok::l_paren);
945 if (
Line.Tokens.size() < 3)
947 auto I =
Line.Tokens.begin();
948 if (I->Tok->isNot(tok::l_paren))
954 return I->Tok->is(tok::l_paren);
960 bool IsJavaRecord =
false) {
962 return Style.BraceWrapping.AfterClass;
965 if (InitialToken.
is(TT_NamespaceMacro))
966 Kind = tok::kw_namespace;
968 const bool WrapRecordAllowed =
970 Style.AllowShortRecordOnASingleLine < FormatStyle::SRS_Empty ||
971 Style.BraceWrapping.SplitEmptyRecord;
974 case tok::kw_namespace:
975 return Style.BraceWrapping.AfterNamespace;
977 return Style.BraceWrapping.AfterClass && WrapRecordAllowed;
979 return Style.BraceWrapping.AfterUnion && WrapRecordAllowed;
981 return Style.BraceWrapping.AfterStruct && WrapRecordAllowed;
983 return Style.BraceWrapping.AfterEnum;
989void UnwrappedLineParser::parseChildBlock() {
990 assert(FormatTok->is(tok::l_brace));
991 FormatTok->setBlockKind(BK_Block);
995 bool SkipIndent = (Style.isJavaScript() &&
996 (isGoogScope(*
Line) || isIIFE(*
Line, Keywords)));
997 ScopedLineState LineState(*
this);
998 ScopedDeclarationState DeclarationState(*
Line, DeclarationScopeStack,
1000 Line->Level += SkipIndent ? 0 : 1;
1001 parseLevel(OpeningBrace);
1002 flushComments(isOnNewLine(*FormatTok));
1003 Line->Level -= SkipIndent ? 0 : 1;
1008void UnwrappedLineParser::parsePPDirective() {
1009 assert(FormatTok->is(tok::hash) &&
"'#' expected");
1010 ScopedMacroState MacroState(*
Line, Tokens, FormatTok);
1014 if (!FormatTok->Tok.getIdentifierInfo()) {
1019 switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {
1020 case tok::pp_define:
1027 case tok::pp_ifndef:
1031 case tok::pp_elifdef:
1032 case tok::pp_elifndef:
1039 case tok::pp_pragma:
1043 case tok::pp_warning:
1045 if (!
eof() && Style.isCpp())
1046 FormatTok->setFinalizedType(TT_AfterPPDirective);
1054void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1055 size_t Line = CurrentLines->size();
1056 if (CurrentLines == &PreprocessorDirectives)
1057 Line += Lines.size();
1060 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1061 PPStack.push_back({PP_Unreachable,
Line});
1063 PPStack.push_back({PP_Conditional,
Line});
1067void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1069 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1070 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1071 PPLevelBranchIndex.push_back(0);
1072 PPLevelBranchCount.push_back(0);
1074 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1075 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1076 conditionalCompilationCondition(Unreachable ||
Skip);
1079void UnwrappedLineParser::conditionalCompilationAlternative() {
1080 if (!PPStack.empty())
1082 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1083 if (!PPChainBranchIndex.empty())
1084 ++PPChainBranchIndex.top();
1085 conditionalCompilationCondition(
1086 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1087 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1090void UnwrappedLineParser::conditionalCompilationEnd() {
1091 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1092 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1093 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1094 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1097 if (PPBranchLevel > -1)
1099 if (!PPChainBranchIndex.empty())
1100 PPChainBranchIndex.pop();
1101 if (!PPStack.empty())
1105void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1106 bool IfNDef = FormatTok->is(tok::pp_ifndef);
1108 bool Unreachable =
false;
1109 if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText ==
"0"))
1111 if (IfDef && !IfNDef && FormatTok->TokenText ==
"SWIG")
1113 conditionalCompilationStart(Unreachable);
1117 bool MaybeIncludeGuard = IfNDef;
1118 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1119 for (
auto &
Line : Lines) {
1120 if (
Line.Tokens.front().Tok->isNot(tok::comment)) {
1121 MaybeIncludeGuard =
false;
1122 IncludeGuard = IG_Rejected;
1130 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1131 IncludeGuard = IG_IfNdefed;
1132 IncludeGuardToken = IfCondition;
1136void UnwrappedLineParser::parsePPElse() {
1138 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1139 IncludeGuard = IG_Rejected;
1141 assert(PPBranchLevel >= -1);
1142 if (PPBranchLevel == -1)
1143 conditionalCompilationStart(
true);
1144 conditionalCompilationAlternative();
1150void UnwrappedLineParser::parsePPEndIf() {
1151 conditionalCompilationEnd();
1155void UnwrappedLineParser::parsePPDefine() {
1158 if (!FormatTok->Tok.getIdentifierInfo()) {
1159 IncludeGuard = IG_Rejected;
1160 IncludeGuardToken =
nullptr;
1165 bool MaybeIncludeGuard =
false;
1166 if (IncludeGuard == IG_IfNdefed &&
1167 IncludeGuardToken->TokenText == FormatTok->TokenText) {
1168 IncludeGuard = IG_Defined;
1169 IncludeGuardToken =
nullptr;
1170 for (
auto &
Line : Lines) {
1171 if (
Line.Tokens.front().Tok->isNoneOf(tok::comment, tok::hash)) {
1172 IncludeGuard = IG_Rejected;
1176 MaybeIncludeGuard = IncludeGuard == IG_Defined;
1184 FormatTok->Tok.setKind(tok::identifier);
1185 FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);
1189 if (MaybeIncludeGuard && !
eof())
1190 IncludeGuard = IG_Rejected;
1192 if (FormatTok->is(tok::l_paren) && !FormatTok->hasWhitespaceBefore())
1194 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
1195 Line->Level += PPBranchLevel + 1;
1199 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1200 assert((
int)
Line->PPLevel >= 0);
1205 Line->InMacroBody =
true;
1207 if (!Style.SkipMacroDefinitionBody) {
1217 for (
auto *Comment : CommentsBeforeNextToken)
1218 Comment->Finalized =
true;
1221 FormatTok->Finalized =
true;
1222 FormatTok = Tokens->getNextToken();
1228void UnwrappedLineParser::parsePPPragma() {
1229 Line->InPragmaDirective =
true;
1233void UnwrappedLineParser::parsePPUnknown() {
1236 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
1237 Line->Level += PPBranchLevel + 1;
1247 return Tok.isNoneOf(tok::semi, tok::l_brace,
1250 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1251 tok::less, tok::greater, tok::slash, tok::percent,
1252 tok::lessless, tok::greatergreater, tok::equal,
1253 tok::plusequal, tok::minusequal, tok::starequal,
1254 tok::slashequal, tok::percentequal, tok::ampequal,
1255 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1268 return FormatTok->
is(tok::identifier) &&
1283 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1294 tok::kw_if, tok::kw_else,
1296 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1298 tok::kw_switch, tok::kw_case,
1300 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1302 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1310 return Tok.isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1311 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1328 if (FuncName->
isNot(tok::identifier))
1336 Tok->isNoneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1340 if (
Next->isNot(tok::star) && !
Next->Tok.getIdentifierInfo())
1344 if (!
Tok ||
Tok->isNot(tok::r_paren))
1348 if (!
Tok ||
Tok->isNot(tok::identifier))
1351 return Tok->Previous &&
Tok->Previous->isOneOf(tok::l_paren, tok::comma);
1354bool UnwrappedLineParser::parseModuleDecl() {
1356 assert(FormatTok->is(Keywords.kw_module));
1358 if (Style.Language == FormatStyle::LK_C ||
1359 Style.Standard < FormatStyle::LS_Cpp20) {
1364 if (FormatTok->isNot(tok::identifier))
1367 for (nextToken(); FormatTok->isNoneOf(tok::semi, tok::eof); nextToken())
1368 if (FormatTok->is(tok::colon))
1369 FormatTok->setFinalizedType(TT_ModulePartitionColon);
1372 Line->IsModuleOrImportDecl =
true;
1377bool UnwrappedLineParser::parseImportDecl() {
1379 assert(FormatTok->is(Keywords.kw_import) &&
"'import' expected");
1381 if (Style.Language == FormatStyle::LK_C ||
1382 Style.Standard < FormatStyle::LS_Cpp20) {
1387 if (FormatTok->is(tok::colon)) {
1388 FormatTok->setFinalizedType(TT_ModulePartitionColon);
1391 if (FormatTok->isNoneOf(tok::identifier, tok::less, tok::string_literal))
1394 for (; FormatTok->isNoneOf(tok::semi, tok::eof); nextToken()) {
1396 if (FormatTok->is(tok::less)) {
1397 for (nextToken(); FormatTok->isNoneOf(tok::greater, tok::semi, tok::eof);
1401 FormatTok->setFinalizedType(TT_ImplicitStringLiteral);
1407 Line->IsModuleOrImportDecl =
true;
1419void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1425 CommentsBeforeNextToken.empty()
1426 ?
Next->NewlinesBefore == 0
1427 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1432 bool PreviousStartsTemplateExpr =
1434 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1437 bool HasAt = llvm::any_of(
Line->Tokens, [](UnwrappedLineNode &LineNode) {
1438 return LineNode.Tok->is(tok::at);
1443 if (
Next->is(tok::exclaim) && PreviousMustBeValue)
1444 return addUnwrappedLine();
1446 bool NextEndsTemplateExpr =
1447 Next->is(TT_TemplateString) &&
Next->TokenText.starts_with(
"}");
1448 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1449 (PreviousMustBeValue ||
1450 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1451 tok::minusminus))) {
1452 return addUnwrappedLine();
1454 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1456 return addUnwrappedLine();
1460void UnwrappedLineParser::parseStructuralElement(
1461 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1462 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1463 if (Style.isTableGen() && FormatTok->is(tok::pp_include)) {
1465 if (FormatTok->is(tok::string_literal))
1472 while (FormatTok->is(tok::l_square) && handleCppAttributes()) {
1474 }
else if (Style.isVerilog()) {
1476 while (FormatTok->is(tok::l_paren) &&
1477 Tokens->peekNextToken()->is(tok::star)) {
1480 skipVerilogQualifiers();
1482 if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
1483 Keywords.kw_unique0)) {
1487 if (Keywords.isVerilogStructuredProcedure(*FormatTok)) {
1488 parseForOrWhileLoop(
false);
1491 if (FormatTok->isOneOf(Keywords.kw_foreach, Keywords.kw_repeat)) {
1492 parseForOrWhileLoop();
1495 if (FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,
1496 Keywords.kw_assume, Keywords.kw_cover)) {
1497 parseIfThenElse(IfKind,
false,
true);
1503 if (FormatTok->isAccessSpecifierKeyword()) {
1504 if (Style.isJava() || Style.isJavaScript() || Style.isCSharp())
1507 parseAccessSpecifier();
1510 switch (FormatTok->Tok.getKind()) {
1513 if (FormatTok->is(tok::l_brace)) {
1514 FormatTok->setFinalizedType(TT_InlineASMBrace);
1516 while (FormatTok && !
eof()) {
1517 if (FormatTok->is(tok::r_brace)) {
1518 FormatTok->setFinalizedType(TT_InlineASMBrace);
1523 FormatTok->Finalized =
true;
1528 case tok::kw_namespace:
1532 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1543 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1547 parseForOrWhileLoop();
1550 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1558 case tok::kw_switch:
1559 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1565 case tok::kw_default: {
1567 if (Style.isVerilog())
1569 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1575 if (FormatTok->is(tok::colon)) {
1576 FormatTok->setFinalizedType(TT_CaseLabelColon);
1580 if (FormatTok->is(tok::arrow)) {
1581 FormatTok->setFinalizedType(TT_CaseLabelArrow);
1582 Default->setFinalizedType(TT_SwitchExpressionLabel);
1591 if (Style.Language == FormatStyle::LK_Proto) {
1595 if (Style.isVerilog()) {
1600 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1609 if (FormatTok->is(tok::kw_case))
1614 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1620 case tok::kw_extern:
1621 if (Style.isVerilog()) {
1624 parseVerilogExtern();
1628 if (FormatTok->is(tok::string_literal)) {
1630 if (FormatTok->is(tok::l_brace)) {
1631 if (Style.BraceWrapping.AfterExternBlock)
1635 unsigned AddLevels =
1636 (Style.IndentExternBlock == FormatStyle::IEBS_Indent) ||
1637 (Style.BraceWrapping.AfterExternBlock &&
1638 Style.IndentExternBlock ==
1639 FormatStyle::IEBS_AfterExternBlock)
1642 parseBlock(
true, AddLevels);
1648 case tok::kw_export:
1651 if (FormatTok->is(tok::kw_namespace)) {
1655 if (FormatTok->is(tok::l_brace)) {
1656 parseCppExportBlock();
1659 if (FormatTok->is(Keywords.kw_module) && parseModuleDecl())
1661 if (FormatTok->is(Keywords.kw_import) && parseImportDecl())
1665 if (Style.isJavaScript()) {
1666 parseJavaScriptEs6ImportExport();
1669 if (Style.isVerilog()) {
1670 parseVerilogExtern();
1674 case tok::kw_inline:
1676 if (FormatTok->is(tok::kw_namespace)) {
1681 case tok::identifier:
1682 if (FormatTok->is(TT_ForEachMacro)) {
1683 parseForOrWhileLoop();
1686 if (FormatTok->is(TT_MacroBlockBegin)) {
1687 parseBlock(
false, 1u,
1691 if (FormatTok->is(Keywords.kw_import)) {
1692 if (IsCpp && parseImportDecl())
1694 if (Style.isJavaScript()) {
1695 parseJavaScriptEs6ImportExport();
1698 if (Style.Language == FormatStyle::LK_Proto) {
1700 if (FormatTok->is(tok::kw_public))
1702 if (FormatTok->isNot(tok::string_literal))
1705 if (FormatTok->is(tok::semi))
1710 if (Style.isVerilog()) {
1711 parseVerilogExtern();
1716 if (FormatTok->is(Keywords.kw_module) && parseModuleDecl())
1718 if (FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
1719 Keywords.kw_slots, Keywords.kw_qslots)) {
1721 if (FormatTok->is(tok::colon)) {
1727 if (FormatTok->is(TT_StatementMacro)) {
1728 parseStatementMacro();
1731 if (FormatTok->is(TT_NamespaceMacro)) {
1740 if (!Style.isJavaScript() && !Style.isVerilog() && !Style.isTableGen() &&
1741 Tokens->peekNextToken()->is(tok::colon) && !
Line->MustBeDeclaration) {
1743 if (!
Line->InMacroBody || CurrentLines->size() > 1)
1744 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1745 FormatTok->setFinalizedType(TT_GotoLabelColon);
1746 parseLabel(Style.IndentGotoLabels);
1751 if (Style.isJava() && FormatTok->is(Keywords.kw_record)) {
1752 parseRecord(
false,
true);
1762 bool SeenEqual =
false;
1763 for (
const bool InRequiresExpression =
1764 OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
1765 TT_CompoundRequirementLBrace);
1768 switch (FormatTok->Tok.getKind()) {
1771 if (FormatTok->is(tok::l_brace)) {
1776 if (Style.isJava() && FormatTok->is(Keywords.kw_interface)) {
1780 switch (
bool IsAutoRelease =
false; FormatTok->Tok.getObjCKeywordID()) {
1781 case tok::objc_public:
1782 case tok::objc_protected:
1783 case tok::objc_package:
1784 case tok::objc_private:
1785 return parseAccessSpecifier();
1786 case tok::objc_interface:
1787 case tok::objc_implementation:
1788 return parseObjCInterfaceOrImplementation();
1789 case tok::objc_protocol:
1790 if (parseObjCProtocol())
1795 case tok::objc_optional:
1796 case tok::objc_required:
1800 case tok::objc_autoreleasepool:
1801 IsAutoRelease =
true;
1803 case tok::objc_synchronized:
1805 if (!IsAutoRelease && FormatTok->is(tok::l_paren)) {
1809 if (FormatTok->is(tok::l_brace)) {
1810 if (Style.BraceWrapping.AfterControlStatement ==
1811 FormatStyle::BWACS_Always) {
1827 case tok::kw_requires: {
1829 bool ParsedClause = parseRequires(SeenEqual);
1850 if (!IsCpp && !Style.isVerilog()) {
1855 case tok::kw_typedef:
1857 if (FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
1858 Keywords.kw_CF_ENUM, Keywords.kw_CF_OPTIONS,
1859 Keywords.kw_CF_CLOSED_ENUM,
1860 Keywords.kw_NS_CLOSED_ENUM)) {
1865 if (Style.isVerilog()) {
1870 if (Style.isTableGen()) {
1877 case tok::kw_struct:
1879 if (parseStructLike())
1882 case tok::kw_decltype:
1884 if (FormatTok->is(tok::l_paren)) {
1886 if (FormatTok->Previous &&
1887 FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,
1889 Line->SeenDecltypeAuto =
true;
1896 if (Style.isJava() && FormatTok && FormatTok->is(tok::kw_class))
1898 if (Style.isJavaScript() && FormatTok &&
1899 FormatTok->Tok.getIdentifierInfo()) {
1912 case tok::string_literal:
1913 if (Style.isVerilog() && FormatTok->is(TT_VerilogProtected)) {
1914 FormatTok->Finalized =
true;
1921 case tok::l_paren: {
1928 Tokens->peekNextToken(
true),
1935 case tok::kw_operator:
1937 if (FormatTok->isBinaryOperator())
1941 const auto *Prev = FormatTok->getPreviousNonComment();
1943 if (Prev && Prev->is(tok::identifier))
1946 if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName(LangOpts)) {
1949 while (FormatTok->is(tok::star))
1953 if (FormatTok->is(tok::l_paren))
1956 if (FormatTok->is(tok::l_brace))
1961 if (InRequiresExpression)
1962 FormatTok->setFinalizedType(TT_BracedListLBrace);
1963 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1964 IsDecltypeAutoFunction =
Line->SeenDecltypeAuto;
1969 if (Style.isJava() &&
1970 Line->Tokens.front().Tok->is(Keywords.kw_synchronized)) {
1973 if (Style.BraceWrapping.AfterControlStatement ==
1974 FormatStyle::BWACS_Always) {
1977 }
else if (Style.BraceWrapping.AfterFunction) {
1981 FormatTok->setFinalizedType(TT_FunctionLBrace);
1983 IsDecltypeAutoFunction =
false;
1991 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1997 if (Style.BraceWrapping.AfterFunction)
2001 case tok::identifier: {
2002 if (Style.isCSharp() && FormatTok->is(Keywords.kw_where) &&
2003 Line->MustBeDeclaration) {
2005 parseCSharpGenericTypeConstraint();
2008 if (FormatTok->is(TT_MacroBlockEnd)) {
2017 size_t TokenCount =
Line->Tokens.size();
2018 if (Style.isJavaScript() && FormatTok->is(Keywords.kw_function) &&
2021 Line->Tokens.front().Tok->isNot(Keywords.kw_async)))) {
2022 tryToParseJSFunction();
2025 if ((Style.isJavaScript() || Style.isJava()) &&
2026 FormatTok->is(Keywords.kw_interface)) {
2027 if (Style.isJavaScript()) {
2032 unsigned StoredPosition = Tokens->getPosition();
2034 FormatTok = Tokens->setPosition(StoredPosition);
2045 if (Style.isVerilog()) {
2046 if (FormatTok->is(Keywords.kw_table)) {
2047 parseVerilogTable();
2050 if (Keywords.isVerilogBegin(*FormatTok) ||
2051 Keywords.isVerilogHierarchy(*FormatTok)) {
2058 if (!IsCpp && FormatTok->is(Keywords.kw_interface)) {
2059 if (parseStructLike())
2064 if (IsCpp && FormatTok->is(TT_StatementMacro)) {
2065 parseStatementMacro();
2070 StringRef
Text = FormatTok->TokenText;
2077 if (Style.isJavaScript())
2080 auto OneTokenSoFar = [&]() {
2081 auto I =
Line->Tokens.begin(), E =
Line->Tokens.end();
2082 while (I != E && I->Tok->is(tok::comment))
2084 if (Style.isVerilog())
2085 while (I != E && I->Tok->is(tok::hash))
2087 return I != E && (++I == E);
2089 if (OneTokenSoFar()) {
2092 bool FunctionLike = FormatTok->is(tok::l_paren);
2096 bool FollowedByNewline =
2097 CommentsBeforeNextToken.empty()
2098 ? FormatTok->NewlinesBefore > 0
2099 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2101 if (FollowedByNewline &&
2102 (
Text.size() >= 5 ||
2103 (FunctionLike && FormatTok->isNot(tok::l_paren))) &&
2105 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2106 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2114 if ((Style.isJavaScript() || Style.isCSharp()) &&
2115 FormatTok->is(TT_FatArrow)) {
2116 tryToParseChildBlock();
2122 if (FormatTok->is(tok::l_brace)) {
2126 if (!Style.isJavaScript())
2127 FormatTok->setBlockKind(BK_BracedInit);
2130 if (Style.isTableGen() &&
2131 Line->Tokens.begin()->Tok->is(Keywords.kw_defset)) {
2132 FormatTok->setFinalizedType(TT_FunctionLBrace);
2133 parseBlock(
false, 1u,
2140 }
else if (Style.Language == FormatStyle::LK_Proto &&
2141 FormatTok->is(tok::less)) {
2143 parseBracedList(
true);
2150 if (Style.isCSharp() &&
2151 (Tokens->peekNextToken()->isAccessSpecifierKeyword() ||
2158 case tok::kw_switch:
2166 if (Style.Language == FormatStyle::LK_Proto) {
2171 if (Style.isVerilog()) {
2176 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
2183 case tok::kw_default:
2185 if (Style.isVerilog()) {
2186 if (FormatTok->is(tok::colon)) {
2190 if (FormatTok->is(Keywords.kw_clocking)) {
2196 parseVerilogCaseLabel();
2202 if (Style.isVerilog()) {
2203 parseVerilogCaseLabel();
2209 if (FormatTok->is(tok::l_brace))
2210 FormatTok->Previous->setFinalizedType(TT_TemplateCloser);
2219bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2220 assert(FormatTok->is(tok::l_brace));
2221 if (!Style.isCSharp())
2224 if (!FormatTok->Previous || FormatTok->Previous->isNot(tok::identifier))
2232 unsigned int StoredPosition = Tokens->getPosition();
2238 bool HasSpecialAccessor =
false;
2239 bool IsTrivialPropertyAccessor =
true;
2242 if (
const bool IsAccessorKeyword =
2243 Tok->
isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set);
2244 IsAccessorKeyword ||
Tok->isAccessSpecifierKeyword() ||
2245 Tok->
isOneOf(tok::l_square, tok::semi, Keywords.kw_internal)) {
2246 if (IsAccessorKeyword)
2247 HasSpecialAccessor =
true;
2248 else if (
Tok->
is(tok::l_square))
2250 Tok = Tokens->getNextToken();
2254 IsTrivialPropertyAccessor =
false;
2259 Tokens->setPosition(StoredPosition);
2265 Tokens->setPosition(StoredPosition);
2266 if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction)
2270 switch (FormatTok->Tok.getKind()) {
2273 if (FormatTok->is(tok::equal)) {
2274 while (!
eof() && FormatTok->isNot(tok::semi))
2287 if (FormatTok->is(TT_FatArrow)) {
2291 }
while (!
eof() && FormatTok->isNot(tok::semi));
2300 if (FormatTok->isOneOf(Keywords.kw_get, Keywords.kw_init,
2302 !IsTrivialPropertyAccessor) {
2314bool UnwrappedLineParser::tryToParseLambda() {
2315 assert(FormatTok->is(tok::l_square));
2321 if (!tryToParseLambdaIntroducer())
2325 bool InTemplateParameterList =
false;
2327 while (FormatTok->isNot(tok::l_brace)) {
2328 if (FormatTok->isTypeName(LangOpts) || FormatTok->isAttribute()) {
2332 switch (FormatTok->Tok.getKind()) {
2336 parseParens(TT_PointerOrReference);
2342 assert(FormatTok->Previous);
2343 if (FormatTok->Previous->is(tok::r_square))
2344 InTemplateParameterList =
true;
2349 case tok::kw_struct:
2351 case tok::kw_template:
2352 case tok::kw_typename:
2356 case tok::kw_constexpr:
2357 case tok::kw_consteval:
2360 case tok::identifier:
2361 case tok::numeric_constant:
2362 case tok::coloncolon:
2363 case tok::kw_mutable:
2364 case tok::kw_noexcept:
2365 case tok::kw_static:
2390 case tok::equalequal:
2391 case tok::exclaimequal:
2392 case tok::greaterequal:
2393 case tok::lessequal:
2399 if (Arrow || InTemplateParameterList) {
2408 case tok::kw_requires:
2409 parseRequiresClause();
2412 if (!InTemplateParameterList)
2421 FormatTok->setFinalizedType(TT_LambdaLBrace);
2422 LSquare.setFinalizedType(TT_LambdaLSquare);
2425 Arrow->setFinalizedType(TT_LambdaArrow);
2427 NestedLambdas.push_back(
Line->SeenDecltypeAuto);
2429 assert(!NestedLambdas.empty());
2430 NestedLambdas.pop_back();
2435bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2440 const auto *PrevPrev =
Previous->getPreviousNonComment();
2441 if (
Previous->is(tok::star) && PrevPrev && PrevPrev->isTypeName(LangOpts))
2449 if (!PrevPrev || PrevPrev->isNoneOf(tok::greater, tok::r_paren))
2453 Previous->isNoneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
2454 tok::kw_co_return)) {
2458 if (LeftSquare->isCppStructuredBinding(IsCpp))
2460 if (FormatTok->is(tok::l_square) ||
tok::isLiteral(FormatTok->Tok.getKind()))
2462 if (FormatTok->is(tok::r_square)) {
2464 if (
Next->is(tok::greater))
2471void UnwrappedLineParser::tryToParseJSFunction() {
2472 assert(FormatTok->is(Keywords.kw_function));
2473 if (FormatTok->is(Keywords.kw_async))
2479 if (FormatTok->is(tok::star)) {
2480 FormatTok->setFinalizedType(TT_OverloadedOperator);
2485 if (FormatTok->is(tok::identifier))
2488 if (FormatTok->isNot(tok::l_paren))
2494 if (FormatTok->is(tok::colon)) {
2500 if (FormatTok->is(tok::l_brace))
2501 tryToParseBracedList();
2503 while (FormatTok->isNoneOf(tok::l_brace, tok::semi) && !
eof())
2507 if (FormatTok->is(tok::semi))
2513bool UnwrappedLineParser::tryToParseBracedList() {
2514 if (FormatTok->is(BK_Unknown))
2515 calculateBraceTypes();
2516 assert(FormatTok->isNot(BK_Unknown));
2517 if (FormatTok->is(BK_Block))
2524bool UnwrappedLineParser::tryToParseChildBlock() {
2525 assert(Style.isJavaScript() || Style.isCSharp());
2526 assert(FormatTok->is(TT_FatArrow));
2531 if (FormatTok->isNot(tok::l_brace))
2537bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2538 assert(!IsAngleBracket || !IsEnum);
2539 bool HasError =
false;
2544 if (Style.isCSharp() && FormatTok->is(TT_FatArrow) &&
2545 tryToParseChildBlock()) {
2548 if (Style.isJavaScript()) {
2549 if (FormatTok->is(Keywords.kw_function)) {
2550 tryToParseJSFunction();
2553 if (FormatTok->is(tok::l_brace)) {
2555 if (tryToParseBracedList())
2560 if (FormatTok->is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2562 FormatTok->setBlockKind(BK_Block);
2563 if (!Style.AllowShortEnumsOnASingleLine)
2569 switch (FormatTok->Tok.getKind()) {
2571 if (Style.isCSharp())
2580 if (Style.isJavaScript()) {
2581 if (FormatTok->is(tok::l_brace))
2589 FormatTok->setBlockKind(BK_BracedInit);
2590 if (!IsAngleBracket) {
2591 auto *Prev = FormatTok->Previous;
2592 if (Prev && Prev->is(tok::greater))
2593 Prev->setFinalizedType(TT_TemplateCloser);
2601 parseBracedList(
true);
2608 if (Style.isJavaScript()) {
2619 if (IsEnum && !Style.AllowShortEnumsOnASingleLine)
2622 case tok::kw_requires:
2623 parseRequiresExpression();
2639bool UnwrappedLineParser::parseParens(TokenType StarAndAmpTokenType,
2641 assert(FormatTok->is(tok::l_paren) &&
"'(' expected.");
2642 auto *LParen = FormatTok;
2643 auto *Prev = FormatTok->Previous;
2644 bool SeenComma =
false;
2645 bool SeenEqual =
false;
2646 bool MightBeFoldExpr =
false;
2648 const bool MightBeStmtExpr = FormatTok->is(tok::l_brace);
2649 if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro))
2652 switch (FormatTok->Tok.getKind()) {
2654 if (parseParens(StarAndAmpTokenType, InMacroCall))
2656 if (Style.isJava() && FormatTok->is(tok::l_brace))
2659 case tok::r_paren: {
2660 auto *RParen = FormatTok;
2663 auto OptionalParens = [&] {
2664 if (Style.RemoveParentheses == FormatStyle::RPS_Leave ||
2665 MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall ||
2666 Line->InMacroBody || RParen->getPreviousNonComment() == LParen) {
2669 const bool DoubleParens =
2670 Prev->is(tok::l_paren) && FormatTok->is(tok::r_paren);
2672 const auto *PrevPrev = Prev->getPreviousNonComment();
2673 const bool Excluded =
2675 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2677 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2678 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2682 const bool CommaSeparated =
2683 Prev->isOneOf(tok::l_paren, tok::comma) &&
2684 FormatTok->isOneOf(tok::comma, tok::r_paren);
2685 if (CommaSeparated &&
2687 !Prev->endsSequence(tok::comma, tok::ellipsis) &&
2689 !(FormatTok->is(tok::comma) &&
2690 Tokens->peekNextToken()->is(tok::ellipsis))) {
2693 const bool ReturnParens =
2694 Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&
2695 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2696 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2697 Prev->isOneOf(tok::kw_return, tok::kw_co_return) &&
2698 FormatTok->is(tok::semi);
2704 if (OptionalParens()) {
2705 LParen->Optional =
true;
2706 RParen->Optional =
true;
2707 }
else if (Prev->is(TT_TypenameMacro)) {
2708 LParen->setFinalizedType(TT_TypeDeclarationParen);
2709 RParen->setFinalizedType(TT_TypeDeclarationParen);
2710 }
else if (Prev->is(tok::greater) && RParen->Previous == LParen) {
2711 Prev->setFinalizedType(TT_TemplateCloser);
2712 }
else if (FormatTok->is(tok::l_brace) && Prev->is(tok::amp) &&
2714 FormatTok->setBlockKind(BK_BracedInit);
2726 if (!tryToParseBracedList())
2731 if (FormatTok->is(tok::l_brace)) {
2741 MightBeFoldExpr =
true;
2746 if (Style.isCSharp() && FormatTok->is(TT_FatArrow))
2747 tryToParseChildBlock();
2752 if (Style.isJavaScript())
2757 case tok::identifier:
2758 if (Style.isJavaScript() && (FormatTok->is(Keywords.kw_function)))
2759 tryToParseJSFunction();
2763 case tok::kw_switch:
2769 case tok::kw_requires:
2770 parseRequiresExpression();
2775 if (StarAndAmpTokenType != TT_Unknown)
2776 FormatTok->setFinalizedType(StarAndAmpTokenType);
2788 assert(FormatTok->is(tok::l_square) &&
"'[' expected.");
2789 if (tryToParseLambda())
2793 switch (FormatTok->Tok.getKind()) {
2806 case tok::l_brace: {
2807 if (!tryToParseBracedList())
2814 if (FormatTok->is(tok::l_brace)) {
2826void UnwrappedLineParser::keepAncestorBraces() {
2827 if (!Style.RemoveBracesLLVM)
2830 const int MaxNestingLevels = 2;
2831 const int Size = NestedTooDeep.size();
2832 if (Size >= MaxNestingLevels)
2833 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2834 NestedTooDeep.push_back(
false);
2838 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2845void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2848 if (Style.InsertBraces && !
Line->InPPDirective && !
Line->Tokens.empty() &&
2849 PreprocessorDirectives.empty() && FormatTok->isNot(tok::semi)) {
2850 Tok = Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Never
2851 ? getLastNonComment(*
Line)
2854 if (
Tok->BraceCount < 0) {
2855 assert(
Tok->BraceCount == -1);
2858 Tok->BraceCount = -1;
2864 ++
Line->UnbracedBodyLevel;
2865 parseStructuralElement();
2866 --
Line->UnbracedBodyLevel;
2869 assert(!
Line->InPPDirective);
2871 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2873 Tok = L.Tokens.back().Tok;
2881 if (CheckEOF &&
eof())
2891 assert(LeftBrace->
is(tok::l_brace));
2899 assert(RightBrace->
is(tok::r_brace));
2907void UnwrappedLineParser::handleAttributes() {
2909 if (FormatTok->isAttribute())
2911 else if (FormatTok->is(tok::l_square))
2912 handleCppAttributes();
2915bool UnwrappedLineParser::handleCppAttributes() {
2917 assert(FormatTok->is(tok::l_square));
2918 if (!tryToParseSimpleAttribute())
2925bool UnwrappedLineParser::isBlockBegin(
const FormatToken &
Tok)
const {
2928 return Style.isVerilog() ? Keywords.isVerilogBegin(
Tok)
2929 :
Tok.
is(tok::l_brace);
2932FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2934 bool IsVerilogAssert) {
2935 assert((FormatTok->is(tok::kw_if) ||
2936 (Style.isVerilog() &&
2937 FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,
2938 Keywords.kw_assume, Keywords.kw_cover))) &&
2942 if (IsVerilogAssert) {
2944 if (FormatTok->is(Keywords.kw_verilogHash)) {
2946 if (FormatTok->is(tok::numeric_constant))
2948 }
else if (FormatTok->isOneOf(Keywords.kw_final, Keywords.kw_property,
2949 Keywords.kw_sequence)) {
2955 if (Style.isTableGen()) {
2956 while (!
eof() && FormatTok->isNot(Keywords.kw_then)) {
2963 if (FormatTok->is(tok::exclaim))
2966 bool KeepIfBraces =
true;
2967 if (FormatTok->is(tok::kw_consteval)) {
2970 KeepIfBraces = !Style.RemoveBracesLLVM || KeepBraces;
2971 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
2973 if (FormatTok->is(tok::l_paren)) {
2974 FormatTok->setFinalizedType(TT_ConditionLParen);
2980 if (IsVerilogAssert && FormatTok->is(tok::semi)) {
2986 bool NeedsUnwrappedLine =
false;
2987 keepAncestorBraces();
2990 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2992 if (isBlockBegin(*FormatTok)) {
2993 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
2994 IfLeftBrace = FormatTok;
2995 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
2996 parseBlock(
false, 1u,
2997 true, KeepIfBraces, &IfBlockKind);
2998 setPreviousRBraceType(TT_ControlStatementRBrace);
2999 if (Style.BraceWrapping.BeforeElse)
3002 NeedsUnwrappedLine =
true;
3003 }
else if (IsVerilogAssert && FormatTok->is(tok::kw_else)) {
3006 parseUnbracedBody();
3009 if (Style.RemoveBracesLLVM) {
3010 assert(!NestedTooDeep.empty());
3011 KeepIfBraces = KeepIfBraces ||
3012 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
3013 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
3014 IfBlockKind == IfStmtKind::IfElseIf;
3017 bool KeepElseBraces = KeepIfBraces;
3019 IfStmtKind
Kind = IfStmtKind::IfOnly;
3021 if (FormatTok->is(tok::kw_else)) {
3022 if (Style.RemoveBracesLLVM) {
3023 NestedTooDeep.back() =
false;
3024 Kind = IfStmtKind::IfElse;
3028 if (isBlockBegin(*FormatTok)) {
3029 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
3030 FormatTok->setFinalizedType(TT_ElseLBrace);
3031 ElseLeftBrace = FormatTok;
3032 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3033 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
3035 parseBlock(
false, 1u,
3036 true, KeepElseBraces, &ElseBlockKind);
3037 setPreviousRBraceType(TT_ElseRBrace);
3038 if (FormatTok->is(tok::kw_else)) {
3039 KeepElseBraces = KeepElseBraces ||
3040 ElseBlockKind == IfStmtKind::IfOnly ||
3041 ElseBlockKind == IfStmtKind::IfElseIf;
3042 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
3043 KeepElseBraces =
true;
3044 assert(ElseLeftBrace->MatchingParen);
3048 }
else if (!IsVerilogAssert && FormatTok->is(tok::kw_if)) {
3051 const bool IsPrecededByComment =
Previous->is(tok::comment);
3052 if (IsPrecededByComment) {
3056 bool TooDeep =
true;
3057 if (Style.RemoveBracesLLVM) {
3058 Kind = IfStmtKind::IfElseIf;
3059 TooDeep = NestedTooDeep.pop_back_val();
3061 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
3062 if (Style.RemoveBracesLLVM)
3063 NestedTooDeep.push_back(TooDeep);
3064 if (IsPrecededByComment)
3067 parseUnbracedBody(
true);
3070 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
3071 if (NeedsUnwrappedLine)
3075 if (!Style.RemoveBracesLLVM)
3078 assert(!NestedTooDeep.empty());
3079 KeepElseBraces = KeepElseBraces ||
3080 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
3081 NestedTooDeep.back();
3083 NestedTooDeep.pop_back();
3085 if (!KeepIfBraces && !KeepElseBraces) {
3088 }
else if (IfLeftBrace) {
3089 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
3091 assert(IfRightBrace->MatchingParen == IfLeftBrace);
3092 assert(!IfLeftBrace->Optional);
3093 assert(!IfRightBrace->Optional);
3094 IfLeftBrace->MatchingParen =
nullptr;
3095 IfRightBrace->MatchingParen =
nullptr;
3105void UnwrappedLineParser::parseTryCatch() {
3106 assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
3108 bool NeedsUnwrappedLine =
false;
3109 bool HasCtorInitializer =
false;
3110 if (FormatTok->is(tok::colon)) {
3111 auto *Colon = FormatTok;
3114 if (FormatTok->is(tok::identifier)) {
3115 HasCtorInitializer =
true;
3116 Colon->setFinalizedType(TT_CtorInitializerColon);
3121 while (FormatTok->is(tok::comma))
3124 while (FormatTok->is(tok::identifier)) {
3126 if (FormatTok->is(tok::l_paren)) {
3128 }
else if (FormatTok->is(tok::l_brace)) {
3135 while (FormatTok->is(tok::comma))
3140 if (Style.isJava() && FormatTok->is(tok::l_paren))
3143 keepAncestorBraces();
3145 if (FormatTok->is(tok::l_brace)) {
3146 if (HasCtorInitializer)
3147 FormatTok->setFinalizedType(TT_FunctionLBrace);
3148 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3150 if (Style.BraceWrapping.BeforeCatch)
3153 NeedsUnwrappedLine =
true;
3154 }
else if (FormatTok->isNot(tok::kw_catch)) {
3160 parseStructuralElement();
3163 for (
bool SeenCatch =
false;;) {
3164 if (FormatTok->is(tok::at))
3166 if (FormatTok->isNoneOf(tok::kw_catch, Keywords.kw___except,
3167 tok::kw___finally, tok::objc_catch,
3168 tok::objc_finally) &&
3169 !((Style.isJava() || Style.isJavaScript()) &&
3170 FormatTok->is(Keywords.kw_finally))) {
3173 if (FormatTok->is(tok::kw_catch))
3176 while (FormatTok->isNot(tok::l_brace)) {
3177 if (FormatTok->is(tok::l_paren)) {
3181 if (FormatTok->isOneOf(tok::semi, tok::r_brace) ||
eof()) {
3182 if (Style.RemoveBracesLLVM)
3183 NestedTooDeep.pop_back();
3189 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3192 NeedsUnwrappedLine =
false;
3193 Line->MustBeDeclaration =
false;
3194 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3196 if (Style.BraceWrapping.BeforeCatch)
3199 NeedsUnwrappedLine =
true;
3202 if (Style.RemoveBracesLLVM)
3203 NestedTooDeep.pop_back();
3205 if (NeedsUnwrappedLine)
3209void UnwrappedLineParser::parseNamespaceOrExportBlock(
unsigned AddLevels) {
3210 bool ManageWhitesmithsBraces =
3211 AddLevels == 0u && Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
3215 if (ManageWhitesmithsBraces)
3220 parseBlock(
true, AddLevels,
true,
3221 true,
nullptr, ManageWhitesmithsBraces);
3223 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3225 if (ManageWhitesmithsBraces)
3229void UnwrappedLineParser::parseNamespace() {
3230 assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3231 "'namespace' expected");
3235 if (InitialToken.is(TT_NamespaceMacro)) {
3238 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3239 tok::l_square, tok::period, tok::l_paren) ||
3240 (Style.isCSharp() && FormatTok->is(tok::kw_union))) {
3241 if (FormatTok->is(tok::l_square))
3243 else if (FormatTok->is(tok::l_paren))
3249 if (FormatTok->is(tok::l_brace)) {
3250 FormatTok->setFinalizedType(TT_NamespaceLBrace);
3253 Tokens->peekNextToken()->is(tok::r_brace))) {
3257 unsigned AddLevels =
3258 Style.NamespaceIndentation == FormatStyle::NI_All ||
3259 (Style.NamespaceIndentation == FormatStyle::NI_Inner &&
3260 DeclarationScopeStack.size() > 1)
3263 parseNamespaceOrExportBlock(AddLevels);
3268void UnwrappedLineParser::parseCppExportBlock() {
3269 parseNamespaceOrExportBlock(Style.IndentExportBlock ? 1 : 0);
3272void UnwrappedLineParser::parseNew() {
3273 assert(FormatTok->is(tok::kw_new) &&
"'new' expected");
3276 if (Style.isCSharp()) {
3279 if (FormatTok->is(tok::l_paren))
3283 if (FormatTok->is(tok::l_brace))
3286 if (FormatTok->isOneOf(tok::semi, tok::comma))
3293 if (!Style.isJava())
3299 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3303 if (FormatTok->is(tok::l_paren)) {
3307 if (FormatTok->is(tok::l_brace))
3315void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3316 keepAncestorBraces();
3318 if (isBlockBegin(*FormatTok)) {
3319 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3321 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3322 parseBlock(
false, 1u,
3324 setPreviousRBraceType(TT_ControlStatementRBrace);
3326 assert(!NestedTooDeep.empty());
3327 if (!NestedTooDeep.back())
3333 parseUnbracedBody();
3337 NestedTooDeep.pop_back();
3340void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3341 assert((FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3342 (Style.isVerilog() &&
3343 FormatTok->isOneOf(Keywords.kw_always, Keywords.kw_always_comb,
3344 Keywords.kw_always_ff, Keywords.kw_always_latch,
3345 Keywords.kw_final, Keywords.kw_initial,
3346 Keywords.kw_foreach, Keywords.kw_forever,
3347 Keywords.kw_repeat))) &&
3348 "'for', 'while' or foreach macro expected");
3349 const bool KeepBraces = !Style.RemoveBracesLLVM ||
3350 FormatTok->isNoneOf(tok::kw_for, tok::kw_while);
3354 if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
3356 if (IsCpp && FormatTok->is(tok::kw_co_await))
3358 if (HasParens && FormatTok->is(tok::l_paren)) {
3362 if (Style.isVerilog())
3363 FormatTok->setFinalizedType(TT_ConditionLParen);
3367 if (Style.isVerilog()) {
3369 parseVerilogSensitivityList();
3370 }
else if (Style.AllowShortLoopsOnASingleLine && FormatTok->is(tok::semi) &&
3371 Tokens->getPreviousToken()->is(tok::r_paren)) {
3378 parseLoopBody(KeepBraces,
true);
3381void UnwrappedLineParser::parseDoWhile() {
3382 assert(FormatTok->is(tok::kw_do) &&
"'do' expected");
3385 parseLoopBody(
true, Style.BraceWrapping.BeforeWhile);
3388 if (FormatTok->isNot(tok::kw_while)) {
3393 FormatTok->setFinalizedType(TT_DoWhile);
3397 if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths)
3401 parseStructuralElement();
3404void UnwrappedLineParser::parseLabel(
3405 FormatStyle::IndentGotoLabelStyle IndentGotoLabels) {
3406 const bool IsGotoLabel = FormatTok->is(TT_GotoLabelColon);
3408 unsigned OldLineLevel =
Line->Level;
3410 switch (IndentGotoLabels) {
3411 case FormatStyle::IGLS_NoIndent:
3414 case FormatStyle::IGLS_OuterIndent:
3415 if (
Line->Level > 1 || (!
Line->InPPDirective &&
Line->Level > 0))
3418 case FormatStyle::IGLS_HalfIndent:
3419 case FormatStyle::IGLS_InnerIndent:
3423 if (!IsGotoLabel && !Style.IndentCaseBlocks &&
3424 CommentsBeforeNextToken.empty() && FormatTok->is(tok::l_brace)) {
3425 CompoundStatementIndenter Indenter(
this,
Line->Level,
3426 Style.BraceWrapping.AfterCaseLabel,
3427 Style.BraceWrapping.IndentBraces);
3429 if (FormatTok->is(tok::kw_break)) {
3430 if (Style.BraceWrapping.AfterControlStatement ==
3431 FormatStyle::BWACS_Always) {
3433 if (!Style.IndentCaseBlocks &&
3434 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {
3438 parseStructuralElement();
3442 if (FormatTok->is(tok::semi))
3446 Line->Level = OldLineLevel;
3447 if (FormatTok->isNot(tok::l_brace)) {
3448 parseStructuralElement();
3453void UnwrappedLineParser::parseCaseLabel() {
3454 assert(FormatTok->is(tok::kw_case) &&
"'case' expected");
3455 auto *Case = FormatTok;
3460 if (FormatTok->is(tok::colon)) {
3461 FormatTok->setFinalizedType(TT_CaseLabelColon);
3464 if (Style.isJava() && FormatTok->is(tok::arrow)) {
3465 FormatTok->setFinalizedType(TT_CaseLabelArrow);
3466 Case->setFinalizedType(TT_SwitchExpressionLabel);
3473void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3474 assert(FormatTok->is(tok::kw_switch) &&
"'switch' expected");
3476 if (FormatTok->is(tok::l_paren))
3479 keepAncestorBraces();
3481 if (FormatTok->is(tok::l_brace)) {
3482 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3483 FormatTok->setFinalizedType(IsExpr ? TT_SwitchExpressionLBrace
3484 : TT_ControlStatementLBrace);
3489 setPreviousRBraceType(TT_ControlStatementRBrace);
3495 parseStructuralElement();
3499 if (Style.RemoveBracesLLVM)
3500 NestedTooDeep.pop_back();
3503void UnwrappedLineParser::parseAccessSpecifier() {
3506 if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
3509 if (FormatTok->is(tok::colon))
3517bool UnwrappedLineParser::parseRequires(
bool SeenEqual) {
3518 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3522 switch (Tokens->peekNextToken(
true)->Tok.getKind()) {
3525 parseRequiresExpression();
3532 parseRequiresClause();
3543 auto *PreviousNonComment = FormatTok->getPreviousNonComment();
3545 if (!PreviousNonComment ||
3546 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3549 parseRequiresClause();
3553 switch (PreviousNonComment->Tok.getKind()) {
3556 case tok::kw_noexcept:
3561 parseRequiresClause();
3570 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3571 if ((PrevPrev && PrevPrev->is(tok::kw_const)) || !SeenEqual) {
3572 parseRequiresClause();
3578 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3580 parseRequiresClause();
3584 parseRequiresExpression();
3594 unsigned StoredPosition = Tokens->getPosition();
3597 auto PeekNext = [&Lookahead, &NextToken,
this] {
3599 NextToken = Tokens->getNextToken();
3602 bool FoundType =
false;
3603 bool LastWasColonColon =
false;
3606 for (; Lookahead < 50; PeekNext()) {
3607 switch (NextToken->Tok.getKind()) {
3608 case tok::kw_volatile:
3611 if (OpenAngles == 0) {
3612 FormatTok = Tokens->setPosition(StoredPosition);
3613 parseRequiresExpression();
3621 case tok::coloncolon:
3622 LastWasColonColon =
true;
3624 case tok::kw_decltype:
3625 case tok::identifier:
3626 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3627 FormatTok = Tokens->setPosition(StoredPosition);
3628 parseRequiresExpression();
3632 LastWasColonColon =
false;
3641 if (NextToken->isTypeName(LangOpts)) {
3642 FormatTok = Tokens->setPosition(StoredPosition);
3643 parseRequiresExpression();
3650 FormatTok = Tokens->setPosition(StoredPosition);
3651 parseRequiresClause();
3660void UnwrappedLineParser::parseRequiresClause() {
3661 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3666 bool InRequiresExpression =
3667 !FormatTok->Previous ||
3668 FormatTok->Previous->is(TT_RequiresExpressionLBrace);
3670 FormatTok->setFinalizedType(InRequiresExpression
3671 ? TT_RequiresClauseInARequiresExpression
3672 : TT_RequiresClause);
3677 parseConstraintExpression();
3679 if (!InRequiresExpression && FormatTok->Previous)
3680 FormatTok->Previous->ClosesRequiresClause =
true;
3688void UnwrappedLineParser::parseRequiresExpression() {
3689 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3691 FormatTok->setFinalizedType(TT_RequiresExpression);
3694 if (FormatTok->is(tok::l_paren)) {
3695 FormatTok->setFinalizedType(TT_RequiresExpressionLParen);
3699 if (FormatTok->is(tok::l_brace)) {
3700 FormatTok->setFinalizedType(TT_RequiresExpressionLBrace);
3709void UnwrappedLineParser::parseConstraintExpression() {
3716 bool LambdaNextTimeAllowed =
true;
3726 bool TopLevelParensAllowed =
true;
3729 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3731 switch (FormatTok->Tok.getKind()) {
3732 case tok::kw_requires:
3733 parseRequiresExpression();
3737 if (!TopLevelParensAllowed)
3739 parseParens(TT_BinaryOperator);
3740 TopLevelParensAllowed =
false;
3744 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3751 case tok::kw_struct:
3761 FormatTok->setFinalizedType(TT_BinaryOperator);
3763 LambdaNextTimeAllowed =
true;
3764 TopLevelParensAllowed =
true;
3769 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3773 case tok::kw_sizeof:
3775 case tok::greaterequal:
3776 case tok::greatergreater:
3778 case tok::lessequal:
3780 case tok::equalequal:
3782 case tok::exclaimequal:
3787 LambdaNextTimeAllowed =
true;
3788 TopLevelParensAllowed =
true;
3793 case tok::numeric_constant:
3794 case tok::coloncolon:
3797 TopLevelParensAllowed =
false;
3802 case tok::kw_static_cast:
3803 case tok::kw_const_cast:
3804 case tok::kw_reinterpret_cast:
3805 case tok::kw_dynamic_cast:
3807 if (FormatTok->isNot(tok::less))
3811 parseBracedList(
true);
3815 if (!FormatTok->Tok.getIdentifierInfo()) {
3825 assert(FormatTok->Previous);
3826 switch (FormatTok->Previous->Tok.getKind()) {
3827 case tok::coloncolon:
3831 case tok::kw_requires:
3840 if (FormatTok->is(tok::less)) {
3842 parseBracedList(
true);
3844 TopLevelParensAllowed =
false;
3850bool UnwrappedLineParser::parseEnum() {
3854 if (FormatTok->is(tok::kw_enum))
3860 if (Style.isJavaScript() && FormatTok->isOneOf(tok::colon, tok::question))
3864 if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))
3869 if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))
3871 while (FormatTok->is(tok::l_square))
3872 if (!handleCppAttributes())
3876 while (FormatTok->Tok.getIdentifierInfo() ||
3877 FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
3878 tok::greater, tok::comma, tok::question,
3880 if (FormatTok->is(tok::colon))
3881 FormatTok->setFinalizedType(TT_EnumUnderlyingTypeColon);
3882 if (Style.isVerilog()) {
3883 FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);
3886 while (FormatTok->is(tok::l_square))
3892 if (FormatTok->is(tok::l_paren))
3894 if (FormatTok->is(tok::identifier)) {
3898 if (IsCpp && FormatTok->is(tok::identifier))
3904 if (FormatTok->isNot(tok::l_brace))
3906 FormatTok->setFinalizedType(TT_EnumLBrace);
3907 FormatTok->setBlockKind(BK_Block);
3909 if (Style.isJava()) {
3911 parseJavaEnumBody();
3914 if (Style.Language == FormatStyle::LK_Proto) {
3919 const bool ManageWhitesmithsBraces =
3920 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
3922 if (!Style.AllowShortEnumsOnASingleLine &&
3924 Tokens->peekNextToken()->is(tok::r_brace))) {
3929 if (ManageWhitesmithsBraces)
3934 if (!Style.AllowShortEnumsOnASingleLine) {
3936 if (!ManageWhitesmithsBraces)
3939 const auto OpeningLineIndex = CurrentLines->empty()
3940 ? UnwrappedLine::kInvalidIndex
3941 : CurrentLines->size() - 1;
3942 bool HasError = !parseBracedList(
false,
true);
3943 if (!Style.AllowShortEnumsOnASingleLine && !ManageWhitesmithsBraces)
3946 if (FormatTok->is(tok::semi))
3950 setPreviousRBraceType(TT_EnumRBrace);
3951 if (ManageWhitesmithsBraces)
3952 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
3960bool UnwrappedLineParser::parseStructLike() {
3965 if (Style.isJava() || Style.isJavaScript() || Style.isCSharp()) {
3966 if (FormatTok->is(tok::semi))
3977class ScopedTokenPosition {
3978 unsigned StoredPosition;
3979 FormatTokenSource *Tokens;
3982 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3983 assert(Tokens &&
"Tokens expected to not be null");
3984 StoredPosition = Tokens->getPosition();
3987 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3993bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3994 ScopedTokenPosition AutoPosition(Tokens);
4002 if (
Tok->
is(tok::r_square))
4004 Tok = Tokens->getNextToken();
4006 if (
Tok->
is(tok::eof))
4008 Tok = Tokens->getNextToken();
4011 Tok = Tokens->getNextToken();
4012 if (
Tok->
is(tok::semi))
4017void UnwrappedLineParser::parseJavaEnumBody() {
4018 assert(FormatTok->is(tok::l_brace));
4024 unsigned StoredPosition = Tokens->getPosition();
4025 bool IsSimple =
true;
4028 if (
Tok->
is(tok::r_brace))
4036 Tok = Tokens->getNextToken();
4038 FormatTok = Tokens->setPosition(StoredPosition);
4055 if (FormatTok->is(tok::l_brace)) {
4057 parseBlock(
true, 1u,
4059 }
else if (FormatTok->is(tok::l_paren)) {
4061 }
else if (FormatTok->is(tok::comma)) {
4064 }
else if (FormatTok->is(tok::semi)) {
4068 }
else if (FormatTok->is(tok::r_brace)) {
4077 parseLevel(OpeningBrace);
4083void UnwrappedLineParser::parseRecord(
bool ParseAsExpr,
bool IsJavaRecord) {
4084 assert(!IsJavaRecord || FormatTok->is(Keywords.kw_record));
4089 IsJavaRecord && FormatTok->is(tok::identifier) ? FormatTok :
nullptr;
4090 bool IsDerived =
false;
4092 return Tok->
is(tok::identifier) &&
Tok->TokenText !=
Tok->TokenText.upper();
4096 bool JSPastExtendsOrImplements =
false;
4100 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
4101 tok::kw_alignas, tok::l_square) ||
4102 FormatTok->isAttribute() ||
4103 ((Style.isJava() || Style.isJavaScript()) &&
4104 FormatTok->isOneOf(tok::period, tok::comma))) {
4105 if (Style.isJavaScript() &&
4106 FormatTok->isOneOf(Keywords.kw_extends, Keywords.kw_implements)) {
4107 JSPastExtendsOrImplements =
true;
4112 if (FormatTok->is(tok::l_brace)) {
4113 tryToParseBracedList();
4117 if (FormatTok->is(tok::l_square) && handleCppAttributes())
4121 switch (FormatTok->Tok.getKind()) {
4124 if (IsJavaRecord || !IsNonMacroIdentifier(
Previous) ||
4126 Previous->Previous == &InitialToken) {
4130 case tok::coloncolon:
4134 if (JSPastExtendsOrImplements || ClassName ||
4145 auto IsListInitialization = [&] {
4146 if (!ClassName || IsDerived || JSPastExtendsOrImplements)
4148 assert(FormatTok->is(tok::l_brace));
4149 const auto *Prev = FormatTok->getPreviousNonComment();
4151 return Prev != ClassName && Prev->is(tok::identifier) &&
4152 Prev->isNot(Keywords.kw_final) && tryToParseBracedList();
4155 if (FormatTok->isOneOf(tok::colon, tok::less)) {
4156 int AngleNestingLevel = 0;
4158 if (FormatTok->is(tok::less))
4159 ++AngleNestingLevel;
4160 else if (FormatTok->is(tok::greater))
4161 --AngleNestingLevel;
4163 if (AngleNestingLevel == 0) {
4164 if (FormatTok->is(tok::colon)) {
4166 }
else if (!IsDerived && FormatTok->is(tok::identifier) &&
4167 FormatTok->Previous->is(tok::coloncolon)) {
4168 ClassName = FormatTok;
4169 }
else if (FormatTok->is(tok::l_paren) &&
4170 IsNonMacroIdentifier(FormatTok->Previous)) {
4174 if (FormatTok->is(tok::l_brace)) {
4175 if (AngleNestingLevel == 0 && IsListInitialization())
4177 calculateBraceTypes(
true);
4178 if (!tryToParseBracedList())
4181 if (FormatTok->is(tok::l_square)) {
4184 !
Previous->isTypeOrIdentifier(LangOpts))) {
4187 if (!tryToParseLambda())
4194 if (FormatTok->is(tok::semi))
4196 if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) {
4199 parseCSharpGenericTypeConstraint();
4206 auto GetBraceTypes =
4207 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4208 switch (RecordTok.Tok.getKind()) {
4210 return {TT_ClassLBrace, TT_ClassRBrace};
4211 case tok::kw_struct:
4212 return {TT_StructLBrace, TT_StructRBrace};
4214 return {TT_UnionLBrace, TT_UnionRBrace};
4217 return {TT_RecordLBrace, TT_RecordRBrace};
4220 if (FormatTok->is(tok::l_brace)) {
4221 if (IsListInitialization())
4224 ClassName->setFinalizedType(TT_ClassHeadName);
4225 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4226 FormatTok->setFinalizedType(OpenBraceType);
4231 Tokens->peekNextToken()->is(tok::r_brace),
4236 unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;
4237 parseBlock(
true, AddLevels,
false);
4239 setPreviousRBraceType(ClosingBraceType);
4246void UnwrappedLineParser::parseObjCMethod() {
4247 assert(FormatTok->isOneOf(tok::l_paren, tok::identifier) &&
4248 "'(' or identifier expected.");
4250 if (FormatTok->is(tok::semi)) {
4254 }
else if (FormatTok->is(tok::l_brace)) {
4255 if (Style.BraceWrapping.AfterFunction)
4266void UnwrappedLineParser::parseObjCProtocolList() {
4267 assert(FormatTok->is(tok::less) &&
"'<' expected.");
4271 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))
4273 }
while (!
eof() && FormatTok->isNot(tok::greater));
4277void UnwrappedLineParser::parseObjCUntilAtEnd() {
4279 if (FormatTok->is(tok::objc_end)) {
4284 if (FormatTok->is(tok::l_brace)) {
4288 }
else if (FormatTok->is(tok::r_brace)) {
4292 }
else if (FormatTok->isOneOf(tok::minus, tok::plus)) {
4294 if (FormatTok->isOneOf(tok::l_paren, tok::identifier))
4297 parseStructuralElement();
4302void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4303 assert(FormatTok->isOneOf(tok::objc_interface, tok::objc_implementation));
4309 if (FormatTok->is(tok::less))
4310 parseObjCLightweightGenerics();
4311 if (FormatTok->is(tok::colon)) {
4315 if (FormatTok->is(tok::less))
4316 parseObjCLightweightGenerics();
4317 }
else if (FormatTok->is(tok::l_paren)) {
4322 if (FormatTok->is(tok::less))
4323 parseObjCProtocolList();
4325 if (FormatTok->is(tok::l_brace)) {
4326 if (Style.BraceWrapping.AfterObjCDeclaration)
4335 parseObjCUntilAtEnd();
4338void UnwrappedLineParser::parseObjCLightweightGenerics() {
4339 assert(FormatTok->is(tok::less));
4347 unsigned NumOpenAngles = 1;
4351 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))
4353 if (FormatTok->is(tok::less)) {
4355 }
else if (FormatTok->is(tok::greater)) {
4356 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4359 }
while (!
eof() && NumOpenAngles != 0);
4365bool UnwrappedLineParser::parseObjCProtocol() {
4366 assert(FormatTok->is(tok::objc_protocol));
4369 if (FormatTok->is(tok::l_paren)) {
4381 if (FormatTok->is(tok::less))
4382 parseObjCProtocolList();
4385 if (FormatTok->is(tok::semi)) {
4392 parseObjCUntilAtEnd();
4396void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4397 bool IsImport = FormatTok->is(Keywords.kw_import);
4398 assert(IsImport || FormatTok->is(tok::kw_export));
4402 if (FormatTok->is(tok::kw_default))
4408 if (FormatTok->is(Keywords.kw_async))
4410 if (FormatTok->is(Keywords.kw_function)) {
4419 if (!IsImport && FormatTok->isNoneOf(tok::l_brace, tok::star) &&
4420 !FormatTok->isStringLiteral() &&
4421 !(FormatTok->is(Keywords.kw_type) &&
4422 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4427 if (FormatTok->is(tok::semi))
4429 if (
Line->Tokens.empty()) {
4434 if (FormatTok->is(tok::l_brace)) {
4435 FormatTok->setBlockKind(BK_Block);
4444void UnwrappedLineParser::parseStatementMacro() {
4446 if (FormatTok->is(tok::l_paren))
4448 if (FormatTok->is(tok::semi))
4453void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4456 if (FormatTok->isOneOf(tok::star, tok::period, tok::periodstar,
4457 tok::coloncolon, tok::hash) ||
4458 Keywords.isVerilogIdentifier(*FormatTok)) {
4460 }
else if (FormatTok->is(tok::l_square)) {
4468void UnwrappedLineParser::parseVerilogSensitivityList() {
4469 if (FormatTok->isNot(tok::at))
4473 if (FormatTok->is(tok::at))
4475 switch (FormatTok->Tok.getKind()) {
4483 parseVerilogHierarchyIdentifier();
4488unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4489 unsigned AddLevels = 0;
4491 if (FormatTok->is(Keywords.kw_clocking)) {
4493 if (Keywords.isVerilogIdentifier(*FormatTok))
4495 parseVerilogSensitivityList();
4496 if (FormatTok->is(tok::semi))
4498 }
else if (FormatTok->isOneOf(tok::kw_case, Keywords.kw_casex,
4499 Keywords.kw_casez, Keywords.kw_randcase,
4500 Keywords.kw_randsequence)) {
4501 if (Style.IndentCaseLabels)
4504 if (FormatTok->is(tok::l_paren)) {
4505 FormatTok->setFinalizedType(TT_ConditionLParen);
4508 if (FormatTok->isOneOf(Keywords.kw_inside, Keywords.kw_matches))
4517 if (FormatTok->is(tok::l_square)) {
4518 auto Prev = FormatTok->getPreviousNonComment();
4519 if (Prev && Keywords.isVerilogIdentifier(*Prev))
4520 Prev->setFinalizedType(TT_VerilogDimensionedTypeName);
4522 }
else if (Keywords.isVerilogIdentifier(*FormatTok) ||
4523 FormatTok->isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
4524 Keywords.kw_automatic, tok::kw_static)) {
4531 auto NewLine = [
this]() {
4533 Line->IsContinuation =
true;
4537 while (FormatTok->is(Keywords.kw_import)) {
4540 parseVerilogHierarchyIdentifier();
4541 if (FormatTok->is(tok::semi))
4546 if (FormatTok->is(Keywords.kw_verilogHash)) {
4549 if (FormatTok->is(tok::l_paren)) {
4550 FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
4554 if (FormatTok->is(tok::l_paren)) {
4556 FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
4561 if (FormatTok->is(Keywords.kw_extends)) {
4564 parseVerilogHierarchyIdentifier();
4565 if (FormatTok->is(tok::l_paren))
4568 if (FormatTok->is(Keywords.kw_implements)) {
4572 parseVerilogHierarchyIdentifier();
4573 }
while (FormatTok->is(tok::comma));
4577 if (FormatTok->is(tok::at)) {
4579 parseVerilogSensitivityList();
4582 if (FormatTok->is(tok::semi))
4590void UnwrappedLineParser::parseVerilogTable() {
4591 assert(FormatTok->is(Keywords.kw_table));
4595 auto InitialLevel =
Line->Level++;
4596 while (!
eof() && !Keywords.isVerilogEnd(*FormatTok)) {
4599 if (
Tok->
is(tok::semi))
4601 else if (
Tok->
isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4602 Tok->setFinalizedType(TT_VerilogTableItem);
4604 Line->Level = InitialLevel;
4609void UnwrappedLineParser::parseVerilogCaseLabel() {
4615 auto OrigLevel =
Line->Level;
4616 auto FirstLine = CurrentLines->size();
4617 if (
Line->Level == 0 || (
Line->InPPDirective &&
Line->Level <= 1))
4619 else if (!Style.IndentCaseBlocks && Keywords.isVerilogBegin(*FormatTok))
4621 parseStructuralElement();
4624 if (CurrentLines->size() > FirstLine)
4625 (*CurrentLines)[FirstLine].Level = OrigLevel;
4626 Line->Level = OrigLevel;
4629void UnwrappedLineParser::parseVerilogExtern() {
4631 FormatTok->isOneOf(tok::kw_extern, tok::kw_export, Keywords.kw_import));
4634 if (FormatTok->is(tok::string_literal))
4636 skipVerilogQualifiers();
4637 if (Keywords.isVerilogIdentifier(*FormatTok))
4639 if (FormatTok->is(tok::equal))
4641 if (Keywords.isVerilogHierarchy(*FormatTok))
4642 parseVerilogHierarchyHeader();
4645void UnwrappedLineParser::skipVerilogQualifiers() {
4646 while (FormatTok->isOneOf(tok::kw_protected, tok::kw_virtual, tok::kw_static,
4647 Keywords.kw_rand, Keywords.kw_context,
4648 Keywords.kw_pure, Keywords.kw_randc,
4649 Keywords.kw_local)) {
4654bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4655 for (
const auto &N :
Line.Tokens) {
4656 if (N.Tok->MacroCtx)
4658 for (
const UnwrappedLine &Child : N.Children)
4659 if (containsExpansion(Child))
4665void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4666 if (
Line->Tokens.empty())
4669 if (!parsingPPDirective()) {
4670 llvm::dbgs() <<
"Adding unwrapped line:\n";
4671 printDebugInfo(*
Line);
4679 bool ClosesWhitesmithsBlock =
4680 Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex &&
4681 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
4686 if (!parsingPPDirective() && !InExpansion && containsExpansion(*
Line)) {
4688 Reconstruct.emplace(
Line->Level, Unexpanded);
4689 Reconstruct->addLine(*
Line);
4694 CurrentExpandedLines.push_back(std::move(*
Line));
4696 if (Reconstruct->finished()) {
4697 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4698 assert(!Reconstructed.Tokens.empty() &&
4699 "Reconstructed must at least contain the macro identifier.");
4700 assert(!parsingPPDirective());
4702 llvm::dbgs() <<
"Adding unexpanded line:\n";
4703 printDebugInfo(Reconstructed);
4705 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4706 Lines.push_back(std::move(Reconstructed));
4707 CurrentExpandedLines.clear();
4708 Reconstruct.reset();
4713 assert(!Reconstruct || (CurrentLines != &Lines) || !PPStack.empty());
4714 CurrentLines->push_back(std::move(*
Line));
4716 Line->Tokens.clear();
4717 Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;
4718 Line->FirstStartColumn = 0;
4719 Line->IsContinuation =
false;
4720 Line->SeenDecltypeAuto =
false;
4722 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4724 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4725 CurrentLines->append(
4726 std::make_move_iterator(PreprocessorDirectives.begin()),
4727 std::make_move_iterator(PreprocessorDirectives.end()));
4728 PreprocessorDirectives.clear();
4731 FormatTok->Previous =
nullptr;
4734bool UnwrappedLineParser::eof()
const {
return FormatTok->is(tok::eof); }
4736bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4737 return (
Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4738 FormatTok.NewlinesBefore > 0;
4746 const llvm::Regex &CommentPragmasRegex) {
4747 if (
Line.Tokens.empty() || Style.ReflowComments != FormatStyle::RCS_Always)
4750 StringRef IndentContent = FormatTok.
TokenText;
4751 if (FormatTok.
TokenText.starts_with(
"//") ||
4752 FormatTok.
TokenText.starts_with(
"/*")) {
4753 IndentContent = FormatTok.
TokenText.substr(2);
4755 if (CommentPragmasRegex.match(IndentContent))
4830 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4832 MinColumnToken = PreviousToken;
4835 PreviousToken = Node.
Tok;
4839 MinColumnToken = Node.
Tok;
4841 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4842 MinColumnToken = PreviousToken;
4848void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4849 bool JustComments =
Line->Tokens.empty();
4859 Tok->ContinuesLineCommentSection =
4860 continuesLineCommentSection(*
Tok, *
Line, Style, CommentPragmasRegex);
4861 if (isOnNewLine(*
Tok) && JustComments && !
Tok->ContinuesLineCommentSection)
4865 if (NewlineBeforeNext && JustComments)
4867 CommentsBeforeNextToken.clear();
4870void UnwrappedLineParser::nextToken(
int LevelDifference) {
4873 flushComments(isOnNewLine(*FormatTok));
4874 pushToken(FormatTok);
4876 if (!Style.isJavaScript())
4877 readToken(LevelDifference);
4879 readTokenWithJavaScriptASI();
4881 if (Style.isVerilog()) {
4888 if (Keywords.isVerilogEnd(*FormatTok))
4889 FormatTok->Tok.setKind(tok::r_brace);
4893void UnwrappedLineParser::distributeComments(
4913 if (Comments.empty())
4915 bool ShouldPushCommentsInCurrentLine =
true;
4916 bool HasTrailAlignedWithNextToken =
false;
4917 unsigned StartOfTrailAlignedWithNextToken = 0;
4920 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4922 HasTrailAlignedWithNextToken =
true;
4923 StartOfTrailAlignedWithNextToken = i;
4927 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4929 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4930 FormatTok->ContinuesLineCommentSection =
false;
4933 *FormatTok, *
Line, Style, CommentPragmasRegex);
4935 if (!FormatTok->ContinuesLineCommentSection &&
4936 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4937 ShouldPushCommentsInCurrentLine =
false;
4939 if (ShouldPushCommentsInCurrentLine)
4940 pushToken(FormatTok);
4942 CommentsBeforeNextToken.push_back(FormatTok);
4946void UnwrappedLineParser::readToken(
int LevelDifference) {
4948 bool PreviousWasComment =
false;
4949 bool FirstNonCommentOnLine =
false;
4951 FormatTok = Tokens->getNextToken();
4953 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4954 TT_ConflictAlternative)) {
4955 if (FormatTok->is(TT_ConflictStart))
4956 conditionalCompilationStart(
false);
4957 else if (FormatTok->is(TT_ConflictAlternative))
4958 conditionalCompilationAlternative();
4959 else if (FormatTok->is(TT_ConflictEnd))
4960 conditionalCompilationEnd();
4961 FormatTok = Tokens->getNextToken();
4962 FormatTok->MustBreakBefore =
true;
4963 FormatTok->MustBreakBeforeFinalized =
true;
4966 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4968 bool PreviousWasComment) {
4970 return Tok.HasUnescapedNewline ||
Tok.IsFirst;
4975 if (PreviousWasComment)
4976 return FirstNonCommentOnLine || IsFirstOnLine(
Tok);
4977 return IsFirstOnLine(
Tok);
4980 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4981 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4982 PreviousWasComment = FormatTok->is(tok::comment);
4984 while (!
Line->InPPDirective && FormatTok->is(tok::hash) &&
4985 FirstNonCommentOnLine) {
4988 const auto *
Next = Tokens->peekNextToken();
4989 if ((Style.isVerilog() && !Keywords.isVerilogPPDirective(*
Next)) ||
4990 (Style.isTableGen() &&
4991 Next->isNoneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,
4992 tok::pp_ifndef, tok::pp_endif))) {
4995 distributeComments(Comments, FormatTok);
4999 bool SwitchToPreprocessorLines = !
Line->Tokens.empty();
5000 ScopedLineState BlockState(*
this, SwitchToPreprocessorLines);
5001 assert((LevelDifference >= 0 ||
5002 static_cast<unsigned>(-LevelDifference) <=
Line->Level) &&
5003 "LevelDifference makes Line->Level negative");
5004 Line->Level += LevelDifference;
5008 if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
5009 PPBranchLevel > 0) {
5010 Line->Level += PPBranchLevel;
5012 assert(
Line->Level >=
Line->UnbracedBodyLevel);
5013 Line->Level -=
Line->UnbracedBodyLevel;
5014 flushComments(isOnNewLine(*FormatTok));
5015 const bool IsEndIf = Tokens->peekNextToken()->is(tok::pp_endif);
5017 PreviousWasComment = FormatTok->is(tok::comment);
5018 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
5019 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
5022 if (IsEndIf && IncludeGuard == IG_Defined && PPBranchLevel == -1 &&
5023 getIncludeGuardState(Style.IndentPPDirectives) == IG_Inited &&
5025 (PreviousWasComment &&
5026 Tokens->peekNextToken(
true)->is(tok::eof)))) {
5027 IncludeGuard = IG_Found;
5031 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
5032 !
Line->InPPDirective) {
5036 if (FormatTok->is(tok::identifier) &&
5037 Macros.defined(FormatTok->TokenText) &&
5039 !
Line->InPPDirective) {
5041 unsigned Position = Tokens->getPosition();
5045 auto PreCall = std::move(
Line);
5046 Line.reset(
new UnwrappedLine);
5047 bool OldInExpansion = InExpansion;
5050 auto Args = parseMacroCall();
5051 InExpansion = OldInExpansion;
5052 assert(
Line->Tokens.front().Tok == ID);
5054 auto UnexpandedLine = std::move(
Line);
5056 Line = std::move(PreCall);
5059 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
5061 llvm::dbgs() <<
"(";
5062 for (
const auto &Arg : Args.value())
5063 for (
const auto &T : Arg)
5064 llvm::dbgs() << T->TokenText <<
" ";
5065 llvm::dbgs() <<
")";
5067 llvm::dbgs() <<
"\n";
5069 if (
Macros.objectLike(
ID->TokenText) && Args &&
5070 !
Macros.hasArity(
ID->TokenText, Args->size())) {
5076 LLVM_DEBUG(llvm::dbgs()
5077 <<
"Macro \"" <<
ID->TokenText
5078 <<
"\" not overloaded for arity " << Args->size()
5079 <<
"or not function-like, using object-like overload.");
5081 UnexpandedLine->Tokens.resize(1);
5082 Tokens->setPosition(Position);
5084 assert(!Args &&
Macros.objectLike(
ID->TokenText));
5086 if ((!Args &&
Macros.objectLike(
ID->TokenText)) ||
5087 (Args &&
Macros.hasArity(
ID->TokenText, Args->size()))) {
5090 Unexpanded[
ID] = std::move(UnexpandedLine);
5092 Macros.expand(ID, std::move(Args));
5093 if (!Expansion.empty())
5094 FormatTok = Tokens->insertTokens(Expansion);
5097 llvm::dbgs() <<
"Expanded: ";
5098 for (
const auto &T : Expansion)
5099 llvm::dbgs() << T->TokenText <<
" ";
5100 llvm::dbgs() <<
"\n";
5104 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
5105 <<
"\", because it was used ";
5107 llvm::dbgs() <<
"with " << Args->size();
5109 llvm::dbgs() <<
"without";
5110 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
5112 Tokens->setPosition(Position);
5117 if (FormatTok->isNot(tok::comment)) {
5118 distributeComments(Comments, FormatTok);
5123 Comments.push_back(FormatTok);
5126 distributeComments(Comments,
nullptr);
5131template <
typename Iterator>
5132void pushTokens(Iterator Begin, Iterator End,
5134 for (
auto I = Begin; I != End; ++I) {
5135 Into.push_back(I->Tok);
5136 for (
const auto &Child : I->Children)
5137 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
5142std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
5143UnwrappedLineParser::parseMacroCall() {
5144 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
5145 assert(
Line->Tokens.empty());
5147 if (FormatTok->isNot(tok::l_paren))
5149 unsigned Position = Tokens->getPosition();
5153 auto ArgStart = std::prev(
Line->Tokens.end());
5157 switch (FormatTok->Tok.getKind()) {
5162 case tok::r_paren: {
5168 Args->push_back({});
5169 pushTokens(std::next(ArgStart),
Line->Tokens.end(), Args->back());
5178 Args->push_back({});
5179 pushTokens(std::next(ArgStart),
Line->Tokens.end(), Args->back());
5181 ArgStart = std::prev(
Line->Tokens.end());
5189 Line->Tokens.resize(1);
5190 Tokens->setPosition(Position);
5196 Line->Tokens.push_back(UnwrappedLineNode(
Tok));
5197 if (AtEndOfPPLine) {
5198 auto &
Tok = *
Line->Tokens.back().Tok;
5199 Tok.MustBreakBefore =
true;
5200 Tok.MustBreakBeforeFinalized =
true;
5201 Tok.FirstAfterPPLine =
true;
5202 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',...
@ 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.