22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/raw_os_ostream.h"
26#include "llvm/Support/raw_ostream.h"
31#define DEBUG_TYPE "format-parser"
38void printLine(llvm::raw_ostream &OS,
const UnwrappedLine &
Line,
39 StringRef Prefix =
"",
bool PrintText =
false) {
40 OS << Prefix <<
"Line(" <<
Line.Level <<
", FSC=" <<
Line.FirstStartColumn
41 <<
")" << (
Line.InPPDirective ?
" MACRO" :
"") <<
": ";
43 for (std::list<UnwrappedLineNode>::const_iterator I =
Line.Tokens.begin(),
44 E =
Line.Tokens.end();
50 OS << I->Tok->Tok.getName() <<
"["
51 <<
"T=" << (
unsigned)I->Tok->getType()
52 <<
", OC=" << I->Tok->OriginalColumn <<
", \"" << I->Tok->TokenText
54 for (SmallVectorImpl<UnwrappedLine>::const_iterator
55 CI = I->Children.begin(),
56 CE = I->Children.end();
59 printLine(OS, *CI, (Prefix +
" ").str());
67LLVM_ATTRIBUTE_UNUSED
static void printDebugInfo(
const UnwrappedLine &
Line) {
68 printLine(llvm::dbgs(),
Line);
71class ScopedDeclarationState {
73 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
74 bool MustBeDeclaration)
75 : Line(Line), Stack(Stack) {
76 Line.MustBeDeclaration = MustBeDeclaration;
77 Stack.push_back(MustBeDeclaration);
79 ~ScopedDeclarationState() {
82 Line.MustBeDeclaration = Stack.back();
84 Line.MustBeDeclaration =
true;
89 llvm::BitVector &Stack;
95 llvm::raw_os_ostream OS(Stream);
103 bool SwitchToPreprocessorLines =
false)
105 if (SwitchToPreprocessorLines)
107 else if (!
Parser.Line->Tokens.empty())
108 Parser.CurrentLines = &
Parser.Line->Tokens.back().Children;
109 PreBlockLine = std::move(
Parser.Line);
110 Parser.Line = std::make_unique<UnwrappedLine>();
111 Parser.Line->Level = PreBlockLine->Level;
112 Parser.Line->PPLevel = PreBlockLine->PPLevel;
113 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
114 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
115 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;
119 if (!
Parser.Line->Tokens.empty())
120 Parser.addUnwrappedLine();
121 assert(
Parser.Line->Tokens.empty());
122 Parser.Line = std::move(PreBlockLine);
123 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
124 Parser.MustBreakBeforeNextToken =
true;
125 Parser.CurrentLines = OriginalLines;
131 std::unique_ptr<UnwrappedLine> PreBlockLine;
140 Style.BraceWrapping.AfterControlStatement,
141 Style.BraceWrapping.IndentBraces) {}
143 bool WrapBrace,
bool IndentBrace)
144 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
146 Parser->addUnwrappedLine();
154 unsigned OldLineLevel;
161 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
164 CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()),
166 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
167 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
168 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
171 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
172 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {
173 assert(IsCpp == LangOpts.CXXOperatorNames);
176void UnwrappedLineParser::reset() {
181 IncludeGuardToken =
nullptr;
183 CommentsBeforeNextToken.clear();
185 MustBreakBeforeNextToken =
false;
186 IsDecltypeAutoFunction =
false;
187 PreprocessorDirectives.clear();
188 CurrentLines = &Lines;
189 DeclarationScopeStack.clear();
190 NestedTooDeep.clear();
191 NestedLambdas.clear();
193 Line->FirstStartColumn = FirstStartColumn;
195 if (!Unexpanded.empty())
197 Token->MacroCtx.reset();
198 CurrentExpandedLines.clear();
199 ExpandedLines.clear();
207 Line->FirstStartColumn = FirstStartColumn;
209 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
211 Tokens = &TokenSource;
219 if (IncludeGuard == IG_Found) {
220 for (
auto &Line : Lines)
221 if (Line.InPPDirective && Line.Level > 0)
227 pushToken(FormatTok);
232 if (!ExpandedLines.empty()) {
233 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
234 for (
const auto &Line : Lines) {
235 if (!Line.Tokens.empty()) {
236 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
237 if (it != ExpandedLines.end()) {
238 for (
const auto &Expanded : it->second) {
239 LLVM_DEBUG(printDebugInfo(Expanded));
245 LLVM_DEBUG(printDebugInfo(Line));
251 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
253 LLVM_DEBUG(printDebugInfo(Line));
258 while (!PPLevelBranchIndex.empty() &&
259 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
260 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
261 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
263 if (!PPLevelBranchIndex.empty()) {
264 ++PPLevelBranchIndex.back();
265 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
266 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
268 }
while (!PPLevelBranchIndex.empty());
271void UnwrappedLineParser::parseFile() {
274 bool MustBeDeclaration = !Line->InPPDirective && !Style.
isJavaScript();
275 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
292 !CommentsBeforeNextToken.empty()) {
299void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
308 parseCSharpGenericTypeConstraint();
317void UnwrappedLineParser::parseCSharpAttribute() {
318 int UnpairedSquareBrackets = 1;
323 --UnpairedSquareBrackets;
324 if (UnpairedSquareBrackets == 0) {
330 ++UnpairedSquareBrackets;
340bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
341 if (!Lines.empty() && Lines.back().InPPDirective)
355bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
357 FormatToken **IfLeftBrace) {
358 const bool InRequiresExpression =
359 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
360 const bool IsPrecededByCommentOrPPDirective =
362 FormatToken *IfLBrace =
nullptr;
363 bool HasDoWhile =
false;
364 bool HasLabel =
false;
365 unsigned StatementCount = 0;
366 bool SwitchLabelEncountered =
false;
371 if (FormatTok->
is(tok::l_paren))
376 if (FormatTok->
is(TT_MacroBlockBegin))
378 else if (FormatTok->
is(TT_MacroBlockEnd))
381 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
382 &HasLabel, &StatementCount] {
383 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
384 HasDoWhile ?
nullptr : &HasDoWhile,
385 HasLabel ?
nullptr : &HasLabel);
387 assert(StatementCount > 0 &&
"StatementCount overflow!");
396 if (InRequiresExpression) {
405 if (!InRequiresExpression && FormatTok->
isNot(TT_MacroBlockBegin)) {
406 if (tryToParseBracedList())
412 assert(StatementCount > 0 &&
"StatementCount overflow!");
418 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
421 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
422 HasDoWhile || IsPrecededByCommentOrPPDirective ||
423 precededByCommentOrPPDirective()) {
427 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
430 *IfLeftBrace = IfLBrace;
436 case tok::kw_default: {
440 if (!Next->isOneOf(tok::colon, tok::arrow)) {
443 parseStructuralElement();
459 if (!SwitchLabelEncountered &&
461 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
462 (Line->InPPDirective && Line->Level == 1))) {
465 SwitchLabelEncountered =
true;
466 parseStructuralElement();
471 parseCSharpAttribute();
474 if (handleCppAttributes())
486void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
492 FormatToken *Tok = FormatTok;
493 const FormatToken *PrevTok = Tok->
Previous;
499 const FormatToken *PrevTok;
501 SmallVector<StackEntry, 8> LBraceStack;
502 assert(Tok->is(tok::l_brace));
507 if (!Line->InMacroBody && !Style.
isTableGen()) {
509 while (NextTok->is(tok::hash)) {
511 if (NextTok->is(tok::pp_not_keyword))
515 }
while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof));
517 while (NextTok->is(tok::comment))
522 switch (Tok->Tok.getKind()) {
525 if (PrevTok->isOneOf(tok::colon, tok::less)) {
536 }
else if (PrevTok->is(tok::r_paren)) {
543 LBraceStack.push_back({Tok, PrevTok});
546 if (LBraceStack.empty())
548 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
549 bool ProbablyBracedList =
false;
551 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
552 }
else if (LBrace->isNot(TT_EnumLBrace)) {
555 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
556 NextTok->OriginalColumn == 0;
566 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
568 ProbablyBracedList = ProbablyBracedList ||
570 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
573 ProbablyBracedList || (IsCpp && NextTok->is(tok::l_paren));
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:
1039void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1040 size_t Line = CurrentLines->size();
1041 if (CurrentLines == &PreprocessorDirectives)
1042 Line += Lines.size();
1045 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1046 PPStack.push_back({PP_Unreachable, Line});
1048 PPStack.push_back({PP_Conditional, Line});
1052void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1054 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1055 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1056 PPLevelBranchIndex.push_back(0);
1057 PPLevelBranchCount.push_back(0);
1059 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1060 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1061 conditionalCompilationCondition(Unreachable || Skip);
1064void UnwrappedLineParser::conditionalCompilationAlternative() {
1065 if (!PPStack.empty())
1067 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1068 if (!PPChainBranchIndex.empty())
1069 ++PPChainBranchIndex.top();
1070 conditionalCompilationCondition(
1071 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1072 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1075void UnwrappedLineParser::conditionalCompilationEnd() {
1076 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1077 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1078 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1079 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1082 if (PPBranchLevel > -1)
1084 if (!PPChainBranchIndex.empty())
1085 PPChainBranchIndex.pop();
1086 if (!PPStack.empty())
1090void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1091 bool IfNDef = FormatTok->
is(tok::pp_ifndef);
1093 bool Unreachable =
false;
1094 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1096 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1098 conditionalCompilationStart(Unreachable);
1099 FormatToken *IfCondition = FormatTok;
1102 bool MaybeIncludeGuard = IfNDef;
1103 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1104 for (
auto &Line : Lines) {
1105 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1106 MaybeIncludeGuard =
false;
1107 IncludeGuard = IG_Rejected;
1115 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1116 IncludeGuard = IG_IfNdefed;
1117 IncludeGuardToken = IfCondition;
1121void UnwrappedLineParser::parsePPElse() {
1123 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1124 IncludeGuard = IG_Rejected;
1126 assert(PPBranchLevel >= -1);
1127 if (PPBranchLevel == -1)
1128 conditionalCompilationStart(
true);
1129 conditionalCompilationAlternative();
1135void UnwrappedLineParser::parsePPEndIf() {
1136 conditionalCompilationEnd();
1140 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1142 IncludeGuard = IG_Found;
1146void UnwrappedLineParser::parsePPDefine() {
1150 IncludeGuard = IG_Rejected;
1151 IncludeGuardToken =
nullptr;
1156 if (IncludeGuard == IG_IfNdefed &&
1158 IncludeGuard = IG_Defined;
1159 IncludeGuardToken =
nullptr;
1160 for (
auto &Line : Lines) {
1161 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1162 IncludeGuard = IG_Rejected;
1176 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1181 Line->Level += PPBranchLevel + 1;
1185 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1186 assert((
int)Line->PPLevel >= 0);
1187 Line->InMacroBody =
true;
1192 FormatTok = Tokens->getNextToken();
1206void UnwrappedLineParser::parsePPPragma() {
1207 Line->InPragmaDirective =
true;
1211void UnwrappedLineParser::parsePPUnknown() {
1216 Line->Level += PPBranchLevel + 1;
1226 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1229 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1230 tok::less, tok::greater, tok::slash, tok::percent,
1231 tok::lessless, tok::greatergreater, tok::equal,
1232 tok::plusequal, tok::minusequal, tok::starequal,
1233 tok::slashequal, tok::percentequal, tok::ampequal,
1234 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1247 return FormatTok->
is(tok::identifier) &&
1262 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1273 tok::kw_if, tok::kw_else,
1275 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1277 tok::kw_switch, tok::kw_case,
1279 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1281 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1289 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1290 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1307 if (FuncName->
isNot(tok::identifier))
1315 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1319 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1323 if (!Tok || Tok->
isNot(tok::r_paren))
1327 if (!Tok || Tok->
isNot(tok::identifier))
1333bool UnwrappedLineParser::parseModuleImport() {
1334 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1336 if (
auto Token = Tokens->peekNextToken(
true);
1338 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1344 if (FormatTok->
is(tok::colon)) {
1348 else if (FormatTok->
is(tok::less)) {
1350 while (!FormatTok->
isOneOf(tok::semi, tok::greater, tok::eof)) {
1353 if (FormatTok->
isNot(tok::comment) &&
1354 !FormatTok->
TokenText.starts_with(
"//")) {
1360 if (FormatTok->
is(tok::semi)) {
1378void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1381 FormatToken *Next = FormatTok;
1384 CommentsBeforeNextToken.empty()
1385 ? Next->NewlinesBefore == 0
1386 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1391 bool PreviousStartsTemplateExpr =
1393 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1396 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1397 return LineNode.Tok->is(tok::at);
1402 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1403 return addUnwrappedLine();
1405 bool NextEndsTemplateExpr =
1406 Next->is(TT_TemplateString) && Next->TokenText.starts_with(
"}");
1407 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1408 (PreviousMustBeValue ||
1409 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1410 tok::minusminus))) {
1411 return addUnwrappedLine();
1413 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1415 return addUnwrappedLine();
1419void UnwrappedLineParser::parseStructuralElement(
1420 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1421 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1423 FormatTok->
is(tok::pp_include)) {
1425 if (FormatTok->
is(tok::string_literal))
1432 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1436 parseForOrWhileLoop(
false);
1440 parseForOrWhileLoop();
1445 parseIfThenElse(IfKind,
false,
true);
1454 }
else if (FormatTok->
is(tok::l_paren) &&
1455 Tokens->peekNextToken()->is(tok::star)) {
1469 parseAccessSpecifier();
1476 if (FormatTok->
is(tok::l_brace)) {
1479 while (FormatTok && !eof()) {
1480 if (FormatTok->
is(tok::r_brace)) {
1491 case tok::kw_namespace:
1499 FormatToken *Tok = parseIfThenElse(IfKind);
1510 parseForOrWhileLoop();
1521 case tok::kw_switch:
1528 case tok::kw_default: {
1538 if (FormatTok->
is(tok::colon)) {
1543 if (FormatTok->
is(tok::arrow)) {
1545 Default->setFinalizedType(TT_SwitchExpressionLabel);
1578 case tok::kw_extern:
1584 parseVerilogHierarchyHeader();
1587 }
else if (FormatTok->
is(tok::string_literal)) {
1589 if (FormatTok->
is(tok::l_brace)) {
1594 unsigned AddLevels =
1601 parseBlock(
true, AddLevels);
1607 case tok::kw_export:
1609 parseJavaScriptEs6ImportExport();
1614 if (FormatTok->
is(tok::kw_namespace)) {
1618 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1622 case tok::kw_inline:
1624 if (FormatTok->
is(tok::kw_namespace)) {
1629 case tok::identifier:
1630 if (FormatTok->
is(TT_ForEachMacro)) {
1631 parseForOrWhileLoop();
1634 if (FormatTok->
is(TT_MacroBlockBegin)) {
1635 parseBlock(
false, 1u,
1641 parseJavaScriptEs6ImportExport();
1646 if (FormatTok->
is(tok::kw_public))
1648 if (FormatTok->
isNot(tok::string_literal))
1651 if (FormatTok->
is(tok::semi))
1656 if (IsCpp && parseModuleImport())
1662 if (FormatTok->
is(tok::colon)) {
1668 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1669 parseStatementMacro();
1672 if (IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1681 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1683 if (!Line->InMacroBody || CurrentLines->size() > 1)
1684 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1697 for (
const bool InRequiresExpression =
1698 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
1701 if (
auto *Next = Tokens->peekNextToken(
true);
1702 Next && Next->isBinaryOperator()) {
1710 if (FormatTok->
is(tok::l_brace)) {
1720 case tok::objc_public:
1721 case tok::objc_protected:
1722 case tok::objc_package:
1723 case tok::objc_private:
1724 return parseAccessSpecifier();
1725 case tok::objc_interface:
1726 case tok::objc_implementation:
1727 return parseObjCInterfaceOrImplementation();
1728 case tok::objc_protocol:
1729 if (parseObjCProtocol())
1734 case tok::objc_optional:
1735 case tok::objc_required:
1739 case tok::objc_autoreleasepool:
1741 if (FormatTok->
is(tok::l_brace)) {
1750 case tok::objc_synchronized:
1752 if (FormatTok->
is(tok::l_paren)) {
1756 if (FormatTok->
is(tok::l_brace)) {
1774 case tok::kw_requires: {
1776 bool ParsedClause = parseRequires();
1802 case tok::kw_typedef:
1824 case tok::kw_struct:
1826 if (parseStructLike())
1829 case tok::kw_decltype:
1831 if (FormatTok->
is(tok::l_paren)) {
1836 Line->SeenDecltypeAuto =
true;
1844 FormatTok->
is(tok::kw_class)) {
1861 case tok::l_paren: {
1865 if (OpeningBrace || !IsCpp || !
Previous || eof())
1868 Tokens->peekNextToken(
true),
1875 case tok::kw_operator:
1886 while (FormatTok->
is(tok::star))
1890 if (FormatTok->
is(tok::l_paren))
1893 if (FormatTok->
is(tok::l_brace))
1897 if (InRequiresExpression)
1899 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1900 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1919 IsDecltypeAutoFunction =
false;
1937 case tok::identifier: {
1939 Line->MustBeDeclaration) {
1941 parseCSharpGenericTypeConstraint();
1944 if (FormatTok->
is(TT_MacroBlockEnd)) {
1953 size_t TokenCount = Line->Tokens.size();
1957 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1958 tryToParseJSFunction();
1968 unsigned StoredPosition = Tokens->getPosition();
1969 FormatToken *Next = Tokens->getNextToken();
1970 FormatTok = Tokens->setPosition(StoredPosition);
1983 parseVerilogTable();
1995 if (parseStructLike())
2000 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
2001 parseStatementMacro();
2008 FormatToken *PreviousToken = FormatTok;
2016 auto OneTokenSoFar = [&]() {
2017 auto I = Line->Tokens.begin(),
E = Line->Tokens.end();
2018 while (I !=
E && I->Tok->is(tok::comment))
2021 while (I !=
E && I->Tok->is(tok::hash))
2023 return I !=
E && (++I ==
E);
2025 if (OneTokenSoFar()) {
2028 bool FunctionLike = FormatTok->
is(tok::l_paren);
2032 bool FollowedByNewline =
2033 CommentsBeforeNextToken.empty()
2035 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2037 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
2039 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2040 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2049 FormatTok->
is(TT_FatArrow)) {
2050 tryToParseChildBlock();
2055 if (FormatTok->
is(tok::l_brace)) {
2064 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2066 parseBlock(
false, 1u,
2074 FormatTok->
is(tok::less)) {
2076 parseBracedList(
true);
2085 case tok::kw_switch:
2109 case tok::kw_default:
2112 if (FormatTok->
is(tok::colon)) {
2122 parseVerilogCaseLabel();
2129 parseVerilogCaseLabel();
2140bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2141 assert(FormatTok->
is(tok::l_brace));
2153 unsigned int StoredPosition = Tokens->getPosition();
2154 FormatToken *Tok = Tokens->getNextToken();
2159 bool HasSpecialAccessor =
false;
2160 bool IsTrivialPropertyAccessor =
true;
2161 bool HasAttribute =
false;
2163 if (
const bool IsAccessorKeyword =
2165 IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||
2166 Tok->isOneOf(tok::l_square, tok::semi, Keywords.
kw_internal)) {
2167 if (IsAccessorKeyword)
2168 HasSpecialAccessor =
true;
2169 else if (Tok->is(tok::l_square))
2170 HasAttribute =
true;
2171 Tok = Tokens->getNextToken();
2174 if (Tok->isNot(tok::r_brace))
2175 IsTrivialPropertyAccessor =
false;
2179 if (!HasSpecialAccessor || HasAttribute) {
2180 Tokens->setPosition(StoredPosition);
2186 Tokens->setPosition(StoredPosition);
2194 if (FormatTok->
is(tok::equal)) {
2195 while (!eof() && FormatTok->
isNot(tok::semi))
2208 if (FormatTok->
is(TT_FatArrow)) {
2212 }
while (!eof() && FormatTok->
isNot(tok::semi));
2223 !IsTrivialPropertyAccessor) {
2235bool UnwrappedLineParser::tryToParseLambda() {
2236 assert(FormatTok->
is(tok::l_square));
2241 FormatToken &LSquare = *FormatTok;
2242 if (!tryToParseLambdaIntroducer())
2245 bool SeenArrow =
false;
2246 bool InTemplateParameterList =
false;
2248 while (FormatTok->
isNot(tok::l_brace)) {
2257 parseParens(TT_PointerOrReference);
2265 InTemplateParameterList =
true;
2270 case tok::kw_struct:
2272 case tok::kw_template:
2273 case tok::kw_typename:
2277 case tok::kw_constexpr:
2278 case tok::kw_consteval:
2281 case tok::identifier:
2282 case tok::numeric_constant:
2283 case tok::coloncolon:
2284 case tok::kw_mutable:
2285 case tok::kw_noexcept:
2286 case tok::kw_static:
2311 case tok::equalequal:
2312 case tok::exclaimequal:
2313 case tok::greaterequal:
2314 case tok::lessequal:
2320 if (SeenArrow || InTemplateParameterList) {
2333 case tok::kw_requires: {
2334 auto *RequiresToken = FormatTok;
2336 parseRequiresClause(RequiresToken);
2340 if (!InTemplateParameterList)
2350 LSquare.setFinalizedType(TT_LambdaLSquare);
2352 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2354 assert(!NestedLambdas.empty());
2355 NestedLambdas.pop_back();
2360bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2362 const FormatToken *LeftSquare = FormatTok;
2365 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2366 tok::kw_co_yield, tok::kw_co_return)) ||
2368 LeftSquare->isCppStructuredBinding(IsCpp)) {
2373 if (FormatTok->
is(tok::r_square)) {
2374 const FormatToken *Next = Tokens->peekNextToken(
true);
2375 if (Next->is(tok::greater))
2382void UnwrappedLineParser::tryToParseJSFunction() {
2390 if (FormatTok->
is(tok::star)) {
2396 if (FormatTok->
is(tok::identifier))
2399 if (FormatTok->
isNot(tok::l_paren))
2405 if (FormatTok->
is(tok::colon)) {
2411 if (FormatTok->
is(tok::l_brace))
2412 tryToParseBracedList();
2414 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2418 if (FormatTok->
is(tok::semi))
2424bool UnwrappedLineParser::tryToParseBracedList() {
2426 calculateBraceTypes();
2435bool UnwrappedLineParser::tryToParseChildBlock() {
2437 assert(FormatTok->
is(TT_FatArrow));
2442 if (FormatTok->
isNot(tok::l_brace))
2448bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2449 assert(!IsAngleBracket || !IsEnum);
2450 bool HasError =
false;
2455 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2456 tryToParseChildBlock()) {
2461 tryToParseJSFunction();
2464 if (FormatTok->
is(tok::l_brace)) {
2466 if (tryToParseBracedList())
2471 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2492 if (FormatTok->
is(tok::l_brace))
2507 parseBracedList(
true);
2541bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2542 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2543 auto *LeftParen = FormatTok;
2544 bool SeenComma =
false;
2545 bool SeenEqual =
false;
2546 bool MightBeFoldExpr =
false;
2547 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2552 if (parseParens(AmpAmpTokenType))
2557 case tok::r_paren: {
2558 const auto *Prev = LeftParen->Previous;
2559 if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
2561 const auto *Next = Tokens->peekNextToken();
2562 const bool DoubleParens =
2563 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2564 const bool CommaSeparated =
2565 !DoubleParens && Prev && Prev->isOneOf(tok::l_paren, tok::comma) &&
2566 Next && Next->isOneOf(tok::comma, tok::r_paren);
2567 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2568 const bool Excluded =
2570 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2573 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2574 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2575 const bool ReturnParens =
2577 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2578 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2579 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2580 Next->is(tok::semi);
2581 if ((DoubleParens && !Excluded) || (CommaSeparated && !SeenComma) ||
2583 LeftParen->Optional =
true;
2587 if (Prev && Prev->is(TT_TypenameMacro)) {
2588 LeftParen->setFinalizedType(TT_TypeDeclarationParen);
2601 if (!tryToParseBracedList())
2606 if (FormatTok->
is(tok::l_brace)) {
2616 MightBeFoldExpr =
true;
2621 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2622 tryToParseChildBlock();
2632 case tok::identifier:
2634 tryToParseJSFunction();
2638 case tok::kw_switch:
2641 case tok::kw_requires: {
2642 auto RequiresToken = FormatTok;
2644 parseRequiresExpression(RequiresToken);
2648 if (AmpAmpTokenType != TT_Unknown)
2659void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2660 if (!LambdaIntroducer) {
2661 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2662 if (tryToParseLambda())
2679 case tok::l_brace: {
2680 if (!tryToParseBracedList())
2686 if (FormatTok->
is(tok::l_brace)) {
2698void UnwrappedLineParser::keepAncestorBraces() {
2702 const int MaxNestingLevels = 2;
2703 const int Size = NestedTooDeep.size();
2704 if (Size >= MaxNestingLevels)
2705 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2706 NestedTooDeep.push_back(
false);
2710 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2717void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2718 FormatToken *Tok =
nullptr;
2720 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2721 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2724 : Line->Tokens.back().Tok;
2726 if (Tok->BraceCount < 0) {
2727 assert(Tok->BraceCount == -1);
2730 Tok->BraceCount = -1;
2736 ++Line->UnbracedBodyLevel;
2737 parseStructuralElement();
2738 --Line->UnbracedBodyLevel;
2741 assert(!Line->InPPDirective);
2743 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2745 Tok = L.Tokens.back().Tok;
2753 if (CheckEOF && eof())
2763 assert(LeftBrace->
is(tok::l_brace));
2771 assert(RightBrace->
is(tok::r_brace));
2779void UnwrappedLineParser::handleAttributes() {
2783 else if (FormatTok->
is(tok::l_square))
2784 handleCppAttributes();
2787bool UnwrappedLineParser::handleCppAttributes() {
2789 assert(FormatTok->
is(tok::l_square));
2790 if (!tryToParseSimpleAttribute())
2797bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2801 : Tok.is(tok::l_brace);
2804FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2806 bool IsVerilogAssert) {
2807 assert((FormatTok->
is(tok::kw_if) ||
2814 if (IsVerilogAssert) {
2818 if (FormatTok->
is(tok::numeric_constant))
2835 if (FormatTok->
is(tok::exclaim))
2838 bool KeepIfBraces =
true;
2839 if (FormatTok->
is(tok::kw_consteval)) {
2843 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2845 if (FormatTok->
is(tok::l_paren)) {
2852 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2858 bool NeedsUnwrappedLine =
false;
2859 keepAncestorBraces();
2861 FormatToken *IfLeftBrace =
nullptr;
2862 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2864 if (isBlockBegin(*FormatTok)) {
2866 IfLeftBrace = FormatTok;
2868 parseBlock(
false, 1u,
2869 true, KeepIfBraces, &IfBlockKind);
2870 setPreviousRBraceType(TT_ControlStatementRBrace);
2874 NeedsUnwrappedLine =
true;
2875 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2878 parseUnbracedBody();
2882 assert(!NestedTooDeep.empty());
2883 KeepIfBraces = KeepIfBraces ||
2884 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2885 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2886 IfBlockKind == IfStmtKind::IfElseIf;
2889 bool KeepElseBraces = KeepIfBraces;
2890 FormatToken *ElseLeftBrace =
nullptr;
2891 IfStmtKind
Kind = IfStmtKind::IfOnly;
2893 if (FormatTok->
is(tok::kw_else)) {
2895 NestedTooDeep.back() =
false;
2896 Kind = IfStmtKind::IfElse;
2900 if (isBlockBegin(*FormatTok)) {
2901 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2903 ElseLeftBrace = FormatTok;
2905 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2906 FormatToken *IfLBrace =
2907 parseBlock(
false, 1u,
2908 true, KeepElseBraces, &ElseBlockKind);
2909 setPreviousRBraceType(TT_ElseRBrace);
2910 if (FormatTok->
is(tok::kw_else)) {
2911 KeepElseBraces = KeepElseBraces ||
2912 ElseBlockKind == IfStmtKind::IfOnly ||
2913 ElseBlockKind == IfStmtKind::IfElseIf;
2914 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2915 KeepElseBraces =
true;
2916 assert(ElseLeftBrace->MatchingParen);
2920 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2921 const FormatToken *
Previous = Tokens->getPreviousToken();
2923 const bool IsPrecededByComment =
Previous->is(tok::comment);
2924 if (IsPrecededByComment) {
2928 bool TooDeep =
true;
2930 Kind = IfStmtKind::IfElseIf;
2931 TooDeep = NestedTooDeep.pop_back_val();
2933 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2935 NestedTooDeep.push_back(TooDeep);
2936 if (IsPrecededByComment)
2939 parseUnbracedBody(
true);
2942 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2943 if (NeedsUnwrappedLine)
2950 assert(!NestedTooDeep.empty());
2951 KeepElseBraces = KeepElseBraces ||
2952 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2953 NestedTooDeep.back();
2955 NestedTooDeep.pop_back();
2957 if (!KeepIfBraces && !KeepElseBraces) {
2960 }
else if (IfLeftBrace) {
2961 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2963 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2964 assert(!IfLeftBrace->Optional);
2965 assert(!IfRightBrace->Optional);
2966 IfLeftBrace->MatchingParen =
nullptr;
2967 IfRightBrace->MatchingParen =
nullptr;
2977void UnwrappedLineParser::parseTryCatch() {
2978 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2980 bool NeedsUnwrappedLine =
false;
2981 bool HasCtorInitializer =
false;
2982 if (FormatTok->
is(tok::colon)) {
2983 auto *Colon = FormatTok;
2986 if (FormatTok->
is(tok::identifier)) {
2987 HasCtorInitializer =
true;
2988 Colon->setFinalizedType(TT_CtorInitializerColon);
2993 while (FormatTok->
is(tok::comma))
2996 while (FormatTok->
is(tok::identifier)) {
2998 if (FormatTok->
is(tok::l_paren)) {
3000 }
else if (FormatTok->
is(tok::l_brace)) {
3007 while (FormatTok->
is(tok::comma))
3015 keepAncestorBraces();
3017 if (FormatTok->
is(tok::l_brace)) {
3018 if (HasCtorInitializer)
3025 NeedsUnwrappedLine =
true;
3026 }
else if (FormatTok->
isNot(tok::kw_catch)) {
3032 parseStructuralElement();
3036 if (FormatTok->
is(tok::at))
3039 tok::kw___finally) ||
3047 while (FormatTok->
isNot(tok::l_brace)) {
3048 if (FormatTok->
is(tok::l_paren)) {
3052 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
3054 NestedTooDeep.pop_back();
3059 NeedsUnwrappedLine =
false;
3060 Line->MustBeDeclaration =
false;
3066 NeedsUnwrappedLine =
true;
3070 NestedTooDeep.pop_back();
3072 if (NeedsUnwrappedLine)
3076void UnwrappedLineParser::parseNamespace() {
3077 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3078 "'namespace' expected");
3080 const FormatToken &InitialToken = *FormatTok;
3082 if (InitialToken.is(TT_NamespaceMacro)) {
3085 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3086 tok::l_square, tok::period, tok::l_paren) ||
3087 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3088 if (FormatTok->
is(tok::l_square))
3090 else if (FormatTok->
is(tok::l_paren))
3096 if (FormatTok->
is(tok::l_brace)) {
3102 unsigned AddLevels =
3105 DeclarationScopeStack.size() > 1)
3108 bool ManageWhitesmithsBraces =
3114 if (ManageWhitesmithsBraces)
3119 parseBlock(
true, AddLevels,
true,
3121 ManageWhitesmithsBraces);
3123 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3125 if (ManageWhitesmithsBraces)
3131void UnwrappedLineParser::parseNew() {
3132 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3138 if (FormatTok->
is(tok::l_paren))
3142 if (FormatTok->
is(tok::l_brace))
3145 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3158 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3162 if (FormatTok->
is(tok::l_paren)) {
3166 if (FormatTok->
is(tok::l_brace))
3174void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3175 keepAncestorBraces();
3177 if (isBlockBegin(*FormatTok)) {
3179 FormatToken *LeftBrace = FormatTok;
3181 parseBlock(
false, 1u,
3183 setPreviousRBraceType(TT_ControlStatementRBrace);
3185 assert(!NestedTooDeep.empty());
3186 if (!NestedTooDeep.back())
3192 parseUnbracedBody();
3196 NestedTooDeep.pop_back();
3199void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3200 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3207 "'for', 'while' or foreach macro expected");
3209 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3215 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3217 if (HasParens && FormatTok->
is(tok::l_paren)) {
3228 parseVerilogSensitivityList();
3230 Tokens->getPreviousToken()->is(tok::r_paren)) {
3237 parseLoopBody(KeepBraces,
true);
3240void UnwrappedLineParser::parseDoWhile() {
3241 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3247 if (FormatTok->
isNot(tok::kw_while)) {
3260 parseStructuralElement();
3263void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3265 unsigned OldLineLevel = Line->Level;
3269 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3273 FormatTok->
is(tok::l_brace)) {
3279 if (FormatTok->
is(tok::kw_break)) {
3288 parseStructuralElement();
3292 if (FormatTok->
is(tok::semi))
3296 Line->Level = OldLineLevel;
3297 if (FormatTok->
isNot(tok::l_brace)) {
3298 parseStructuralElement();
3303void UnwrappedLineParser::parseCaseLabel() {
3304 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3305 auto *Case = FormatTok;
3310 if (FormatTok->
is(tok::colon)) {
3316 Case->setFinalizedType(TT_SwitchExpressionLabel);
3323void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3324 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3326 if (FormatTok->
is(tok::l_paren))
3329 keepAncestorBraces();
3331 if (FormatTok->
is(tok::l_brace)) {
3334 : TT_ControlStatementLBrace);
3339 setPreviousRBraceType(TT_ControlStatementRBrace);
3345 parseStructuralElement();
3350 NestedTooDeep.pop_back();
3360 case tok::caretequal:
3364 case tok::equalequal:
3366 case tok::exclaimequal:
3368 case tok::greaterequal:
3369 case tok::greatergreater:
3370 case tok::greatergreaterequal:
3374 case tok::lessequal:
3376 case tok::lesslessequal:
3378 case tok::minusequal:
3379 case tok::minusminus:
3381 case tok::percentequal:
3384 case tok::pipeequal:
3387 case tok::plusequal:
3395 case tok::slashequal:
3397 case tok::starequal:
3404void UnwrappedLineParser::parseAccessSpecifier() {
3405 FormatToken *AccessSpecifierCandidate = FormatTok;
3411 if (FormatTok->
is(tok::colon)) {
3414 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3418 }
else if (AccessSpecifierCandidate) {
3420 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3427bool UnwrappedLineParser::parseRequires() {
3428 assert(FormatTok->
is(tok::kw_requires) &&
"'requires' expected");
3429 auto RequiresToken = FormatTok;
3438 parseRequiresExpression(RequiresToken);
3445 parseRequiresClause(RequiresToken);
3456 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3458 if (!PreviousNonComment ||
3459 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3462 parseRequiresClause(RequiresToken);
3466 switch (PreviousNonComment->Tok.getKind()) {
3469 case tok::kw_noexcept:
3472 parseRequiresClause(RequiresToken);
3482 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3483 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3484 parseRequiresClause(RequiresToken);
3490 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3492 parseRequiresClause(RequiresToken);
3496 parseRequiresExpression(RequiresToken);
3506 unsigned StoredPosition = Tokens->getPosition();
3507 FormatToken *NextToken = Tokens->getNextToken();
3509 auto PeekNext = [&Lookahead, &NextToken,
this] {
3511 NextToken = Tokens->getNextToken();
3514 bool FoundType =
false;
3515 bool LastWasColonColon =
false;
3518 for (; Lookahead < 50; PeekNext()) {
3519 switch (NextToken->Tok.getKind()) {
3520 case tok::kw_volatile:
3523 if (OpenAngles == 0) {
3524 FormatTok = Tokens->setPosition(StoredPosition);
3525 parseRequiresExpression(RequiresToken);
3533 case tok::coloncolon:
3534 LastWasColonColon =
true;
3536 case tok::kw_decltype:
3537 case tok::identifier:
3538 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3539 FormatTok = Tokens->setPosition(StoredPosition);
3540 parseRequiresExpression(RequiresToken);
3544 LastWasColonColon =
false;
3553 if (NextToken->isTypeName(LangOpts)) {
3554 FormatTok = Tokens->setPosition(StoredPosition);
3555 parseRequiresExpression(RequiresToken);
3562 FormatTok = Tokens->setPosition(StoredPosition);
3563 parseRequiresClause(RequiresToken);
3574void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3576 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3581 bool InRequiresExpression =
3582 !RequiresToken->Previous ||
3583 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3585 RequiresToken->setFinalizedType(InRequiresExpression
3586 ? TT_RequiresClauseInARequiresExpression
3587 : TT_RequiresClause);
3591 parseConstraintExpression();
3593 if (!InRequiresExpression)
3604void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3606 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3608 RequiresToken->setFinalizedType(TT_RequiresExpression);
3610 if (FormatTok->
is(tok::l_paren)) {
3615 if (FormatTok->
is(tok::l_brace)) {
3625void UnwrappedLineParser::parseConstraintExpression() {
3632 bool LambdaNextTimeAllowed =
true;
3642 bool TopLevelParensAllowed =
true;
3645 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3648 case tok::kw_requires: {
3649 auto RequiresToken = FormatTok;
3651 parseRequiresExpression(RequiresToken);
3656 if (!TopLevelParensAllowed)
3658 parseParens(TT_BinaryOperator);
3659 TopLevelParensAllowed =
false;
3663 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3670 case tok::kw_struct:
3682 LambdaNextTimeAllowed =
true;
3683 TopLevelParensAllowed =
true;
3688 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3692 case tok::kw_sizeof:
3694 case tok::greaterequal:
3695 case tok::greatergreater:
3697 case tok::lessequal:
3699 case tok::equalequal:
3701 case tok::exclaimequal:
3706 LambdaNextTimeAllowed =
true;
3707 TopLevelParensAllowed =
true;
3712 case tok::numeric_constant:
3713 case tok::coloncolon:
3716 TopLevelParensAllowed =
false;
3721 case tok::kw_static_cast:
3722 case tok::kw_const_cast:
3723 case tok::kw_reinterpret_cast:
3724 case tok::kw_dynamic_cast:
3726 if (FormatTok->
isNot(tok::less))
3730 parseBracedList(
true);
3746 case tok::coloncolon:
3750 case tok::kw_requires:
3759 if (FormatTok->
is(tok::less)) {
3761 parseBracedList(
true);
3763 TopLevelParensAllowed =
false;
3769bool UnwrappedLineParser::parseEnum() {
3770 const FormatToken &InitialToken = *FormatTok;
3773 if (FormatTok->
is(tok::kw_enum))
3788 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3790 while (FormatTok->
is(tok::l_square))
3791 if (!handleCppAttributes())
3796 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3797 tok::greater, tok::comma, tok::question,
3803 while (FormatTok->
is(tok::l_square))
3809 if (FormatTok->
is(tok::l_paren))
3811 if (FormatTok->
is(tok::identifier)) {
3815 if (IsCpp && FormatTok->
is(tok::identifier))
3821 if (FormatTok->
isNot(tok::l_brace))
3828 parseJavaEnumBody();
3846 bool HasError = !parseBracedList(
false,
true);
3850 if (FormatTok->
is(tok::semi))
3854 setPreviousRBraceType(TT_EnumRBrace);
3862bool UnwrappedLineParser::parseStructLike() {
3869 if (FormatTok->
is(tok::semi))
3880class ScopedTokenPosition {
3881 unsigned StoredPosition;
3882 FormatTokenSource *Tokens;
3885 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3886 assert(Tokens &&
"Tokens expected to not be null");
3887 StoredPosition = Tokens->getPosition();
3890 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3896bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3897 ScopedTokenPosition AutoPosition(Tokens);
3898 FormatToken *Tok = Tokens->getNextToken();
3900 if (Tok->isNot(tok::l_square))
3904 while (Tok->isNot(tok::eof)) {
3905 if (Tok->is(tok::r_square))
3907 Tok = Tokens->getNextToken();
3909 if (Tok->is(tok::eof))
3911 Tok = Tokens->getNextToken();
3912 if (Tok->isNot(tok::r_square))
3914 Tok = Tokens->getNextToken();
3915 if (Tok->is(tok::semi))
3920void UnwrappedLineParser::parseJavaEnumBody() {
3921 assert(FormatTok->
is(tok::l_brace));
3922 const FormatToken *OpeningBrace = FormatTok;
3927 unsigned StoredPosition = Tokens->getPosition();
3928 bool IsSimple =
true;
3929 FormatToken *Tok = Tokens->getNextToken();
3930 while (Tok->isNot(tok::eof)) {
3931 if (Tok->is(tok::r_brace))
3933 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3939 Tok = Tokens->getNextToken();
3941 FormatTok = Tokens->setPosition(StoredPosition);
3958 if (FormatTok->
is(tok::l_brace)) {
3960 parseBlock(
true, 1u,
3962 }
else if (FormatTok->
is(tok::l_paren)) {
3964 }
else if (FormatTok->
is(tok::comma)) {
3967 }
else if (FormatTok->
is(tok::semi)) {
3971 }
else if (FormatTok->
is(tok::r_brace)) {
3980 parseLevel(OpeningBrace);
3986void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
3987 const FormatToken &InitialToken = *FormatTok;
3990 const FormatToken *ClassName =
nullptr;
3991 bool IsDerived =
false;
3992 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
3993 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
3998 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3999 tok::kw_alignas, tok::l_square) ||
4002 FormatTok->
isOneOf(tok::period, tok::comma))) {
4009 if (FormatTok->
is(tok::l_brace)) {
4010 tryToParseBracedList();
4014 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
4021 if (!IsNonMacroIdentifier(
Previous) ||
4023 Previous->Previous == &InitialToken) {
4027 case tok::coloncolon:
4030 if (!ClassName &&
Previous->is(tok::identifier) &&
4031 Previous->isNot(TT_AttributeMacro)) {
4037 auto IsListInitialization = [&] {
4038 if (!ClassName || IsDerived)
4040 assert(FormatTok->
is(tok::l_brace));
4043 return Prev != ClassName && Prev->is(tok::identifier) &&
4044 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
4047 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
4048 int AngleNestingLevel = 0;
4050 if (FormatTok->
is(tok::less))
4051 ++AngleNestingLevel;
4052 else if (FormatTok->
is(tok::greater))
4053 --AngleNestingLevel;
4055 if (AngleNestingLevel == 0) {
4056 if (FormatTok->
is(tok::colon)) {
4058 }
else if (FormatTok->
is(tok::identifier) &&
4060 ClassName = FormatTok;
4061 }
else if (FormatTok->
is(tok::l_paren) &&
4062 IsNonMacroIdentifier(FormatTok->
Previous)) {
4066 if (FormatTok->
is(tok::l_brace)) {
4067 if (AngleNestingLevel == 0 && IsListInitialization())
4069 calculateBraceTypes(
true);
4070 if (!tryToParseBracedList())
4073 if (FormatTok->
is(tok::l_square)) {
4076 !
Previous->isTypeOrIdentifier(LangOpts))) {
4079 if (!tryToParseLambda())
4086 if (FormatTok->
is(tok::semi))
4091 parseCSharpGenericTypeConstraint();
4098 auto GetBraceTypes =
4099 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4100 switch (RecordTok.Tok.getKind()) {
4102 return {TT_ClassLBrace, TT_ClassRBrace};
4103 case tok::kw_struct:
4104 return {TT_StructLBrace, TT_StructRBrace};
4106 return {TT_UnionLBrace, TT_UnionRBrace};
4109 return {TT_RecordLBrace, TT_RecordRBrace};
4112 if (FormatTok->
is(tok::l_brace)) {
4113 if (IsListInitialization())
4115 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4124 parseBlock(
true, AddLevels,
false);
4126 setPreviousRBraceType(ClosingBraceType);
4133void UnwrappedLineParser::parseObjCMethod() {
4134 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4135 "'(' or identifier expected.");
4137 if (FormatTok->
is(tok::semi)) {
4141 }
else if (FormatTok->
is(tok::l_brace)) {
4153void UnwrappedLineParser::parseObjCProtocolList() {
4154 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4158 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4162 }
while (!eof() && FormatTok->
isNot(tok::greater));
4166void UnwrappedLineParser::parseObjCUntilAtEnd() {
4173 if (FormatTok->
is(tok::l_brace)) {
4177 }
else if (FormatTok->
is(tok::r_brace)) {
4181 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4185 parseStructuralElement();
4190void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4198 if (FormatTok->
is(tok::less))
4199 parseObjCLightweightGenerics();
4200 if (FormatTok->
is(tok::colon)) {
4204 if (FormatTok->
is(tok::less))
4205 parseObjCLightweightGenerics();
4206 }
else if (FormatTok->
is(tok::l_paren)) {
4211 if (FormatTok->
is(tok::less))
4212 parseObjCProtocolList();
4214 if (FormatTok->
is(tok::l_brace)) {
4224 parseObjCUntilAtEnd();
4227void UnwrappedLineParser::parseObjCLightweightGenerics() {
4228 assert(FormatTok->
is(tok::less));
4236 unsigned NumOpenAngles = 1;
4240 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4244 if (FormatTok->
is(tok::less)) {
4246 }
else if (FormatTok->
is(tok::greater)) {
4247 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4250 }
while (!eof() && NumOpenAngles != 0);
4256bool UnwrappedLineParser::parseObjCProtocol() {
4260 if (FormatTok->
is(tok::l_paren)) {
4272 if (FormatTok->
is(tok::less))
4273 parseObjCProtocolList();
4276 if (FormatTok->
is(tok::semi)) {
4283 parseObjCUntilAtEnd();
4287void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4288 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4289 assert(IsImport || FormatTok->
is(tok::kw_export));
4293 if (FormatTok->
is(tok::kw_default))
4310 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4313 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4318 if (FormatTok->
is(tok::semi))
4320 if (Line->Tokens.empty()) {
4325 if (FormatTok->
is(tok::l_brace)) {
4335void UnwrappedLineParser::parseStatementMacro() {
4337 if (FormatTok->
is(tok::l_paren))
4339 if (FormatTok->
is(tok::semi))
4344void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4347 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4348 tok::coloncolon, tok::hash) ||
4351 }
else if (FormatTok->
is(tok::l_square)) {
4359void UnwrappedLineParser::parseVerilogSensitivityList() {
4360 if (FormatTok->
isNot(tok::at))
4364 if (FormatTok->
is(tok::at))
4374 parseVerilogHierarchyIdentifier();
4379unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4380 unsigned AddLevels = 0;
4386 parseVerilogSensitivityList();
4387 if (FormatTok->
is(tok::semi))
4395 if (FormatTok->
is(tok::l_paren)) {
4408 if (FormatTok->
is(tok::l_square)) {
4423 Line->IsContinuation =
true;
4430 parseVerilogHierarchyIdentifier();
4431 if (FormatTok->
is(tok::semi))
4439 if (FormatTok->
is(tok::l_paren)) {
4444 if (FormatTok->
is(tok::l_paren)) {
4454 parseVerilogHierarchyIdentifier();
4455 if (FormatTok->
is(tok::l_paren))
4462 parseVerilogHierarchyIdentifier();
4463 }
while (FormatTok->
is(tok::comma));
4467 if (FormatTok->
is(tok::at)) {
4469 parseVerilogSensitivityList();
4472 if (FormatTok->
is(tok::semi))
4480void UnwrappedLineParser::parseVerilogTable() {
4485 auto InitialLevel = Line->Level++;
4487 FormatToken *Tok = FormatTok;
4489 if (Tok->is(tok::semi))
4491 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4492 Tok->setFinalizedType(TT_VerilogTableItem);
4494 Line->Level = InitialLevel;
4499void UnwrappedLineParser::parseVerilogCaseLabel() {
4505 auto OrigLevel = Line->Level;
4506 auto FirstLine = CurrentLines->size();
4507 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4511 parseStructuralElement();
4514 if (CurrentLines->size() > FirstLine)
4515 (*CurrentLines)[FirstLine].Level = OrigLevel;
4516 Line->Level = OrigLevel;
4519bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4520 for (
const auto &N : Line.Tokens) {
4521 if (N.Tok->MacroCtx)
4523 for (
const UnwrappedLine &Child : N.Children)
4524 if (containsExpansion(Child))
4530void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4531 if (Line->Tokens.empty())
4534 if (!parsingPPDirective()) {
4535 llvm::dbgs() <<
"Adding unwrapped line:\n";
4536 printDebugInfo(*Line);
4544 bool ClosesWhitesmithsBlock =
4551 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4553 Reconstruct.emplace(Line->Level, Unexpanded);
4554 Reconstruct->addLine(*Line);
4559 CurrentExpandedLines.push_back(std::move(*Line));
4561 if (Reconstruct->finished()) {
4562 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4563 assert(!Reconstructed.Tokens.empty() &&
4564 "Reconstructed must at least contain the macro identifier.");
4565 assert(!parsingPPDirective());
4567 llvm::dbgs() <<
"Adding unexpanded line:\n";
4568 printDebugInfo(Reconstructed);
4570 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4571 Lines.push_back(std::move(Reconstructed));
4572 CurrentExpandedLines.clear();
4573 Reconstruct.reset();
4578 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4579 CurrentLines->push_back(std::move(*Line));
4581 Line->Tokens.clear();
4583 Line->FirstStartColumn = 0;
4584 Line->IsContinuation =
false;
4585 Line->SeenDecltypeAuto =
false;
4587 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4589 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4590 CurrentLines->append(
4591 std::make_move_iterator(PreprocessorDirectives.begin()),
4592 std::make_move_iterator(PreprocessorDirectives.end()));
4593 PreprocessorDirectives.clear();
4599bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4601bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4602 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4603 FormatTok.NewlinesBefore > 0;
4611 const llvm::Regex &CommentPragmasRegex) {
4612 if (
Line.Tokens.empty())
4615 StringRef IndentContent = FormatTok.
TokenText;
4616 if (FormatTok.
TokenText.starts_with(
"//") ||
4617 FormatTok.
TokenText.starts_with(
"/*")) {
4618 IndentContent = FormatTok.
TokenText.substr(2);
4620 if (CommentPragmasRegex.match(IndentContent))
4695 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4697 MinColumnToken = PreviousToken;
4700 PreviousToken =
Node.Tok;
4703 if (
Node.Tok->NewlinesBefore > 0)
4704 MinColumnToken =
Node.Tok;
4706 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4707 MinColumnToken = PreviousToken;
4713void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4714 bool JustComments = Line->Tokens.empty();
4715 for (FormatToken *Tok : CommentsBeforeNextToken) {
4724 Tok->ContinuesLineCommentSection =
4726 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4730 if (NewlineBeforeNext && JustComments)
4732 CommentsBeforeNextToken.clear();
4735void UnwrappedLineParser::nextToken(
int LevelDifference) {
4738 flushComments(isOnNewLine(*FormatTok));
4739 pushToken(FormatTok);
4742 readToken(LevelDifference);
4744 readTokenWithJavaScriptASI();
4754 FormatTok->Tok.setKind(tok::r_brace);
4758void UnwrappedLineParser::distributeComments(
4759 const SmallVectorImpl<FormatToken *> &Comments,
4760 const FormatToken *NextTok) {
4779 if (Comments.empty())
4781 bool ShouldPushCommentsInCurrentLine =
true;
4782 bool HasTrailAlignedWithNextToken =
false;
4783 unsigned StartOfTrailAlignedWithNextToken = 0;
4786 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4787 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4788 HasTrailAlignedWithNextToken =
true;
4789 StartOfTrailAlignedWithNextToken = i;
4793 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4794 FormatToken *FormatTok = Comments[i];
4795 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4796 FormatTok->ContinuesLineCommentSection =
false;
4798 FormatTok->ContinuesLineCommentSection =
4801 if (!FormatTok->ContinuesLineCommentSection &&
4802 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4803 ShouldPushCommentsInCurrentLine =
false;
4805 if (ShouldPushCommentsInCurrentLine)
4806 pushToken(FormatTok);
4808 CommentsBeforeNextToken.push_back(FormatTok);
4812void UnwrappedLineParser::readToken(
int LevelDifference) {
4813 SmallVector<FormatToken *, 1> Comments;
4814 bool PreviousWasComment =
false;
4815 bool FirstNonCommentOnLine =
false;
4817 FormatTok = Tokens->getNextToken();
4819 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4820 TT_ConflictAlternative)) {
4821 if (FormatTok->is(TT_ConflictStart))
4822 conditionalCompilationStart(
false);
4823 else if (FormatTok->is(TT_ConflictAlternative))
4824 conditionalCompilationAlternative();
4825 else if (FormatTok->is(TT_ConflictEnd))
4826 conditionalCompilationEnd();
4827 FormatTok = Tokens->getNextToken();
4828 FormatTok->MustBreakBefore =
true;
4829 FormatTok->MustBreakBeforeFinalized =
true;
4832 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4833 const FormatToken &Tok,
4834 bool PreviousWasComment) {
4835 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4836 return Tok.HasUnescapedNewline || Tok.IsFirst;
4841 if (PreviousWasComment)
4842 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4843 return IsFirstOnLine(Tok);
4846 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4847 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4848 PreviousWasComment = FormatTok->is(tok::comment);
4850 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4853 FirstNonCommentOnLine) {
4854 distributeComments(Comments, FormatTok);
4858 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4860 assert((LevelDifference >= 0 ||
4861 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4862 "LevelDifference makes Line->Level negative");
4863 Line->Level += LevelDifference;
4868 PPBranchLevel > 0) {
4869 Line->Level += PPBranchLevel;
4871 assert(Line->Level >= Line->UnbracedBodyLevel);
4872 Line->Level -= Line->UnbracedBodyLevel;
4873 flushComments(isOnNewLine(*FormatTok));
4875 PreviousWasComment = FormatTok->is(tok::comment);
4876 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4877 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4880 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4881 !Line->InPPDirective) {
4885 if (FormatTok->is(tok::identifier) &&
4886 Macros.
defined(FormatTok->TokenText) &&
4888 !Line->InPPDirective) {
4889 FormatToken *
ID = FormatTok;
4890 unsigned Position = Tokens->getPosition();
4894 auto PreCall = std::move(Line);
4895 Line.reset(
new UnwrappedLine);
4896 bool OldInExpansion = InExpansion;
4899 auto Args = parseMacroCall();
4900 InExpansion = OldInExpansion;
4901 assert(Line->Tokens.front().Tok ==
ID);
4903 auto UnexpandedLine = std::move(Line);
4905 Line = std::move(PreCall);
4908 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4910 llvm::dbgs() <<
"(";
4911 for (
const auto &Arg : Args.value())
4912 for (
const auto &
T : Arg)
4913 llvm::dbgs() <<
T->TokenText <<
" ";
4914 llvm::dbgs() <<
")";
4916 llvm::dbgs() <<
"\n";
4919 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4925 LLVM_DEBUG(llvm::dbgs()
4926 <<
"Macro \"" <<
ID->TokenText
4927 <<
"\" not overloaded for arity " << Args->size()
4928 <<
"or not function-like, using object-like overload.");
4930 UnexpandedLine->Tokens.resize(1);
4931 Tokens->setPosition(Position);
4936 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4939 Unexpanded[
ID] = std::move(UnexpandedLine);
4940 SmallVector<FormatToken *, 8> Expansion =
4941 Macros.
expand(
ID, std::move(Args));
4942 if (!Expansion.empty())
4943 FormatTok = Tokens->insertTokens(Expansion);
4946 llvm::dbgs() <<
"Expanded: ";
4947 for (
const auto &
T : Expansion)
4948 llvm::dbgs() <<
T->TokenText <<
" ";
4949 llvm::dbgs() <<
"\n";
4953 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4954 <<
"\", because it was used ";
4956 llvm::dbgs() <<
"with " << Args->size();
4958 llvm::dbgs() <<
"without";
4959 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4961 Tokens->setPosition(Position);
4966 if (FormatTok->isNot(tok::comment)) {
4967 distributeComments(Comments, FormatTok);
4972 Comments.push_back(FormatTok);
4975 distributeComments(Comments,
nullptr);
4980template <
typename Iterator>
4981void pushTokens(Iterator
Begin, Iterator End,
4983 for (
auto I =
Begin; I != End; ++I) {
4984 Into.push_back(I->Tok);
4985 for (
const auto &Child : I->Children)
4986 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
4991std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
4992UnwrappedLineParser::parseMacroCall() {
4993 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
4994 assert(Line->Tokens.empty());
4996 if (FormatTok->isNot(tok::l_paren))
4998 unsigned Position = Tokens->getPosition();
4999 FormatToken *Tok = FormatTok;
5002 auto ArgStart = std::prev(Line->Tokens.end());
5006 switch (FormatTok->Tok.getKind()) {
5011 case tok::r_paren: {
5017 Args->push_back({});
5018 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5027 Args->push_back({});
5028 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5030 ArgStart = std::prev(Line->Tokens.end());
5038 Line->Tokens.resize(1);
5039 Tokens->setPosition(Position);
5044void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5045 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5046 if (MustBreakBeforeNextToken) {
5047 Line->Tokens.back().Tok->MustBreakBefore =
true;
5048 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
5049 MustBreakBeforeNextToken =
false;
enum clang::sema::@1653::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.