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->is(tok::pp_not_keyword))
513 }
while (!NextTok->HasUnescapedNewline && 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(Keywords.
kw_import) && parseModuleImport())
1632 case tok::kw_inline:
1634 if (FormatTok->
is(tok::kw_namespace)) {
1639 case tok::identifier:
1640 if (FormatTok->
is(TT_ForEachMacro)) {
1641 parseForOrWhileLoop();
1644 if (FormatTok->
is(TT_MacroBlockBegin)) {
1645 parseBlock(
false, 1u,
1651 parseJavaScriptEs6ImportExport();
1656 if (FormatTok->
is(tok::kw_public))
1658 if (FormatTok->
isNot(tok::string_literal))
1661 if (FormatTok->
is(tok::semi))
1666 if (IsCpp && parseModuleImport())
1672 if (FormatTok->
is(tok::colon)) {
1678 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1679 parseStatementMacro();
1682 if (IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1691 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1693 if (!Line->InMacroBody || CurrentLines->size() > 1)
1694 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1707 for (
const bool InRequiresExpression =
1708 OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
1709 TT_CompoundRequirementLBrace);
1712 if (
auto *Next = Tokens->peekNextToken(
true);
1713 Next && Next->isBinaryOperator()) {
1721 if (FormatTok->
is(tok::l_brace)) {
1731 case tok::objc_public:
1732 case tok::objc_protected:
1733 case tok::objc_package:
1734 case tok::objc_private:
1735 return parseAccessSpecifier();
1736 case tok::objc_interface:
1737 case tok::objc_implementation:
1738 return parseObjCInterfaceOrImplementation();
1739 case tok::objc_protocol:
1740 if (parseObjCProtocol())
1745 case tok::objc_optional:
1746 case tok::objc_required:
1750 case tok::objc_autoreleasepool:
1752 if (FormatTok->
is(tok::l_brace)) {
1761 case tok::objc_synchronized:
1763 if (FormatTok->
is(tok::l_paren)) {
1767 if (FormatTok->
is(tok::l_brace)) {
1785 case tok::kw_requires: {
1787 bool ParsedClause = parseRequires();
1813 case tok::kw_typedef:
1835 case tok::kw_struct:
1837 if (parseStructLike())
1840 case tok::kw_decltype:
1842 if (FormatTok->
is(tok::l_paren)) {
1847 Line->SeenDecltypeAuto =
true;
1855 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:
1897 while (FormatTok->
is(tok::star))
1901 if (FormatTok->
is(tok::l_paren))
1904 if (FormatTok->
is(tok::l_brace))
1908 if (InRequiresExpression)
1910 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1911 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1930 IsDecltypeAutoFunction =
false;
1948 case tok::identifier: {
1950 Line->MustBeDeclaration) {
1952 parseCSharpGenericTypeConstraint();
1955 if (FormatTok->
is(TT_MacroBlockEnd)) {
1964 size_t TokenCount = Line->Tokens.size();
1968 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1969 tryToParseJSFunction();
1979 unsigned StoredPosition = Tokens->getPosition();
1980 FormatToken *Next = Tokens->getNextToken();
1981 FormatTok = Tokens->setPosition(StoredPosition);
1994 parseVerilogTable();
2006 if (parseStructLike())
2011 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
2012 parseStatementMacro();
2019 FormatToken *PreviousToken = FormatTok;
2027 auto OneTokenSoFar = [&]() {
2028 auto I = Line->Tokens.begin(),
E = Line->Tokens.end();
2029 while (I !=
E && I->Tok->is(tok::comment))
2032 while (I !=
E && I->Tok->is(tok::hash))
2034 return I !=
E && (++I ==
E);
2036 if (OneTokenSoFar()) {
2039 bool FunctionLike = FormatTok->
is(tok::l_paren);
2043 bool FollowedByNewline =
2044 CommentsBeforeNextToken.empty()
2046 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2048 if (FollowedByNewline &&
2049 (
Text.size() >= 5 ||
2050 (FunctionLike && FormatTok->
isNot(tok::l_paren))) &&
2052 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2053 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2062 FormatTok->
is(TT_FatArrow)) {
2063 tryToParseChildBlock();
2068 if (FormatTok->
is(tok::l_brace)) {
2077 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2079 parseBlock(
false, 1u,
2087 FormatTok->
is(tok::less)) {
2089 parseBracedList(
true);
2098 case tok::kw_switch:
2123 case tok::kw_default:
2126 if (FormatTok->
is(tok::colon)) {
2136 parseVerilogCaseLabel();
2143 parseVerilogCaseLabel();
2149 if (FormatTok->
is(tok::l_brace))
2159bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2160 assert(FormatTok->
is(tok::l_brace));
2172 unsigned int StoredPosition = Tokens->getPosition();
2173 FormatToken *Tok = Tokens->getNextToken();
2178 bool HasSpecialAccessor =
false;
2179 bool IsTrivialPropertyAccessor =
true;
2180 bool HasAttribute =
false;
2182 if (
const bool IsAccessorKeyword =
2184 IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||
2185 Tok->isOneOf(tok::l_square, tok::semi, Keywords.
kw_internal)) {
2186 if (IsAccessorKeyword)
2187 HasSpecialAccessor =
true;
2188 else if (Tok->is(tok::l_square))
2189 HasAttribute =
true;
2190 Tok = Tokens->getNextToken();
2193 if (Tok->isNot(tok::r_brace))
2194 IsTrivialPropertyAccessor =
false;
2198 if (!HasSpecialAccessor || HasAttribute) {
2199 Tokens->setPosition(StoredPosition);
2205 Tokens->setPosition(StoredPosition);
2213 if (FormatTok->
is(tok::equal)) {
2214 while (!eof() && FormatTok->
isNot(tok::semi))
2227 if (FormatTok->
is(TT_FatArrow)) {
2231 }
while (!eof() && FormatTok->
isNot(tok::semi));
2242 !IsTrivialPropertyAccessor) {
2254bool UnwrappedLineParser::tryToParseLambda() {
2255 assert(FormatTok->
is(tok::l_square));
2260 FormatToken &LSquare = *FormatTok;
2261 if (!tryToParseLambdaIntroducer())
2264 bool SeenArrow =
false;
2265 bool InTemplateParameterList =
false;
2267 while (FormatTok->
isNot(tok::l_brace)) {
2276 parseParens(TT_PointerOrReference);
2284 InTemplateParameterList =
true;
2289 case tok::kw_struct:
2291 case tok::kw_template:
2292 case tok::kw_typename:
2296 case tok::kw_constexpr:
2297 case tok::kw_consteval:
2300 case tok::identifier:
2301 case tok::numeric_constant:
2302 case tok::coloncolon:
2303 case tok::kw_mutable:
2304 case tok::kw_noexcept:
2305 case tok::kw_static:
2330 case tok::equalequal:
2331 case tok::exclaimequal:
2332 case tok::greaterequal:
2333 case tok::lessequal:
2339 if (SeenArrow || InTemplateParameterList) {
2352 case tok::kw_requires: {
2353 auto *RequiresToken = FormatTok;
2355 parseRequiresClause(RequiresToken);
2359 if (!InTemplateParameterList)
2369 LSquare.setFinalizedType(TT_LambdaLSquare);
2371 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2373 assert(!NestedLambdas.empty());
2374 NestedLambdas.pop_back();
2379bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2381 const FormatToken *LeftSquare = FormatTok;
2384 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2385 tok::kw_co_yield, tok::kw_co_return)) ||
2387 LeftSquare->isCppStructuredBinding(IsCpp)) {
2392 if (FormatTok->
is(tok::r_square)) {
2393 const FormatToken *Next = Tokens->peekNextToken(
true);
2394 if (Next->is(tok::greater))
2401void UnwrappedLineParser::tryToParseJSFunction() {
2409 if (FormatTok->
is(tok::star)) {
2415 if (FormatTok->
is(tok::identifier))
2418 if (FormatTok->
isNot(tok::l_paren))
2424 if (FormatTok->
is(tok::colon)) {
2430 if (FormatTok->
is(tok::l_brace))
2431 tryToParseBracedList();
2433 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2437 if (FormatTok->
is(tok::semi))
2443bool UnwrappedLineParser::tryToParseBracedList() {
2445 calculateBraceTypes();
2454bool UnwrappedLineParser::tryToParseChildBlock() {
2456 assert(FormatTok->
is(TT_FatArrow));
2461 if (FormatTok->
isNot(tok::l_brace))
2467bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2468 assert(!IsAngleBracket || !IsEnum);
2469 bool HasError =
false;
2474 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2475 tryToParseChildBlock()) {
2480 tryToParseJSFunction();
2483 if (FormatTok->
is(tok::l_brace)) {
2485 if (tryToParseBracedList())
2490 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2511 if (FormatTok->
is(tok::l_brace))
2520 if (!IsAngleBracket) {
2522 if (Prev && Prev->is(tok::greater))
2531 parseBracedList(
true);
2565bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2566 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2567 auto *LeftParen = FormatTok;
2568 bool SeenComma =
false;
2569 bool SeenEqual =
false;
2570 bool MightBeFoldExpr =
false;
2571 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2576 if (parseParens(AmpAmpTokenType))
2581 case tok::r_paren: {
2582 auto *Prev = LeftParen->Previous;
2583 if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
2585 const auto *Next = Tokens->peekNextToken();
2586 const bool DoubleParens =
2587 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2588 const bool CommaSeparated =
2589 !DoubleParens && Prev && Prev->isOneOf(tok::l_paren, tok::comma) &&
2590 Next && Next->isOneOf(tok::comma, tok::r_paren);
2591 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2592 const bool Excluded =
2594 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2597 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2598 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2599 const bool ReturnParens =
2601 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2602 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2603 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2604 Next->is(tok::semi);
2605 if ((DoubleParens && !Excluded) || (CommaSeparated && !SeenComma) ||
2607 LeftParen->Optional =
true;
2612 if (Prev->is(TT_TypenameMacro)) {
2613 LeftParen->setFinalizedType(TT_TypeDeclarationParen);
2615 }
else if (Prev->is(tok::greater) && FormatTok->
Previous == LeftParen) {
2616 Prev->setFinalizedType(TT_TemplateCloser);
2629 if (!tryToParseBracedList())
2634 if (FormatTok->
is(tok::l_brace)) {
2644 MightBeFoldExpr =
true;
2649 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2650 tryToParseChildBlock();
2660 case tok::identifier:
2662 tryToParseJSFunction();
2666 case tok::kw_switch:
2672 case tok::kw_requires: {
2673 auto RequiresToken = FormatTok;
2675 parseRequiresExpression(RequiresToken);
2679 if (AmpAmpTokenType != TT_Unknown)
2690void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2691 if (!LambdaIntroducer) {
2692 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2693 if (tryToParseLambda())
2710 case tok::l_brace: {
2711 if (!tryToParseBracedList())
2718 if (FormatTok->
is(tok::l_brace)) {
2730void UnwrappedLineParser::keepAncestorBraces() {
2734 const int MaxNestingLevels = 2;
2735 const int Size = NestedTooDeep.size();
2736 if (Size >= MaxNestingLevels)
2737 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2738 NestedTooDeep.push_back(
false);
2742 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2749void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2750 FormatToken *Tok =
nullptr;
2752 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2753 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2756 : Line->Tokens.back().Tok;
2758 if (Tok->BraceCount < 0) {
2759 assert(Tok->BraceCount == -1);
2762 Tok->BraceCount = -1;
2768 ++Line->UnbracedBodyLevel;
2769 parseStructuralElement();
2770 --Line->UnbracedBodyLevel;
2773 assert(!Line->InPPDirective);
2775 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2777 Tok = L.Tokens.back().Tok;
2785 if (CheckEOF && eof())
2795 assert(LeftBrace->
is(tok::l_brace));
2803 assert(RightBrace->
is(tok::r_brace));
2811void UnwrappedLineParser::handleAttributes() {
2815 else if (FormatTok->
is(tok::l_square))
2816 handleCppAttributes();
2819bool UnwrappedLineParser::handleCppAttributes() {
2821 assert(FormatTok->
is(tok::l_square));
2822 if (!tryToParseSimpleAttribute())
2829bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2833 : Tok.is(tok::l_brace);
2836FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2838 bool IsVerilogAssert) {
2839 assert((FormatTok->
is(tok::kw_if) ||
2846 if (IsVerilogAssert) {
2850 if (FormatTok->
is(tok::numeric_constant))
2867 if (FormatTok->
is(tok::exclaim))
2870 bool KeepIfBraces =
true;
2871 if (FormatTok->
is(tok::kw_consteval)) {
2875 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2877 if (FormatTok->
is(tok::l_paren)) {
2884 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2890 bool NeedsUnwrappedLine =
false;
2891 keepAncestorBraces();
2893 FormatToken *IfLeftBrace =
nullptr;
2894 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2896 if (isBlockBegin(*FormatTok)) {
2898 IfLeftBrace = FormatTok;
2900 parseBlock(
false, 1u,
2901 true, KeepIfBraces, &IfBlockKind);
2902 setPreviousRBraceType(TT_ControlStatementRBrace);
2906 NeedsUnwrappedLine =
true;
2907 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2910 parseUnbracedBody();
2914 assert(!NestedTooDeep.empty());
2915 KeepIfBraces = KeepIfBraces ||
2916 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2917 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2918 IfBlockKind == IfStmtKind::IfElseIf;
2921 bool KeepElseBraces = KeepIfBraces;
2922 FormatToken *ElseLeftBrace =
nullptr;
2923 IfStmtKind
Kind = IfStmtKind::IfOnly;
2925 if (FormatTok->
is(tok::kw_else)) {
2927 NestedTooDeep.back() =
false;
2928 Kind = IfStmtKind::IfElse;
2932 if (isBlockBegin(*FormatTok)) {
2933 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2935 ElseLeftBrace = FormatTok;
2937 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2938 FormatToken *IfLBrace =
2939 parseBlock(
false, 1u,
2940 true, KeepElseBraces, &ElseBlockKind);
2941 setPreviousRBraceType(TT_ElseRBrace);
2942 if (FormatTok->
is(tok::kw_else)) {
2943 KeepElseBraces = KeepElseBraces ||
2944 ElseBlockKind == IfStmtKind::IfOnly ||
2945 ElseBlockKind == IfStmtKind::IfElseIf;
2946 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2947 KeepElseBraces =
true;
2948 assert(ElseLeftBrace->MatchingParen);
2952 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2953 const FormatToken *
Previous = Tokens->getPreviousToken();
2955 const bool IsPrecededByComment =
Previous->is(tok::comment);
2956 if (IsPrecededByComment) {
2960 bool TooDeep =
true;
2962 Kind = IfStmtKind::IfElseIf;
2963 TooDeep = NestedTooDeep.pop_back_val();
2965 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2967 NestedTooDeep.push_back(TooDeep);
2968 if (IsPrecededByComment)
2971 parseUnbracedBody(
true);
2974 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2975 if (NeedsUnwrappedLine)
2982 assert(!NestedTooDeep.empty());
2983 KeepElseBraces = KeepElseBraces ||
2984 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2985 NestedTooDeep.back();
2987 NestedTooDeep.pop_back();
2989 if (!KeepIfBraces && !KeepElseBraces) {
2992 }
else if (IfLeftBrace) {
2993 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2995 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2996 assert(!IfLeftBrace->Optional);
2997 assert(!IfRightBrace->Optional);
2998 IfLeftBrace->MatchingParen =
nullptr;
2999 IfRightBrace->MatchingParen =
nullptr;
3009void UnwrappedLineParser::parseTryCatch() {
3010 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
3012 bool NeedsUnwrappedLine =
false;
3013 bool HasCtorInitializer =
false;
3014 if (FormatTok->
is(tok::colon)) {
3015 auto *Colon = FormatTok;
3018 if (FormatTok->
is(tok::identifier)) {
3019 HasCtorInitializer =
true;
3020 Colon->setFinalizedType(TT_CtorInitializerColon);
3025 while (FormatTok->
is(tok::comma))
3028 while (FormatTok->
is(tok::identifier)) {
3030 if (FormatTok->
is(tok::l_paren)) {
3032 }
else if (FormatTok->
is(tok::l_brace)) {
3039 while (FormatTok->
is(tok::comma))
3047 keepAncestorBraces();
3049 if (FormatTok->
is(tok::l_brace)) {
3050 if (HasCtorInitializer)
3057 NeedsUnwrappedLine =
true;
3058 }
else if (FormatTok->
isNot(tok::kw_catch)) {
3064 parseStructuralElement();
3068 if (FormatTok->
is(tok::at))
3071 tok::kw___finally) ||
3079 while (FormatTok->
isNot(tok::l_brace)) {
3080 if (FormatTok->
is(tok::l_paren)) {
3084 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
3086 NestedTooDeep.pop_back();
3091 NeedsUnwrappedLine =
false;
3092 Line->MustBeDeclaration =
false;
3098 NeedsUnwrappedLine =
true;
3102 NestedTooDeep.pop_back();
3104 if (NeedsUnwrappedLine)
3108void UnwrappedLineParser::parseNamespace() {
3109 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3110 "'namespace' expected");
3112 const FormatToken &InitialToken = *FormatTok;
3114 if (InitialToken.is(TT_NamespaceMacro)) {
3117 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3118 tok::l_square, tok::period, tok::l_paren) ||
3119 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3120 if (FormatTok->
is(tok::l_square))
3122 else if (FormatTok->
is(tok::l_paren))
3128 if (FormatTok->
is(tok::l_brace)) {
3134 unsigned AddLevels =
3137 DeclarationScopeStack.size() > 1)
3140 bool ManageWhitesmithsBraces =
3146 if (ManageWhitesmithsBraces)
3151 parseBlock(
true, AddLevels,
true,
3153 ManageWhitesmithsBraces);
3155 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3157 if (ManageWhitesmithsBraces)
3163void UnwrappedLineParser::parseNew() {
3164 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3170 if (FormatTok->
is(tok::l_paren))
3174 if (FormatTok->
is(tok::l_brace))
3177 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3190 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3194 if (FormatTok->
is(tok::l_paren)) {
3198 if (FormatTok->
is(tok::l_brace))
3206void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3207 keepAncestorBraces();
3209 if (isBlockBegin(*FormatTok)) {
3211 FormatToken *LeftBrace = FormatTok;
3213 parseBlock(
false, 1u,
3215 setPreviousRBraceType(TT_ControlStatementRBrace);
3217 assert(!NestedTooDeep.empty());
3218 if (!NestedTooDeep.back())
3224 parseUnbracedBody();
3228 NestedTooDeep.pop_back();
3231void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3232 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3239 "'for', 'while' or foreach macro expected");
3241 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3247 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3249 if (HasParens && FormatTok->
is(tok::l_paren)) {
3260 parseVerilogSensitivityList();
3262 Tokens->getPreviousToken()->is(tok::r_paren)) {
3269 parseLoopBody(KeepBraces,
true);
3272void UnwrappedLineParser::parseDoWhile() {
3273 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3279 if (FormatTok->
isNot(tok::kw_while)) {
3292 parseStructuralElement();
3295void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3297 unsigned OldLineLevel = Line->Level;
3301 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3305 FormatTok->
is(tok::l_brace)) {
3311 if (FormatTok->
is(tok::kw_break)) {
3320 parseStructuralElement();
3324 if (FormatTok->
is(tok::semi))
3328 Line->Level = OldLineLevel;
3329 if (FormatTok->
isNot(tok::l_brace)) {
3330 parseStructuralElement();
3335void UnwrappedLineParser::parseCaseLabel() {
3336 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3337 auto *Case = FormatTok;
3342 if (FormatTok->
is(tok::colon)) {
3348 Case->setFinalizedType(TT_SwitchExpressionLabel);
3355void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3356 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3358 if (FormatTok->
is(tok::l_paren))
3361 keepAncestorBraces();
3363 if (FormatTok->
is(tok::l_brace)) {
3366 : TT_ControlStatementLBrace);
3371 setPreviousRBraceType(TT_ControlStatementRBrace);
3377 parseStructuralElement();
3382 NestedTooDeep.pop_back();
3392 case tok::caretequal:
3396 case tok::equalequal:
3398 case tok::exclaimequal:
3400 case tok::greaterequal:
3401 case tok::greatergreater:
3402 case tok::greatergreaterequal:
3406 case tok::lessequal:
3408 case tok::lesslessequal:
3410 case tok::minusequal:
3411 case tok::minusminus:
3413 case tok::percentequal:
3416 case tok::pipeequal:
3419 case tok::plusequal:
3427 case tok::slashequal:
3429 case tok::starequal:
3436void UnwrappedLineParser::parseAccessSpecifier() {
3437 FormatToken *AccessSpecifierCandidate = FormatTok;
3443 if (FormatTok->
is(tok::colon)) {
3446 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3450 }
else if (AccessSpecifierCandidate) {
3452 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3459bool UnwrappedLineParser::parseRequires() {
3460 assert(FormatTok->
is(tok::kw_requires) &&
"'requires' expected");
3461 auto RequiresToken = FormatTok;
3470 parseRequiresExpression(RequiresToken);
3477 parseRequiresClause(RequiresToken);
3488 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3490 if (!PreviousNonComment ||
3491 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3494 parseRequiresClause(RequiresToken);
3498 switch (PreviousNonComment->Tok.getKind()) {
3501 case tok::kw_noexcept:
3505 parseRequiresClause(RequiresToken);
3514 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3515 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3516 parseRequiresClause(RequiresToken);
3522 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3524 parseRequiresClause(RequiresToken);
3528 parseRequiresExpression(RequiresToken);
3538 unsigned StoredPosition = Tokens->getPosition();
3539 FormatToken *NextToken = Tokens->getNextToken();
3541 auto PeekNext = [&Lookahead, &NextToken,
this] {
3543 NextToken = Tokens->getNextToken();
3546 bool FoundType =
false;
3547 bool LastWasColonColon =
false;
3550 for (; Lookahead < 50; PeekNext()) {
3551 switch (NextToken->Tok.getKind()) {
3552 case tok::kw_volatile:
3555 if (OpenAngles == 0) {
3556 FormatTok = Tokens->setPosition(StoredPosition);
3557 parseRequiresExpression(RequiresToken);
3565 case tok::coloncolon:
3566 LastWasColonColon =
true;
3568 case tok::kw_decltype:
3569 case tok::identifier:
3570 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3571 FormatTok = Tokens->setPosition(StoredPosition);
3572 parseRequiresExpression(RequiresToken);
3576 LastWasColonColon =
false;
3585 if (NextToken->isTypeName(LangOpts)) {
3586 FormatTok = Tokens->setPosition(StoredPosition);
3587 parseRequiresExpression(RequiresToken);
3594 FormatTok = Tokens->setPosition(StoredPosition);
3595 parseRequiresClause(RequiresToken);
3606void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3608 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3613 bool InRequiresExpression =
3614 !RequiresToken->Previous ||
3615 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3617 RequiresToken->setFinalizedType(InRequiresExpression
3618 ? TT_RequiresClauseInARequiresExpression
3619 : TT_RequiresClause);
3623 parseConstraintExpression();
3625 if (!InRequiresExpression)
3636void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3638 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3640 RequiresToken->setFinalizedType(TT_RequiresExpression);
3642 if (FormatTok->
is(tok::l_paren)) {
3647 if (FormatTok->
is(tok::l_brace)) {
3657void UnwrappedLineParser::parseConstraintExpression() {
3664 bool LambdaNextTimeAllowed =
true;
3674 bool TopLevelParensAllowed =
true;
3677 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3680 case tok::kw_requires: {
3681 auto RequiresToken = FormatTok;
3683 parseRequiresExpression(RequiresToken);
3688 if (!TopLevelParensAllowed)
3690 parseParens(TT_BinaryOperator);
3691 TopLevelParensAllowed =
false;
3695 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3702 case tok::kw_struct:
3714 LambdaNextTimeAllowed =
true;
3715 TopLevelParensAllowed =
true;
3720 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3724 case tok::kw_sizeof:
3726 case tok::greaterequal:
3727 case tok::greatergreater:
3729 case tok::lessequal:
3731 case tok::equalequal:
3733 case tok::exclaimequal:
3738 LambdaNextTimeAllowed =
true;
3739 TopLevelParensAllowed =
true;
3744 case tok::numeric_constant:
3745 case tok::coloncolon:
3748 TopLevelParensAllowed =
false;
3753 case tok::kw_static_cast:
3754 case tok::kw_const_cast:
3755 case tok::kw_reinterpret_cast:
3756 case tok::kw_dynamic_cast:
3758 if (FormatTok->
isNot(tok::less))
3762 parseBracedList(
true);
3778 case tok::coloncolon:
3782 case tok::kw_requires:
3791 if (FormatTok->
is(tok::less)) {
3793 parseBracedList(
true);
3795 TopLevelParensAllowed =
false;
3801bool UnwrappedLineParser::parseEnum() {
3802 const FormatToken &InitialToken = *FormatTok;
3805 if (FormatTok->
is(tok::kw_enum))
3820 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3822 while (FormatTok->
is(tok::l_square))
3823 if (!handleCppAttributes())
3828 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3829 tok::greater, tok::comma, tok::question,
3835 while (FormatTok->
is(tok::l_square))
3841 if (FormatTok->
is(tok::l_paren))
3843 if (FormatTok->
is(tok::identifier)) {
3847 if (IsCpp && FormatTok->
is(tok::identifier))
3853 if (FormatTok->
isNot(tok::l_brace))
3860 parseJavaEnumBody();
3878 bool HasError = !parseBracedList(
false,
true);
3882 if (FormatTok->
is(tok::semi))
3886 setPreviousRBraceType(TT_EnumRBrace);
3894bool UnwrappedLineParser::parseStructLike() {
3901 if (FormatTok->
is(tok::semi))
3912class ScopedTokenPosition {
3913 unsigned StoredPosition;
3914 FormatTokenSource *Tokens;
3917 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3918 assert(Tokens &&
"Tokens expected to not be null");
3919 StoredPosition = Tokens->getPosition();
3922 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3928bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3929 ScopedTokenPosition AutoPosition(Tokens);
3930 FormatToken *Tok = Tokens->getNextToken();
3932 if (Tok->isNot(tok::l_square))
3936 while (Tok->isNot(tok::eof)) {
3937 if (Tok->is(tok::r_square))
3939 Tok = Tokens->getNextToken();
3941 if (Tok->is(tok::eof))
3943 Tok = Tokens->getNextToken();
3944 if (Tok->isNot(tok::r_square))
3946 Tok = Tokens->getNextToken();
3947 if (Tok->is(tok::semi))
3952void UnwrappedLineParser::parseJavaEnumBody() {
3953 assert(FormatTok->
is(tok::l_brace));
3954 const FormatToken *OpeningBrace = FormatTok;
3959 unsigned StoredPosition = Tokens->getPosition();
3960 bool IsSimple =
true;
3961 FormatToken *Tok = Tokens->getNextToken();
3962 while (Tok->isNot(tok::eof)) {
3963 if (Tok->is(tok::r_brace))
3965 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3971 Tok = Tokens->getNextToken();
3973 FormatTok = Tokens->setPosition(StoredPosition);
3990 if (FormatTok->
is(tok::l_brace)) {
3992 parseBlock(
true, 1u,
3994 }
else if (FormatTok->
is(tok::l_paren)) {
3996 }
else if (FormatTok->
is(tok::comma)) {
3999 }
else if (FormatTok->
is(tok::semi)) {
4003 }
else if (FormatTok->
is(tok::r_brace)) {
4012 parseLevel(OpeningBrace);
4018void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
4019 const FormatToken &InitialToken = *FormatTok;
4022 const FormatToken *ClassName =
nullptr;
4023 bool IsDerived =
false;
4024 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
4025 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
4029 bool JSPastExtendsOrImplements =
false;
4033 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
4034 tok::kw_alignas, tok::l_square) ||
4037 FormatTok->
isOneOf(tok::period, tok::comma))) {
4040 JSPastExtendsOrImplements =
true;
4045 if (FormatTok->
is(tok::l_brace)) {
4046 tryToParseBracedList();
4050 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
4057 if (!IsNonMacroIdentifier(
Previous) ||
4059 Previous->Previous == &InitialToken) {
4063 case tok::coloncolon:
4067 if (!JSPastExtendsOrImplements && !ClassName &&
4074 auto IsListInitialization = [&] {
4075 if (!ClassName || IsDerived || JSPastExtendsOrImplements)
4077 assert(FormatTok->
is(tok::l_brace));
4080 return Prev != ClassName && Prev->is(tok::identifier) &&
4081 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
4084 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
4085 int AngleNestingLevel = 0;
4087 if (FormatTok->
is(tok::less))
4088 ++AngleNestingLevel;
4089 else if (FormatTok->
is(tok::greater))
4090 --AngleNestingLevel;
4092 if (AngleNestingLevel == 0) {
4093 if (FormatTok->
is(tok::colon)) {
4095 }
else if (FormatTok->
is(tok::identifier) &&
4097 ClassName = FormatTok;
4098 }
else if (FormatTok->
is(tok::l_paren) &&
4099 IsNonMacroIdentifier(FormatTok->
Previous)) {
4103 if (FormatTok->
is(tok::l_brace)) {
4104 if (AngleNestingLevel == 0 && IsListInitialization())
4106 calculateBraceTypes(
true);
4107 if (!tryToParseBracedList())
4110 if (FormatTok->
is(tok::l_square)) {
4113 !
Previous->isTypeOrIdentifier(LangOpts))) {
4116 if (!tryToParseLambda())
4123 if (FormatTok->
is(tok::semi))
4128 parseCSharpGenericTypeConstraint();
4135 auto GetBraceTypes =
4136 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4137 switch (RecordTok.Tok.getKind()) {
4139 return {TT_ClassLBrace, TT_ClassRBrace};
4140 case tok::kw_struct:
4141 return {TT_StructLBrace, TT_StructRBrace};
4143 return {TT_UnionLBrace, TT_UnionRBrace};
4146 return {TT_RecordLBrace, TT_RecordRBrace};
4149 if (FormatTok->
is(tok::l_brace)) {
4150 if (IsListInitialization())
4152 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4161 parseBlock(
true, AddLevels,
false);
4163 setPreviousRBraceType(ClosingBraceType);
4170void UnwrappedLineParser::parseObjCMethod() {
4171 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4172 "'(' or identifier expected.");
4174 if (FormatTok->
is(tok::semi)) {
4178 }
else if (FormatTok->
is(tok::l_brace)) {
4190void UnwrappedLineParser::parseObjCProtocolList() {
4191 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4195 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4199 }
while (!eof() && FormatTok->
isNot(tok::greater));
4203void UnwrappedLineParser::parseObjCUntilAtEnd() {
4210 if (FormatTok->
is(tok::l_brace)) {
4214 }
else if (FormatTok->
is(tok::r_brace)) {
4218 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4222 parseStructuralElement();
4227void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
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) ||
4281 if (FormatTok->
is(tok::less)) {
4283 }
else if (FormatTok->
is(tok::greater)) {
4284 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4287 }
while (!eof() && NumOpenAngles != 0);
4293bool UnwrappedLineParser::parseObjCProtocol() {
4297 if (FormatTok->
is(tok::l_paren)) {
4309 if (FormatTok->
is(tok::less))
4310 parseObjCProtocolList();
4313 if (FormatTok->
is(tok::semi)) {
4320 parseObjCUntilAtEnd();
4324void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4325 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4326 assert(IsImport || FormatTok->
is(tok::kw_export));
4330 if (FormatTok->
is(tok::kw_default))
4347 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4350 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4355 if (FormatTok->
is(tok::semi))
4357 if (Line->Tokens.empty()) {
4362 if (FormatTok->
is(tok::l_brace)) {
4372void UnwrappedLineParser::parseStatementMacro() {
4374 if (FormatTok->
is(tok::l_paren))
4376 if (FormatTok->
is(tok::semi))
4381void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4384 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4385 tok::coloncolon, tok::hash) ||
4388 }
else if (FormatTok->
is(tok::l_square)) {
4396void UnwrappedLineParser::parseVerilogSensitivityList() {
4397 if (FormatTok->
isNot(tok::at))
4401 if (FormatTok->
is(tok::at))
4411 parseVerilogHierarchyIdentifier();
4416unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4417 unsigned AddLevels = 0;
4423 parseVerilogSensitivityList();
4424 if (FormatTok->
is(tok::semi))
4432 if (FormatTok->
is(tok::l_paren)) {
4445 if (FormatTok->
is(tok::l_square)) {
4451 FormatTok->
isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
4461 Line->IsContinuation =
true;
4468 parseVerilogHierarchyIdentifier();
4469 if (FormatTok->
is(tok::semi))
4477 if (FormatTok->
is(tok::l_paren)) {
4482 if (FormatTok->
is(tok::l_paren)) {
4492 parseVerilogHierarchyIdentifier();
4493 if (FormatTok->
is(tok::l_paren))
4500 parseVerilogHierarchyIdentifier();
4501 }
while (FormatTok->
is(tok::comma));
4505 if (FormatTok->
is(tok::at)) {
4507 parseVerilogSensitivityList();
4510 if (FormatTok->
is(tok::semi))
4518void UnwrappedLineParser::parseVerilogTable() {
4523 auto InitialLevel = Line->Level++;
4525 FormatToken *Tok = FormatTok;
4527 if (Tok->is(tok::semi))
4529 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4530 Tok->setFinalizedType(TT_VerilogTableItem);
4532 Line->Level = InitialLevel;
4537void UnwrappedLineParser::parseVerilogCaseLabel() {
4543 auto OrigLevel = Line->Level;
4544 auto FirstLine = CurrentLines->size();
4545 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4549 parseStructuralElement();
4552 if (CurrentLines->size() > FirstLine)
4553 (*CurrentLines)[FirstLine].Level = OrigLevel;
4554 Line->Level = OrigLevel;
4557bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4558 for (
const auto &N : Line.Tokens) {
4559 if (N.Tok->MacroCtx)
4561 for (
const UnwrappedLine &Child : N.Children)
4562 if (containsExpansion(Child))
4568void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4569 if (Line->Tokens.empty())
4572 if (!parsingPPDirective()) {
4573 llvm::dbgs() <<
"Adding unwrapped line:\n";
4574 printDebugInfo(*Line);
4582 bool ClosesWhitesmithsBlock =
4589 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4591 Reconstruct.emplace(Line->Level, Unexpanded);
4592 Reconstruct->addLine(*Line);
4597 CurrentExpandedLines.push_back(std::move(*Line));
4599 if (Reconstruct->finished()) {
4600 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4601 assert(!Reconstructed.Tokens.empty() &&
4602 "Reconstructed must at least contain the macro identifier.");
4603 assert(!parsingPPDirective());
4605 llvm::dbgs() <<
"Adding unexpanded line:\n";
4606 printDebugInfo(Reconstructed);
4608 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4609 Lines.push_back(std::move(Reconstructed));
4610 CurrentExpandedLines.clear();
4611 Reconstruct.reset();
4616 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4617 CurrentLines->push_back(std::move(*Line));
4619 Line->Tokens.clear();
4621 Line->FirstStartColumn = 0;
4622 Line->IsContinuation =
false;
4623 Line->SeenDecltypeAuto =
false;
4625 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4627 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4628 CurrentLines->append(
4629 std::make_move_iterator(PreprocessorDirectives.begin()),
4630 std::make_move_iterator(PreprocessorDirectives.end()));
4631 PreprocessorDirectives.clear();
4637bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4639bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4640 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4641 FormatTok.NewlinesBefore > 0;
4649 const llvm::Regex &CommentPragmasRegex) {
4653 StringRef IndentContent = FormatTok.
TokenText;
4654 if (FormatTok.
TokenText.starts_with(
"//") ||
4655 FormatTok.
TokenText.starts_with(
"/*")) {
4656 IndentContent = FormatTok.
TokenText.substr(2);
4658 if (CommentPragmasRegex.match(IndentContent))
4733 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4735 MinColumnToken = PreviousToken;
4738 PreviousToken =
Node.Tok;
4741 if (
Node.Tok->NewlinesBefore > 0)
4742 MinColumnToken =
Node.Tok;
4744 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4745 MinColumnToken = PreviousToken;
4751void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4752 bool JustComments = Line->Tokens.empty();
4753 for (FormatToken *Tok : CommentsBeforeNextToken) {
4762 Tok->ContinuesLineCommentSection =
4764 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4768 if (NewlineBeforeNext && JustComments)
4770 CommentsBeforeNextToken.clear();
4773void UnwrappedLineParser::nextToken(
int LevelDifference) {
4776 flushComments(isOnNewLine(*FormatTok));
4777 pushToken(FormatTok);
4780 readToken(LevelDifference);
4782 readTokenWithJavaScriptASI();
4792 FormatTok->Tok.setKind(tok::r_brace);
4796void UnwrappedLineParser::distributeComments(
4797 const ArrayRef<FormatToken *> &Comments,
const FormatToken *NextTok) {
4816 if (Comments.empty())
4818 bool ShouldPushCommentsInCurrentLine =
true;
4819 bool HasTrailAlignedWithNextToken =
false;
4820 unsigned StartOfTrailAlignedWithNextToken = 0;
4823 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4824 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4825 HasTrailAlignedWithNextToken =
true;
4826 StartOfTrailAlignedWithNextToken = i;
4830 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4831 FormatToken *FormatTok = Comments[i];
4832 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4833 FormatTok->ContinuesLineCommentSection =
false;
4836 *FormatTok, *Line, Style, CommentPragmasRegex);
4838 if (!FormatTok->ContinuesLineCommentSection &&
4839 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4840 ShouldPushCommentsInCurrentLine =
false;
4842 if (ShouldPushCommentsInCurrentLine)
4843 pushToken(FormatTok);
4845 CommentsBeforeNextToken.push_back(FormatTok);
4849void UnwrappedLineParser::readToken(
int LevelDifference) {
4850 SmallVector<FormatToken *, 1> Comments;
4851 bool PreviousWasComment =
false;
4852 bool FirstNonCommentOnLine =
false;
4854 FormatTok = Tokens->getNextToken();
4856 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4857 TT_ConflictAlternative)) {
4858 if (FormatTok->is(TT_ConflictStart))
4859 conditionalCompilationStart(
false);
4860 else if (FormatTok->is(TT_ConflictAlternative))
4861 conditionalCompilationAlternative();
4862 else if (FormatTok->is(TT_ConflictEnd))
4863 conditionalCompilationEnd();
4864 FormatTok = Tokens->getNextToken();
4865 FormatTok->MustBreakBefore =
true;
4866 FormatTok->MustBreakBeforeFinalized =
true;
4869 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4870 const FormatToken &Tok,
4871 bool PreviousWasComment) {
4872 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4873 return Tok.HasUnescapedNewline || Tok.IsFirst;
4878 if (PreviousWasComment)
4879 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4880 return IsFirstOnLine(Tok);
4883 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4884 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4885 PreviousWasComment = FormatTok->is(tok::comment);
4887 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4890 FirstNonCommentOnLine) {
4891 distributeComments(Comments, FormatTok);
4895 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4897 assert((LevelDifference >= 0 ||
4898 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4899 "LevelDifference makes Line->Level negative");
4900 Line->Level += LevelDifference;
4905 PPBranchLevel > 0) {
4906 Line->Level += PPBranchLevel;
4908 assert(Line->Level >= Line->UnbracedBodyLevel);
4909 Line->Level -= Line->UnbracedBodyLevel;
4910 flushComments(isOnNewLine(*FormatTok));
4912 PreviousWasComment = FormatTok->is(tok::comment);
4913 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4914 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4917 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4918 !Line->InPPDirective) {
4922 if (FormatTok->is(tok::identifier) &&
4923 Macros.
defined(FormatTok->TokenText) &&
4925 !Line->InPPDirective) {
4926 FormatToken *
ID = FormatTok;
4927 unsigned Position = Tokens->getPosition();
4931 auto PreCall = std::move(Line);
4932 Line.reset(
new UnwrappedLine);
4933 bool OldInExpansion = InExpansion;
4936 auto Args = parseMacroCall();
4937 InExpansion = OldInExpansion;
4938 assert(Line->Tokens.front().Tok ==
ID);
4940 auto UnexpandedLine = std::move(Line);
4942 Line = std::move(PreCall);
4945 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4947 llvm::dbgs() <<
"(";
4948 for (
const auto &Arg : Args.value())
4949 for (
const auto &
T : Arg)
4950 llvm::dbgs() <<
T->TokenText <<
" ";
4951 llvm::dbgs() <<
")";
4953 llvm::dbgs() <<
"\n";
4956 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4962 LLVM_DEBUG(llvm::dbgs()
4963 <<
"Macro \"" <<
ID->TokenText
4964 <<
"\" not overloaded for arity " << Args->size()
4965 <<
"or not function-like, using object-like overload.");
4967 UnexpandedLine->Tokens.resize(1);
4968 Tokens->setPosition(Position);
4973 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4976 Unexpanded[
ID] = std::move(UnexpandedLine);
4977 SmallVector<FormatToken *, 8> Expansion =
4978 Macros.
expand(
ID, std::move(Args));
4979 if (!Expansion.empty())
4980 FormatTok = Tokens->insertTokens(Expansion);
4983 llvm::dbgs() <<
"Expanded: ";
4984 for (
const auto &
T : Expansion)
4985 llvm::dbgs() <<
T->TokenText <<
" ";
4986 llvm::dbgs() <<
"\n";
4990 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4991 <<
"\", because it was used ";
4993 llvm::dbgs() <<
"with " << Args->size();
4995 llvm::dbgs() <<
"without";
4996 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4998 Tokens->setPosition(Position);
5003 if (FormatTok->isNot(tok::comment)) {
5004 distributeComments(Comments, FormatTok);
5009 Comments.push_back(FormatTok);
5012 distributeComments(Comments,
nullptr);
5017template <
typename Iterator>
5018void pushTokens(Iterator
Begin, Iterator End,
5019 SmallVectorImpl<FormatToken *> &Into) {
5020 for (
auto I =
Begin; I != End; ++I) {
5021 Into.push_back(I->Tok);
5022 for (
const auto &Child : I->Children)
5023 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
5028std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
5029UnwrappedLineParser::parseMacroCall() {
5030 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
5031 assert(Line->Tokens.empty());
5033 if (FormatTok->isNot(tok::l_paren))
5035 unsigned Position = Tokens->getPosition();
5036 FormatToken *Tok = FormatTok;
5039 auto ArgStart = std::prev(Line->Tokens.end());
5043 switch (FormatTok->Tok.getKind()) {
5048 case tok::r_paren: {
5054 Args->push_back({});
5055 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5064 Args->push_back({});
5065 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5067 ArgStart = std::prev(Line->Tokens.end());
5075 Line->Tokens.resize(1);
5076 Tokens->setPosition(Position);
5081void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5082 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5083 if (MustBreakBeforeNextToken) {
5084 Line->Tokens.back().Tok->MustBreakBefore =
true;
5085 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
5086 MustBreakBeforeNextToken =
false;
enum clang::sema::@1724::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.