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 (
const auto *CI = I->Children.begin(), *CE = I->Children.end();
57 printLine(OS, *CI, (Prefix +
" ").str());
65LLVM_ATTRIBUTE_UNUSED
static void printDebugInfo(
const UnwrappedLine &
Line) {
66 printLine(llvm::dbgs(),
Line);
69class ScopedDeclarationState {
71 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
72 bool MustBeDeclaration)
73 : Line(Line), Stack(Stack) {
74 Line.MustBeDeclaration = MustBeDeclaration;
75 Stack.push_back(MustBeDeclaration);
77 ~ScopedDeclarationState() {
80 Line.MustBeDeclaration = Stack.back();
82 Line.MustBeDeclaration =
true;
87 llvm::BitVector &Stack;
93 llvm::raw_os_ostream OS(Stream);
101 bool SwitchToPreprocessorLines =
false)
103 if (SwitchToPreprocessorLines)
105 else if (!
Parser.Line->Tokens.empty())
106 Parser.CurrentLines = &
Parser.Line->Tokens.back().Children;
107 PreBlockLine = std::move(
Parser.Line);
108 Parser.Line = std::make_unique<UnwrappedLine>();
109 Parser.Line->Level = PreBlockLine->Level;
110 Parser.Line->PPLevel = PreBlockLine->PPLevel;
111 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
112 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
113 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;
117 if (!
Parser.Line->Tokens.empty())
118 Parser.addUnwrappedLine();
119 assert(
Parser.Line->Tokens.empty());
120 Parser.Line = std::move(PreBlockLine);
121 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
122 Parser.MustBreakBeforeNextToken =
true;
123 Parser.CurrentLines = OriginalLines;
129 std::unique_ptr<UnwrappedLine> PreBlockLine;
138 Style.BraceWrapping.AfterControlStatement,
139 Style.BraceWrapping.IndentBraces) {}
141 bool WrapBrace,
bool IndentBrace)
142 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
144 Parser->addUnwrappedLine();
152 unsigned OldLineLevel;
159 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
162 CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()),
164 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
165 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
166 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
169 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
170 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {
171 assert(IsCpp == LangOpts.CXXOperatorNames);
174void UnwrappedLineParser::reset() {
179 IncludeGuardToken =
nullptr;
181 CommentsBeforeNextToken.clear();
183 MustBreakBeforeNextToken =
false;
184 IsDecltypeAutoFunction =
false;
185 PreprocessorDirectives.clear();
186 CurrentLines = &Lines;
187 DeclarationScopeStack.clear();
188 NestedTooDeep.clear();
189 NestedLambdas.clear();
191 Line->FirstStartColumn = FirstStartColumn;
193 if (!Unexpanded.empty())
195 Token->MacroCtx.reset();
196 CurrentExpandedLines.clear();
197 ExpandedLines.clear();
205 Line->FirstStartColumn = FirstStartColumn;
207 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
209 Tokens = &TokenSource;
217 if (IncludeGuard == IG_Found) {
218 for (
auto &Line : Lines)
219 if (Line.InPPDirective && Line.Level > 0)
225 pushToken(FormatTok);
230 if (!ExpandedLines.empty()) {
231 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
232 for (
const auto &Line : Lines) {
233 if (!Line.Tokens.empty()) {
234 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
235 if (it != ExpandedLines.end()) {
236 for (
const auto &Expanded : it->second) {
237 LLVM_DEBUG(printDebugInfo(Expanded));
243 LLVM_DEBUG(printDebugInfo(Line));
249 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
251 LLVM_DEBUG(printDebugInfo(Line));
256 while (!PPLevelBranchIndex.empty() &&
257 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
258 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
259 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
261 if (!PPLevelBranchIndex.empty()) {
262 ++PPLevelBranchIndex.back();
263 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
264 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
266 }
while (!PPLevelBranchIndex.empty());
269void UnwrappedLineParser::parseFile() {
272 bool MustBeDeclaration = !Line->InPPDirective && !Style.
isJavaScript();
273 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
290 !CommentsBeforeNextToken.empty()) {
297void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
306 parseCSharpGenericTypeConstraint();
315void UnwrappedLineParser::parseCSharpAttribute() {
316 int UnpairedSquareBrackets = 1;
321 --UnpairedSquareBrackets;
322 if (UnpairedSquareBrackets == 0) {
328 ++UnpairedSquareBrackets;
338bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
339 if (!Lines.empty() && Lines.back().InPPDirective)
353bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
355 FormatToken **IfLeftBrace) {
356 const bool InRequiresExpression =
357 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
358 const bool IsPrecededByCommentOrPPDirective =
360 FormatToken *IfLBrace =
nullptr;
361 bool HasDoWhile =
false;
362 bool HasLabel =
false;
363 unsigned StatementCount = 0;
364 bool SwitchLabelEncountered =
false;
369 if (FormatTok->
is(tok::l_paren))
374 if (FormatTok->
is(TT_MacroBlockBegin))
376 else if (FormatTok->
is(TT_MacroBlockEnd))
379 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
380 &HasLabel, &StatementCount] {
381 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
382 HasDoWhile ?
nullptr : &HasDoWhile,
383 HasLabel ?
nullptr : &HasLabel);
385 assert(StatementCount > 0 &&
"StatementCount overflow!");
394 if (InRequiresExpression) {
403 if (!InRequiresExpression && FormatTok->
isNot(TT_MacroBlockBegin)) {
404 if (tryToParseBracedList())
410 assert(StatementCount > 0 &&
"StatementCount overflow!");
416 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
419 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
420 HasDoWhile || IsPrecededByCommentOrPPDirective ||
421 precededByCommentOrPPDirective()) {
425 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
428 *IfLeftBrace = IfLBrace;
434 case tok::kw_default: {
438 if (!Next->isOneOf(tok::colon, tok::arrow)) {
441 parseStructuralElement();
457 if (!SwitchLabelEncountered &&
459 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
460 (Line->InPPDirective && Line->Level == 1))) {
463 SwitchLabelEncountered =
true;
464 parseStructuralElement();
469 parseCSharpAttribute();
472 if (handleCppAttributes())
484void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
490 FormatToken *Tok = FormatTok;
491 const FormatToken *PrevTok = Tok->
Previous;
497 const FormatToken *PrevTok;
499 SmallVector<StackEntry, 8> LBraceStack;
500 assert(Tok->is(tok::l_brace));
505 if (!Line->InMacroBody && !Style.
isTableGen()) {
507 while (NextTok->is(tok::hash)) {
509 if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))
513 }
while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof));
515 while (NextTok->is(tok::comment))
520 switch (Tok->Tok.getKind()) {
523 if (PrevTok->isOneOf(tok::colon, tok::less)) {
534 }
else if (PrevTok->is(tok::r_paren)) {
541 LBraceStack.push_back({Tok, PrevTok});
544 if (LBraceStack.empty())
546 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
547 bool ProbablyBracedList =
false;
549 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
550 }
else if (LBrace->isNot(TT_EnumLBrace)) {
553 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
554 NextTok->OriginalColumn == 0;
564 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
566 ProbablyBracedList = ProbablyBracedList ||
568 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
571 ProbablyBracedList ||
572 (IsCpp && (PrevTok->Tok.isLiteral() ||
573 NextTok->isOneOf(tok::l_paren, tok::arrow)));
580 ProbablyBracedList ||
581 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
582 tok::r_paren, tok::r_square, tok::ellipsis);
587 ProbablyBracedList ||
588 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
589 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
593 ProbablyBracedList ||
594 (NextTok->is(tok::identifier) &&
595 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
597 ProbablyBracedList = ProbablyBracedList ||
598 (NextTok->is(tok::semi) &&
599 (!ExpectClassBody || LBraceStack.size() != 1));
602 ProbablyBracedList ||
603 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
605 if (!Style.
isCSharp() && NextTok->is(tok::l_square)) {
609 ProbablyBracedList = NextTok->
isNot(tok::l_square);
613 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
614 !FormatTok->
Previous && NextTok->
is(tok::eof) &&
618 !PrevTok->isOneOf(tok::semi,
BK_Block, tok::colon)) {
619 ProbablyBracedList =
true;
623 Tok->setBlockKind(BlockKind);
624 LBrace->setBlockKind(BlockKind);
626 LBraceStack.pop_back();
628 case tok::identifier:
629 if (Tok->isNot(TT_StatementMacro))
640 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
641 LBraceStack.back().Tok->setBlockKind(
BK_Block);
649 }
while (Tok->isNot(tok::eof) && !LBraceStack.empty());
652 for (
const auto &Entry : LBraceStack)
660void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
662 Prev && Prev->
is(tok::r_brace)) {
670 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
673size_t UnwrappedLineParser::computePPHash()
const {
675 for (
const auto &i : PPStack) {
686bool UnwrappedLineParser::mightFitOnOneLine(
687 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
689 if (ColumnLimit == 0)
692 auto &Tokens = ParsedLine.Tokens;
693 assert(!Tokens.empty());
695 const auto *LastToken = Tokens.back().Tok;
698 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
701 for (
const auto &Token : Tokens) {
703 auto &SavedToken = SavedTokens[Index++];
704 SavedToken.Tok =
new FormatToken;
705 SavedToken.Tok->copyFrom(*Token.Tok);
706 SavedToken.Children = std::move(Token.Children);
709 AnnotatedLine Line(ParsedLine);
710 assert(Line.Last == LastToken);
712 TokenAnnotator Annotator(Style, Keywords);
713 Annotator.annotate(Line);
714 Annotator.calculateFormattingInformation(Line);
716 auto Length = LastToken->TotalLength;
718 assert(OpeningBrace != Tokens.front().Tok);
719 if (
auto Prev = OpeningBrace->Previous;
720 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
721 Length -= ColumnLimit;
723 Length -= OpeningBrace->TokenText.size() + 1;
726 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
727 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
728 Length -= FirstToken->TokenText.size() + 1;
732 for (
auto &Token : Tokens) {
733 const auto &SavedToken = SavedTokens[Index++];
734 Token.Tok->copyFrom(*SavedToken.Tok);
735 Token.Children = std::move(SavedToken.Children);
736 delete SavedToken.Tok;
740 assert(!Line.InMacroBody);
741 assert(!Line.InPPDirective);
742 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
745FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
746 unsigned AddLevels,
bool MunchSemi,
749 bool UnindentWhitesmithsBraces) {
750 auto HandleVerilogBlockLabel = [
this]() {
752 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
761 const bool VerilogHierarchy =
763 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
766 "'{' or macro block token expected");
767 FormatToken *Tok = FormatTok;
768 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
769 auto Index = CurrentLines->size();
770 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
775 if (!VerilogHierarchy && AddLevels > 0 &&
780 size_t PPStartHash = computePPHash();
782 const unsigned InitialLevel = Line->Level;
783 if (VerilogHierarchy) {
784 AddLevels += parseVerilogHierarchyHeader();
786 nextToken(AddLevels);
787 HandleVerilogBlockLabel();
791 if (Line->Level > 300)
794 if (MacroBlock && FormatTok->
is(tok::l_paren))
797 size_t NbPreprocessorDirectives =
798 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
800 size_t OpeningLineIndex =
801 CurrentLines->empty()
803 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
808 if (UnindentWhitesmithsBraces)
811 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
814 Line->Level += AddLevels;
816 FormatToken *IfLBrace =
nullptr;
817 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
822 if (MacroBlock ? FormatTok->
isNot(TT_MacroBlockEnd)
823 : FormatTok->
isNot(tok::r_brace)) {
824 Line->Level = InitialLevel;
829 if (FormatTok->
is(tok::r_brace)) {
831 if (Tok->is(TT_NamespaceLBrace))
835 const bool IsFunctionRBrace =
836 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
838 auto RemoveBraces = [=]()
mutable {
841 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
842 assert(FormatTok->
is(tok::r_brace));
843 const bool WrappedOpeningBrace = !Tok->Previous;
844 if (WrappedOpeningBrace && FollowedByComment)
846 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
847 if (KeepBraces && !HasRequiredIfBraces)
849 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
850 const FormatToken *
Previous = Tokens->getPreviousToken();
855 assert(!CurrentLines->empty());
856 auto &LastLine = CurrentLines->back();
857 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
859 if (Tok->is(TT_ElseLBrace))
861 if (WrappedOpeningBrace) {
866 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
868 if (RemoveBraces()) {
869 Tok->MatchingParen = FormatTok;
873 size_t PPEndHash = computePPHash();
876 nextToken(-AddLevels);
882 while (FormatTok->
is(tok::semi)) {
888 HandleVerilogBlockLabel();
890 if (MacroBlock && FormatTok->
is(tok::l_paren))
893 Line->Level = InitialLevel;
895 if (FormatTok->
is(tok::kw_noexcept)) {
900 if (FormatTok->
is(tok::arrow)) {
904 parseStructuralElement();
907 if (MunchSemi && FormatTok->
is(tok::semi))
910 if (PPStartHash == PPEndHash) {
911 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
914 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
915 CurrentLines->size() - 1;
925 if (
Line.Tokens.size() < 4)
927 auto I =
Line.Tokens.begin();
928 if (I->Tok->TokenText !=
"goog")
931 if (I->Tok->isNot(tok::period))
934 if (I->Tok->TokenText !=
"scope")
937 return I->Tok->is(tok::l_paren);
946 if (
Line.Tokens.size() < 3)
948 auto I =
Line.Tokens.begin();
949 if (I->Tok->isNot(tok::l_paren))
955 return I->Tok->is(tok::l_paren);
961 if (InitialToken.
is(TT_NamespaceMacro))
962 Kind = tok::kw_namespace;
965 case tok::kw_namespace:
980void UnwrappedLineParser::parseChildBlock() {
981 assert(FormatTok->
is(tok::l_brace));
983 const FormatToken *OpeningBrace = FormatTok;
989 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
991 Line->Level += SkipIndent ? 0 : 1;
992 parseLevel(OpeningBrace);
993 flushComments(isOnNewLine(*FormatTok));
994 Line->Level -= SkipIndent ? 0 : 1;
999void UnwrappedLineParser::parsePPDirective() {
1000 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
1001 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
1011 case tok::pp_define:
1018 case tok::pp_ifndef:
1022 case tok::pp_elifdef:
1023 case tok::pp_elifndef:
1030 case tok::pp_pragma:
1034 case tok::pp_warning:
1036 if (!eof() && Style.
isCpp())
1045void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1046 size_t Line = CurrentLines->size();
1047 if (CurrentLines == &PreprocessorDirectives)
1048 Line += Lines.size();
1051 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1052 PPStack.push_back({PP_Unreachable, Line});
1054 PPStack.push_back({PP_Conditional, Line});
1058void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1060 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1061 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1062 PPLevelBranchIndex.push_back(0);
1063 PPLevelBranchCount.push_back(0);
1065 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1066 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1067 conditionalCompilationCondition(Unreachable ||
Skip);
1070void UnwrappedLineParser::conditionalCompilationAlternative() {
1071 if (!PPStack.empty())
1073 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1074 if (!PPChainBranchIndex.empty())
1075 ++PPChainBranchIndex.top();
1076 conditionalCompilationCondition(
1077 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1078 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1081void UnwrappedLineParser::conditionalCompilationEnd() {
1082 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1083 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1084 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1085 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1088 if (PPBranchLevel > -1)
1090 if (!PPChainBranchIndex.empty())
1091 PPChainBranchIndex.pop();
1092 if (!PPStack.empty())
1096void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1097 bool IfNDef = FormatTok->
is(tok::pp_ifndef);
1099 bool Unreachable =
false;
1100 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1102 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1104 conditionalCompilationStart(Unreachable);
1105 FormatToken *IfCondition = FormatTok;
1108 bool MaybeIncludeGuard = IfNDef;
1109 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1110 for (
auto &Line : Lines) {
1111 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1112 MaybeIncludeGuard =
false;
1113 IncludeGuard = IG_Rejected;
1121 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1122 IncludeGuard = IG_IfNdefed;
1123 IncludeGuardToken = IfCondition;
1127void UnwrappedLineParser::parsePPElse() {
1129 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1130 IncludeGuard = IG_Rejected;
1132 assert(PPBranchLevel >= -1);
1133 if (PPBranchLevel == -1)
1134 conditionalCompilationStart(
true);
1135 conditionalCompilationAlternative();
1141void UnwrappedLineParser::parsePPEndIf() {
1142 conditionalCompilationEnd();
1146 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1148 IncludeGuard = IG_Found;
1152void UnwrappedLineParser::parsePPDefine() {
1156 IncludeGuard = IG_Rejected;
1157 IncludeGuardToken =
nullptr;
1162 if (IncludeGuard == IG_IfNdefed &&
1164 IncludeGuard = IG_Defined;
1165 IncludeGuardToken =
nullptr;
1166 for (
auto &Line : Lines) {
1167 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1168 IncludeGuard = IG_Rejected;
1182 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1187 Line->Level += PPBranchLevel + 1;
1191 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1192 assert((
int)Line->PPLevel >= 0);
1193 Line->InMacroBody =
true;
1198 FormatTok = Tokens->getNextToken();
1212void UnwrappedLineParser::parsePPPragma() {
1213 Line->InPragmaDirective =
true;
1217void UnwrappedLineParser::parsePPUnknown() {
1221 Line->Level += PPBranchLevel + 1;
1231 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1234 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1235 tok::less, tok::greater, tok::slash, tok::percent,
1236 tok::lessless, tok::greatergreater, tok::equal,
1237 tok::plusequal, tok::minusequal, tok::starequal,
1238 tok::slashequal, tok::percentequal, tok::ampequal,
1239 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1252 return FormatTok->
is(tok::identifier) &&
1267 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1278 tok::kw_if, tok::kw_else,
1280 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1282 tok::kw_switch, tok::kw_case,
1284 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1286 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1294 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1295 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1312 if (FuncName->
isNot(tok::identifier))
1320 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1324 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1328 if (!Tok || Tok->
isNot(tok::r_paren))
1332 if (!Tok || Tok->
isNot(tok::identifier))
1338bool UnwrappedLineParser::parseModuleImport() {
1339 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1341 if (
auto Token = Tokens->peekNextToken(
true);
1343 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1349 if (FormatTok->
is(tok::colon)) {
1353 else if (FormatTok->
is(tok::less)) {
1355 while (!FormatTok->
isOneOf(tok::semi, tok::greater, tok::eof)) {
1358 if (FormatTok->
isNot(tok::comment) &&
1359 !FormatTok->
TokenText.starts_with(
"//")) {
1365 if (FormatTok->
is(tok::semi)) {
1383void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1386 FormatToken *Next = FormatTok;
1389 CommentsBeforeNextToken.empty()
1390 ? Next->NewlinesBefore == 0
1391 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1396 bool PreviousStartsTemplateExpr =
1398 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1401 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1402 return LineNode.Tok->is(tok::at);
1407 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1408 return addUnwrappedLine();
1410 bool NextEndsTemplateExpr =
1411 Next->is(TT_TemplateString) && Next->TokenText.starts_with(
"}");
1412 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1413 (PreviousMustBeValue ||
1414 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1415 tok::minusminus))) {
1416 return addUnwrappedLine();
1418 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1420 return addUnwrappedLine();
1424void UnwrappedLineParser::parseStructuralElement(
1425 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1426 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1428 FormatTok->
is(tok::pp_include)) {
1430 if (FormatTok->
is(tok::string_literal))
1437 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1441 parseForOrWhileLoop(
false);
1445 parseForOrWhileLoop();
1450 parseIfThenElse(IfKind,
false,
true);
1459 }
else if (FormatTok->
is(tok::l_paren) &&
1460 Tokens->peekNextToken()->is(tok::star)) {
1474 parseAccessSpecifier();
1481 if (FormatTok->
is(tok::l_brace)) {
1484 while (FormatTok && !eof()) {
1485 if (FormatTok->
is(tok::r_brace)) {
1496 case tok::kw_namespace:
1504 FormatToken *Tok = parseIfThenElse(IfKind);
1515 parseForOrWhileLoop();
1526 case tok::kw_switch:
1533 case tok::kw_default: {
1543 if (FormatTok->
is(tok::colon)) {
1548 if (FormatTok->
is(tok::arrow)) {
1550 Default->setFinalizedType(TT_SwitchExpressionLabel);
1577 if (FormatTok->
is(tok::kw_case))
1588 case tok::kw_extern:
1594 parseVerilogHierarchyHeader();
1597 }
else if (FormatTok->
is(tok::string_literal)) {
1599 if (FormatTok->
is(tok::l_brace)) {
1604 unsigned AddLevels =
1611 parseBlock(
true, AddLevels);
1617 case tok::kw_export:
1619 parseJavaScriptEs6ImportExport();
1624 if (FormatTok->
is(tok::kw_namespace)) {
1628 if (FormatTok->
is(tok::l_brace)) {
1629 parseCppExportBlock();
1632 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1636 case tok::kw_inline:
1638 if (FormatTok->
is(tok::kw_namespace)) {
1643 case tok::identifier:
1644 if (FormatTok->
is(TT_ForEachMacro)) {
1645 parseForOrWhileLoop();
1648 if (FormatTok->
is(TT_MacroBlockBegin)) {
1649 parseBlock(
false, 1u,
1655 parseJavaScriptEs6ImportExport();
1660 if (FormatTok->
is(tok::kw_public))
1662 if (FormatTok->
isNot(tok::string_literal))
1665 if (FormatTok->
is(tok::semi))
1670 if (IsCpp && parseModuleImport())
1676 if (FormatTok->
is(tok::colon)) {
1682 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1683 parseStatementMacro();
1686 if (IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1695 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1697 if (!Line->InMacroBody || CurrentLines->size() > 1)
1698 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1711 for (
const bool InRequiresExpression =
1712 OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
1713 TT_CompoundRequirementLBrace);
1716 if (
auto *Next = Tokens->peekNextToken(
true);
1717 Next && Next->isBinaryOperator()) {
1725 if (FormatTok->
is(tok::l_brace)) {
1735 case tok::objc_public:
1736 case tok::objc_protected:
1737 case tok::objc_package:
1738 case tok::objc_private:
1739 return parseAccessSpecifier();
1740 case tok::objc_interface:
1741 case tok::objc_implementation:
1742 return parseObjCInterfaceOrImplementation();
1743 case tok::objc_protocol:
1744 if (parseObjCProtocol())
1749 case tok::objc_optional:
1750 case tok::objc_required:
1754 case tok::objc_autoreleasepool:
1756 if (FormatTok->
is(tok::l_brace)) {
1765 case tok::objc_synchronized:
1767 if (FormatTok->
is(tok::l_paren)) {
1771 if (FormatTok->
is(tok::l_brace)) {
1789 case tok::kw_requires: {
1791 bool ParsedClause = parseRequires();
1817 case tok::kw_typedef:
1839 case tok::kw_struct:
1841 if (parseStructLike())
1844 case tok::kw_decltype:
1846 if (FormatTok->
is(tok::l_paren)) {
1851 Line->SeenDecltypeAuto =
true;
1859 FormatTok->
is(tok::kw_class)) {
1876 case tok::l_paren: {
1880 if (OpeningBrace || !IsCpp || !
Previous || eof())
1883 Tokens->peekNextToken(
true),
1890 case tok::kw_operator:
1901 while (FormatTok->
is(tok::star))
1905 if (FormatTok->
is(tok::l_paren))
1908 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();
2072 if (FormatTok->
is(tok::l_brace)) {
2081 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2083 parseBlock(
false, 1u,
2091 FormatTok->
is(tok::less)) {
2093 parseBracedList(
true);
2102 case tok::kw_switch:
2127 case tok::kw_default:
2130 if (FormatTok->
is(tok::colon)) {
2140 parseVerilogCaseLabel();
2147 parseVerilogCaseLabel();
2153 if (FormatTok->
is(tok::l_brace))
2163bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2164 assert(FormatTok->
is(tok::l_brace));
2176 unsigned int StoredPosition = Tokens->getPosition();
2177 FormatToken *Tok = Tokens->getNextToken();
2182 bool HasSpecialAccessor =
false;
2183 bool IsTrivialPropertyAccessor =
true;
2184 bool HasAttribute =
false;
2186 if (
const bool IsAccessorKeyword =
2188 IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||
2189 Tok->isOneOf(tok::l_square, tok::semi, Keywords.
kw_internal)) {
2190 if (IsAccessorKeyword)
2191 HasSpecialAccessor =
true;
2192 else if (Tok->is(tok::l_square))
2193 HasAttribute =
true;
2194 Tok = Tokens->getNextToken();
2197 if (Tok->isNot(tok::r_brace))
2198 IsTrivialPropertyAccessor =
false;
2202 if (!HasSpecialAccessor || HasAttribute) {
2203 Tokens->setPosition(StoredPosition);
2209 Tokens->setPosition(StoredPosition);
2217 if (FormatTok->
is(tok::equal)) {
2218 while (!eof() && FormatTok->
isNot(tok::semi))
2231 if (FormatTok->
is(TT_FatArrow)) {
2235 }
while (!eof() && FormatTok->
isNot(tok::semi));
2246 !IsTrivialPropertyAccessor) {
2258bool UnwrappedLineParser::tryToParseLambda() {
2259 assert(FormatTok->
is(tok::l_square));
2264 FormatToken &LSquare = *FormatTok;
2265 if (!tryToParseLambdaIntroducer())
2268 bool SeenArrow =
false;
2269 bool InTemplateParameterList =
false;
2271 while (FormatTok->
isNot(tok::l_brace)) {
2280 parseParens(TT_PointerOrReference);
2288 InTemplateParameterList =
true;
2293 case tok::kw_struct:
2295 case tok::kw_template:
2296 case tok::kw_typename:
2300 case tok::kw_constexpr:
2301 case tok::kw_consteval:
2304 case tok::identifier:
2305 case tok::numeric_constant:
2306 case tok::coloncolon:
2307 case tok::kw_mutable:
2308 case tok::kw_noexcept:
2309 case tok::kw_static:
2334 case tok::equalequal:
2335 case tok::exclaimequal:
2336 case tok::greaterequal:
2337 case tok::lessequal:
2343 if (SeenArrow || InTemplateParameterList) {
2356 case tok::kw_requires: {
2357 auto *RequiresToken = FormatTok;
2359 parseRequiresClause(RequiresToken);
2363 if (!InTemplateParameterList)
2373 LSquare.setFinalizedType(TT_LambdaLSquare);
2375 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2377 assert(!NestedLambdas.empty());
2378 NestedLambdas.pop_back();
2383bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2385 const FormatToken *LeftSquare = FormatTok;
2388 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2389 tok::kw_co_yield, tok::kw_co_return)) ||
2391 LeftSquare->isCppStructuredBinding(IsCpp)) {
2396 if (FormatTok->
is(tok::r_square)) {
2397 const FormatToken *Next = Tokens->peekNextToken(
true);
2398 if (Next->is(tok::greater))
2405void UnwrappedLineParser::tryToParseJSFunction() {
2413 if (FormatTok->
is(tok::star)) {
2419 if (FormatTok->
is(tok::identifier))
2422 if (FormatTok->
isNot(tok::l_paren))
2428 if (FormatTok->
is(tok::colon)) {
2434 if (FormatTok->
is(tok::l_brace))
2435 tryToParseBracedList();
2437 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2441 if (FormatTok->
is(tok::semi))
2447bool UnwrappedLineParser::tryToParseBracedList() {
2449 calculateBraceTypes();
2458bool UnwrappedLineParser::tryToParseChildBlock() {
2460 assert(FormatTok->
is(TT_FatArrow));
2465 if (FormatTok->
isNot(tok::l_brace))
2471bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2472 assert(!IsAngleBracket || !IsEnum);
2473 bool HasError =
false;
2478 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2479 tryToParseChildBlock()) {
2484 tryToParseJSFunction();
2487 if (FormatTok->
is(tok::l_brace)) {
2489 if (tryToParseBracedList())
2494 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2515 if (FormatTok->
is(tok::l_brace))
2524 if (!IsAngleBracket) {
2526 if (Prev && Prev->is(tok::greater))
2535 parseBracedList(
true);
2569bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2570 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2571 auto *LeftParen = FormatTok;
2572 bool SeenComma =
false;
2573 bool SeenEqual =
false;
2574 bool MightBeFoldExpr =
false;
2575 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2580 if (parseParens(AmpAmpTokenType))
2585 case tok::r_paren: {
2586 auto *Prev = LeftParen->Previous;
2587 if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
2589 const auto *Next = Tokens->peekNextToken();
2590 const bool DoubleParens =
2591 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2592 const bool CommaSeparated =
2593 !DoubleParens && Prev && Prev->isOneOf(tok::l_paren, tok::comma) &&
2594 Next && Next->isOneOf(tok::comma, tok::r_paren);
2595 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2596 const bool Excluded =
2598 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2601 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2602 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2603 const bool ReturnParens =
2605 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2606 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2607 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2608 Next->is(tok::semi);
2609 if ((DoubleParens && !Excluded) || (CommaSeparated && !SeenComma) ||
2611 LeftParen->Optional =
true;
2616 if (Prev->is(TT_TypenameMacro)) {
2617 LeftParen->setFinalizedType(TT_TypeDeclarationParen);
2619 }
else if (Prev->is(tok::greater) && FormatTok->
Previous == LeftParen) {
2620 Prev->setFinalizedType(TT_TemplateCloser);
2633 if (!tryToParseBracedList())
2638 if (FormatTok->
is(tok::l_brace)) {
2648 MightBeFoldExpr =
true;
2653 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2654 tryToParseChildBlock();
2664 case tok::identifier:
2666 tryToParseJSFunction();
2670 case tok::kw_switch:
2676 case tok::kw_requires: {
2677 auto RequiresToken = FormatTok;
2679 parseRequiresExpression(RequiresToken);
2683 if (AmpAmpTokenType != TT_Unknown)
2694void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2695 if (!LambdaIntroducer) {
2696 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2697 if (tryToParseLambda())
2714 case tok::l_brace: {
2715 if (!tryToParseBracedList())
2722 if (FormatTok->
is(tok::l_brace)) {
2734void UnwrappedLineParser::keepAncestorBraces() {
2738 const int MaxNestingLevels = 2;
2739 const int Size = NestedTooDeep.size();
2740 if (Size >= MaxNestingLevels)
2741 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2742 NestedTooDeep.push_back(
false);
2746 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2753void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2754 FormatToken *Tok =
nullptr;
2756 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2757 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2760 : Line->Tokens.back().Tok;
2762 if (Tok->BraceCount < 0) {
2763 assert(Tok->BraceCount == -1);
2766 Tok->BraceCount = -1;
2772 ++Line->UnbracedBodyLevel;
2773 parseStructuralElement();
2774 --Line->UnbracedBodyLevel;
2777 assert(!Line->InPPDirective);
2779 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2781 Tok = L.Tokens.back().Tok;
2789 if (CheckEOF && eof())
2799 assert(LeftBrace->
is(tok::l_brace));
2807 assert(RightBrace->
is(tok::r_brace));
2815void UnwrappedLineParser::handleAttributes() {
2819 else if (FormatTok->
is(tok::l_square))
2820 handleCppAttributes();
2823bool UnwrappedLineParser::handleCppAttributes() {
2825 assert(FormatTok->
is(tok::l_square));
2826 if (!tryToParseSimpleAttribute())
2833bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2837 : Tok.is(tok::l_brace);
2840FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2842 bool IsVerilogAssert) {
2843 assert((FormatTok->
is(tok::kw_if) ||
2850 if (IsVerilogAssert) {
2854 if (FormatTok->
is(tok::numeric_constant))
2871 if (FormatTok->
is(tok::exclaim))
2874 bool KeepIfBraces =
true;
2875 if (FormatTok->
is(tok::kw_consteval)) {
2879 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2881 if (FormatTok->
is(tok::l_paren)) {
2888 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2894 bool NeedsUnwrappedLine =
false;
2895 keepAncestorBraces();
2897 FormatToken *IfLeftBrace =
nullptr;
2898 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2900 if (isBlockBegin(*FormatTok)) {
2902 IfLeftBrace = FormatTok;
2904 parseBlock(
false, 1u,
2905 true, KeepIfBraces, &IfBlockKind);
2906 setPreviousRBraceType(TT_ControlStatementRBrace);
2910 NeedsUnwrappedLine =
true;
2911 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2914 parseUnbracedBody();
2918 assert(!NestedTooDeep.empty());
2919 KeepIfBraces = KeepIfBraces ||
2920 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2921 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2922 IfBlockKind == IfStmtKind::IfElseIf;
2925 bool KeepElseBraces = KeepIfBraces;
2926 FormatToken *ElseLeftBrace =
nullptr;
2927 IfStmtKind
Kind = IfStmtKind::IfOnly;
2929 if (FormatTok->
is(tok::kw_else)) {
2931 NestedTooDeep.back() =
false;
2932 Kind = IfStmtKind::IfElse;
2936 if (isBlockBegin(*FormatTok)) {
2937 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2939 ElseLeftBrace = FormatTok;
2941 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2942 FormatToken *IfLBrace =
2943 parseBlock(
false, 1u,
2944 true, KeepElseBraces, &ElseBlockKind);
2945 setPreviousRBraceType(TT_ElseRBrace);
2946 if (FormatTok->
is(tok::kw_else)) {
2947 KeepElseBraces = KeepElseBraces ||
2948 ElseBlockKind == IfStmtKind::IfOnly ||
2949 ElseBlockKind == IfStmtKind::IfElseIf;
2950 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2951 KeepElseBraces =
true;
2952 assert(ElseLeftBrace->MatchingParen);
2956 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2957 const FormatToken *
Previous = Tokens->getPreviousToken();
2959 const bool IsPrecededByComment =
Previous->is(tok::comment);
2960 if (IsPrecededByComment) {
2964 bool TooDeep =
true;
2966 Kind = IfStmtKind::IfElseIf;
2967 TooDeep = NestedTooDeep.pop_back_val();
2969 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2971 NestedTooDeep.push_back(TooDeep);
2972 if (IsPrecededByComment)
2975 parseUnbracedBody(
true);
2978 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2979 if (NeedsUnwrappedLine)
2986 assert(!NestedTooDeep.empty());
2987 KeepElseBraces = KeepElseBraces ||
2988 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2989 NestedTooDeep.back();
2991 NestedTooDeep.pop_back();
2993 if (!KeepIfBraces && !KeepElseBraces) {
2996 }
else if (IfLeftBrace) {
2997 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2999 assert(IfRightBrace->MatchingParen == IfLeftBrace);
3000 assert(!IfLeftBrace->Optional);
3001 assert(!IfRightBrace->Optional);
3002 IfLeftBrace->MatchingParen =
nullptr;
3003 IfRightBrace->MatchingParen =
nullptr;
3013void UnwrappedLineParser::parseTryCatch() {
3014 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
3016 bool NeedsUnwrappedLine =
false;
3017 bool HasCtorInitializer =
false;
3018 if (FormatTok->
is(tok::colon)) {
3019 auto *Colon = FormatTok;
3022 if (FormatTok->
is(tok::identifier)) {
3023 HasCtorInitializer =
true;
3024 Colon->setFinalizedType(TT_CtorInitializerColon);
3029 while (FormatTok->
is(tok::comma))
3032 while (FormatTok->
is(tok::identifier)) {
3034 if (FormatTok->
is(tok::l_paren)) {
3036 }
else if (FormatTok->
is(tok::l_brace)) {
3043 while (FormatTok->
is(tok::comma))
3051 keepAncestorBraces();
3053 if (FormatTok->
is(tok::l_brace)) {
3054 if (HasCtorInitializer)
3061 NeedsUnwrappedLine =
true;
3062 }
else if (FormatTok->
isNot(tok::kw_catch)) {
3068 parseStructuralElement();
3072 if (FormatTok->
is(tok::at))
3075 tok::kw___finally) ||
3083 while (FormatTok->
isNot(tok::l_brace)) {
3084 if (FormatTok->
is(tok::l_paren)) {
3088 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
3090 NestedTooDeep.pop_back();
3095 NeedsUnwrappedLine =
false;
3096 Line->MustBeDeclaration =
false;
3102 NeedsUnwrappedLine =
true;
3106 NestedTooDeep.pop_back();
3108 if (NeedsUnwrappedLine)
3112void UnwrappedLineParser::parseNamespaceOrExportBlock(
unsigned AddLevels) {
3113 bool ManageWhitesmithsBraces =
3118 if (ManageWhitesmithsBraces)
3123 parseBlock(
true, AddLevels,
true,
3124 true,
nullptr, ManageWhitesmithsBraces);
3126 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3128 if (ManageWhitesmithsBraces)
3132void UnwrappedLineParser::parseNamespace() {
3133 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3134 "'namespace' expected");
3136 const FormatToken &InitialToken = *FormatTok;
3138 if (InitialToken.is(TT_NamespaceMacro)) {
3141 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3142 tok::l_square, tok::period, tok::l_paren) ||
3143 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3144 if (FormatTok->
is(tok::l_square))
3146 else if (FormatTok->
is(tok::l_paren))
3152 if (FormatTok->
is(tok::l_brace)) {
3158 unsigned AddLevels =
3161 DeclarationScopeStack.size() > 1)
3164 parseNamespaceOrExportBlock(AddLevels);
3169void UnwrappedLineParser::parseCppExportBlock() {
3173void UnwrappedLineParser::parseNew() {
3174 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3180 if (FormatTok->
is(tok::l_paren))
3184 if (FormatTok->
is(tok::l_brace))
3187 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3200 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3204 if (FormatTok->
is(tok::l_paren)) {
3208 if (FormatTok->
is(tok::l_brace))
3216void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3217 keepAncestorBraces();
3219 if (isBlockBegin(*FormatTok)) {
3221 FormatToken *LeftBrace = FormatTok;
3223 parseBlock(
false, 1u,
3225 setPreviousRBraceType(TT_ControlStatementRBrace);
3227 assert(!NestedTooDeep.empty());
3228 if (!NestedTooDeep.back())
3234 parseUnbracedBody();
3238 NestedTooDeep.pop_back();
3241void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3242 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3249 "'for', 'while' or foreach macro expected");
3251 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3257 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3259 if (HasParens && FormatTok->
is(tok::l_paren)) {
3270 parseVerilogSensitivityList();
3272 Tokens->getPreviousToken()->is(tok::r_paren)) {
3279 parseLoopBody(KeepBraces,
true);
3282void UnwrappedLineParser::parseDoWhile() {
3283 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3289 if (FormatTok->
isNot(tok::kw_while)) {
3302 parseStructuralElement();
3305void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3307 unsigned OldLineLevel = Line->Level;
3311 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3315 FormatTok->
is(tok::l_brace)) {
3321 if (FormatTok->
is(tok::kw_break)) {
3330 parseStructuralElement();
3334 if (FormatTok->
is(tok::semi))
3338 Line->Level = OldLineLevel;
3339 if (FormatTok->
isNot(tok::l_brace)) {
3340 parseStructuralElement();
3345void UnwrappedLineParser::parseCaseLabel() {
3346 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3347 auto *Case = FormatTok;
3352 if (FormatTok->
is(tok::colon)) {
3358 Case->setFinalizedType(TT_SwitchExpressionLabel);
3365void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3366 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3368 if (FormatTok->
is(tok::l_paren))
3371 keepAncestorBraces();
3373 if (FormatTok->
is(tok::l_brace)) {
3376 : TT_ControlStatementLBrace);
3381 setPreviousRBraceType(TT_ControlStatementRBrace);
3387 parseStructuralElement();
3392 NestedTooDeep.pop_back();
3402 case tok::caretequal:
3406 case tok::equalequal:
3408 case tok::exclaimequal:
3410 case tok::greaterequal:
3411 case tok::greatergreater:
3412 case tok::greatergreaterequal:
3416 case tok::lessequal:
3418 case tok::lesslessequal:
3420 case tok::minusequal:
3421 case tok::minusminus:
3423 case tok::percentequal:
3426 case tok::pipeequal:
3429 case tok::plusequal:
3437 case tok::slashequal:
3439 case tok::starequal:
3446void UnwrappedLineParser::parseAccessSpecifier() {
3447 FormatToken *AccessSpecifierCandidate = FormatTok;
3453 if (FormatTok->
is(tok::colon)) {
3456 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3460 }
else if (AccessSpecifierCandidate) {
3462 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3469bool UnwrappedLineParser::parseRequires() {
3470 assert(FormatTok->
is(tok::kw_requires) &&
"'requires' expected");
3471 auto RequiresToken = FormatTok;
3480 parseRequiresExpression(RequiresToken);
3487 parseRequiresClause(RequiresToken);
3498 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3500 if (!PreviousNonComment ||
3501 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3504 parseRequiresClause(RequiresToken);
3508 switch (PreviousNonComment->Tok.getKind()) {
3511 case tok::kw_noexcept:
3515 parseRequiresClause(RequiresToken);
3524 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3525 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3526 parseRequiresClause(RequiresToken);
3532 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3534 parseRequiresClause(RequiresToken);
3538 parseRequiresExpression(RequiresToken);
3548 unsigned StoredPosition = Tokens->getPosition();
3549 FormatToken *NextToken = Tokens->getNextToken();
3551 auto PeekNext = [&Lookahead, &NextToken,
this] {
3553 NextToken = Tokens->getNextToken();
3556 bool FoundType =
false;
3557 bool LastWasColonColon =
false;
3560 for (; Lookahead < 50; PeekNext()) {
3561 switch (NextToken->Tok.getKind()) {
3562 case tok::kw_volatile:
3565 if (OpenAngles == 0) {
3566 FormatTok = Tokens->setPosition(StoredPosition);
3567 parseRequiresExpression(RequiresToken);
3575 case tok::coloncolon:
3576 LastWasColonColon =
true;
3578 case tok::kw_decltype:
3579 case tok::identifier:
3580 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3581 FormatTok = Tokens->setPosition(StoredPosition);
3582 parseRequiresExpression(RequiresToken);
3586 LastWasColonColon =
false;
3595 if (NextToken->isTypeName(LangOpts)) {
3596 FormatTok = Tokens->setPosition(StoredPosition);
3597 parseRequiresExpression(RequiresToken);
3604 FormatTok = Tokens->setPosition(StoredPosition);
3605 parseRequiresClause(RequiresToken);
3616void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3618 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3623 bool InRequiresExpression =
3624 !RequiresToken->Previous ||
3625 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3627 RequiresToken->setFinalizedType(InRequiresExpression
3628 ? TT_RequiresClauseInARequiresExpression
3629 : TT_RequiresClause);
3633 parseConstraintExpression();
3635 if (!InRequiresExpression)
3646void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3648 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3650 RequiresToken->setFinalizedType(TT_RequiresExpression);
3652 if (FormatTok->
is(tok::l_paren)) {
3657 if (FormatTok->
is(tok::l_brace)) {
3667void UnwrappedLineParser::parseConstraintExpression() {
3674 bool LambdaNextTimeAllowed =
true;
3684 bool TopLevelParensAllowed =
true;
3687 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3690 case tok::kw_requires: {
3691 auto RequiresToken = FormatTok;
3693 parseRequiresExpression(RequiresToken);
3698 if (!TopLevelParensAllowed)
3700 parseParens(TT_BinaryOperator);
3701 TopLevelParensAllowed =
false;
3705 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3712 case tok::kw_struct:
3724 LambdaNextTimeAllowed =
true;
3725 TopLevelParensAllowed =
true;
3730 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3734 case tok::kw_sizeof:
3736 case tok::greaterequal:
3737 case tok::greatergreater:
3739 case tok::lessequal:
3741 case tok::equalequal:
3743 case tok::exclaimequal:
3748 LambdaNextTimeAllowed =
true;
3749 TopLevelParensAllowed =
true;
3754 case tok::numeric_constant:
3755 case tok::coloncolon:
3758 TopLevelParensAllowed =
false;
3763 case tok::kw_static_cast:
3764 case tok::kw_const_cast:
3765 case tok::kw_reinterpret_cast:
3766 case tok::kw_dynamic_cast:
3768 if (FormatTok->
isNot(tok::less))
3772 parseBracedList(
true);
3788 case tok::coloncolon:
3792 case tok::kw_requires:
3801 if (FormatTok->
is(tok::less)) {
3803 parseBracedList(
true);
3805 TopLevelParensAllowed =
false;
3811bool UnwrappedLineParser::parseEnum() {
3812 const FormatToken &InitialToken = *FormatTok;
3815 if (FormatTok->
is(tok::kw_enum))
3830 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3832 while (FormatTok->
is(tok::l_square))
3833 if (!handleCppAttributes())
3838 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3839 tok::greater, tok::comma, tok::question,
3845 while (FormatTok->
is(tok::l_square))
3851 if (FormatTok->
is(tok::l_paren))
3853 if (FormatTok->
is(tok::identifier)) {
3857 if (IsCpp && FormatTok->
is(tok::identifier))
3863 if (FormatTok->
isNot(tok::l_brace))
3870 parseJavaEnumBody();
3888 bool HasError = !parseBracedList(
false,
true);
3892 if (FormatTok->
is(tok::semi))
3896 setPreviousRBraceType(TT_EnumRBrace);
3904bool UnwrappedLineParser::parseStructLike() {
3911 if (FormatTok->
is(tok::semi))
3922class ScopedTokenPosition {
3923 unsigned StoredPosition;
3924 FormatTokenSource *Tokens;
3927 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3928 assert(Tokens &&
"Tokens expected to not be null");
3929 StoredPosition = Tokens->getPosition();
3932 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3938bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3939 ScopedTokenPosition AutoPosition(Tokens);
3940 FormatToken *Tok = Tokens->getNextToken();
3942 if (Tok->isNot(tok::l_square))
3946 while (Tok->isNot(tok::eof)) {
3947 if (Tok->is(tok::r_square))
3949 Tok = Tokens->getNextToken();
3951 if (Tok->is(tok::eof))
3953 Tok = Tokens->getNextToken();
3954 if (Tok->isNot(tok::r_square))
3956 Tok = Tokens->getNextToken();
3957 if (Tok->is(tok::semi))
3962void UnwrappedLineParser::parseJavaEnumBody() {
3963 assert(FormatTok->
is(tok::l_brace));
3964 const FormatToken *OpeningBrace = FormatTok;
3969 unsigned StoredPosition = Tokens->getPosition();
3970 bool IsSimple =
true;
3971 FormatToken *Tok = Tokens->getNextToken();
3972 while (Tok->isNot(tok::eof)) {
3973 if (Tok->is(tok::r_brace))
3975 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3981 Tok = Tokens->getNextToken();
3983 FormatTok = Tokens->setPosition(StoredPosition);
4000 if (FormatTok->
is(tok::l_brace)) {
4002 parseBlock(
true, 1u,
4004 }
else if (FormatTok->
is(tok::l_paren)) {
4006 }
else if (FormatTok->
is(tok::comma)) {
4009 }
else if (FormatTok->
is(tok::semi)) {
4013 }
else if (FormatTok->
is(tok::r_brace)) {
4022 parseLevel(OpeningBrace);
4028void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
4029 const FormatToken &InitialToken = *FormatTok;
4032 const FormatToken *ClassName =
nullptr;
4033 bool IsDerived =
false;
4034 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
4035 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
4039 bool JSPastExtendsOrImplements =
false;
4043 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
4044 tok::kw_alignas, tok::l_square) ||
4047 FormatTok->
isOneOf(tok::period, tok::comma))) {
4050 JSPastExtendsOrImplements =
true;
4055 if (FormatTok->
is(tok::l_brace)) {
4056 tryToParseBracedList();
4060 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
4067 if (!IsNonMacroIdentifier(
Previous) ||
4069 Previous->Previous == &InitialToken) {
4073 case tok::coloncolon:
4077 if (!JSPastExtendsOrImplements && !ClassName &&
4084 auto IsListInitialization = [&] {
4085 if (!ClassName || IsDerived || JSPastExtendsOrImplements)
4087 assert(FormatTok->
is(tok::l_brace));
4090 return Prev != ClassName && Prev->is(tok::identifier) &&
4091 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
4094 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
4095 int AngleNestingLevel = 0;
4097 if (FormatTok->
is(tok::less))
4098 ++AngleNestingLevel;
4099 else if (FormatTok->
is(tok::greater))
4100 --AngleNestingLevel;
4102 if (AngleNestingLevel == 0) {
4103 if (FormatTok->
is(tok::colon)) {
4105 }
else if (FormatTok->
is(tok::identifier) &&
4107 ClassName = FormatTok;
4108 }
else if (FormatTok->
is(tok::l_paren) &&
4109 IsNonMacroIdentifier(FormatTok->
Previous)) {
4113 if (FormatTok->
is(tok::l_brace)) {
4114 if (AngleNestingLevel == 0 && IsListInitialization())
4116 calculateBraceTypes(
true);
4117 if (!tryToParseBracedList())
4120 if (FormatTok->
is(tok::l_square)) {
4123 !
Previous->isTypeOrIdentifier(LangOpts))) {
4126 if (!tryToParseLambda())
4133 if (FormatTok->
is(tok::semi))
4138 parseCSharpGenericTypeConstraint();
4145 auto GetBraceTypes =
4146 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4147 switch (RecordTok.Tok.getKind()) {
4149 return {TT_ClassLBrace, TT_ClassRBrace};
4150 case tok::kw_struct:
4151 return {TT_StructLBrace, TT_StructRBrace};
4153 return {TT_UnionLBrace, TT_UnionRBrace};
4156 return {TT_RecordLBrace, TT_RecordRBrace};
4159 if (FormatTok->
is(tok::l_brace)) {
4160 if (IsListInitialization())
4162 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4171 parseBlock(
true, AddLevels,
false);
4173 setPreviousRBraceType(ClosingBraceType);
4180void UnwrappedLineParser::parseObjCMethod() {
4181 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4182 "'(' or identifier expected.");
4184 if (FormatTok->
is(tok::semi)) {
4188 }
else if (FormatTok->
is(tok::l_brace)) {
4200void UnwrappedLineParser::parseObjCProtocolList() {
4201 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4205 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4209 }
while (!eof() && FormatTok->
isNot(tok::greater));
4213void UnwrappedLineParser::parseObjCUntilAtEnd() {
4220 if (FormatTok->
is(tok::l_brace)) {
4224 }
else if (FormatTok->
is(tok::r_brace)) {
4228 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4232 parseStructuralElement();
4237void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4245 if (FormatTok->
is(tok::less))
4246 parseObjCLightweightGenerics();
4247 if (FormatTok->
is(tok::colon)) {
4251 if (FormatTok->
is(tok::less))
4252 parseObjCLightweightGenerics();
4253 }
else if (FormatTok->
is(tok::l_paren)) {
4258 if (FormatTok->
is(tok::less))
4259 parseObjCProtocolList();
4261 if (FormatTok->
is(tok::l_brace)) {
4271 parseObjCUntilAtEnd();
4274void UnwrappedLineParser::parseObjCLightweightGenerics() {
4275 assert(FormatTok->
is(tok::less));
4283 unsigned NumOpenAngles = 1;
4287 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4291 if (FormatTok->
is(tok::less)) {
4293 }
else if (FormatTok->
is(tok::greater)) {
4294 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4297 }
while (!eof() && NumOpenAngles != 0);
4303bool UnwrappedLineParser::parseObjCProtocol() {
4307 if (FormatTok->
is(tok::l_paren)) {
4319 if (FormatTok->
is(tok::less))
4320 parseObjCProtocolList();
4323 if (FormatTok->
is(tok::semi)) {
4330 parseObjCUntilAtEnd();
4334void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4335 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4336 assert(IsImport || FormatTok->
is(tok::kw_export));
4340 if (FormatTok->
is(tok::kw_default))
4357 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4360 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4365 if (FormatTok->
is(tok::semi))
4367 if (Line->Tokens.empty()) {
4372 if (FormatTok->
is(tok::l_brace)) {
4382void UnwrappedLineParser::parseStatementMacro() {
4384 if (FormatTok->
is(tok::l_paren))
4386 if (FormatTok->
is(tok::semi))
4391void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4394 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4395 tok::coloncolon, tok::hash) ||
4398 }
else if (FormatTok->
is(tok::l_square)) {
4406void UnwrappedLineParser::parseVerilogSensitivityList() {
4407 if (FormatTok->
isNot(tok::at))
4411 if (FormatTok->
is(tok::at))
4421 parseVerilogHierarchyIdentifier();
4426unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4427 unsigned AddLevels = 0;
4433 parseVerilogSensitivityList();
4434 if (FormatTok->
is(tok::semi))
4442 if (FormatTok->
is(tok::l_paren)) {
4455 if (FormatTok->
is(tok::l_square)) {
4461 FormatTok->
isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
4471 Line->IsContinuation =
true;
4478 parseVerilogHierarchyIdentifier();
4479 if (FormatTok->
is(tok::semi))
4487 if (FormatTok->
is(tok::l_paren)) {
4492 if (FormatTok->
is(tok::l_paren)) {
4502 parseVerilogHierarchyIdentifier();
4503 if (FormatTok->
is(tok::l_paren))
4510 parseVerilogHierarchyIdentifier();
4511 }
while (FormatTok->
is(tok::comma));
4515 if (FormatTok->
is(tok::at)) {
4517 parseVerilogSensitivityList();
4520 if (FormatTok->
is(tok::semi))
4528void UnwrappedLineParser::parseVerilogTable() {
4533 auto InitialLevel = Line->Level++;
4535 FormatToken *Tok = FormatTok;
4537 if (Tok->is(tok::semi))
4539 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4540 Tok->setFinalizedType(TT_VerilogTableItem);
4542 Line->Level = InitialLevel;
4547void UnwrappedLineParser::parseVerilogCaseLabel() {
4553 auto OrigLevel = Line->Level;
4554 auto FirstLine = CurrentLines->size();
4555 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4559 parseStructuralElement();
4562 if (CurrentLines->size() > FirstLine)
4563 (*CurrentLines)[FirstLine].Level = OrigLevel;
4564 Line->Level = OrigLevel;
4567bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4568 for (
const auto &N : Line.Tokens) {
4569 if (N.Tok->MacroCtx)
4571 for (
const UnwrappedLine &Child : N.Children)
4572 if (containsExpansion(Child))
4578void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4579 if (Line->Tokens.empty())
4582 if (!parsingPPDirective()) {
4583 llvm::dbgs() <<
"Adding unwrapped line:\n";
4584 printDebugInfo(*Line);
4592 bool ClosesWhitesmithsBlock =
4599 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4601 Reconstruct.emplace(Line->Level, Unexpanded);
4602 Reconstruct->addLine(*Line);
4607 CurrentExpandedLines.push_back(std::move(*Line));
4609 if (Reconstruct->finished()) {
4610 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4611 assert(!Reconstructed.Tokens.empty() &&
4612 "Reconstructed must at least contain the macro identifier.");
4613 assert(!parsingPPDirective());
4615 llvm::dbgs() <<
"Adding unexpanded line:\n";
4616 printDebugInfo(Reconstructed);
4618 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4619 Lines.push_back(std::move(Reconstructed));
4620 CurrentExpandedLines.clear();
4621 Reconstruct.reset();
4626 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4627 CurrentLines->push_back(std::move(*Line));
4629 Line->Tokens.clear();
4631 Line->FirstStartColumn = 0;
4632 Line->IsContinuation =
false;
4633 Line->SeenDecltypeAuto =
false;
4635 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4637 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4638 CurrentLines->append(
4639 std::make_move_iterator(PreprocessorDirectives.begin()),
4640 std::make_move_iterator(PreprocessorDirectives.end()));
4641 PreprocessorDirectives.clear();
4647bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4649bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4650 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4651 FormatTok.NewlinesBefore > 0;
4659 const llvm::Regex &CommentPragmasRegex) {
4663 StringRef IndentContent = FormatTok.
TokenText;
4664 if (FormatTok.
TokenText.starts_with(
"//") ||
4665 FormatTok.
TokenText.starts_with(
"/*")) {
4666 IndentContent = FormatTok.
TokenText.substr(2);
4668 if (CommentPragmasRegex.match(IndentContent))
4743 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4745 MinColumnToken = PreviousToken;
4748 PreviousToken =
Node.Tok;
4751 if (
Node.Tok->NewlinesBefore > 0)
4752 MinColumnToken =
Node.Tok;
4754 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4755 MinColumnToken = PreviousToken;
4761void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4762 bool JustComments = Line->Tokens.empty();
4763 for (FormatToken *Tok : CommentsBeforeNextToken) {
4772 Tok->ContinuesLineCommentSection =
4774 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4778 if (NewlineBeforeNext && JustComments)
4780 CommentsBeforeNextToken.clear();
4783void UnwrappedLineParser::nextToken(
int LevelDifference) {
4786 flushComments(isOnNewLine(*FormatTok));
4787 pushToken(FormatTok);
4790 readToken(LevelDifference);
4792 readTokenWithJavaScriptASI();
4802 FormatTok->Tok.setKind(tok::r_brace);
4806void UnwrappedLineParser::distributeComments(
4807 const ArrayRef<FormatToken *> &Comments,
const FormatToken *NextTok) {
4826 if (Comments.empty())
4828 bool ShouldPushCommentsInCurrentLine =
true;
4829 bool HasTrailAlignedWithNextToken =
false;
4830 unsigned StartOfTrailAlignedWithNextToken = 0;
4833 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4834 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4835 HasTrailAlignedWithNextToken =
true;
4836 StartOfTrailAlignedWithNextToken = i;
4840 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4841 FormatToken *FormatTok = Comments[i];
4842 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4843 FormatTok->ContinuesLineCommentSection =
false;
4846 *FormatTok, *Line, Style, CommentPragmasRegex);
4848 if (!FormatTok->ContinuesLineCommentSection &&
4849 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4850 ShouldPushCommentsInCurrentLine =
false;
4852 if (ShouldPushCommentsInCurrentLine)
4853 pushToken(FormatTok);
4855 CommentsBeforeNextToken.push_back(FormatTok);
4859void UnwrappedLineParser::readToken(
int LevelDifference) {
4860 SmallVector<FormatToken *, 1> Comments;
4861 bool PreviousWasComment =
false;
4862 bool FirstNonCommentOnLine =
false;
4864 FormatTok = Tokens->getNextToken();
4866 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4867 TT_ConflictAlternative)) {
4868 if (FormatTok->is(TT_ConflictStart))
4869 conditionalCompilationStart(
false);
4870 else if (FormatTok->is(TT_ConflictAlternative))
4871 conditionalCompilationAlternative();
4872 else if (FormatTok->is(TT_ConflictEnd))
4873 conditionalCompilationEnd();
4874 FormatTok = Tokens->getNextToken();
4875 FormatTok->MustBreakBefore =
true;
4876 FormatTok->MustBreakBeforeFinalized =
true;
4879 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4880 const FormatToken &Tok,
4881 bool PreviousWasComment) {
4882 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4883 return Tok.HasUnescapedNewline || Tok.IsFirst;
4888 if (PreviousWasComment)
4889 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4890 return IsFirstOnLine(Tok);
4893 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4894 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4895 PreviousWasComment = FormatTok->is(tok::comment);
4897 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4900 FirstNonCommentOnLine) {
4901 distributeComments(Comments, FormatTok);
4905 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4907 assert((LevelDifference >= 0 ||
4908 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4909 "LevelDifference makes Line->Level negative");
4910 Line->Level += LevelDifference;
4915 PPBranchLevel > 0) {
4916 Line->Level += PPBranchLevel;
4918 assert(Line->Level >= Line->UnbracedBodyLevel);
4919 Line->Level -= Line->UnbracedBodyLevel;
4920 flushComments(isOnNewLine(*FormatTok));
4922 PreviousWasComment = FormatTok->is(tok::comment);
4923 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4924 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4927 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4928 !Line->InPPDirective) {
4932 if (FormatTok->is(tok::identifier) &&
4933 Macros.
defined(FormatTok->TokenText) &&
4935 !Line->InPPDirective) {
4936 FormatToken *
ID = FormatTok;
4937 unsigned Position = Tokens->getPosition();
4941 auto PreCall = std::move(Line);
4942 Line.reset(
new UnwrappedLine);
4943 bool OldInExpansion = InExpansion;
4946 auto Args = parseMacroCall();
4947 InExpansion = OldInExpansion;
4948 assert(Line->Tokens.front().Tok ==
ID);
4950 auto UnexpandedLine = std::move(Line);
4952 Line = std::move(PreCall);
4955 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4957 llvm::dbgs() <<
"(";
4958 for (
const auto &Arg : Args.value())
4959 for (
const auto &
T : Arg)
4960 llvm::dbgs() <<
T->TokenText <<
" ";
4961 llvm::dbgs() <<
")";
4963 llvm::dbgs() <<
"\n";
4966 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4972 LLVM_DEBUG(llvm::dbgs()
4973 <<
"Macro \"" <<
ID->TokenText
4974 <<
"\" not overloaded for arity " << Args->size()
4975 <<
"or not function-like, using object-like overload.");
4977 UnexpandedLine->Tokens.resize(1);
4978 Tokens->setPosition(Position);
4983 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4986 Unexpanded[
ID] = std::move(UnexpandedLine);
4987 SmallVector<FormatToken *, 8> Expansion =
4988 Macros.
expand(
ID, std::move(Args));
4989 if (!Expansion.empty())
4990 FormatTok = Tokens->insertTokens(Expansion);
4993 llvm::dbgs() <<
"Expanded: ";
4994 for (
const auto &
T : Expansion)
4995 llvm::dbgs() <<
T->TokenText <<
" ";
4996 llvm::dbgs() <<
"\n";
5000 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
5001 <<
"\", because it was used ";
5003 llvm::dbgs() <<
"with " << Args->size();
5005 llvm::dbgs() <<
"without";
5006 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
5008 Tokens->setPosition(Position);
5013 if (FormatTok->isNot(tok::comment)) {
5014 distributeComments(Comments, FormatTok);
5019 Comments.push_back(FormatTok);
5022 distributeComments(Comments,
nullptr);
5027template <
typename Iterator>
5028void pushTokens(Iterator
Begin, Iterator End,
5029 SmallVectorImpl<FormatToken *> &Into) {
5030 for (
auto I =
Begin; I != End; ++I) {
5031 Into.push_back(I->Tok);
5032 for (
const auto &Child : I->Children)
5033 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
5038std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
5039UnwrappedLineParser::parseMacroCall() {
5040 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
5041 assert(Line->Tokens.empty());
5043 if (FormatTok->isNot(tok::l_paren))
5045 unsigned Position = Tokens->getPosition();
5046 FormatToken *Tok = FormatTok;
5049 auto ArgStart = std::prev(Line->Tokens.end());
5053 switch (FormatTok->Tok.getKind()) {
5058 case tok::r_paren: {
5064 Args->push_back({});
5065 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5074 Args->push_back({});
5075 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5077 ArgStart = std::prev(Line->Tokens.end());
5085 Line->Tokens.resize(1);
5086 Tokens->setPosition(Position);
5091void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5092 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5093 if (MustBreakBeforeNextToken) {
5094 Line->Tokens.back().Tok->MustBreakBefore =
true;
5095 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
5096 MustBreakBeforeNextToken =
false;
enum clang::sema::@1726::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.