22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/raw_os_ostream.h"
26#include "llvm/Support/raw_ostream.h"
31#define DEBUG_TYPE "format-parser"
38void printLine(llvm::raw_ostream &OS,
const UnwrappedLine &
Line,
39 StringRef Prefix =
"",
bool PrintText =
false) {
40 OS << Prefix <<
"Line(" <<
Line.Level <<
", FSC=" <<
Line.FirstStartColumn
41 <<
")" << (
Line.InPPDirective ?
" MACRO" :
"") <<
": ";
43 for (std::list<UnwrappedLineNode>::const_iterator I =
Line.Tokens.begin(),
44 E =
Line.Tokens.end();
50 OS << I->Tok->Tok.getName() <<
"["
51 <<
"T=" << (
unsigned)I->Tok->getType()
52 <<
", OC=" << I->Tok->OriginalColumn <<
", \"" << I->Tok->TokenText
54 for (SmallVectorImpl<UnwrappedLine>::const_iterator
55 CI = I->Children.begin(),
56 CE = I->Children.end();
59 printLine(OS, *CI, (Prefix +
" ").str());
67LLVM_ATTRIBUTE_UNUSED
static void printDebugInfo(
const UnwrappedLine &
Line) {
68 printLine(llvm::dbgs(),
Line);
71class ScopedDeclarationState {
73 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
74 bool MustBeDeclaration)
75 : Line(Line), Stack(Stack) {
76 Line.MustBeDeclaration = MustBeDeclaration;
77 Stack.push_back(MustBeDeclaration);
79 ~ScopedDeclarationState() {
82 Line.MustBeDeclaration = Stack.back();
84 Line.MustBeDeclaration =
true;
89 llvm::BitVector &Stack;
95 llvm::raw_os_ostream OS(Stream);
103 bool SwitchToPreprocessorLines =
false)
105 if (SwitchToPreprocessorLines)
107 else if (!
Parser.Line->Tokens.empty())
108 Parser.CurrentLines = &
Parser.Line->Tokens.back().Children;
109 PreBlockLine = std::move(
Parser.Line);
110 Parser.Line = std::make_unique<UnwrappedLine>();
111 Parser.Line->Level = PreBlockLine->Level;
112 Parser.Line->PPLevel = PreBlockLine->PPLevel;
113 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
114 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
115 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;
119 if (!
Parser.Line->Tokens.empty())
120 Parser.addUnwrappedLine();
121 assert(
Parser.Line->Tokens.empty());
122 Parser.Line = std::move(PreBlockLine);
123 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
124 Parser.MustBreakBeforeNextToken =
true;
125 Parser.CurrentLines = OriginalLines;
131 std::unique_ptr<UnwrappedLine> PreBlockLine;
140 Style.BraceWrapping.AfterControlStatement,
141 Style.BraceWrapping.IndentBraces) {}
143 bool WrapBrace,
bool IndentBrace)
144 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
146 Parser->addUnwrappedLine();
154 unsigned OldLineLevel;
161 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
164 CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()),
166 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
167 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
168 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
171 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
172 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {
173 assert(IsCpp == LangOpts.CXXOperatorNames);
176void UnwrappedLineParser::reset() {
181 IncludeGuardToken =
nullptr;
183 CommentsBeforeNextToken.clear();
185 MustBreakBeforeNextToken =
false;
186 IsDecltypeAutoFunction =
false;
187 PreprocessorDirectives.clear();
188 CurrentLines = &Lines;
189 DeclarationScopeStack.clear();
190 NestedTooDeep.clear();
191 NestedLambdas.clear();
193 Line->FirstStartColumn = FirstStartColumn;
195 if (!Unexpanded.empty())
197 Token->MacroCtx.reset();
198 CurrentExpandedLines.clear();
199 ExpandedLines.clear();
207 Line->FirstStartColumn = FirstStartColumn;
209 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
211 Tokens = &TokenSource;
219 if (IncludeGuard == IG_Found) {
220 for (
auto &Line : Lines)
221 if (Line.InPPDirective && Line.Level > 0)
227 pushToken(FormatTok);
232 if (!ExpandedLines.empty()) {
233 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
234 for (
const auto &Line : Lines) {
235 if (!Line.Tokens.empty()) {
236 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
237 if (it != ExpandedLines.end()) {
238 for (
const auto &Expanded : it->second) {
239 LLVM_DEBUG(printDebugInfo(Expanded));
245 LLVM_DEBUG(printDebugInfo(Line));
251 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
253 LLVM_DEBUG(printDebugInfo(Line));
258 while (!PPLevelBranchIndex.empty() &&
259 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
260 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
261 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
263 if (!PPLevelBranchIndex.empty()) {
264 ++PPLevelBranchIndex.back();
265 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
266 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
268 }
while (!PPLevelBranchIndex.empty());
271void UnwrappedLineParser::parseFile() {
274 bool MustBeDeclaration = !Line->InPPDirective && !Style.
isJavaScript();
275 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
292 !CommentsBeforeNextToken.empty()) {
299void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
308 parseCSharpGenericTypeConstraint();
317void UnwrappedLineParser::parseCSharpAttribute() {
318 int UnpairedSquareBrackets = 1;
323 --UnpairedSquareBrackets;
324 if (UnpairedSquareBrackets == 0) {
330 ++UnpairedSquareBrackets;
340bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
341 if (!Lines.empty() && Lines.back().InPPDirective)
355bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
357 FormatToken **IfLeftBrace) {
358 const bool InRequiresExpression =
359 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
360 const bool IsPrecededByCommentOrPPDirective =
362 FormatToken *IfLBrace =
nullptr;
363 bool HasDoWhile =
false;
364 bool HasLabel =
false;
365 unsigned StatementCount = 0;
366 bool SwitchLabelEncountered =
false;
371 if (FormatTok->
is(tok::l_paren))
376 if (FormatTok->
is(TT_MacroBlockBegin))
378 else if (FormatTok->
is(TT_MacroBlockEnd))
381 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
382 &HasLabel, &StatementCount] {
383 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
384 HasDoWhile ?
nullptr : &HasDoWhile,
385 HasLabel ?
nullptr : &HasLabel);
387 assert(StatementCount > 0 &&
"StatementCount overflow!");
396 if (InRequiresExpression) {
405 if (!InRequiresExpression && FormatTok->
isNot(TT_MacroBlockBegin)) {
406 if (tryToParseBracedList())
412 assert(StatementCount > 0 &&
"StatementCount overflow!");
418 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
421 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
422 HasDoWhile || IsPrecededByCommentOrPPDirective ||
423 precededByCommentOrPPDirective()) {
427 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
430 *IfLeftBrace = IfLBrace;
436 case tok::kw_default: {
440 if (!Next->isOneOf(tok::colon, tok::arrow)) {
443 parseStructuralElement();
459 if (!SwitchLabelEncountered &&
461 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
462 (Line->InPPDirective && Line->Level == 1))) {
465 SwitchLabelEncountered =
true;
466 parseStructuralElement();
471 parseCSharpAttribute();
474 if (handleCppAttributes())
486void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
492 FormatToken *Tok = FormatTok;
493 const FormatToken *PrevTok = Tok->
Previous;
499 const FormatToken *PrevTok;
501 SmallVector<StackEntry, 8> LBraceStack;
502 assert(Tok->is(tok::l_brace));
507 if (!Line->InMacroBody && !Style.
isTableGen()) {
509 while (NextTok->is(tok::hash)) {
511 if (NextTok->is(tok::pp_not_keyword))
515 }
while (!NextTok->HasUnescapedNewline && NextTok->isNot(tok::eof));
517 while (NextTok->is(tok::comment))
522 switch (Tok->Tok.getKind()) {
525 if (PrevTok->isOneOf(tok::colon, tok::less)) {
536 }
else if (PrevTok->is(tok::r_paren)) {
543 LBraceStack.push_back({Tok, PrevTok});
546 if (LBraceStack.empty())
548 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
549 bool ProbablyBracedList =
false;
551 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
552 }
else if (LBrace->isNot(TT_EnumLBrace)) {
555 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
556 NextTok->OriginalColumn == 0;
566 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
568 ProbablyBracedList = ProbablyBracedList ||
570 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
573 ProbablyBracedList ||
574 (IsCpp && (PrevTok->Tok.isLiteral() ||
575 NextTok->isOneOf(tok::l_paren, tok::arrow)));
582 ProbablyBracedList ||
583 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
584 tok::r_paren, tok::r_square, tok::ellipsis);
589 ProbablyBracedList ||
590 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
591 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
595 ProbablyBracedList ||
596 (NextTok->is(tok::identifier) &&
597 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
599 ProbablyBracedList = ProbablyBracedList ||
600 (NextTok->is(tok::semi) &&
601 (!ExpectClassBody || LBraceStack.size() != 1));
604 ProbablyBracedList ||
605 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
607 if (!Style.
isCSharp() && NextTok->is(tok::l_square)) {
611 ProbablyBracedList = NextTok->
isNot(tok::l_square);
615 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
616 !FormatTok->
Previous && NextTok->
is(tok::eof) &&
620 !PrevTok->isOneOf(tok::semi,
BK_Block, tok::colon)) {
621 ProbablyBracedList =
true;
625 Tok->setBlockKind(BlockKind);
626 LBrace->setBlockKind(BlockKind);
628 LBraceStack.pop_back();
630 case tok::identifier:
631 if (Tok->isNot(TT_StatementMacro))
642 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
643 LBraceStack.back().Tok->setBlockKind(
BK_Block);
651 }
while (Tok->isNot(tok::eof) && !LBraceStack.empty());
654 for (
const auto &Entry : LBraceStack)
662void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
664 Prev && Prev->
is(tok::r_brace)) {
672 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
675size_t UnwrappedLineParser::computePPHash()
const {
677 for (
const auto &i : PPStack) {
688bool UnwrappedLineParser::mightFitOnOneLine(
689 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
691 if (ColumnLimit == 0)
694 auto &Tokens = ParsedLine.Tokens;
695 assert(!Tokens.empty());
697 const auto *LastToken = Tokens.back().Tok;
700 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
703 for (
const auto &Token : Tokens) {
705 auto &SavedToken = SavedTokens[Index++];
706 SavedToken.Tok =
new FormatToken;
707 SavedToken.Tok->copyFrom(*Token.Tok);
708 SavedToken.Children = std::move(Token.Children);
711 AnnotatedLine Line(ParsedLine);
712 assert(Line.Last == LastToken);
714 TokenAnnotator Annotator(Style, Keywords);
715 Annotator.annotate(Line);
716 Annotator.calculateFormattingInformation(Line);
718 auto Length = LastToken->TotalLength;
720 assert(OpeningBrace != Tokens.front().Tok);
721 if (
auto Prev = OpeningBrace->Previous;
722 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
723 Length -= ColumnLimit;
725 Length -= OpeningBrace->TokenText.size() + 1;
728 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
729 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
730 Length -= FirstToken->TokenText.size() + 1;
734 for (
auto &Token : Tokens) {
735 const auto &SavedToken = SavedTokens[Index++];
736 Token.Tok->copyFrom(*SavedToken.Tok);
737 Token.Children = std::move(SavedToken.Children);
738 delete SavedToken.Tok;
742 assert(!Line.InMacroBody);
743 assert(!Line.InPPDirective);
744 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
747FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
748 unsigned AddLevels,
bool MunchSemi,
751 bool UnindentWhitesmithsBraces) {
752 auto HandleVerilogBlockLabel = [
this]() {
754 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
763 const bool VerilogHierarchy =
765 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
768 "'{' or macro block token expected");
769 FormatToken *Tok = FormatTok;
770 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
771 auto Index = CurrentLines->size();
772 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
777 if (!VerilogHierarchy && AddLevels > 0 &&
782 size_t PPStartHash = computePPHash();
784 const unsigned InitialLevel = Line->Level;
785 if (VerilogHierarchy) {
786 AddLevels += parseVerilogHierarchyHeader();
788 nextToken(AddLevels);
789 HandleVerilogBlockLabel();
793 if (Line->Level > 300)
796 if (MacroBlock && FormatTok->
is(tok::l_paren))
799 size_t NbPreprocessorDirectives =
800 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
802 size_t OpeningLineIndex =
803 CurrentLines->empty()
805 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
810 if (UnindentWhitesmithsBraces)
813 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
816 Line->Level += AddLevels;
818 FormatToken *IfLBrace =
nullptr;
819 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
824 if (MacroBlock ? FormatTok->
isNot(TT_MacroBlockEnd)
825 : FormatTok->
isNot(tok::r_brace)) {
826 Line->Level = InitialLevel;
831 if (FormatTok->
is(tok::r_brace)) {
833 if (Tok->is(TT_NamespaceLBrace))
837 const bool IsFunctionRBrace =
838 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
840 auto RemoveBraces = [=]()
mutable {
843 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
844 assert(FormatTok->
is(tok::r_brace));
845 const bool WrappedOpeningBrace = !Tok->Previous;
846 if (WrappedOpeningBrace && FollowedByComment)
848 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
849 if (KeepBraces && !HasRequiredIfBraces)
851 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
852 const FormatToken *
Previous = Tokens->getPreviousToken();
857 assert(!CurrentLines->empty());
858 auto &LastLine = CurrentLines->back();
859 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
861 if (Tok->is(TT_ElseLBrace))
863 if (WrappedOpeningBrace) {
868 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
870 if (RemoveBraces()) {
871 Tok->MatchingParen = FormatTok;
875 size_t PPEndHash = computePPHash();
878 nextToken(-AddLevels);
884 while (FormatTok->
is(tok::semi)) {
890 HandleVerilogBlockLabel();
892 if (MacroBlock && FormatTok->
is(tok::l_paren))
895 Line->Level = InitialLevel;
897 if (FormatTok->
is(tok::kw_noexcept)) {
902 if (FormatTok->
is(tok::arrow)) {
906 parseStructuralElement();
909 if (MunchSemi && FormatTok->
is(tok::semi))
912 if (PPStartHash == PPEndHash) {
913 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
916 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
917 CurrentLines->size() - 1;
927 if (
Line.Tokens.size() < 4)
929 auto I =
Line.Tokens.begin();
930 if (I->Tok->TokenText !=
"goog")
933 if (I->Tok->isNot(tok::period))
936 if (I->Tok->TokenText !=
"scope")
939 return I->Tok->is(tok::l_paren);
948 if (
Line.Tokens.size() < 3)
950 auto I =
Line.Tokens.begin();
951 if (I->Tok->isNot(tok::l_paren))
957 return I->Tok->is(tok::l_paren);
963 if (InitialToken.
is(TT_NamespaceMacro))
964 Kind = tok::kw_namespace;
967 case tok::kw_namespace:
982void UnwrappedLineParser::parseChildBlock() {
983 assert(FormatTok->
is(tok::l_brace));
985 const FormatToken *OpeningBrace = FormatTok;
991 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
993 Line->Level += SkipIndent ? 0 : 1;
994 parseLevel(OpeningBrace);
995 flushComments(isOnNewLine(*FormatTok));
996 Line->Level -= SkipIndent ? 0 : 1;
1001void UnwrappedLineParser::parsePPDirective() {
1002 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
1003 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
1013 case tok::pp_define:
1020 case tok::pp_ifndef:
1024 case tok::pp_elifdef:
1025 case tok::pp_elifndef:
1032 case tok::pp_pragma:
1041void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1042 size_t Line = CurrentLines->size();
1043 if (CurrentLines == &PreprocessorDirectives)
1044 Line += Lines.size();
1047 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1048 PPStack.push_back({PP_Unreachable, Line});
1050 PPStack.push_back({PP_Conditional, Line});
1054void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1056 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1057 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1058 PPLevelBranchIndex.push_back(0);
1059 PPLevelBranchCount.push_back(0);
1061 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1062 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1063 conditionalCompilationCondition(Unreachable ||
Skip);
1066void UnwrappedLineParser::conditionalCompilationAlternative() {
1067 if (!PPStack.empty())
1069 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1070 if (!PPChainBranchIndex.empty())
1071 ++PPChainBranchIndex.top();
1072 conditionalCompilationCondition(
1073 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1074 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1077void UnwrappedLineParser::conditionalCompilationEnd() {
1078 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1079 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1080 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1081 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1084 if (PPBranchLevel > -1)
1086 if (!PPChainBranchIndex.empty())
1087 PPChainBranchIndex.pop();
1088 if (!PPStack.empty())
1092void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1093 bool IfNDef = FormatTok->
is(tok::pp_ifndef);
1095 bool Unreachable =
false;
1096 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1098 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1100 conditionalCompilationStart(Unreachable);
1101 FormatToken *IfCondition = FormatTok;
1104 bool MaybeIncludeGuard = IfNDef;
1105 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1106 for (
auto &Line : Lines) {
1107 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1108 MaybeIncludeGuard =
false;
1109 IncludeGuard = IG_Rejected;
1117 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1118 IncludeGuard = IG_IfNdefed;
1119 IncludeGuardToken = IfCondition;
1123void UnwrappedLineParser::parsePPElse() {
1125 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1126 IncludeGuard = IG_Rejected;
1128 assert(PPBranchLevel >= -1);
1129 if (PPBranchLevel == -1)
1130 conditionalCompilationStart(
true);
1131 conditionalCompilationAlternative();
1137void UnwrappedLineParser::parsePPEndIf() {
1138 conditionalCompilationEnd();
1142 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1144 IncludeGuard = IG_Found;
1148void UnwrappedLineParser::parsePPDefine() {
1152 IncludeGuard = IG_Rejected;
1153 IncludeGuardToken =
nullptr;
1158 if (IncludeGuard == IG_IfNdefed &&
1160 IncludeGuard = IG_Defined;
1161 IncludeGuardToken =
nullptr;
1162 for (
auto &Line : Lines) {
1163 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1164 IncludeGuard = IG_Rejected;
1178 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1183 Line->Level += PPBranchLevel + 1;
1187 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1188 assert((
int)Line->PPLevel >= 0);
1189 Line->InMacroBody =
true;
1194 FormatTok = Tokens->getNextToken();
1208void UnwrappedLineParser::parsePPPragma() {
1209 Line->InPragmaDirective =
true;
1213void UnwrappedLineParser::parsePPUnknown() {
1218 Line->Level += PPBranchLevel + 1;
1228 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1231 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1232 tok::less, tok::greater, tok::slash, tok::percent,
1233 tok::lessless, tok::greatergreater, tok::equal,
1234 tok::plusequal, tok::minusequal, tok::starequal,
1235 tok::slashequal, tok::percentequal, tok::ampequal,
1236 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1249 return FormatTok->
is(tok::identifier) &&
1264 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1275 tok::kw_if, tok::kw_else,
1277 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1279 tok::kw_switch, tok::kw_case,
1281 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1283 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1291 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1292 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1309 if (FuncName->
isNot(tok::identifier))
1317 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1321 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1325 if (!Tok || Tok->
isNot(tok::r_paren))
1329 if (!Tok || Tok->
isNot(tok::identifier))
1335bool UnwrappedLineParser::parseModuleImport() {
1336 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1338 if (
auto Token = Tokens->peekNextToken(
true);
1340 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1346 if (FormatTok->
is(tok::colon)) {
1350 else if (FormatTok->
is(tok::less)) {
1352 while (!FormatTok->
isOneOf(tok::semi, tok::greater, tok::eof)) {
1355 if (FormatTok->
isNot(tok::comment) &&
1356 !FormatTok->
TokenText.starts_with(
"//")) {
1362 if (FormatTok->
is(tok::semi)) {
1380void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1383 FormatToken *Next = FormatTok;
1386 CommentsBeforeNextToken.empty()
1387 ? Next->NewlinesBefore == 0
1388 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1393 bool PreviousStartsTemplateExpr =
1395 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1398 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1399 return LineNode.Tok->is(tok::at);
1404 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1405 return addUnwrappedLine();
1407 bool NextEndsTemplateExpr =
1408 Next->is(TT_TemplateString) && Next->TokenText.starts_with(
"}");
1409 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1410 (PreviousMustBeValue ||
1411 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1412 tok::minusminus))) {
1413 return addUnwrappedLine();
1415 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1417 return addUnwrappedLine();
1421void UnwrappedLineParser::parseStructuralElement(
1422 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1423 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1425 FormatTok->
is(tok::pp_include)) {
1427 if (FormatTok->
is(tok::string_literal))
1434 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1438 parseForOrWhileLoop(
false);
1442 parseForOrWhileLoop();
1447 parseIfThenElse(IfKind,
false,
true);
1456 }
else if (FormatTok->
is(tok::l_paren) &&
1457 Tokens->peekNextToken()->is(tok::star)) {
1471 parseAccessSpecifier();
1478 if (FormatTok->
is(tok::l_brace)) {
1481 while (FormatTok && !eof()) {
1482 if (FormatTok->
is(tok::r_brace)) {
1493 case tok::kw_namespace:
1501 FormatToken *Tok = parseIfThenElse(IfKind);
1512 parseForOrWhileLoop();
1523 case tok::kw_switch:
1530 case tok::kw_default: {
1540 if (FormatTok->
is(tok::colon)) {
1545 if (FormatTok->
is(tok::arrow)) {
1547 Default->setFinalizedType(TT_SwitchExpressionLabel);
1574 if (FormatTok->
is(tok::kw_case))
1585 case tok::kw_extern:
1591 parseVerilogHierarchyHeader();
1594 }
else if (FormatTok->
is(tok::string_literal)) {
1596 if (FormatTok->
is(tok::l_brace)) {
1601 unsigned AddLevels =
1608 parseBlock(
true, AddLevels);
1614 case tok::kw_export:
1616 parseJavaScriptEs6ImportExport();
1621 if (FormatTok->
is(tok::kw_namespace)) {
1625 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1629 case tok::kw_inline:
1631 if (FormatTok->
is(tok::kw_namespace)) {
1636 case tok::identifier:
1637 if (FormatTok->
is(TT_ForEachMacro)) {
1638 parseForOrWhileLoop();
1641 if (FormatTok->
is(TT_MacroBlockBegin)) {
1642 parseBlock(
false, 1u,
1648 parseJavaScriptEs6ImportExport();
1653 if (FormatTok->
is(tok::kw_public))
1655 if (FormatTok->
isNot(tok::string_literal))
1658 if (FormatTok->
is(tok::semi))
1663 if (IsCpp && parseModuleImport())
1669 if (FormatTok->
is(tok::colon)) {
1675 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1676 parseStatementMacro();
1679 if (IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1688 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1690 if (!Line->InMacroBody || CurrentLines->size() > 1)
1691 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1704 for (
const bool InRequiresExpression =
1705 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
1708 if (
auto *Next = Tokens->peekNextToken(
true);
1709 Next && Next->isBinaryOperator()) {
1717 if (FormatTok->
is(tok::l_brace)) {
1727 case tok::objc_public:
1728 case tok::objc_protected:
1729 case tok::objc_package:
1730 case tok::objc_private:
1731 return parseAccessSpecifier();
1732 case tok::objc_interface:
1733 case tok::objc_implementation:
1734 return parseObjCInterfaceOrImplementation();
1735 case tok::objc_protocol:
1736 if (parseObjCProtocol())
1741 case tok::objc_optional:
1742 case tok::objc_required:
1746 case tok::objc_autoreleasepool:
1748 if (FormatTok->
is(tok::l_brace)) {
1757 case tok::objc_synchronized:
1759 if (FormatTok->
is(tok::l_paren)) {
1763 if (FormatTok->
is(tok::l_brace)) {
1781 case tok::kw_requires: {
1783 bool ParsedClause = parseRequires();
1809 case tok::kw_typedef:
1831 case tok::kw_struct:
1833 if (parseStructLike())
1836 case tok::kw_decltype:
1838 if (FormatTok->
is(tok::l_paren)) {
1843 Line->SeenDecltypeAuto =
true;
1851 FormatTok->
is(tok::kw_class)) {
1868 case tok::l_paren: {
1872 if (OpeningBrace || !IsCpp || !
Previous || eof())
1875 Tokens->peekNextToken(
true),
1882 case tok::kw_operator:
1893 while (FormatTok->
is(tok::star))
1897 if (FormatTok->
is(tok::l_paren))
1900 if (FormatTok->
is(tok::l_brace))
1904 if (InRequiresExpression)
1906 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1907 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1926 IsDecltypeAutoFunction =
false;
1944 case tok::identifier: {
1946 Line->MustBeDeclaration) {
1948 parseCSharpGenericTypeConstraint();
1951 if (FormatTok->
is(TT_MacroBlockEnd)) {
1960 size_t TokenCount = Line->Tokens.size();
1964 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1965 tryToParseJSFunction();
1975 unsigned StoredPosition = Tokens->getPosition();
1976 FormatToken *Next = Tokens->getNextToken();
1977 FormatTok = Tokens->setPosition(StoredPosition);
1990 parseVerilogTable();
2002 if (parseStructLike())
2007 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
2008 parseStatementMacro();
2015 FormatToken *PreviousToken = FormatTok;
2023 auto OneTokenSoFar = [&]() {
2024 auto I = Line->Tokens.begin(),
E = Line->Tokens.end();
2025 while (I !=
E && I->Tok->is(tok::comment))
2028 while (I !=
E && I->Tok->is(tok::hash))
2030 return I !=
E && (++I ==
E);
2032 if (OneTokenSoFar()) {
2035 bool FunctionLike = FormatTok->
is(tok::l_paren);
2039 bool FollowedByNewline =
2040 CommentsBeforeNextToken.empty()
2042 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2044 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
2046 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2047 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2056 FormatTok->
is(TT_FatArrow)) {
2057 tryToParseChildBlock();
2062 if (FormatTok->
is(tok::l_brace)) {
2071 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2073 parseBlock(
false, 1u,
2081 FormatTok->
is(tok::less)) {
2083 parseBracedList(
true);
2092 case tok::kw_switch:
2117 case tok::kw_default:
2120 if (FormatTok->
is(tok::colon)) {
2130 parseVerilogCaseLabel();
2137 parseVerilogCaseLabel();
2143 if (FormatTok->
is(tok::l_brace))
2153bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2154 assert(FormatTok->
is(tok::l_brace));
2166 unsigned int StoredPosition = Tokens->getPosition();
2167 FormatToken *Tok = Tokens->getNextToken();
2172 bool HasSpecialAccessor =
false;
2173 bool IsTrivialPropertyAccessor =
true;
2174 bool HasAttribute =
false;
2176 if (
const bool IsAccessorKeyword =
2178 IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||
2179 Tok->isOneOf(tok::l_square, tok::semi, Keywords.
kw_internal)) {
2180 if (IsAccessorKeyword)
2181 HasSpecialAccessor =
true;
2182 else if (Tok->is(tok::l_square))
2183 HasAttribute =
true;
2184 Tok = Tokens->getNextToken();
2187 if (Tok->isNot(tok::r_brace))
2188 IsTrivialPropertyAccessor =
false;
2192 if (!HasSpecialAccessor || HasAttribute) {
2193 Tokens->setPosition(StoredPosition);
2199 Tokens->setPosition(StoredPosition);
2207 if (FormatTok->
is(tok::equal)) {
2208 while (!eof() && FormatTok->
isNot(tok::semi))
2221 if (FormatTok->
is(TT_FatArrow)) {
2225 }
while (!eof() && FormatTok->
isNot(tok::semi));
2236 !IsTrivialPropertyAccessor) {
2248bool UnwrappedLineParser::tryToParseLambda() {
2249 assert(FormatTok->
is(tok::l_square));
2254 FormatToken &LSquare = *FormatTok;
2255 if (!tryToParseLambdaIntroducer())
2258 bool SeenArrow =
false;
2259 bool InTemplateParameterList =
false;
2261 while (FormatTok->
isNot(tok::l_brace)) {
2270 parseParens(TT_PointerOrReference);
2278 InTemplateParameterList =
true;
2283 case tok::kw_struct:
2285 case tok::kw_template:
2286 case tok::kw_typename:
2290 case tok::kw_constexpr:
2291 case tok::kw_consteval:
2294 case tok::identifier:
2295 case tok::numeric_constant:
2296 case tok::coloncolon:
2297 case tok::kw_mutable:
2298 case tok::kw_noexcept:
2299 case tok::kw_static:
2324 case tok::equalequal:
2325 case tok::exclaimequal:
2326 case tok::greaterequal:
2327 case tok::lessequal:
2333 if (SeenArrow || InTemplateParameterList) {
2346 case tok::kw_requires: {
2347 auto *RequiresToken = FormatTok;
2349 parseRequiresClause(RequiresToken);
2353 if (!InTemplateParameterList)
2363 LSquare.setFinalizedType(TT_LambdaLSquare);
2365 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2367 assert(!NestedLambdas.empty());
2368 NestedLambdas.pop_back();
2373bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2375 const FormatToken *LeftSquare = FormatTok;
2378 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2379 tok::kw_co_yield, tok::kw_co_return)) ||
2381 LeftSquare->isCppStructuredBinding(IsCpp)) {
2386 if (FormatTok->
is(tok::r_square)) {
2387 const FormatToken *Next = Tokens->peekNextToken(
true);
2388 if (Next->is(tok::greater))
2395void UnwrappedLineParser::tryToParseJSFunction() {
2403 if (FormatTok->
is(tok::star)) {
2409 if (FormatTok->
is(tok::identifier))
2412 if (FormatTok->
isNot(tok::l_paren))
2418 if (FormatTok->
is(tok::colon)) {
2424 if (FormatTok->
is(tok::l_brace))
2425 tryToParseBracedList();
2427 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2431 if (FormatTok->
is(tok::semi))
2437bool UnwrappedLineParser::tryToParseBracedList() {
2439 calculateBraceTypes();
2448bool UnwrappedLineParser::tryToParseChildBlock() {
2450 assert(FormatTok->
is(TT_FatArrow));
2455 if (FormatTok->
isNot(tok::l_brace))
2461bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2462 assert(!IsAngleBracket || !IsEnum);
2463 bool HasError =
false;
2468 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2469 tryToParseChildBlock()) {
2474 tryToParseJSFunction();
2477 if (FormatTok->
is(tok::l_brace)) {
2479 if (tryToParseBracedList())
2484 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2505 if (FormatTok->
is(tok::l_brace))
2514 if (!IsAngleBracket) {
2516 if (Prev && Prev->is(tok::greater))
2525 parseBracedList(
true);
2559bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2560 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2561 auto *LeftParen = FormatTok;
2562 bool SeenComma =
false;
2563 bool SeenEqual =
false;
2564 bool MightBeFoldExpr =
false;
2565 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2570 if (parseParens(AmpAmpTokenType))
2575 case tok::r_paren: {
2576 auto *Prev = LeftParen->Previous;
2577 if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
2579 const auto *Next = Tokens->peekNextToken();
2580 const bool DoubleParens =
2581 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2582 const bool CommaSeparated =
2583 !DoubleParens && Prev && Prev->isOneOf(tok::l_paren, tok::comma) &&
2584 Next && Next->isOneOf(tok::comma, tok::r_paren);
2585 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2586 const bool Excluded =
2588 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2591 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2592 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2593 const bool ReturnParens =
2595 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2596 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2597 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2598 Next->is(tok::semi);
2599 if ((DoubleParens && !Excluded) || (CommaSeparated && !SeenComma) ||
2601 LeftParen->Optional =
true;
2606 if (Prev->is(TT_TypenameMacro)) {
2607 LeftParen->setFinalizedType(TT_TypeDeclarationParen);
2609 }
else if (Prev->is(tok::greater) && FormatTok->
Previous == LeftParen) {
2610 Prev->setFinalizedType(TT_TemplateCloser);
2623 if (!tryToParseBracedList())
2628 if (FormatTok->
is(tok::l_brace)) {
2638 MightBeFoldExpr =
true;
2643 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2644 tryToParseChildBlock();
2654 case tok::identifier:
2656 tryToParseJSFunction();
2660 case tok::kw_switch:
2666 case tok::kw_requires: {
2667 auto RequiresToken = FormatTok;
2669 parseRequiresExpression(RequiresToken);
2673 if (AmpAmpTokenType != TT_Unknown)
2684void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2685 if (!LambdaIntroducer) {
2686 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2687 if (tryToParseLambda())
2704 case tok::l_brace: {
2705 if (!tryToParseBracedList())
2712 if (FormatTok->
is(tok::l_brace)) {
2724void UnwrappedLineParser::keepAncestorBraces() {
2728 const int MaxNestingLevels = 2;
2729 const int Size = NestedTooDeep.size();
2730 if (Size >= MaxNestingLevels)
2731 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2732 NestedTooDeep.push_back(
false);
2736 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2743void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2744 FormatToken *Tok =
nullptr;
2746 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2747 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2750 : Line->Tokens.back().Tok;
2752 if (Tok->BraceCount < 0) {
2753 assert(Tok->BraceCount == -1);
2756 Tok->BraceCount = -1;
2762 ++Line->UnbracedBodyLevel;
2763 parseStructuralElement();
2764 --Line->UnbracedBodyLevel;
2767 assert(!Line->InPPDirective);
2769 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2771 Tok = L.Tokens.back().Tok;
2779 if (CheckEOF && eof())
2789 assert(LeftBrace->
is(tok::l_brace));
2797 assert(RightBrace->
is(tok::r_brace));
2805void UnwrappedLineParser::handleAttributes() {
2809 else if (FormatTok->
is(tok::l_square))
2810 handleCppAttributes();
2813bool UnwrappedLineParser::handleCppAttributes() {
2815 assert(FormatTok->
is(tok::l_square));
2816 if (!tryToParseSimpleAttribute())
2823bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2827 : Tok.is(tok::l_brace);
2830FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2832 bool IsVerilogAssert) {
2833 assert((FormatTok->
is(tok::kw_if) ||
2840 if (IsVerilogAssert) {
2844 if (FormatTok->
is(tok::numeric_constant))
2861 if (FormatTok->
is(tok::exclaim))
2864 bool KeepIfBraces =
true;
2865 if (FormatTok->
is(tok::kw_consteval)) {
2869 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2871 if (FormatTok->
is(tok::l_paren)) {
2878 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2884 bool NeedsUnwrappedLine =
false;
2885 keepAncestorBraces();
2887 FormatToken *IfLeftBrace =
nullptr;
2888 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2890 if (isBlockBegin(*FormatTok)) {
2892 IfLeftBrace = FormatTok;
2894 parseBlock(
false, 1u,
2895 true, KeepIfBraces, &IfBlockKind);
2896 setPreviousRBraceType(TT_ControlStatementRBrace);
2900 NeedsUnwrappedLine =
true;
2901 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2904 parseUnbracedBody();
2908 assert(!NestedTooDeep.empty());
2909 KeepIfBraces = KeepIfBraces ||
2910 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2911 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2912 IfBlockKind == IfStmtKind::IfElseIf;
2915 bool KeepElseBraces = KeepIfBraces;
2916 FormatToken *ElseLeftBrace =
nullptr;
2917 IfStmtKind
Kind = IfStmtKind::IfOnly;
2919 if (FormatTok->
is(tok::kw_else)) {
2921 NestedTooDeep.back() =
false;
2922 Kind = IfStmtKind::IfElse;
2926 if (isBlockBegin(*FormatTok)) {
2927 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2929 ElseLeftBrace = FormatTok;
2931 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2932 FormatToken *IfLBrace =
2933 parseBlock(
false, 1u,
2934 true, KeepElseBraces, &ElseBlockKind);
2935 setPreviousRBraceType(TT_ElseRBrace);
2936 if (FormatTok->
is(tok::kw_else)) {
2937 KeepElseBraces = KeepElseBraces ||
2938 ElseBlockKind == IfStmtKind::IfOnly ||
2939 ElseBlockKind == IfStmtKind::IfElseIf;
2940 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2941 KeepElseBraces =
true;
2942 assert(ElseLeftBrace->MatchingParen);
2946 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2947 const FormatToken *
Previous = Tokens->getPreviousToken();
2949 const bool IsPrecededByComment =
Previous->is(tok::comment);
2950 if (IsPrecededByComment) {
2954 bool TooDeep =
true;
2956 Kind = IfStmtKind::IfElseIf;
2957 TooDeep = NestedTooDeep.pop_back_val();
2959 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2961 NestedTooDeep.push_back(TooDeep);
2962 if (IsPrecededByComment)
2965 parseUnbracedBody(
true);
2968 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2969 if (NeedsUnwrappedLine)
2976 assert(!NestedTooDeep.empty());
2977 KeepElseBraces = KeepElseBraces ||
2978 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2979 NestedTooDeep.back();
2981 NestedTooDeep.pop_back();
2983 if (!KeepIfBraces && !KeepElseBraces) {
2986 }
else if (IfLeftBrace) {
2987 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2989 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2990 assert(!IfLeftBrace->Optional);
2991 assert(!IfRightBrace->Optional);
2992 IfLeftBrace->MatchingParen =
nullptr;
2993 IfRightBrace->MatchingParen =
nullptr;
3003void UnwrappedLineParser::parseTryCatch() {
3004 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
3006 bool NeedsUnwrappedLine =
false;
3007 bool HasCtorInitializer =
false;
3008 if (FormatTok->
is(tok::colon)) {
3009 auto *Colon = FormatTok;
3012 if (FormatTok->
is(tok::identifier)) {
3013 HasCtorInitializer =
true;
3014 Colon->setFinalizedType(TT_CtorInitializerColon);
3019 while (FormatTok->
is(tok::comma))
3022 while (FormatTok->
is(tok::identifier)) {
3024 if (FormatTok->
is(tok::l_paren)) {
3026 }
else if (FormatTok->
is(tok::l_brace)) {
3033 while (FormatTok->
is(tok::comma))
3041 keepAncestorBraces();
3043 if (FormatTok->
is(tok::l_brace)) {
3044 if (HasCtorInitializer)
3051 NeedsUnwrappedLine =
true;
3052 }
else if (FormatTok->
isNot(tok::kw_catch)) {
3058 parseStructuralElement();
3062 if (FormatTok->
is(tok::at))
3065 tok::kw___finally) ||
3073 while (FormatTok->
isNot(tok::l_brace)) {
3074 if (FormatTok->
is(tok::l_paren)) {
3078 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
3080 NestedTooDeep.pop_back();
3085 NeedsUnwrappedLine =
false;
3086 Line->MustBeDeclaration =
false;
3092 NeedsUnwrappedLine =
true;
3096 NestedTooDeep.pop_back();
3098 if (NeedsUnwrappedLine)
3102void UnwrappedLineParser::parseNamespace() {
3103 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3104 "'namespace' expected");
3106 const FormatToken &InitialToken = *FormatTok;
3108 if (InitialToken.is(TT_NamespaceMacro)) {
3111 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3112 tok::l_square, tok::period, tok::l_paren) ||
3113 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3114 if (FormatTok->
is(tok::l_square))
3116 else if (FormatTok->
is(tok::l_paren))
3122 if (FormatTok->
is(tok::l_brace)) {
3128 unsigned AddLevels =
3131 DeclarationScopeStack.size() > 1)
3134 bool ManageWhitesmithsBraces =
3140 if (ManageWhitesmithsBraces)
3145 parseBlock(
true, AddLevels,
true,
3147 ManageWhitesmithsBraces);
3149 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3151 if (ManageWhitesmithsBraces)
3157void UnwrappedLineParser::parseNew() {
3158 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3164 if (FormatTok->
is(tok::l_paren))
3168 if (FormatTok->
is(tok::l_brace))
3171 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3184 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3188 if (FormatTok->
is(tok::l_paren)) {
3192 if (FormatTok->
is(tok::l_brace))
3200void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3201 keepAncestorBraces();
3203 if (isBlockBegin(*FormatTok)) {
3205 FormatToken *LeftBrace = FormatTok;
3207 parseBlock(
false, 1u,
3209 setPreviousRBraceType(TT_ControlStatementRBrace);
3211 assert(!NestedTooDeep.empty());
3212 if (!NestedTooDeep.back())
3218 parseUnbracedBody();
3222 NestedTooDeep.pop_back();
3225void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3226 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3233 "'for', 'while' or foreach macro expected");
3235 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3241 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3243 if (HasParens && FormatTok->
is(tok::l_paren)) {
3254 parseVerilogSensitivityList();
3256 Tokens->getPreviousToken()->is(tok::r_paren)) {
3263 parseLoopBody(KeepBraces,
true);
3266void UnwrappedLineParser::parseDoWhile() {
3267 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3273 if (FormatTok->
isNot(tok::kw_while)) {
3286 parseStructuralElement();
3289void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3291 unsigned OldLineLevel = Line->Level;
3295 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3299 FormatTok->
is(tok::l_brace)) {
3305 if (FormatTok->
is(tok::kw_break)) {
3314 parseStructuralElement();
3318 if (FormatTok->
is(tok::semi))
3322 Line->Level = OldLineLevel;
3323 if (FormatTok->
isNot(tok::l_brace)) {
3324 parseStructuralElement();
3329void UnwrappedLineParser::parseCaseLabel() {
3330 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3331 auto *Case = FormatTok;
3336 if (FormatTok->
is(tok::colon)) {
3342 Case->setFinalizedType(TT_SwitchExpressionLabel);
3349void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3350 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3352 if (FormatTok->
is(tok::l_paren))
3355 keepAncestorBraces();
3357 if (FormatTok->
is(tok::l_brace)) {
3360 : TT_ControlStatementLBrace);
3365 setPreviousRBraceType(TT_ControlStatementRBrace);
3371 parseStructuralElement();
3376 NestedTooDeep.pop_back();
3386 case tok::caretequal:
3390 case tok::equalequal:
3392 case tok::exclaimequal:
3394 case tok::greaterequal:
3395 case tok::greatergreater:
3396 case tok::greatergreaterequal:
3400 case tok::lessequal:
3402 case tok::lesslessequal:
3404 case tok::minusequal:
3405 case tok::minusminus:
3407 case tok::percentequal:
3410 case tok::pipeequal:
3413 case tok::plusequal:
3421 case tok::slashequal:
3423 case tok::starequal:
3430void UnwrappedLineParser::parseAccessSpecifier() {
3431 FormatToken *AccessSpecifierCandidate = FormatTok;
3437 if (FormatTok->
is(tok::colon)) {
3440 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3444 }
else if (AccessSpecifierCandidate) {
3446 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3453bool UnwrappedLineParser::parseRequires() {
3454 assert(FormatTok->
is(tok::kw_requires) &&
"'requires' expected");
3455 auto RequiresToken = FormatTok;
3464 parseRequiresExpression(RequiresToken);
3471 parseRequiresClause(RequiresToken);
3482 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3484 if (!PreviousNonComment ||
3485 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3488 parseRequiresClause(RequiresToken);
3492 switch (PreviousNonComment->Tok.getKind()) {
3495 case tok::kw_noexcept:
3499 parseRequiresClause(RequiresToken);
3508 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3509 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3510 parseRequiresClause(RequiresToken);
3516 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3518 parseRequiresClause(RequiresToken);
3522 parseRequiresExpression(RequiresToken);
3532 unsigned StoredPosition = Tokens->getPosition();
3533 FormatToken *NextToken = Tokens->getNextToken();
3535 auto PeekNext = [&Lookahead, &NextToken,
this] {
3537 NextToken = Tokens->getNextToken();
3540 bool FoundType =
false;
3541 bool LastWasColonColon =
false;
3544 for (; Lookahead < 50; PeekNext()) {
3545 switch (NextToken->Tok.getKind()) {
3546 case tok::kw_volatile:
3549 if (OpenAngles == 0) {
3550 FormatTok = Tokens->setPosition(StoredPosition);
3551 parseRequiresExpression(RequiresToken);
3559 case tok::coloncolon:
3560 LastWasColonColon =
true;
3562 case tok::kw_decltype:
3563 case tok::identifier:
3564 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3565 FormatTok = Tokens->setPosition(StoredPosition);
3566 parseRequiresExpression(RequiresToken);
3570 LastWasColonColon =
false;
3579 if (NextToken->isTypeName(LangOpts)) {
3580 FormatTok = Tokens->setPosition(StoredPosition);
3581 parseRequiresExpression(RequiresToken);
3588 FormatTok = Tokens->setPosition(StoredPosition);
3589 parseRequiresClause(RequiresToken);
3600void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3602 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3607 bool InRequiresExpression =
3608 !RequiresToken->Previous ||
3609 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3611 RequiresToken->setFinalizedType(InRequiresExpression
3612 ? TT_RequiresClauseInARequiresExpression
3613 : TT_RequiresClause);
3617 parseConstraintExpression();
3619 if (!InRequiresExpression)
3630void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3632 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3634 RequiresToken->setFinalizedType(TT_RequiresExpression);
3636 if (FormatTok->
is(tok::l_paren)) {
3641 if (FormatTok->
is(tok::l_brace)) {
3651void UnwrappedLineParser::parseConstraintExpression() {
3658 bool LambdaNextTimeAllowed =
true;
3668 bool TopLevelParensAllowed =
true;
3671 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3674 case tok::kw_requires: {
3675 auto RequiresToken = FormatTok;
3677 parseRequiresExpression(RequiresToken);
3682 if (!TopLevelParensAllowed)
3684 parseParens(TT_BinaryOperator);
3685 TopLevelParensAllowed =
false;
3689 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3696 case tok::kw_struct:
3708 LambdaNextTimeAllowed =
true;
3709 TopLevelParensAllowed =
true;
3714 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3718 case tok::kw_sizeof:
3720 case tok::greaterequal:
3721 case tok::greatergreater:
3723 case tok::lessequal:
3725 case tok::equalequal:
3727 case tok::exclaimequal:
3732 LambdaNextTimeAllowed =
true;
3733 TopLevelParensAllowed =
true;
3738 case tok::numeric_constant:
3739 case tok::coloncolon:
3742 TopLevelParensAllowed =
false;
3747 case tok::kw_static_cast:
3748 case tok::kw_const_cast:
3749 case tok::kw_reinterpret_cast:
3750 case tok::kw_dynamic_cast:
3752 if (FormatTok->
isNot(tok::less))
3756 parseBracedList(
true);
3772 case tok::coloncolon:
3776 case tok::kw_requires:
3785 if (FormatTok->
is(tok::less)) {
3787 parseBracedList(
true);
3789 TopLevelParensAllowed =
false;
3795bool UnwrappedLineParser::parseEnum() {
3796 const FormatToken &InitialToken = *FormatTok;
3799 if (FormatTok->
is(tok::kw_enum))
3814 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3816 while (FormatTok->
is(tok::l_square))
3817 if (!handleCppAttributes())
3822 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3823 tok::greater, tok::comma, tok::question,
3829 while (FormatTok->
is(tok::l_square))
3835 if (FormatTok->
is(tok::l_paren))
3837 if (FormatTok->
is(tok::identifier)) {
3841 if (IsCpp && FormatTok->
is(tok::identifier))
3847 if (FormatTok->
isNot(tok::l_brace))
3854 parseJavaEnumBody();
3872 bool HasError = !parseBracedList(
false,
true);
3876 if (FormatTok->
is(tok::semi))
3880 setPreviousRBraceType(TT_EnumRBrace);
3888bool UnwrappedLineParser::parseStructLike() {
3895 if (FormatTok->
is(tok::semi))
3906class ScopedTokenPosition {
3907 unsigned StoredPosition;
3908 FormatTokenSource *Tokens;
3911 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3912 assert(Tokens &&
"Tokens expected to not be null");
3913 StoredPosition = Tokens->getPosition();
3916 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3922bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3923 ScopedTokenPosition AutoPosition(Tokens);
3924 FormatToken *Tok = Tokens->getNextToken();
3926 if (Tok->isNot(tok::l_square))
3930 while (Tok->isNot(tok::eof)) {
3931 if (Tok->is(tok::r_square))
3933 Tok = Tokens->getNextToken();
3935 if (Tok->is(tok::eof))
3937 Tok = Tokens->getNextToken();
3938 if (Tok->isNot(tok::r_square))
3940 Tok = Tokens->getNextToken();
3941 if (Tok->is(tok::semi))
3946void UnwrappedLineParser::parseJavaEnumBody() {
3947 assert(FormatTok->
is(tok::l_brace));
3948 const FormatToken *OpeningBrace = FormatTok;
3953 unsigned StoredPosition = Tokens->getPosition();
3954 bool IsSimple =
true;
3955 FormatToken *Tok = Tokens->getNextToken();
3956 while (Tok->isNot(tok::eof)) {
3957 if (Tok->is(tok::r_brace))
3959 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3965 Tok = Tokens->getNextToken();
3967 FormatTok = Tokens->setPosition(StoredPosition);
3984 if (FormatTok->
is(tok::l_brace)) {
3986 parseBlock(
true, 1u,
3988 }
else if (FormatTok->
is(tok::l_paren)) {
3990 }
else if (FormatTok->
is(tok::comma)) {
3993 }
else if (FormatTok->
is(tok::semi)) {
3997 }
else if (FormatTok->
is(tok::r_brace)) {
4006 parseLevel(OpeningBrace);
4012void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
4013 const FormatToken &InitialToken = *FormatTok;
4016 const FormatToken *ClassName =
nullptr;
4017 bool IsDerived =
false;
4018 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
4019 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
4023 bool JSPastExtendsOrImplements =
false;
4027 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
4028 tok::kw_alignas, tok::l_square) ||
4031 FormatTok->
isOneOf(tok::period, tok::comma))) {
4034 JSPastExtendsOrImplements =
true;
4039 if (FormatTok->
is(tok::l_brace)) {
4040 tryToParseBracedList();
4044 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
4051 if (!IsNonMacroIdentifier(
Previous) ||
4053 Previous->Previous == &InitialToken) {
4057 case tok::coloncolon:
4061 if (!JSPastExtendsOrImplements && !ClassName &&
4068 auto IsListInitialization = [&] {
4069 if (!ClassName || IsDerived || JSPastExtendsOrImplements)
4071 assert(FormatTok->
is(tok::l_brace));
4074 return Prev != ClassName && Prev->is(tok::identifier) &&
4075 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
4078 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
4079 int AngleNestingLevel = 0;
4081 if (FormatTok->
is(tok::less))
4082 ++AngleNestingLevel;
4083 else if (FormatTok->
is(tok::greater))
4084 --AngleNestingLevel;
4086 if (AngleNestingLevel == 0) {
4087 if (FormatTok->
is(tok::colon)) {
4089 }
else if (FormatTok->
is(tok::identifier) &&
4091 ClassName = FormatTok;
4092 }
else if (FormatTok->
is(tok::l_paren) &&
4093 IsNonMacroIdentifier(FormatTok->
Previous)) {
4097 if (FormatTok->
is(tok::l_brace)) {
4098 if (AngleNestingLevel == 0 && IsListInitialization())
4100 calculateBraceTypes(
true);
4101 if (!tryToParseBracedList())
4104 if (FormatTok->
is(tok::l_square)) {
4107 !
Previous->isTypeOrIdentifier(LangOpts))) {
4110 if (!tryToParseLambda())
4117 if (FormatTok->
is(tok::semi))
4122 parseCSharpGenericTypeConstraint();
4129 auto GetBraceTypes =
4130 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4131 switch (RecordTok.Tok.getKind()) {
4133 return {TT_ClassLBrace, TT_ClassRBrace};
4134 case tok::kw_struct:
4135 return {TT_StructLBrace, TT_StructRBrace};
4137 return {TT_UnionLBrace, TT_UnionRBrace};
4140 return {TT_RecordLBrace, TT_RecordRBrace};
4143 if (FormatTok->
is(tok::l_brace)) {
4144 if (IsListInitialization())
4146 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4155 parseBlock(
true, AddLevels,
false);
4157 setPreviousRBraceType(ClosingBraceType);
4164void UnwrappedLineParser::parseObjCMethod() {
4165 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4166 "'(' or identifier expected.");
4168 if (FormatTok->
is(tok::semi)) {
4172 }
else if (FormatTok->
is(tok::l_brace)) {
4184void UnwrappedLineParser::parseObjCProtocolList() {
4185 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4189 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4193 }
while (!eof() && FormatTok->
isNot(tok::greater));
4197void UnwrappedLineParser::parseObjCUntilAtEnd() {
4204 if (FormatTok->
is(tok::l_brace)) {
4208 }
else if (FormatTok->
is(tok::r_brace)) {
4212 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4216 parseStructuralElement();
4221void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4229 if (FormatTok->
is(tok::less))
4230 parseObjCLightweightGenerics();
4231 if (FormatTok->
is(tok::colon)) {
4235 if (FormatTok->
is(tok::less))
4236 parseObjCLightweightGenerics();
4237 }
else if (FormatTok->
is(tok::l_paren)) {
4242 if (FormatTok->
is(tok::less))
4243 parseObjCProtocolList();
4245 if (FormatTok->
is(tok::l_brace)) {
4255 parseObjCUntilAtEnd();
4258void UnwrappedLineParser::parseObjCLightweightGenerics() {
4259 assert(FormatTok->
is(tok::less));
4267 unsigned NumOpenAngles = 1;
4271 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4275 if (FormatTok->
is(tok::less)) {
4277 }
else if (FormatTok->
is(tok::greater)) {
4278 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4281 }
while (!eof() && NumOpenAngles != 0);
4287bool UnwrappedLineParser::parseObjCProtocol() {
4291 if (FormatTok->
is(tok::l_paren)) {
4303 if (FormatTok->
is(tok::less))
4304 parseObjCProtocolList();
4307 if (FormatTok->
is(tok::semi)) {
4314 parseObjCUntilAtEnd();
4318void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4319 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4320 assert(IsImport || FormatTok->
is(tok::kw_export));
4324 if (FormatTok->
is(tok::kw_default))
4341 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4344 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4349 if (FormatTok->
is(tok::semi))
4351 if (Line->Tokens.empty()) {
4356 if (FormatTok->
is(tok::l_brace)) {
4366void UnwrappedLineParser::parseStatementMacro() {
4368 if (FormatTok->
is(tok::l_paren))
4370 if (FormatTok->
is(tok::semi))
4375void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4378 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4379 tok::coloncolon, tok::hash) ||
4382 }
else if (FormatTok->
is(tok::l_square)) {
4390void UnwrappedLineParser::parseVerilogSensitivityList() {
4391 if (FormatTok->
isNot(tok::at))
4395 if (FormatTok->
is(tok::at))
4405 parseVerilogHierarchyIdentifier();
4410unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4411 unsigned AddLevels = 0;
4417 parseVerilogSensitivityList();
4418 if (FormatTok->
is(tok::semi))
4426 if (FormatTok->
is(tok::l_paren)) {
4439 if (FormatTok->
is(tok::l_square)) {
4445 FormatTok->
isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
4455 Line->IsContinuation =
true;
4462 parseVerilogHierarchyIdentifier();
4463 if (FormatTok->
is(tok::semi))
4471 if (FormatTok->
is(tok::l_paren)) {
4476 if (FormatTok->
is(tok::l_paren)) {
4486 parseVerilogHierarchyIdentifier();
4487 if (FormatTok->
is(tok::l_paren))
4494 parseVerilogHierarchyIdentifier();
4495 }
while (FormatTok->
is(tok::comma));
4499 if (FormatTok->
is(tok::at)) {
4501 parseVerilogSensitivityList();
4504 if (FormatTok->
is(tok::semi))
4512void UnwrappedLineParser::parseVerilogTable() {
4517 auto InitialLevel = Line->Level++;
4519 FormatToken *Tok = FormatTok;
4521 if (Tok->is(tok::semi))
4523 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4524 Tok->setFinalizedType(TT_VerilogTableItem);
4526 Line->Level = InitialLevel;
4531void UnwrappedLineParser::parseVerilogCaseLabel() {
4537 auto OrigLevel = Line->Level;
4538 auto FirstLine = CurrentLines->size();
4539 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4543 parseStructuralElement();
4546 if (CurrentLines->size() > FirstLine)
4547 (*CurrentLines)[FirstLine].Level = OrigLevel;
4548 Line->Level = OrigLevel;
4551bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4552 for (
const auto &N : Line.Tokens) {
4553 if (N.Tok->MacroCtx)
4555 for (
const UnwrappedLine &Child : N.Children)
4556 if (containsExpansion(Child))
4562void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4563 if (Line->Tokens.empty())
4566 if (!parsingPPDirective()) {
4567 llvm::dbgs() <<
"Adding unwrapped line:\n";
4568 printDebugInfo(*Line);
4576 bool ClosesWhitesmithsBlock =
4583 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4585 Reconstruct.emplace(Line->Level, Unexpanded);
4586 Reconstruct->addLine(*Line);
4591 CurrentExpandedLines.push_back(std::move(*Line));
4593 if (Reconstruct->finished()) {
4594 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4595 assert(!Reconstructed.Tokens.empty() &&
4596 "Reconstructed must at least contain the macro identifier.");
4597 assert(!parsingPPDirective());
4599 llvm::dbgs() <<
"Adding unexpanded line:\n";
4600 printDebugInfo(Reconstructed);
4602 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4603 Lines.push_back(std::move(Reconstructed));
4604 CurrentExpandedLines.clear();
4605 Reconstruct.reset();
4610 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4611 CurrentLines->push_back(std::move(*Line));
4613 Line->Tokens.clear();
4615 Line->FirstStartColumn = 0;
4616 Line->IsContinuation =
false;
4617 Line->SeenDecltypeAuto =
false;
4619 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4621 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4622 CurrentLines->append(
4623 std::make_move_iterator(PreprocessorDirectives.begin()),
4624 std::make_move_iterator(PreprocessorDirectives.end()));
4625 PreprocessorDirectives.clear();
4631bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4633bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4634 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4635 FormatTok.NewlinesBefore > 0;
4643 const llvm::Regex &CommentPragmasRegex) {
4647 StringRef IndentContent = FormatTok.
TokenText;
4648 if (FormatTok.
TokenText.starts_with(
"//") ||
4649 FormatTok.
TokenText.starts_with(
"/*")) {
4650 IndentContent = FormatTok.
TokenText.substr(2);
4652 if (CommentPragmasRegex.match(IndentContent))
4727 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4729 MinColumnToken = PreviousToken;
4732 PreviousToken =
Node.Tok;
4735 if (
Node.Tok->NewlinesBefore > 0)
4736 MinColumnToken =
Node.Tok;
4738 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4739 MinColumnToken = PreviousToken;
4745void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4746 bool JustComments = Line->Tokens.empty();
4747 for (FormatToken *Tok : CommentsBeforeNextToken) {
4756 Tok->ContinuesLineCommentSection =
4758 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4762 if (NewlineBeforeNext && JustComments)
4764 CommentsBeforeNextToken.clear();
4767void UnwrappedLineParser::nextToken(
int LevelDifference) {
4770 flushComments(isOnNewLine(*FormatTok));
4771 pushToken(FormatTok);
4774 readToken(LevelDifference);
4776 readTokenWithJavaScriptASI();
4786 FormatTok->Tok.setKind(tok::r_brace);
4790void UnwrappedLineParser::distributeComments(
4791 const SmallVectorImpl<FormatToken *> &Comments,
4792 const FormatToken *NextTok) {
4811 if (Comments.empty())
4813 bool ShouldPushCommentsInCurrentLine =
true;
4814 bool HasTrailAlignedWithNextToken =
false;
4815 unsigned StartOfTrailAlignedWithNextToken = 0;
4818 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4819 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4820 HasTrailAlignedWithNextToken =
true;
4821 StartOfTrailAlignedWithNextToken = i;
4825 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4826 FormatToken *FormatTok = Comments[i];
4827 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4828 FormatTok->ContinuesLineCommentSection =
false;
4831 *FormatTok, *Line, Style, CommentPragmasRegex);
4833 if (!FormatTok->ContinuesLineCommentSection &&
4834 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4835 ShouldPushCommentsInCurrentLine =
false;
4837 if (ShouldPushCommentsInCurrentLine)
4838 pushToken(FormatTok);
4840 CommentsBeforeNextToken.push_back(FormatTok);
4844void UnwrappedLineParser::readToken(
int LevelDifference) {
4845 SmallVector<FormatToken *, 1> Comments;
4846 bool PreviousWasComment =
false;
4847 bool FirstNonCommentOnLine =
false;
4849 FormatTok = Tokens->getNextToken();
4851 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4852 TT_ConflictAlternative)) {
4853 if (FormatTok->is(TT_ConflictStart))
4854 conditionalCompilationStart(
false);
4855 else if (FormatTok->is(TT_ConflictAlternative))
4856 conditionalCompilationAlternative();
4857 else if (FormatTok->is(TT_ConflictEnd))
4858 conditionalCompilationEnd();
4859 FormatTok = Tokens->getNextToken();
4860 FormatTok->MustBreakBefore =
true;
4861 FormatTok->MustBreakBeforeFinalized =
true;
4864 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4865 const FormatToken &Tok,
4866 bool PreviousWasComment) {
4867 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4868 return Tok.HasUnescapedNewline || Tok.IsFirst;
4873 if (PreviousWasComment)
4874 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4875 return IsFirstOnLine(Tok);
4878 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4879 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4880 PreviousWasComment = FormatTok->is(tok::comment);
4882 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4885 FirstNonCommentOnLine) {
4886 distributeComments(Comments, FormatTok);
4890 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4892 assert((LevelDifference >= 0 ||
4893 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4894 "LevelDifference makes Line->Level negative");
4895 Line->Level += LevelDifference;
4900 PPBranchLevel > 0) {
4901 Line->Level += PPBranchLevel;
4903 assert(Line->Level >= Line->UnbracedBodyLevel);
4904 Line->Level -= Line->UnbracedBodyLevel;
4905 flushComments(isOnNewLine(*FormatTok));
4907 PreviousWasComment = FormatTok->is(tok::comment);
4908 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4909 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4912 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4913 !Line->InPPDirective) {
4917 if (FormatTok->is(tok::identifier) &&
4918 Macros.
defined(FormatTok->TokenText) &&
4920 !Line->InPPDirective) {
4921 FormatToken *
ID = FormatTok;
4922 unsigned Position = Tokens->getPosition();
4926 auto PreCall = std::move(Line);
4927 Line.reset(
new UnwrappedLine);
4928 bool OldInExpansion = InExpansion;
4931 auto Args = parseMacroCall();
4932 InExpansion = OldInExpansion;
4933 assert(Line->Tokens.front().Tok ==
ID);
4935 auto UnexpandedLine = std::move(Line);
4937 Line = std::move(PreCall);
4940 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4942 llvm::dbgs() <<
"(";
4943 for (
const auto &Arg : Args.value())
4944 for (
const auto &
T : Arg)
4945 llvm::dbgs() <<
T->TokenText <<
" ";
4946 llvm::dbgs() <<
")";
4948 llvm::dbgs() <<
"\n";
4951 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4957 LLVM_DEBUG(llvm::dbgs()
4958 <<
"Macro \"" <<
ID->TokenText
4959 <<
"\" not overloaded for arity " << Args->size()
4960 <<
"or not function-like, using object-like overload.");
4962 UnexpandedLine->Tokens.resize(1);
4963 Tokens->setPosition(Position);
4968 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4971 Unexpanded[
ID] = std::move(UnexpandedLine);
4972 SmallVector<FormatToken *, 8> Expansion =
4973 Macros.
expand(
ID, std::move(Args));
4974 if (!Expansion.empty())
4975 FormatTok = Tokens->insertTokens(Expansion);
4978 llvm::dbgs() <<
"Expanded: ";
4979 for (
const auto &
T : Expansion)
4980 llvm::dbgs() <<
T->TokenText <<
" ";
4981 llvm::dbgs() <<
"\n";
4985 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4986 <<
"\", because it was used ";
4988 llvm::dbgs() <<
"with " << Args->size();
4990 llvm::dbgs() <<
"without";
4991 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4993 Tokens->setPosition(Position);
4998 if (FormatTok->isNot(tok::comment)) {
4999 distributeComments(Comments, FormatTok);
5004 Comments.push_back(FormatTok);
5007 distributeComments(Comments,
nullptr);
5012template <
typename Iterator>
5013void pushTokens(Iterator
Begin, Iterator End,
5015 for (
auto I =
Begin; I != End; ++I) {
5016 Into.push_back(I->Tok);
5017 for (
const auto &Child : I->Children)
5018 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
5023std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
5024UnwrappedLineParser::parseMacroCall() {
5025 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
5026 assert(Line->Tokens.empty());
5028 if (FormatTok->isNot(tok::l_paren))
5030 unsigned Position = Tokens->getPosition();
5031 FormatToken *Tok = FormatTok;
5034 auto ArgStart = std::prev(Line->Tokens.end());
5038 switch (FormatTok->Tok.getKind()) {
5043 case tok::r_paren: {
5049 Args->push_back({});
5050 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5059 Args->push_back({});
5060 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5062 ArgStart = std::prev(Line->Tokens.end());
5070 Line->Tokens.resize(1);
5071 Tokens->setPosition(Position);
5076void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5077 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5078 if (MustBreakBeforeNextToken) {
5079 Line->Tokens.back().Tok->MustBreakBefore =
true;
5080 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
5081 MustBreakBeforeNextToken =
false;
enum clang::sema::@1718::IndirectLocalPathEntry::EntryKind Kind
This file contains the main building blocks of macro support in clang-format.
This file implements a token annotator, i.e.
Defines the clang::TokenKind enum and support functions.
This file contains the declaration of the UnwrappedLineParser, which turns a stream of tokens into Un...
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
Implements an efficient mapping from strings to IdentifierInfo nodes.
Parser - This implements a parser for the C family of languages.
This class handles loading and caching of source files into memory.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
void setKind(tok::TokenKind K)
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
tok::TokenKind getKind() const
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
void setIdentifierInfo(IdentifierInfo *II)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isLiteral(TokenKind K)
Return true if this is a "literal" kind, like a numeric constant, string, etc.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
@ Parens
New-expression has a C++98 paren-delimited initializer.