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());
63LLVM_ATTRIBUTE_UNUSED
static void printDebugInfo(
const UnwrappedLine &
Line) {
64 printLine(llvm::dbgs(),
Line);
67class ScopedDeclarationState {
69 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
70 bool MustBeDeclaration)
71 : Line(Line), Stack(Stack) {
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)
101 if (SwitchToPreprocessorLines)
103 else if (!
Parser.Line->Tokens.empty())
104 Parser.CurrentLines = &
Parser.Line->Tokens.back().Children;
105 PreBlockLine = std::move(
Parser.Line);
106 Parser.Line = std::make_unique<UnwrappedLine>();
107 Parser.Line->Level = PreBlockLine->Level;
108 Parser.Line->PPLevel = PreBlockLine->PPLevel;
109 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
110 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
111 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;
115 if (!
Parser.Line->Tokens.empty())
116 Parser.addUnwrappedLine();
117 assert(
Parser.Line->Tokens.empty());
118 Parser.Line = std::move(PreBlockLine);
119 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
120 Parser.AtEndOfPPLine =
true;
121 Parser.CurrentLines = OriginalLines;
127 std::unique_ptr<UnwrappedLine> PreBlockLine;
136 Style.BraceWrapping.AfterControlStatement ==
138 Style.BraceWrapping.IndentBraces) {}
140 bool WrapBrace,
bool IndentBrace)
141 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
143 Parser->addUnwrappedLine();
151 unsigned OldLineLevel;
158 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
161 Style(Style), IsCpp(Style.isCpp()),
163 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
164 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
165 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
168 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
169 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}
171void UnwrappedLineParser::reset() {
176 IncludeGuardToken =
nullptr;
178 CommentsBeforeNextToken.clear();
180 AtEndOfPPLine =
false;
181 IsDecltypeAutoFunction =
false;
182 PreprocessorDirectives.clear();
183 CurrentLines = &Lines;
184 DeclarationScopeStack.clear();
185 NestedTooDeep.clear();
186 NestedLambdas.clear();
188 Line->FirstStartColumn = FirstStartColumn;
190 if (!Unexpanded.empty())
192 Token->MacroCtx.reset();
193 CurrentExpandedLines.clear();
194 ExpandedLines.clear();
202 Line->FirstStartColumn = FirstStartColumn;
204 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
206 Tokens = &TokenSource;
214 if (IncludeGuard == IG_Found) {
215 for (
auto &Line : Lines)
216 if (Line.InPPDirective && Line.Level > 0)
222 pushToken(FormatTok);
227 if (!ExpandedLines.empty()) {
228 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
229 for (
const auto &Line : Lines) {
230 if (!Line.Tokens.empty()) {
231 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
232 if (it != ExpandedLines.end()) {
233 for (
const auto &Expanded : it->second) {
234 LLVM_DEBUG(printDebugInfo(Expanded));
240 LLVM_DEBUG(printDebugInfo(Line));
246 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
248 LLVM_DEBUG(printDebugInfo(Line));
253 while (!PPLevelBranchIndex.empty() &&
254 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
255 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
256 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
258 if (!PPLevelBranchIndex.empty()) {
259 ++PPLevelBranchIndex.back();
260 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
261 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
263 }
while (!PPLevelBranchIndex.empty());
266void UnwrappedLineParser::parseFile() {
269 bool MustBeDeclaration = !Line->InPPDirective && !Style.
isJavaScript();
270 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
286 if (Style.
isTextProto() && !CommentsBeforeNextToken.empty())
292void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
302 parseCSharpGenericTypeConstraint();
311void UnwrappedLineParser::parseCSharpAttribute() {
312 int UnpairedSquareBrackets = 1;
317 --UnpairedSquareBrackets;
318 if (UnpairedSquareBrackets == 0) {
324 ++UnpairedSquareBrackets;
334bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
335 if (!Lines.empty() && Lines.back().InPPDirective)
349bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
351 FormatToken **IfLeftBrace) {
352 const bool InRequiresExpression =
353 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
354 const bool IsPrecededByCommentOrPPDirective =
356 FormatToken *IfLBrace =
nullptr;
357 bool HasDoWhile =
false;
358 bool HasLabel =
false;
359 unsigned StatementCount = 0;
360 bool SwitchLabelEncountered =
false;
365 if (FormatTok->
is(tok::l_paren))
370 if (FormatTok->
is(TT_MacroBlockBegin))
372 else if (FormatTok->
is(TT_MacroBlockEnd))
375 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
376 &HasLabel, &StatementCount] {
377 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
378 HasDoWhile ?
nullptr : &HasDoWhile,
379 HasLabel ?
nullptr : &HasLabel);
381 assert(StatementCount > 0 &&
"StatementCount overflow!");
390 if (InRequiresExpression) {
399 if (!InRequiresExpression && FormatTok->
isNot(TT_MacroBlockBegin)) {
400 if (tryToParseBracedList())
406 assert(StatementCount > 0 &&
"StatementCount overflow!");
412 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
415 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
416 HasDoWhile || IsPrecededByCommentOrPPDirective ||
417 precededByCommentOrPPDirective()) {
421 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
424 *IfLeftBrace = IfLBrace;
430 case tok::kw_default: {
434 if (!Next->isOneOf(tok::colon, tok::arrow)) {
437 parseStructuralElement();
453 if (!SwitchLabelEncountered &&
455 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
456 (Line->InPPDirective && Line->Level == 1))) {
459 SwitchLabelEncountered =
true;
460 parseStructuralElement();
465 parseCSharpAttribute();
468 if (handleCppAttributes())
480void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
486 FormatToken *Tok = FormatTok;
487 const FormatToken *PrevTok = Tok->
Previous;
493 const FormatToken *PrevTok;
495 SmallVector<StackEntry, 8> LBraceStack;
496 assert(Tok->is(tok::l_brace));
501 if (!Line->InMacroBody && !Style.
isTableGen()) {
503 while (NextTok->is(tok::hash)) {
505 if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))
509 }
while (!NextTok->HasUnescapedNewline && NextTok->isNot(tok::eof));
511 while (NextTok->is(tok::comment))
516 switch (Tok->Tok.getKind()) {
519 if (PrevTok->isOneOf(tok::colon, tok::less)) {
530 }
else if (PrevTok->is(tok::r_paren)) {
537 LBraceStack.push_back({Tok, PrevTok});
540 if (LBraceStack.empty())
542 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
543 bool ProbablyBracedList =
false;
545 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
546 }
else if (LBrace->isNot(TT_EnumLBrace)) {
549 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
550 NextTok->OriginalColumn == 0;
560 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
562 ProbablyBracedList = ProbablyBracedList ||
564 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
567 ProbablyBracedList ||
568 (IsCpp && (PrevTok->Tok.isLiteral() ||
569 NextTok->isOneOf(tok::l_paren, tok::arrow)));
576 ProbablyBracedList ||
577 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
578 tok::r_paren, tok::r_square, tok::ellipsis);
583 ProbablyBracedList ||
584 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
585 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
589 ProbablyBracedList ||
590 (NextTok->is(tok::identifier) &&
591 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
593 ProbablyBracedList = ProbablyBracedList ||
594 (NextTok->is(tok::semi) &&
595 (!ExpectClassBody || LBraceStack.size() != 1));
598 ProbablyBracedList ||
599 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
601 if (!Style.
isCSharp() && NextTok->is(tok::l_square)) {
605 ProbablyBracedList = NextTok->
isNot(tok::l_square);
609 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
610 !FormatTok->
Previous && NextTok->
is(tok::eof) &&
614 !PrevTok->isOneOf(tok::semi,
BK_Block, tok::colon)) {
615 ProbablyBracedList =
true;
619 Tok->setBlockKind(BlockKind);
620 LBrace->setBlockKind(BlockKind);
622 LBraceStack.pop_back();
624 case tok::identifier:
625 if (Tok->isNot(TT_StatementMacro))
636 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
637 LBraceStack.back().Tok->setBlockKind(
BK_Block);
645 }
while (Tok->isNot(tok::eof) && !LBraceStack.empty());
648 for (
const auto &Entry : LBraceStack)
656void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
658 Prev && Prev->
is(tok::r_brace)) {
666 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
669size_t UnwrappedLineParser::computePPHash()
const {
671 for (
const auto &i : PPStack) {
682bool UnwrappedLineParser::mightFitOnOneLine(
683 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
685 if (ColumnLimit == 0)
688 auto &Tokens = ParsedLine.Tokens;
689 assert(!Tokens.empty());
691 const auto *LastToken = Tokens.back().Tok;
694 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
697 for (
const auto &Token : Tokens) {
699 auto &SavedToken = SavedTokens[Index++];
700 SavedToken.Tok =
new FormatToken;
701 SavedToken.Tok->copyFrom(*Token.Tok);
702 SavedToken.Children = std::move(Token.Children);
705 AnnotatedLine Line(ParsedLine);
706 assert(Line.Last == LastToken);
708 TokenAnnotator Annotator(Style, Keywords);
709 Annotator.annotate(Line);
710 Annotator.calculateFormattingInformation(Line);
712 auto Length = LastToken->TotalLength;
714 assert(OpeningBrace != Tokens.front().Tok);
715 if (
auto Prev = OpeningBrace->Previous;
716 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
717 Length -= ColumnLimit;
719 Length -= OpeningBrace->TokenText.size() + 1;
722 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
723 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
724 Length -= FirstToken->TokenText.size() + 1;
728 for (
auto &Token : Tokens) {
729 const auto &SavedToken = SavedTokens[Index++];
730 Token.Tok->copyFrom(*SavedToken.Tok);
731 Token.Children = std::move(SavedToken.Children);
732 delete SavedToken.Tok;
736 assert(!Line.InMacroBody);
737 assert(!Line.InPPDirective);
738 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
741FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
742 unsigned AddLevels,
bool MunchSemi,
745 bool UnindentWhitesmithsBraces) {
746 auto HandleVerilogBlockLabel = [
this]() {
748 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
757 const bool VerilogHierarchy =
759 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
762 "'{' or macro block token expected");
763 FormatToken *Tok = FormatTok;
764 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
765 auto Index = CurrentLines->size();
766 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
771 if (!VerilogHierarchy && AddLevels > 0 &&
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,
810 Line->Level += AddLevels;
812 FormatToken *IfLBrace =
nullptr;
813 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
818 if (MacroBlock ? FormatTok->
isNot(TT_MacroBlockEnd)
819 : FormatTok->
isNot(tok::r_brace)) {
820 Line->Level = InitialLevel;
825 if (FormatTok->
is(tok::r_brace)) {
827 if (Tok->is(TT_NamespaceLBrace))
831 const bool IsFunctionRBrace =
832 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
834 auto RemoveBraces = [=]()
mutable {
837 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
838 assert(FormatTok->
is(tok::r_brace));
839 const bool WrappedOpeningBrace = !Tok->Previous;
840 if (WrappedOpeningBrace && FollowedByComment)
842 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
843 if (KeepBraces && !HasRequiredIfBraces)
845 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
846 const FormatToken *
Previous = Tokens->getPreviousToken();
851 assert(!CurrentLines->empty());
852 auto &LastLine = CurrentLines->back();
853 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
855 if (Tok->is(TT_ElseLBrace))
857 if (WrappedOpeningBrace) {
862 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
864 if (RemoveBraces()) {
865 Tok->MatchingParen = FormatTok;
869 size_t PPEndHash = computePPHash();
872 nextToken(-AddLevels);
878 while (FormatTok->
is(tok::semi)) {
884 HandleVerilogBlockLabel();
886 if (MacroBlock && FormatTok->
is(tok::l_paren))
889 Line->Level = InitialLevel;
891 if (FormatTok->
is(tok::kw_noexcept)) {
896 if (FormatTok->
is(tok::arrow)) {
900 parseStructuralElement();
903 if (MunchSemi && FormatTok->
is(tok::semi))
906 if (PPStartHash == PPEndHash) {
907 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
910 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
911 CurrentLines->size() - 1;
921 if (
Line.Tokens.size() < 4)
923 auto I =
Line.Tokens.begin();
924 if (I->Tok->TokenText !=
"goog")
927 if (I->Tok->isNot(tok::period))
930 if (I->Tok->TokenText !=
"scope")
933 return I->Tok->is(tok::l_paren);
942 if (
Line.Tokens.size() < 3)
944 auto I =
Line.Tokens.begin();
945 if (I->Tok->isNot(tok::l_paren))
951 return I->Tok->is(tok::l_paren);
957 if (InitialToken.
is(TT_NamespaceMacro))
958 Kind = tok::kw_namespace;
961 case tok::kw_namespace:
976void UnwrappedLineParser::parseChildBlock() {
977 assert(FormatTok->
is(tok::l_brace));
979 const FormatToken *OpeningBrace = FormatTok;
985 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
987 Line->Level += SkipIndent ? 0 : 1;
988 parseLevel(OpeningBrace);
989 flushComments(isOnNewLine(*FormatTok));
990 Line->Level -= SkipIndent ? 0 : 1;
995void UnwrappedLineParser::parsePPDirective() {
996 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
997 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
1007 case tok::pp_define:
1014 case tok::pp_ifndef:
1018 case tok::pp_elifdef:
1019 case tok::pp_elifndef:
1026 case tok::pp_pragma:
1030 case tok::pp_warning:
1032 if (!eof() && Style.
isCpp())
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 bool MaybeIncludeGuard =
false;
1159 if (IncludeGuard == IG_IfNdefed &&
1161 IncludeGuard = IG_Defined;
1162 IncludeGuardToken =
nullptr;
1163 for (
auto &Line : Lines) {
1164 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1165 IncludeGuard = IG_Rejected;
1169 MaybeIncludeGuard = IncludeGuard == IG_Defined;
1182 if (MaybeIncludeGuard && !eof())
1183 IncludeGuard = IG_Rejected;
1188 Line->Level += PPBranchLevel + 1;
1192 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1193 assert((
int)Line->PPLevel >= 0);
1198 Line->InMacroBody =
true;
1210 for (
auto *Comment : CommentsBeforeNextToken)
1211 Comment->Finalized =
true;
1215 FormatTok = Tokens->getNextToken();
1221void UnwrappedLineParser::parsePPPragma() {
1222 Line->InPragmaDirective =
true;
1226void UnwrappedLineParser::parsePPUnknown() {
1230 Line->Level += PPBranchLevel + 1;
1240 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1243 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1244 tok::less, tok::greater, tok::slash, tok::percent,
1245 tok::lessless, tok::greatergreater, tok::equal,
1246 tok::plusequal, tok::minusequal, tok::starequal,
1247 tok::slashequal, tok::percentequal, tok::ampequal,
1248 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1261 return FormatTok->
is(tok::identifier) &&
1276 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1287 tok::kw_if, tok::kw_else,
1289 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1291 tok::kw_switch, tok::kw_case,
1293 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1295 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1303 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1304 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1321 if (FuncName->
isNot(tok::identifier))
1329 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1333 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1337 if (!Tok || Tok->
isNot(tok::r_paren))
1341 if (!Tok || Tok->
isNot(tok::identifier))
1347bool UnwrappedLineParser::parseModuleImport() {
1348 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1350 if (
auto Token = Tokens->peekNextToken(
true);
1352 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1358 if (FormatTok->
is(tok::colon)) {
1362 else if (FormatTok->
is(tok::less)) {
1364 while (!FormatTok->
isOneOf(tok::semi, tok::greater) && !eof()) {
1367 if (FormatTok->
isNot(tok::comment) &&
1368 !FormatTok->
TokenText.starts_with(
"//")) {
1374 if (FormatTok->
is(tok::semi)) {
1392void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1395 FormatToken *Next = FormatTok;
1398 CommentsBeforeNextToken.empty()
1399 ? Next->NewlinesBefore == 0
1400 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1405 bool PreviousStartsTemplateExpr =
1407 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1410 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1411 return LineNode.Tok->is(tok::at);
1416 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1417 return addUnwrappedLine();
1419 bool NextEndsTemplateExpr =
1420 Next->is(TT_TemplateString) && Next->TokenText.starts_with(
"}");
1421 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1422 (PreviousMustBeValue ||
1423 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1424 tok::minusminus))) {
1425 return addUnwrappedLine();
1427 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1429 return addUnwrappedLine();
1433void UnwrappedLineParser::parseStructuralElement(
1434 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1435 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1436 if (Style.
isTableGen() && FormatTok->
is(tok::pp_include)) {
1438 if (FormatTok->
is(tok::string_literal))
1445 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1449 parseForOrWhileLoop(
false);
1453 parseForOrWhileLoop();
1458 parseIfThenElse(IfKind,
false,
true);
1467 }
else if (FormatTok->
is(tok::l_paren) &&
1468 Tokens->peekNextToken()->is(tok::star)) {
1481 parseAccessSpecifier();
1487 if (FormatTok->
is(tok::l_brace)) {
1490 while (FormatTok && !eof()) {
1491 if (FormatTok->
is(tok::r_brace)) {
1502 case tok::kw_namespace:
1510 FormatToken *Tok = parseIfThenElse(IfKind);
1521 parseForOrWhileLoop();
1532 case tok::kw_switch:
1539 case tok::kw_default: {
1549 if (FormatTok->
is(tok::colon)) {
1554 if (FormatTok->
is(tok::arrow)) {
1556 Default->setFinalizedType(TT_SwitchExpressionLabel);
1583 if (FormatTok->
is(tok::kw_case))
1594 case tok::kw_extern:
1600 parseVerilogHierarchyHeader();
1603 }
else if (FormatTok->
is(tok::string_literal)) {
1605 if (FormatTok->
is(tok::l_brace)) {
1610 unsigned AddLevels =
1617 parseBlock(
true, AddLevels);
1623 case tok::kw_export:
1625 parseJavaScriptEs6ImportExport();
1630 if (FormatTok->
is(tok::kw_namespace)) {
1634 if (FormatTok->
is(tok::l_brace)) {
1635 parseCppExportBlock();
1638 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1642 case tok::kw_inline:
1644 if (FormatTok->
is(tok::kw_namespace)) {
1649 case tok::identifier:
1650 if (FormatTok->
is(TT_ForEachMacro)) {
1651 parseForOrWhileLoop();
1654 if (FormatTok->
is(TT_MacroBlockBegin)) {
1655 parseBlock(
false, 1u,
1661 parseJavaScriptEs6ImportExport();
1666 if (FormatTok->
is(tok::kw_public))
1668 if (FormatTok->
isNot(tok::string_literal))
1671 if (FormatTok->
is(tok::semi))
1676 if (IsCpp && parseModuleImport())
1682 if (FormatTok->
is(tok::colon)) {
1688 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1689 parseStatementMacro();
1692 if (IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1701 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1703 if (!Line->InMacroBody || CurrentLines->size() > 1)
1704 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1712 parseRecord(
false,
true);
1722 bool SeenEqual =
false;
1723 for (
const bool InRequiresExpression =
1724 OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
1725 TT_CompoundRequirementLBrace);
1731 if (FormatTok->
is(tok::l_brace)) {
1741 case tok::objc_public:
1742 case tok::objc_protected:
1743 case tok::objc_package:
1744 case tok::objc_private:
1745 return parseAccessSpecifier();
1746 case tok::objc_interface:
1747 case tok::objc_implementation:
1748 return parseObjCInterfaceOrImplementation();
1749 case tok::objc_protocol:
1750 if (parseObjCProtocol())
1755 case tok::objc_optional:
1756 case tok::objc_required:
1760 case tok::objc_autoreleasepool:
1761 IsAutoRelease =
true;
1763 case tok::objc_synchronized:
1765 if (!IsAutoRelease && FormatTok->
is(tok::l_paren)) {
1769 if (FormatTok->
is(tok::l_brace)) {
1787 case tok::kw_requires: {
1789 bool ParsedClause = parseRequires(SeenEqual);
1815 case tok::kw_typedef:
1837 case tok::kw_struct:
1839 if (parseStructLike())
1842 case tok::kw_decltype:
1844 if (FormatTok->
is(tok::l_paren)) {
1849 Line->SeenDecltypeAuto =
true;
1856 if (Style.
isJava() && FormatTok && FormatTok->
is(tok::kw_class))
1872 case tok::l_paren: {
1876 if (OpeningBrace || !IsCpp || !
Previous || eof())
1879 Tokens->peekNextToken(
true),
1886 case tok::kw_operator:
1894 if (Prev && Prev->is(tok::identifier))
1900 while (FormatTok->
is(tok::star))
1904 if (FormatTok->
is(tok::l_paren))
1907 if (FormatTok->
is(tok::l_brace))
1912 if (InRequiresExpression)
1914 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1915 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1934 IsDecltypeAutoFunction =
false;
1952 case tok::identifier: {
1954 Line->MustBeDeclaration) {
1956 parseCSharpGenericTypeConstraint();
1959 if (FormatTok->
is(TT_MacroBlockEnd)) {
1968 size_t TokenCount = Line->Tokens.size();
1972 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1973 tryToParseJSFunction();
1983 unsigned StoredPosition = Tokens->getPosition();
1984 FormatToken *Next = Tokens->getNextToken();
1985 FormatTok = Tokens->setPosition(StoredPosition);
1998 parseVerilogTable();
2010 if (parseStructLike())
2015 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
2016 parseStatementMacro();
2023 FormatToken *PreviousToken = FormatTok;
2031 auto OneTokenSoFar = [&]() {
2032 auto I = Line->Tokens.begin(),
E = Line->Tokens.end();
2033 while (I !=
E && I->Tok->is(tok::comment))
2036 while (I !=
E && I->Tok->is(tok::hash))
2038 return I !=
E && (++I ==
E);
2040 if (OneTokenSoFar()) {
2043 bool FunctionLike = FormatTok->
is(tok::l_paren);
2047 bool FollowedByNewline =
2048 CommentsBeforeNextToken.empty()
2050 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2052 if (FollowedByNewline &&
2053 (
Text.size() >= 5 ||
2054 (FunctionLike && FormatTok->
isNot(tok::l_paren))) &&
2056 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2057 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2066 FormatTok->
is(TT_FatArrow)) {
2067 tryToParseChildBlock();
2073 if (FormatTok->
is(tok::l_brace)) {
2082 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2084 parseBlock(
false, 1u,
2092 FormatTok->
is(tok::less)) {
2094 parseBracedList(
true);
2102 (Tokens->peekNextToken()->isAccessSpecifierKeyword() ||
2109 case tok::kw_switch:
2134 case tok::kw_default:
2137 if (FormatTok->
is(tok::colon)) {
2147 parseVerilogCaseLabel();
2154 parseVerilogCaseLabel();
2160 if (FormatTok->
is(tok::l_brace))
2170bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2171 assert(FormatTok->
is(tok::l_brace));
2183 unsigned int StoredPosition = Tokens->getPosition();
2184 FormatToken *Tok = Tokens->getNextToken();
2189 bool HasSpecialAccessor =
false;
2190 bool IsTrivialPropertyAccessor =
true;
2193 if (
const bool IsAccessorKeyword =
2195 IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||
2196 Tok->isOneOf(tok::l_square, tok::semi, Keywords.
kw_internal)) {
2197 if (IsAccessorKeyword)
2198 HasSpecialAccessor =
true;
2199 else if (Tok->is(tok::l_square))
2201 Tok = Tokens->getNextToken();
2204 if (Tok->isNot(tok::r_brace))
2205 IsTrivialPropertyAccessor =
false;
2210 Tokens->setPosition(StoredPosition);
2216 Tokens->setPosition(StoredPosition);
2224 if (FormatTok->
is(tok::equal)) {
2225 while (!eof() && FormatTok->
isNot(tok::semi))
2238 if (FormatTok->
is(TT_FatArrow)) {
2242 }
while (!eof() && FormatTok->
isNot(tok::semi));
2253 !IsTrivialPropertyAccessor) {
2265bool UnwrappedLineParser::tryToParseLambda() {
2266 assert(FormatTok->
is(tok::l_square));
2271 FormatToken &LSquare = *FormatTok;
2272 if (!tryToParseLambdaIntroducer())
2275 bool SeenArrow =
false;
2276 bool InTemplateParameterList =
false;
2278 while (FormatTok->
isNot(tok::l_brace)) {
2287 parseParens(TT_PointerOrReference);
2295 InTemplateParameterList =
true;
2300 case tok::kw_struct:
2302 case tok::kw_template:
2303 case tok::kw_typename:
2307 case tok::kw_constexpr:
2308 case tok::kw_consteval:
2311 case tok::identifier:
2312 case tok::numeric_constant:
2313 case tok::coloncolon:
2314 case tok::kw_mutable:
2315 case tok::kw_noexcept:
2316 case tok::kw_static:
2341 case tok::equalequal:
2342 case tok::exclaimequal:
2343 case tok::greaterequal:
2344 case tok::lessequal:
2350 if (SeenArrow || InTemplateParameterList) {
2363 case tok::kw_requires: {
2364 auto *RequiresToken = FormatTok;
2366 parseRequiresClause(RequiresToken);
2370 if (!InTemplateParameterList)
2380 LSquare.setFinalizedType(TT_LambdaLSquare);
2382 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2384 assert(!NestedLambdas.empty());
2385 NestedLambdas.pop_back();
2390bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2392 const FormatToken *LeftSquare = FormatTok;
2395 if (
Previous->Tok.getIdentifierInfo() &&
2396 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
2397 tok::kw_co_return)) {
2404 const auto *BeforeRParen =
Previous->getPreviousNonComment();
2407 if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
2411 if (LeftSquare->isCppStructuredBinding(IsCpp))
2415 if (FormatTok->
is(tok::r_square)) {
2416 const FormatToken *Next = Tokens->peekNextToken(
true);
2417 if (Next->is(tok::greater))
2424void UnwrappedLineParser::tryToParseJSFunction() {
2432 if (FormatTok->
is(tok::star)) {
2438 if (FormatTok->
is(tok::identifier))
2441 if (FormatTok->
isNot(tok::l_paren))
2447 if (FormatTok->
is(tok::colon)) {
2453 if (FormatTok->
is(tok::l_brace))
2454 tryToParseBracedList();
2456 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2460 if (FormatTok->
is(tok::semi))
2466bool UnwrappedLineParser::tryToParseBracedList() {
2468 calculateBraceTypes();
2477bool UnwrappedLineParser::tryToParseChildBlock() {
2479 assert(FormatTok->
is(TT_FatArrow));
2484 if (FormatTok->
isNot(tok::l_brace))
2490bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2491 assert(!IsAngleBracket || !IsEnum);
2492 bool HasError =
false;
2497 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2498 tryToParseChildBlock()) {
2503 tryToParseJSFunction();
2506 if (FormatTok->
is(tok::l_brace)) {
2508 if (tryToParseBracedList())
2513 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2534 if (FormatTok->
is(tok::l_brace))
2543 if (!IsAngleBracket) {
2545 if (Prev && Prev->is(tok::greater))
2554 parseBracedList(
true);
2588bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType,
2590 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2591 auto *LParen = FormatTok;
2593 bool SeenComma =
false;
2594 bool SeenEqual =
false;
2595 bool MightBeFoldExpr =
false;
2597 const bool MightBeStmtExpr = FormatTok->
is(tok::l_brace);
2598 if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro))
2603 if (parseParens(AmpAmpTokenType, InMacroCall))
2605 if (Style.
isJava() && FormatTok->
is(tok::l_brace))
2608 case tok::r_paren: {
2609 auto *RParen = FormatTok;
2612 auto OptionalParens = [&] {
2613 if (MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall ||
2614 Line->InMacroBody ||
2616 RParen->getPreviousNonComment() == LParen) {
2619 const bool DoubleParens =
2620 Prev->is(tok::l_paren) && FormatTok->
is(tok::r_paren);
2622 const auto *PrevPrev = Prev->getPreviousNonComment();
2623 const bool Excluded =
2625 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2627 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2628 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2632 const bool CommaSeparated =
2633 Prev->isOneOf(tok::l_paren, tok::comma) &&
2634 FormatTok->
isOneOf(tok::comma, tok::r_paren);
2635 if (CommaSeparated &&
2637 !Prev->endsSequence(tok::comma, tok::ellipsis) &&
2639 !(FormatTok->
is(tok::comma) &&
2640 Tokens->peekNextToken()->is(tok::ellipsis))) {
2643 const bool ReturnParens =
2645 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2646 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2647 Prev->isOneOf(tok::kw_return, tok::kw_co_return) &&
2648 FormatTok->
is(tok::semi);
2654 if (Prev->is(TT_TypenameMacro)) {
2655 LParen->setFinalizedType(TT_TypeDeclarationParen);
2656 RParen->setFinalizedType(TT_TypeDeclarationParen);
2657 }
else if (Prev->is(tok::greater) && RParen->Previous == LParen) {
2658 Prev->setFinalizedType(TT_TemplateCloser);
2659 }
else if (OptionalParens()) {
2660 LParen->Optional =
true;
2661 RParen->Optional =
true;
2673 if (!tryToParseBracedList())
2678 if (FormatTok->
is(tok::l_brace)) {
2688 MightBeFoldExpr =
true;
2693 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2694 tryToParseChildBlock();
2704 case tok::identifier:
2706 tryToParseJSFunction();
2710 case tok::kw_switch:
2716 case tok::kw_requires: {
2717 auto RequiresToken = FormatTok;
2719 parseRequiresExpression(RequiresToken);
2723 if (AmpAmpTokenType != TT_Unknown)
2734void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2735 if (!LambdaIntroducer) {
2736 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2737 if (tryToParseLambda())
2754 case tok::l_brace: {
2755 if (!tryToParseBracedList())
2762 if (FormatTok->
is(tok::l_brace)) {
2774void UnwrappedLineParser::keepAncestorBraces() {
2778 const int MaxNestingLevels = 2;
2779 const int Size = NestedTooDeep.size();
2780 if (Size >= MaxNestingLevels)
2781 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2782 NestedTooDeep.push_back(
false);
2786 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2793void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2794 FormatToken *Tok =
nullptr;
2796 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2797 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2800 : Line->Tokens.back().Tok;
2802 if (Tok->BraceCount < 0) {
2803 assert(Tok->BraceCount == -1);
2806 Tok->BraceCount = -1;
2812 ++Line->UnbracedBodyLevel;
2813 parseStructuralElement();
2814 --Line->UnbracedBodyLevel;
2817 assert(!Line->InPPDirective);
2819 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2821 Tok = L.Tokens.back().Tok;
2829 if (CheckEOF && eof())
2839 assert(LeftBrace->
is(tok::l_brace));
2847 assert(RightBrace->
is(tok::r_brace));
2855void UnwrappedLineParser::handleAttributes() {
2859 else if (FormatTok->
is(tok::l_square))
2860 handleCppAttributes();
2863bool UnwrappedLineParser::handleCppAttributes() {
2865 assert(FormatTok->
is(tok::l_square));
2866 if (!tryToParseSimpleAttribute())
2873bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2877 : Tok.is(tok::l_brace);
2880FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2882 bool IsVerilogAssert) {
2883 assert((FormatTok->
is(tok::kw_if) ||
2890 if (IsVerilogAssert) {
2894 if (FormatTok->
is(tok::numeric_constant))
2911 if (FormatTok->
is(tok::exclaim))
2914 bool KeepIfBraces =
true;
2915 if (FormatTok->
is(tok::kw_consteval)) {
2919 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2921 if (FormatTok->
is(tok::l_paren)) {
2928 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2934 bool NeedsUnwrappedLine =
false;
2935 keepAncestorBraces();
2937 FormatToken *IfLeftBrace =
nullptr;
2938 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2940 if (isBlockBegin(*FormatTok)) {
2942 IfLeftBrace = FormatTok;
2944 parseBlock(
false, 1u,
2945 true, KeepIfBraces, &IfBlockKind);
2946 setPreviousRBraceType(TT_ControlStatementRBrace);
2950 NeedsUnwrappedLine =
true;
2951 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2954 parseUnbracedBody();
2958 assert(!NestedTooDeep.empty());
2959 KeepIfBraces = KeepIfBraces ||
2960 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2961 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2962 IfBlockKind == IfStmtKind::IfElseIf;
2965 bool KeepElseBraces = KeepIfBraces;
2966 FormatToken *ElseLeftBrace =
nullptr;
2967 IfStmtKind
Kind = IfStmtKind::IfOnly;
2969 if (FormatTok->
is(tok::kw_else)) {
2971 NestedTooDeep.back() =
false;
2972 Kind = IfStmtKind::IfElse;
2976 if (isBlockBegin(*FormatTok)) {
2977 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2979 ElseLeftBrace = FormatTok;
2981 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2982 FormatToken *IfLBrace =
2983 parseBlock(
false, 1u,
2984 true, KeepElseBraces, &ElseBlockKind);
2985 setPreviousRBraceType(TT_ElseRBrace);
2986 if (FormatTok->
is(tok::kw_else)) {
2987 KeepElseBraces = KeepElseBraces ||
2988 ElseBlockKind == IfStmtKind::IfOnly ||
2989 ElseBlockKind == IfStmtKind::IfElseIf;
2990 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2991 KeepElseBraces =
true;
2992 assert(ElseLeftBrace->MatchingParen);
2996 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2997 const FormatToken *
Previous = Tokens->getPreviousToken();
2999 const bool IsPrecededByComment =
Previous->is(tok::comment);
3000 if (IsPrecededByComment) {
3004 bool TooDeep =
true;
3006 Kind = IfStmtKind::IfElseIf;
3007 TooDeep = NestedTooDeep.pop_back_val();
3009 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
3011 NestedTooDeep.push_back(TooDeep);
3012 if (IsPrecededByComment)
3015 parseUnbracedBody(
true);
3018 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
3019 if (NeedsUnwrappedLine)
3026 assert(!NestedTooDeep.empty());
3027 KeepElseBraces = KeepElseBraces ||
3028 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
3029 NestedTooDeep.back();
3031 NestedTooDeep.pop_back();
3033 if (!KeepIfBraces && !KeepElseBraces) {
3036 }
else if (IfLeftBrace) {
3037 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
3039 assert(IfRightBrace->MatchingParen == IfLeftBrace);
3040 assert(!IfLeftBrace->Optional);
3041 assert(!IfRightBrace->Optional);
3042 IfLeftBrace->MatchingParen =
nullptr;
3043 IfRightBrace->MatchingParen =
nullptr;
3053void UnwrappedLineParser::parseTryCatch() {
3054 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
3056 bool NeedsUnwrappedLine =
false;
3057 bool HasCtorInitializer =
false;
3058 if (FormatTok->
is(tok::colon)) {
3059 auto *Colon = FormatTok;
3062 if (FormatTok->
is(tok::identifier)) {
3063 HasCtorInitializer =
true;
3064 Colon->setFinalizedType(TT_CtorInitializerColon);
3069 while (FormatTok->
is(tok::comma))
3072 while (FormatTok->
is(tok::identifier)) {
3074 if (FormatTok->
is(tok::l_paren)) {
3076 }
else if (FormatTok->
is(tok::l_brace)) {
3083 while (FormatTok->
is(tok::comma))
3088 if (Style.
isJava() && FormatTok->
is(tok::l_paren))
3091 keepAncestorBraces();
3093 if (FormatTok->
is(tok::l_brace)) {
3094 if (HasCtorInitializer)
3101 NeedsUnwrappedLine =
true;
3102 }
else if (FormatTok->
isNot(tok::kw_catch)) {
3108 parseStructuralElement();
3111 for (
bool SeenCatch =
false;;) {
3112 if (FormatTok->
is(tok::at))
3115 tok::kw___finally, tok::objc_catch,
3116 tok::objc_finally) ||
3121 if (FormatTok->
is(tok::kw_catch))
3124 while (FormatTok->
isNot(tok::l_brace)) {
3125 if (FormatTok->
is(tok::l_paren)) {
3129 if (FormatTok->
isOneOf(tok::semi, tok::r_brace) || eof()) {
3131 NestedTooDeep.pop_back();
3140 NeedsUnwrappedLine =
false;
3141 Line->MustBeDeclaration =
false;
3147 NeedsUnwrappedLine =
true;
3151 NestedTooDeep.pop_back();
3153 if (NeedsUnwrappedLine)
3157void UnwrappedLineParser::parseNamespaceOrExportBlock(
unsigned AddLevels) {
3158 bool ManageWhitesmithsBraces =
3163 if (ManageWhitesmithsBraces)
3168 parseBlock(
true, AddLevels,
true,
3169 true,
nullptr, ManageWhitesmithsBraces);
3171 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3173 if (ManageWhitesmithsBraces)
3177void UnwrappedLineParser::parseNamespace() {
3178 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3179 "'namespace' expected");
3181 const FormatToken &InitialToken = *FormatTok;
3183 if (InitialToken.is(TT_NamespaceMacro)) {
3186 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3187 tok::l_square, tok::period, tok::l_paren) ||
3188 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3189 if (FormatTok->
is(tok::l_square))
3191 else if (FormatTok->
is(tok::l_paren))
3197 if (FormatTok->
is(tok::l_brace)) {
3203 unsigned AddLevels =
3206 DeclarationScopeStack.size() > 1)
3209 parseNamespaceOrExportBlock(AddLevels);
3214void UnwrappedLineParser::parseCppExportBlock() {
3218void UnwrappedLineParser::parseNew() {
3219 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3225 if (FormatTok->
is(tok::l_paren))
3229 if (FormatTok->
is(tok::l_brace))
3232 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3245 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3249 if (FormatTok->
is(tok::l_paren)) {
3253 if (FormatTok->
is(tok::l_brace))
3261void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3262 keepAncestorBraces();
3264 if (isBlockBegin(*FormatTok)) {
3266 FormatToken *LeftBrace = FormatTok;
3268 parseBlock(
false, 1u,
3270 setPreviousRBraceType(TT_ControlStatementRBrace);
3272 assert(!NestedTooDeep.empty());
3273 if (!NestedTooDeep.back())
3279 parseUnbracedBody();
3283 NestedTooDeep.pop_back();
3286void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3287 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3294 "'for', 'while' or foreach macro expected");
3296 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3302 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3304 if (HasParens && FormatTok->
is(tok::l_paren)) {
3315 parseVerilogSensitivityList();
3317 Tokens->getPreviousToken()->is(tok::r_paren)) {
3324 parseLoopBody(KeepBraces,
true);
3327void UnwrappedLineParser::parseDoWhile() {
3328 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3334 if (FormatTok->
isNot(tok::kw_while)) {
3347 parseStructuralElement();
3350void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3352 unsigned OldLineLevel = Line->Level;
3356 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3360 FormatTok->
is(tok::l_brace)) {
3366 if (FormatTok->
is(tok::kw_break)) {
3375 parseStructuralElement();
3379 if (FormatTok->
is(tok::semi))
3383 Line->Level = OldLineLevel;
3384 if (FormatTok->
isNot(tok::l_brace)) {
3385 parseStructuralElement();
3390void UnwrappedLineParser::parseCaseLabel() {
3391 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3392 auto *Case = FormatTok;
3397 if (FormatTok->
is(tok::colon)) {
3401 if (Style.
isJava() && FormatTok->
is(tok::arrow)) {
3403 Case->setFinalizedType(TT_SwitchExpressionLabel);
3410void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3411 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3413 if (FormatTok->
is(tok::l_paren))
3416 keepAncestorBraces();
3418 if (FormatTok->
is(tok::l_brace)) {
3421 : TT_ControlStatementLBrace);
3426 setPreviousRBraceType(TT_ControlStatementRBrace);
3432 parseStructuralElement();
3437 NestedTooDeep.pop_back();
3440void UnwrappedLineParser::parseAccessSpecifier() {
3446 if (FormatTok->
is(tok::colon))
3454bool UnwrappedLineParser::parseRequires(
bool SeenEqual) {
3455 assert(FormatTok->
is(tok::kw_requires) &&
"'requires' expected");
3456 auto RequiresToken = FormatTok;
3465 parseRequiresExpression(RequiresToken);
3472 parseRequiresClause(RequiresToken);
3483 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3485 if (!PreviousNonComment ||
3486 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3489 parseRequiresClause(RequiresToken);
3493 switch (PreviousNonComment->Tok.getKind()) {
3496 case tok::kw_noexcept:
3501 parseRequiresClause(RequiresToken);
3510 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3511 if ((PrevPrev && PrevPrev->is(tok::kw_const)) || !SeenEqual) {
3512 parseRequiresClause(RequiresToken);
3518 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3520 parseRequiresClause(RequiresToken);
3524 parseRequiresExpression(RequiresToken);
3534 unsigned StoredPosition = Tokens->getPosition();
3535 FormatToken *NextToken = Tokens->getNextToken();
3537 auto PeekNext = [&Lookahead, &NextToken,
this] {
3539 NextToken = Tokens->getNextToken();
3542 bool FoundType =
false;
3543 bool LastWasColonColon =
false;
3546 for (; Lookahead < 50; PeekNext()) {
3547 switch (NextToken->Tok.getKind()) {
3548 case tok::kw_volatile:
3551 if (OpenAngles == 0) {
3552 FormatTok = Tokens->setPosition(StoredPosition);
3553 parseRequiresExpression(RequiresToken);
3561 case tok::coloncolon:
3562 LastWasColonColon =
true;
3564 case tok::kw_decltype:
3565 case tok::identifier:
3566 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3567 FormatTok = Tokens->setPosition(StoredPosition);
3568 parseRequiresExpression(RequiresToken);
3572 LastWasColonColon =
false;
3581 if (NextToken->isTypeName(LangOpts)) {
3582 FormatTok = Tokens->setPosition(StoredPosition);
3583 parseRequiresExpression(RequiresToken);
3590 FormatTok = Tokens->setPosition(StoredPosition);
3591 parseRequiresClause(RequiresToken);
3602void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3604 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3609 bool InRequiresExpression =
3610 !RequiresToken->Previous ||
3611 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3613 RequiresToken->setFinalizedType(InRequiresExpression
3614 ? TT_RequiresClauseInARequiresExpression
3615 : TT_RequiresClause);
3619 parseConstraintExpression();
3621 if (!InRequiresExpression && FormatTok->
Previous)
3632void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3634 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3636 RequiresToken->setFinalizedType(TT_RequiresExpression);
3638 if (FormatTok->
is(tok::l_paren)) {
3643 if (FormatTok->
is(tok::l_brace)) {
3653void UnwrappedLineParser::parseConstraintExpression() {
3660 bool LambdaNextTimeAllowed =
true;
3670 bool TopLevelParensAllowed =
true;
3673 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3676 case tok::kw_requires: {
3677 auto RequiresToken = FormatTok;
3679 parseRequiresExpression(RequiresToken);
3684 if (!TopLevelParensAllowed)
3686 parseParens(TT_BinaryOperator);
3687 TopLevelParensAllowed =
false;
3691 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3698 case tok::kw_struct:
3710 LambdaNextTimeAllowed =
true;
3711 TopLevelParensAllowed =
true;
3716 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3720 case tok::kw_sizeof:
3722 case tok::greaterequal:
3723 case tok::greatergreater:
3725 case tok::lessequal:
3727 case tok::equalequal:
3729 case tok::exclaimequal:
3734 LambdaNextTimeAllowed =
true;
3735 TopLevelParensAllowed =
true;
3740 case tok::numeric_constant:
3741 case tok::coloncolon:
3744 TopLevelParensAllowed =
false;
3749 case tok::kw_static_cast:
3750 case tok::kw_const_cast:
3751 case tok::kw_reinterpret_cast:
3752 case tok::kw_dynamic_cast:
3754 if (FormatTok->
isNot(tok::less))
3758 parseBracedList(
true);
3774 case tok::coloncolon:
3778 case tok::kw_requires:
3787 if (FormatTok->
is(tok::less)) {
3789 parseBracedList(
true);
3791 TopLevelParensAllowed =
false;
3797bool UnwrappedLineParser::parseEnum() {
3798 const FormatToken &InitialToken = *FormatTok;
3801 if (FormatTok->
is(tok::kw_enum))
3816 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3818 while (FormatTok->
is(tok::l_square))
3819 if (!handleCppAttributes())
3824 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3825 tok::greater, tok::comma, tok::question,
3831 while (FormatTok->
is(tok::l_square))
3837 if (FormatTok->
is(tok::l_paren))
3839 if (FormatTok->
is(tok::identifier)) {
3843 if (IsCpp && FormatTok->
is(tok::identifier))
3849 if (FormatTok->
isNot(tok::l_brace))
3856 parseJavaEnumBody();
3874 bool HasError = !parseBracedList(
false,
true);
3878 if (FormatTok->
is(tok::semi))
3882 setPreviousRBraceType(TT_EnumRBrace);
3890bool UnwrappedLineParser::parseStructLike() {
3896 if (FormatTok->
is(tok::semi))
3907class ScopedTokenPosition {
3908 unsigned StoredPosition;
3909 FormatTokenSource *Tokens;
3912 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3913 assert(Tokens &&
"Tokens expected to not be null");
3914 StoredPosition = Tokens->getPosition();
3917 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3923bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3924 ScopedTokenPosition AutoPosition(Tokens);
3925 FormatToken *Tok = Tokens->getNextToken();
3927 if (Tok->isNot(tok::l_square))
3931 while (Tok->isNot(tok::eof)) {
3932 if (Tok->is(tok::r_square))
3934 Tok = Tokens->getNextToken();
3936 if (Tok->is(tok::eof))
3938 Tok = Tokens->getNextToken();
3939 if (Tok->isNot(tok::r_square))
3941 Tok = Tokens->getNextToken();
3942 if (Tok->is(tok::semi))
3947void UnwrappedLineParser::parseJavaEnumBody() {
3948 assert(FormatTok->
is(tok::l_brace));
3949 const FormatToken *OpeningBrace = FormatTok;
3954 unsigned StoredPosition = Tokens->getPosition();
3955 bool IsSimple =
true;
3956 FormatToken *Tok = Tokens->getNextToken();
3957 while (Tok->isNot(tok::eof)) {
3958 if (Tok->is(tok::r_brace))
3960 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3966 Tok = Tokens->getNextToken();
3968 FormatTok = Tokens->setPosition(StoredPosition);
3985 if (FormatTok->
is(tok::l_brace)) {
3987 parseBlock(
true, 1u,
3989 }
else if (FormatTok->
is(tok::l_paren)) {
3991 }
else if (FormatTok->
is(tok::comma)) {
3994 }
else if (FormatTok->
is(tok::semi)) {
3998 }
else if (FormatTok->
is(tok::r_brace)) {
4007 parseLevel(OpeningBrace);
4013void UnwrappedLineParser::parseRecord(
bool ParseAsExpr,
bool IsJavaRecord) {
4014 assert(!IsJavaRecord || FormatTok->
is(Keywords.
kw_record));
4015 const FormatToken &InitialToken = *FormatTok;
4018 FormatToken *ClassName =
4019 IsJavaRecord && FormatTok->
is(tok::identifier) ? FormatTok :
nullptr;
4020 bool IsDerived =
false;
4021 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
4022 return Tok->
is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
4026 bool JSPastExtendsOrImplements =
false;
4030 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
4031 tok::kw_alignas, tok::l_square) ||
4034 FormatTok->
isOneOf(tok::period, tok::comma))) {
4037 JSPastExtendsOrImplements =
true;
4042 if (FormatTok->
is(tok::l_brace)) {
4043 tryToParseBracedList();
4047 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
4054 if (IsJavaRecord || !IsNonMacroIdentifier(
Previous) ||
4056 Previous->Previous == &InitialToken) {
4060 case tok::coloncolon:
4064 if (JSPastExtendsOrImplements || ClassName ||
4075 auto IsListInitialization = [&] {
4076 if (!ClassName || IsDerived || JSPastExtendsOrImplements)
4078 assert(FormatTok->
is(tok::l_brace));
4081 return Prev != ClassName && Prev->is(tok::identifier) &&
4082 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
4085 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
4086 int AngleNestingLevel = 0;
4088 if (FormatTok->
is(tok::less))
4089 ++AngleNestingLevel;
4090 else if (FormatTok->
is(tok::greater))
4091 --AngleNestingLevel;
4093 if (AngleNestingLevel == 0) {
4094 if (FormatTok->
is(tok::colon)) {
4096 }
else if (!IsDerived && FormatTok->
is(tok::identifier) &&
4098 ClassName = FormatTok;
4099 }
else if (FormatTok->
is(tok::l_paren) &&
4100 IsNonMacroIdentifier(FormatTok->
Previous)) {
4104 if (FormatTok->
is(tok::l_brace)) {
4105 if (AngleNestingLevel == 0 && IsListInitialization())
4107 calculateBraceTypes(
true);
4108 if (!tryToParseBracedList())
4111 if (FormatTok->
is(tok::l_square)) {
4114 !
Previous->isTypeOrIdentifier(LangOpts))) {
4117 if (!tryToParseLambda())
4124 if (FormatTok->
is(tok::semi))
4129 parseCSharpGenericTypeConstraint();
4136 auto GetBraceTypes =
4137 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4138 switch (RecordTok.Tok.getKind()) {
4140 return {TT_ClassLBrace, TT_ClassRBrace};
4141 case tok::kw_struct:
4142 return {TT_StructLBrace, TT_StructRBrace};
4144 return {TT_UnionLBrace, TT_UnionRBrace};
4147 return {TT_RecordLBrace, TT_RecordRBrace};
4150 if (FormatTok->
is(tok::l_brace)) {
4151 if (IsListInitialization())
4154 ClassName->setFinalizedType(TT_ClassHeadName);
4155 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4164 parseBlock(
true, AddLevels,
false);
4166 setPreviousRBraceType(ClosingBraceType);
4173void UnwrappedLineParser::parseObjCMethod() {
4174 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4175 "'(' or identifier expected.");
4177 if (FormatTok->
is(tok::semi)) {
4181 }
else if (FormatTok->
is(tok::l_brace)) {
4193void UnwrappedLineParser::parseObjCProtocolList() {
4194 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4198 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::objc_end))
4200 }
while (!eof() && FormatTok->
isNot(tok::greater));
4204void UnwrappedLineParser::parseObjCUntilAtEnd() {
4206 if (FormatTok->
is(tok::objc_end)) {
4211 if (FormatTok->
is(tok::l_brace)) {
4215 }
else if (FormatTok->
is(tok::r_brace)) {
4219 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4223 parseStructuralElement();
4228void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4229 assert(FormatTok->
isOneOf(tok::objc_interface, tok::objc_implementation));
4235 if (FormatTok->
is(tok::less))
4236 parseObjCLightweightGenerics();
4237 if (FormatTok->
is(tok::colon)) {
4241 if (FormatTok->
is(tok::less))
4242 parseObjCLightweightGenerics();
4243 }
else if (FormatTok->
is(tok::l_paren)) {
4248 if (FormatTok->
is(tok::less))
4249 parseObjCProtocolList();
4251 if (FormatTok->
is(tok::l_brace)) {
4261 parseObjCUntilAtEnd();
4264void UnwrappedLineParser::parseObjCLightweightGenerics() {
4265 assert(FormatTok->
is(tok::less));
4273 unsigned NumOpenAngles = 1;
4277 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::objc_end))
4279 if (FormatTok->
is(tok::less)) {
4281 }
else if (FormatTok->
is(tok::greater)) {
4282 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4285 }
while (!eof() && NumOpenAngles != 0);
4291bool UnwrappedLineParser::parseObjCProtocol() {
4292 assert(FormatTok->
is(tok::objc_protocol));
4295 if (FormatTok->
is(tok::l_paren)) {
4307 if (FormatTok->
is(tok::less))
4308 parseObjCProtocolList();
4311 if (FormatTok->
is(tok::semi)) {
4318 parseObjCUntilAtEnd();
4322void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4323 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4324 assert(IsImport || FormatTok->
is(tok::kw_export));
4328 if (FormatTok->
is(tok::kw_default))
4345 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4348 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4353 if (FormatTok->
is(tok::semi))
4355 if (Line->Tokens.empty()) {
4360 if (FormatTok->
is(tok::l_brace)) {
4370void UnwrappedLineParser::parseStatementMacro() {
4372 if (FormatTok->
is(tok::l_paren))
4374 if (FormatTok->
is(tok::semi))
4379void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4382 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4383 tok::coloncolon, tok::hash) ||
4386 }
else if (FormatTok->
is(tok::l_square)) {
4394void UnwrappedLineParser::parseVerilogSensitivityList() {
4395 if (FormatTok->
isNot(tok::at))
4399 if (FormatTok->
is(tok::at))
4409 parseVerilogHierarchyIdentifier();
4414unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4415 unsigned AddLevels = 0;
4421 parseVerilogSensitivityList();
4422 if (FormatTok->
is(tok::semi))
4430 if (FormatTok->
is(tok::l_paren)) {
4443 if (FormatTok->
is(tok::l_square)) {
4449 FormatTok->
isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
4459 Line->IsContinuation =
true;
4466 parseVerilogHierarchyIdentifier();
4467 if (FormatTok->
is(tok::semi))
4475 if (FormatTok->
is(tok::l_paren)) {
4480 if (FormatTok->
is(tok::l_paren)) {
4490 parseVerilogHierarchyIdentifier();
4491 if (FormatTok->
is(tok::l_paren))
4498 parseVerilogHierarchyIdentifier();
4499 }
while (FormatTok->
is(tok::comma));
4503 if (FormatTok->
is(tok::at)) {
4505 parseVerilogSensitivityList();
4508 if (FormatTok->
is(tok::semi))
4516void UnwrappedLineParser::parseVerilogTable() {
4521 auto InitialLevel = Line->Level++;
4523 FormatToken *Tok = FormatTok;
4525 if (Tok->is(tok::semi))
4527 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4528 Tok->setFinalizedType(TT_VerilogTableItem);
4530 Line->Level = InitialLevel;
4535void UnwrappedLineParser::parseVerilogCaseLabel() {
4541 auto OrigLevel = Line->Level;
4542 auto FirstLine = CurrentLines->size();
4543 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4547 parseStructuralElement();
4550 if (CurrentLines->size() > FirstLine)
4551 (*CurrentLines)[FirstLine].Level = OrigLevel;
4552 Line->Level = OrigLevel;
4555bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4556 for (
const auto &N : Line.Tokens) {
4557 if (N.Tok->MacroCtx)
4559 for (
const UnwrappedLine &Child : N.Children)
4560 if (containsExpansion(Child))
4566void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4567 if (Line->Tokens.empty())
4570 if (!parsingPPDirective()) {
4571 llvm::dbgs() <<
"Adding unwrapped line:\n";
4572 printDebugInfo(*Line);
4580 bool ClosesWhitesmithsBlock =
4587 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4589 Reconstruct.emplace(Line->Level, Unexpanded);
4590 Reconstruct->addLine(*Line);
4595 CurrentExpandedLines.push_back(std::move(*Line));
4597 if (Reconstruct->finished()) {
4598 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4599 assert(!Reconstructed.Tokens.empty() &&
4600 "Reconstructed must at least contain the macro identifier.");
4601 assert(!parsingPPDirective());
4603 llvm::dbgs() <<
"Adding unexpanded line:\n";
4604 printDebugInfo(Reconstructed);
4606 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4607 Lines.push_back(std::move(Reconstructed));
4608 CurrentExpandedLines.clear();
4609 Reconstruct.reset();
4614 assert(!Reconstruct || (CurrentLines != &Lines) || !PPStack.empty());
4615 CurrentLines->push_back(std::move(*Line));
4617 Line->Tokens.clear();
4619 Line->FirstStartColumn = 0;
4620 Line->IsContinuation =
false;
4621 Line->SeenDecltypeAuto =
false;
4623 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4625 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4626 CurrentLines->append(
4627 std::make_move_iterator(PreprocessorDirectives.begin()),
4628 std::make_move_iterator(PreprocessorDirectives.end()));
4629 PreprocessorDirectives.clear();
4635bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4637bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4638 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4639 FormatTok.NewlinesBefore > 0;
4647 const llvm::Regex &CommentPragmasRegex) {
4651 StringRef IndentContent = FormatTok.
TokenText;
4652 if (FormatTok.
TokenText.starts_with(
"//") ||
4653 FormatTok.
TokenText.starts_with(
"/*")) {
4654 IndentContent = FormatTok.
TokenText.substr(2);
4656 if (CommentPragmasRegex.match(IndentContent))
4731 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4733 MinColumnToken = PreviousToken;
4736 PreviousToken =
Node.Tok;
4739 if (
Node.Tok->NewlinesBefore > 0)
4740 MinColumnToken =
Node.Tok;
4742 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4743 MinColumnToken = PreviousToken;
4749void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4750 bool JustComments = Line->Tokens.empty();
4751 for (FormatToken *Tok : CommentsBeforeNextToken) {
4760 Tok->ContinuesLineCommentSection =
4762 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4766 if (NewlineBeforeNext && JustComments)
4768 CommentsBeforeNextToken.clear();
4771void UnwrappedLineParser::nextToken(
int LevelDifference) {
4774 flushComments(isOnNewLine(*FormatTok));
4775 pushToken(FormatTok);
4778 readToken(LevelDifference);
4780 readTokenWithJavaScriptASI();
4790 FormatTok->Tok.setKind(tok::r_brace);
4794void UnwrappedLineParser::distributeComments(
4795 const ArrayRef<FormatToken *> &Comments,
const FormatToken *NextTok) {
4814 if (Comments.empty())
4816 bool ShouldPushCommentsInCurrentLine =
true;
4817 bool HasTrailAlignedWithNextToken =
false;
4818 unsigned StartOfTrailAlignedWithNextToken = 0;
4821 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4822 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4823 HasTrailAlignedWithNextToken =
true;
4824 StartOfTrailAlignedWithNextToken = i;
4828 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4829 FormatToken *FormatTok = Comments[i];
4830 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4831 FormatTok->ContinuesLineCommentSection =
false;
4834 *FormatTok, *Line, Style, CommentPragmasRegex);
4836 if (!FormatTok->ContinuesLineCommentSection &&
4837 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4838 ShouldPushCommentsInCurrentLine =
false;
4840 if (ShouldPushCommentsInCurrentLine)
4841 pushToken(FormatTok);
4843 CommentsBeforeNextToken.push_back(FormatTok);
4847void UnwrappedLineParser::readToken(
int LevelDifference) {
4848 SmallVector<FormatToken *, 1> Comments;
4849 bool PreviousWasComment =
false;
4850 bool FirstNonCommentOnLine =
false;
4852 FormatTok = Tokens->getNextToken();
4854 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4855 TT_ConflictAlternative)) {
4856 if (FormatTok->is(TT_ConflictStart))
4857 conditionalCompilationStart(
false);
4858 else if (FormatTok->is(TT_ConflictAlternative))
4859 conditionalCompilationAlternative();
4860 else if (FormatTok->is(TT_ConflictEnd))
4861 conditionalCompilationEnd();
4862 FormatTok = Tokens->getNextToken();
4863 FormatTok->MustBreakBefore =
true;
4864 FormatTok->MustBreakBeforeFinalized =
true;
4867 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4868 const FormatToken &Tok,
4869 bool PreviousWasComment) {
4870 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4871 return Tok.HasUnescapedNewline || Tok.IsFirst;
4876 if (PreviousWasComment)
4877 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4878 return IsFirstOnLine(Tok);
4881 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4882 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4883 PreviousWasComment = FormatTok->is(tok::comment);
4885 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4886 FirstNonCommentOnLine) {
4889 const auto *Next = Tokens->peekNextToken();
4892 !Next->isOneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,
4893 tok::pp_ifndef, tok::pp_endif))) {
4896 distributeComments(Comments, FormatTok);
4900 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4902 assert((LevelDifference >= 0 ||
4903 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4904 "LevelDifference makes Line->Level negative");
4905 Line->Level += LevelDifference;
4910 PPBranchLevel > 0) {
4911 Line->Level += PPBranchLevel;
4913 assert(Line->Level >= Line->UnbracedBodyLevel);
4914 Line->Level -= Line->UnbracedBodyLevel;
4915 flushComments(isOnNewLine(*FormatTok));
4917 PreviousWasComment = FormatTok->is(tok::comment);
4918 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4919 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4922 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4923 !Line->InPPDirective) {
4927 if (FormatTok->is(tok::identifier) &&
4928 Macros.
defined(FormatTok->TokenText) &&
4930 !Line->InPPDirective) {
4931 FormatToken *
ID = FormatTok;
4932 unsigned Position = Tokens->getPosition();
4936 auto PreCall = std::move(Line);
4937 Line.reset(
new UnwrappedLine);
4938 bool OldInExpansion = InExpansion;
4941 auto Args = parseMacroCall();
4942 InExpansion = OldInExpansion;
4943 assert(Line->Tokens.front().Tok ==
ID);
4945 auto UnexpandedLine = std::move(Line);
4947 Line = std::move(PreCall);
4950 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4952 llvm::dbgs() <<
"(";
4953 for (
const auto &Arg : Args.value())
4954 for (
const auto &
T : Arg)
4955 llvm::dbgs() <<
T->TokenText <<
" ";
4956 llvm::dbgs() <<
")";
4958 llvm::dbgs() <<
"\n";
4961 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4967 LLVM_DEBUG(llvm::dbgs()
4968 <<
"Macro \"" <<
ID->TokenText
4969 <<
"\" not overloaded for arity " << Args->size()
4970 <<
"or not function-like, using object-like overload.");
4972 UnexpandedLine->Tokens.resize(1);
4973 Tokens->setPosition(Position);
4978 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4981 Unexpanded[
ID] = std::move(UnexpandedLine);
4982 SmallVector<FormatToken *, 8> Expansion =
4983 Macros.
expand(
ID, std::move(Args));
4984 if (!Expansion.empty())
4985 FormatTok = Tokens->insertTokens(Expansion);
4988 llvm::dbgs() <<
"Expanded: ";
4989 for (
const auto &
T : Expansion)
4990 llvm::dbgs() <<
T->TokenText <<
" ";
4991 llvm::dbgs() <<
"\n";
4995 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4996 <<
"\", because it was used ";
4998 llvm::dbgs() <<
"with " << Args->size();
5000 llvm::dbgs() <<
"without";
5001 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
5003 Tokens->setPosition(Position);
5008 if (FormatTok->isNot(tok::comment)) {
5009 distributeComments(Comments, FormatTok);
5014 Comments.push_back(FormatTok);
5017 distributeComments(Comments,
nullptr);
5022template <
typename Iterator>
5023void pushTokens(Iterator
Begin, Iterator End,
5024 SmallVectorImpl<FormatToken *> &Into) {
5025 for (
auto I =
Begin; I != End; ++I) {
5026 Into.push_back(I->Tok);
5027 for (
const auto &Child : I->Children)
5028 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
5033std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
5034UnwrappedLineParser::parseMacroCall() {
5035 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
5036 assert(Line->Tokens.empty());
5038 if (FormatTok->isNot(tok::l_paren))
5040 unsigned Position = Tokens->getPosition();
5041 FormatToken *Tok = FormatTok;
5044 auto ArgStart = std::prev(Line->Tokens.end());
5048 switch (FormatTok->Tok.getKind()) {
5053 case tok::r_paren: {
5059 Args->push_back({});
5060 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5069 Args->push_back({});
5070 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5072 ArgStart = std::prev(Line->Tokens.end());
5080 Line->Tokens.resize(1);
5081 Tokens->setPosition(Position);
5086void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5087 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5088 if (AtEndOfPPLine) {
5089 auto &Tok = *Line->Tokens.back().Tok;
5090 Tok.MustBreakBefore =
true;
5091 Tok.MustBreakBeforeFinalized =
true;
5092 Tok.FirstAfterPPLine =
true;
5093 AtEndOfPPLine =
false;
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
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...
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(Ts... Ks) 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.