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)) {
512 }
while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof));
514 while (NextTok->is(tok::comment))
519 switch (Tok->Tok.getKind()) {
522 if (PrevTok->isOneOf(tok::colon, tok::less)) {
533 }
else if (PrevTok->is(tok::r_paren)) {
540 LBraceStack.push_back({Tok, PrevTok});
543 if (LBraceStack.empty())
545 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
546 bool ProbablyBracedList =
false;
548 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
549 }
else if (LBrace->isNot(TT_EnumLBrace)) {
552 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
553 NextTok->OriginalColumn == 0;
563 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
565 ProbablyBracedList = ProbablyBracedList ||
567 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
570 ProbablyBracedList || (IsCpp && NextTok->is(tok::l_paren));
577 ProbablyBracedList ||
578 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
579 tok::r_paren, tok::r_square, tok::ellipsis);
584 ProbablyBracedList ||
585 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
586 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
590 ProbablyBracedList ||
591 (NextTok->is(tok::identifier) &&
592 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
594 ProbablyBracedList = ProbablyBracedList ||
595 (NextTok->is(tok::semi) &&
596 (!ExpectClassBody || LBraceStack.size() != 1));
599 ProbablyBracedList ||
600 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
602 if (!Style.
isCSharp() && NextTok->is(tok::l_square)) {
606 ProbablyBracedList = NextTok->
isNot(tok::l_square);
610 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
611 !FormatTok->
Previous && NextTok->
is(tok::eof) &&
615 !PrevTok->isOneOf(tok::semi,
BK_Block, tok::colon)) {
616 ProbablyBracedList =
true;
620 Tok->setBlockKind(BlockKind);
621 LBrace->setBlockKind(BlockKind);
623 LBraceStack.pop_back();
625 case tok::identifier:
626 if (Tok->isNot(TT_StatementMacro))
637 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
638 LBraceStack.back().Tok->setBlockKind(
BK_Block);
646 }
while (Tok->isNot(tok::eof) && !LBraceStack.empty());
649 for (
const auto &Entry : LBraceStack)
657void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
659 Prev && Prev->
is(tok::r_brace)) {
667 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
670size_t UnwrappedLineParser::computePPHash()
const {
672 for (
const auto &i : PPStack) {
683bool UnwrappedLineParser::mightFitOnOneLine(
684 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
686 if (ColumnLimit == 0)
689 auto &Tokens = ParsedLine.Tokens;
690 assert(!Tokens.empty());
692 const auto *LastToken = Tokens.back().Tok;
695 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
698 for (
const auto &Token : Tokens) {
700 auto &SavedToken = SavedTokens[Index++];
701 SavedToken.Tok =
new FormatToken;
702 SavedToken.Tok->copyFrom(*Token.Tok);
703 SavedToken.Children = std::move(Token.Children);
706 AnnotatedLine Line(ParsedLine);
707 assert(Line.Last == LastToken);
709 TokenAnnotator Annotator(Style, Keywords);
710 Annotator.annotate(Line);
711 Annotator.calculateFormattingInformation(Line);
713 auto Length = LastToken->TotalLength;
715 assert(OpeningBrace != Tokens.front().Tok);
716 if (
auto Prev = OpeningBrace->Previous;
717 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
718 Length -= ColumnLimit;
720 Length -= OpeningBrace->TokenText.size() + 1;
723 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
724 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
725 Length -= FirstToken->TokenText.size() + 1;
729 for (
auto &Token : Tokens) {
730 const auto &SavedToken = SavedTokens[Index++];
731 Token.Tok->copyFrom(*SavedToken.Tok);
732 Token.Children = std::move(SavedToken.Children);
733 delete SavedToken.Tok;
737 assert(!Line.InMacroBody);
738 assert(!Line.InPPDirective);
739 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
742FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
743 unsigned AddLevels,
bool MunchSemi,
746 bool UnindentWhitesmithsBraces) {
747 auto HandleVerilogBlockLabel = [
this]() {
749 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
758 const bool VerilogHierarchy =
760 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
763 "'{' or macro block token expected");
764 FormatToken *Tok = FormatTok;
765 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
766 auto Index = CurrentLines->size();
767 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
772 if (!VerilogHierarchy && AddLevels > 0 &&
777 size_t PPStartHash = computePPHash();
779 const unsigned InitialLevel = Line->Level;
780 if (VerilogHierarchy) {
781 AddLevels += parseVerilogHierarchyHeader();
783 nextToken(AddLevels);
784 HandleVerilogBlockLabel();
788 if (Line->Level > 300)
791 if (MacroBlock && FormatTok->
is(tok::l_paren))
794 size_t NbPreprocessorDirectives =
795 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
797 size_t OpeningLineIndex =
798 CurrentLines->empty()
800 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
805 if (UnindentWhitesmithsBraces)
808 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
811 Line->Level += AddLevels;
813 FormatToken *IfLBrace =
nullptr;
814 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
819 if (MacroBlock ? FormatTok->
isNot(TT_MacroBlockEnd)
820 : FormatTok->
isNot(tok::r_brace)) {
821 Line->Level = InitialLevel;
826 if (FormatTok->
is(tok::r_brace)) {
828 if (Tok->is(TT_NamespaceLBrace))
832 const bool IsFunctionRBrace =
833 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
835 auto RemoveBraces = [=]()
mutable {
838 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
839 assert(FormatTok->
is(tok::r_brace));
840 const bool WrappedOpeningBrace = !Tok->Previous;
841 if (WrappedOpeningBrace && FollowedByComment)
843 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
844 if (KeepBraces && !HasRequiredIfBraces)
846 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
847 const FormatToken *
Previous = Tokens->getPreviousToken();
852 assert(!CurrentLines->empty());
853 auto &LastLine = CurrentLines->back();
854 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
856 if (Tok->is(TT_ElseLBrace))
858 if (WrappedOpeningBrace) {
863 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
865 if (RemoveBraces()) {
866 Tok->MatchingParen = FormatTok;
870 size_t PPEndHash = computePPHash();
873 nextToken(-AddLevels);
879 while (FormatTok->
is(tok::semi)) {
885 HandleVerilogBlockLabel();
887 if (MacroBlock && FormatTok->
is(tok::l_paren))
890 Line->Level = InitialLevel;
892 if (FormatTok->
is(tok::kw_noexcept)) {
897 if (FormatTok->
is(tok::arrow)) {
901 parseStructuralElement();
904 if (MunchSemi && FormatTok->
is(tok::semi))
907 if (PPStartHash == PPEndHash) {
908 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
911 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
912 CurrentLines->size() - 1;
922 if (
Line.Tokens.size() < 4)
924 auto I =
Line.Tokens.begin();
925 if (I->Tok->TokenText !=
"goog")
928 if (I->Tok->isNot(tok::period))
931 if (I->Tok->TokenText !=
"scope")
934 return I->Tok->is(tok::l_paren);
943 if (
Line.Tokens.size() < 3)
945 auto I =
Line.Tokens.begin();
946 if (I->Tok->isNot(tok::l_paren))
952 return I->Tok->is(tok::l_paren);
958 if (InitialToken.
is(TT_NamespaceMacro))
959 Kind = tok::kw_namespace;
962 case tok::kw_namespace:
977void UnwrappedLineParser::parseChildBlock() {
978 assert(FormatTok->
is(tok::l_brace));
980 const FormatToken *OpeningBrace = FormatTok;
986 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
988 Line->Level += SkipIndent ? 0 : 1;
989 parseLevel(OpeningBrace);
990 flushComments(isOnNewLine(*FormatTok));
991 Line->Level -= SkipIndent ? 0 : 1;
996void UnwrappedLineParser::parsePPDirective() {
997 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
998 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
1008 case tok::pp_define:
1015 case tok::pp_ifndef:
1019 case tok::pp_elifdef:
1020 case tok::pp_elifndef:
1027 case tok::pp_pragma:
1036void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1037 size_t Line = CurrentLines->size();
1038 if (CurrentLines == &PreprocessorDirectives)
1039 Line += Lines.size();
1042 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1043 PPStack.push_back({PP_Unreachable, Line});
1045 PPStack.push_back({PP_Conditional, Line});
1049void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1051 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1052 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1053 PPLevelBranchIndex.push_back(0);
1054 PPLevelBranchCount.push_back(0);
1056 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1057 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1058 conditionalCompilationCondition(Unreachable || Skip);
1061void UnwrappedLineParser::conditionalCompilationAlternative() {
1062 if (!PPStack.empty())
1064 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1065 if (!PPChainBranchIndex.empty())
1066 ++PPChainBranchIndex.top();
1067 conditionalCompilationCondition(
1068 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1069 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1072void UnwrappedLineParser::conditionalCompilationEnd() {
1073 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1074 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1075 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1076 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1079 if (PPBranchLevel > -1)
1081 if (!PPChainBranchIndex.empty())
1082 PPChainBranchIndex.pop();
1083 if (!PPStack.empty())
1087void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1088 bool IfNDef = FormatTok->
is(tok::pp_ifndef);
1090 bool Unreachable =
false;
1091 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1093 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1095 conditionalCompilationStart(Unreachable);
1096 FormatToken *IfCondition = FormatTok;
1099 bool MaybeIncludeGuard = IfNDef;
1100 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1101 for (
auto &Line : Lines) {
1102 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1103 MaybeIncludeGuard =
false;
1104 IncludeGuard = IG_Rejected;
1112 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1113 IncludeGuard = IG_IfNdefed;
1114 IncludeGuardToken = IfCondition;
1118void UnwrappedLineParser::parsePPElse() {
1120 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1121 IncludeGuard = IG_Rejected;
1123 assert(PPBranchLevel >= -1);
1124 if (PPBranchLevel == -1)
1125 conditionalCompilationStart(
true);
1126 conditionalCompilationAlternative();
1132void UnwrappedLineParser::parsePPEndIf() {
1133 conditionalCompilationEnd();
1137 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1139 IncludeGuard = IG_Found;
1143void UnwrappedLineParser::parsePPDefine() {
1147 IncludeGuard = IG_Rejected;
1148 IncludeGuardToken =
nullptr;
1153 if (IncludeGuard == IG_IfNdefed &&
1155 IncludeGuard = IG_Defined;
1156 IncludeGuardToken =
nullptr;
1157 for (
auto &Line : Lines) {
1158 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1159 IncludeGuard = IG_Rejected;
1173 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1178 Line->Level += PPBranchLevel + 1;
1182 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1183 assert((
int)Line->PPLevel >= 0);
1184 Line->InMacroBody =
true;
1189 FormatTok = Tokens->getNextToken();
1203void UnwrappedLineParser::parsePPPragma() {
1204 Line->InPragmaDirective =
true;
1208void UnwrappedLineParser::parsePPUnknown() {
1213 Line->Level += PPBranchLevel + 1;
1223 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1226 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1227 tok::less, tok::greater, tok::slash, tok::percent,
1228 tok::lessless, tok::greatergreater, tok::equal,
1229 tok::plusequal, tok::minusequal, tok::starequal,
1230 tok::slashequal, tok::percentequal, tok::ampequal,
1231 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1244 return FormatTok->
is(tok::identifier) &&
1259 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1270 tok::kw_if, tok::kw_else,
1272 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1274 tok::kw_switch, tok::kw_case,
1276 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1278 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1286 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1287 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1304 if (FuncName->
isNot(tok::identifier))
1312 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1316 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1320 if (!Tok || Tok->
isNot(tok::r_paren))
1324 if (!Tok || Tok->
isNot(tok::identifier))
1330bool UnwrappedLineParser::parseModuleImport() {
1331 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1333 if (
auto Token = Tokens->peekNextToken(
true);
1335 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1341 if (FormatTok->
is(tok::colon)) {
1345 else if (FormatTok->
is(tok::less)) {
1347 while (!FormatTok->
isOneOf(tok::semi, tok::greater, tok::eof)) {
1350 if (FormatTok->
isNot(tok::comment) &&
1351 !FormatTok->
TokenText.starts_with(
"//")) {
1357 if (FormatTok->
is(tok::semi)) {
1375void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1378 FormatToken *Next = FormatTok;
1381 CommentsBeforeNextToken.empty()
1382 ? Next->NewlinesBefore == 0
1383 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1388 bool PreviousStartsTemplateExpr =
1390 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1393 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1394 return LineNode.Tok->is(tok::at);
1399 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1400 return addUnwrappedLine();
1402 bool NextEndsTemplateExpr =
1403 Next->is(TT_TemplateString) && Next->TokenText.starts_with(
"}");
1404 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1405 (PreviousMustBeValue ||
1406 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1407 tok::minusminus))) {
1408 return addUnwrappedLine();
1410 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1412 return addUnwrappedLine();
1416void UnwrappedLineParser::parseStructuralElement(
1417 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1418 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1420 FormatTok->
is(tok::pp_include)) {
1422 if (FormatTok->
is(tok::string_literal))
1429 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1433 parseForOrWhileLoop(
false);
1437 parseForOrWhileLoop();
1442 parseIfThenElse(IfKind,
false,
true);
1451 }
else if (FormatTok->
is(tok::l_paren) &&
1452 Tokens->peekNextToken()->is(tok::star)) {
1466 parseAccessSpecifier();
1473 if (FormatTok->
is(tok::l_brace)) {
1476 while (FormatTok && !eof()) {
1477 if (FormatTok->
is(tok::r_brace)) {
1488 case tok::kw_namespace:
1496 FormatToken *Tok = parseIfThenElse(IfKind);
1507 parseForOrWhileLoop();
1518 case tok::kw_switch:
1525 case tok::kw_default: {
1535 if (FormatTok->
is(tok::colon)) {
1540 if (FormatTok->
is(tok::arrow)) {
1542 Default->setFinalizedType(TT_SwitchExpressionLabel);
1575 case tok::kw_extern:
1581 parseVerilogHierarchyHeader();
1584 }
else if (FormatTok->
is(tok::string_literal)) {
1586 if (FormatTok->
is(tok::l_brace)) {
1591 unsigned AddLevels =
1598 parseBlock(
true, AddLevels);
1604 case tok::kw_export:
1606 parseJavaScriptEs6ImportExport();
1611 if (FormatTok->
is(tok::kw_namespace)) {
1615 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1619 case tok::kw_inline:
1621 if (FormatTok->
is(tok::kw_namespace)) {
1626 case tok::identifier:
1627 if (FormatTok->
is(TT_ForEachMacro)) {
1628 parseForOrWhileLoop();
1631 if (FormatTok->
is(TT_MacroBlockBegin)) {
1632 parseBlock(
false, 1u,
1638 parseJavaScriptEs6ImportExport();
1643 if (FormatTok->
is(tok::kw_public))
1645 if (FormatTok->
isNot(tok::string_literal))
1648 if (FormatTok->
is(tok::semi))
1653 if (IsCpp && parseModuleImport())
1659 if (FormatTok->
is(tok::colon)) {
1665 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1666 parseStatementMacro();
1669 if (IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1678 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1680 if (!Line->InMacroBody || CurrentLines->size() > 1)
1681 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1694 for (
const bool InRequiresExpression =
1695 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
1698 if (
auto *Next = Tokens->peekNextToken(
true);
1699 Next && Next->isBinaryOperator()) {
1707 if (FormatTok->
is(tok::l_brace)) {
1717 case tok::objc_public:
1718 case tok::objc_protected:
1719 case tok::objc_package:
1720 case tok::objc_private:
1721 return parseAccessSpecifier();
1722 case tok::objc_interface:
1723 case tok::objc_implementation:
1724 return parseObjCInterfaceOrImplementation();
1725 case tok::objc_protocol:
1726 if (parseObjCProtocol())
1731 case tok::objc_optional:
1732 case tok::objc_required:
1736 case tok::objc_autoreleasepool:
1738 if (FormatTok->
is(tok::l_brace)) {
1747 case tok::objc_synchronized:
1749 if (FormatTok->
is(tok::l_paren)) {
1753 if (FormatTok->
is(tok::l_brace)) {
1771 case tok::kw_requires: {
1773 bool ParsedClause = parseRequires();
1799 case tok::kw_typedef:
1821 case tok::kw_struct:
1823 if (parseStructLike())
1826 case tok::kw_decltype:
1828 if (FormatTok->
is(tok::l_paren)) {
1833 Line->SeenDecltypeAuto =
true;
1841 FormatTok->
is(tok::kw_class)) {
1858 case tok::l_paren: {
1862 if (OpeningBrace || !IsCpp || !
Previous || eof())
1865 Tokens->peekNextToken(
true),
1872 case tok::kw_operator:
1883 while (FormatTok->
is(tok::star))
1887 if (FormatTok->
is(tok::l_paren))
1890 if (FormatTok->
is(tok::l_brace))
1894 if (InRequiresExpression)
1896 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1897 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1916 IsDecltypeAutoFunction =
false;
1934 case tok::identifier: {
1936 Line->MustBeDeclaration) {
1938 parseCSharpGenericTypeConstraint();
1941 if (FormatTok->
is(TT_MacroBlockEnd)) {
1950 size_t TokenCount = Line->Tokens.size();
1954 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1955 tryToParseJSFunction();
1965 unsigned StoredPosition = Tokens->getPosition();
1966 FormatToken *Next = Tokens->getNextToken();
1967 FormatTok = Tokens->setPosition(StoredPosition);
1980 parseVerilogTable();
1992 if (parseStructLike())
1997 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1998 parseStatementMacro();
2005 FormatToken *PreviousToken = FormatTok;
2013 auto OneTokenSoFar = [&]() {
2014 auto I = Line->Tokens.begin(),
E = Line->Tokens.end();
2015 while (I !=
E && I->Tok->is(tok::comment))
2018 while (I !=
E && I->Tok->is(tok::hash))
2020 return I !=
E && (++I ==
E);
2022 if (OneTokenSoFar()) {
2025 bool FunctionLike = FormatTok->
is(tok::l_paren);
2029 bool FollowedByNewline =
2030 CommentsBeforeNextToken.empty()
2032 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2034 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
2036 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2037 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2046 FormatTok->
is(TT_FatArrow)) {
2047 tryToParseChildBlock();
2052 if (FormatTok->
is(tok::l_brace)) {
2061 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2063 parseBlock(
false, 1u,
2071 FormatTok->
is(tok::less)) {
2073 parseBracedList(
true);
2082 case tok::kw_switch:
2106 case tok::kw_default:
2109 if (FormatTok->
is(tok::colon)) {
2119 parseVerilogCaseLabel();
2126 parseVerilogCaseLabel();
2137bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2138 assert(FormatTok->
is(tok::l_brace));
2150 unsigned int StoredPosition = Tokens->getPosition();
2151 FormatToken *Tok = Tokens->getNextToken();
2156 bool HasSpecialAccessor =
false;
2157 bool IsTrivialPropertyAccessor =
true;
2159 if (Tok->isAccessSpecifierKeyword() ||
2163 HasSpecialAccessor =
true;
2164 Tok = Tokens->getNextToken();
2167 if (Tok->isNot(tok::r_brace))
2168 IsTrivialPropertyAccessor =
false;
2172 if (!HasSpecialAccessor) {
2173 Tokens->setPosition(StoredPosition);
2179 Tokens->setPosition(StoredPosition);
2187 if (FormatTok->
is(tok::equal)) {
2188 while (!eof() && FormatTok->
isNot(tok::semi))
2201 if (FormatTok->
is(TT_FatArrow)) {
2205 }
while (!eof() && FormatTok->
isNot(tok::semi));
2216 !IsTrivialPropertyAccessor) {
2228bool UnwrappedLineParser::tryToParseLambda() {
2229 assert(FormatTok->
is(tok::l_square));
2234 FormatToken &LSquare = *FormatTok;
2235 if (!tryToParseLambdaIntroducer())
2238 bool SeenArrow =
false;
2239 bool InTemplateParameterList =
false;
2241 while (FormatTok->
isNot(tok::l_brace)) {
2250 parseParens(TT_PointerOrReference);
2258 InTemplateParameterList =
true;
2263 case tok::kw_struct:
2265 case tok::kw_template:
2266 case tok::kw_typename:
2270 case tok::kw_constexpr:
2271 case tok::kw_consteval:
2274 case tok::identifier:
2275 case tok::numeric_constant:
2276 case tok::coloncolon:
2277 case tok::kw_mutable:
2278 case tok::kw_noexcept:
2279 case tok::kw_static:
2304 case tok::equalequal:
2305 case tok::exclaimequal:
2306 case tok::greaterequal:
2307 case tok::lessequal:
2313 if (SeenArrow || InTemplateParameterList) {
2326 case tok::kw_requires: {
2327 auto *RequiresToken = FormatTok;
2329 parseRequiresClause(RequiresToken);
2333 if (!InTemplateParameterList)
2343 LSquare.setFinalizedType(TT_LambdaLSquare);
2345 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2347 assert(!NestedLambdas.empty());
2348 NestedLambdas.pop_back();
2353bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2355 const FormatToken *LeftSquare = FormatTok;
2358 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2359 tok::kw_co_yield, tok::kw_co_return)) ||
2361 LeftSquare->isCppStructuredBinding(IsCpp)) {
2366 if (FormatTok->
is(tok::r_square)) {
2367 const FormatToken *Next = Tokens->peekNextToken(
true);
2368 if (Next->is(tok::greater))
2375void UnwrappedLineParser::tryToParseJSFunction() {
2383 if (FormatTok->
is(tok::star)) {
2389 if (FormatTok->
is(tok::identifier))
2392 if (FormatTok->
isNot(tok::l_paren))
2398 if (FormatTok->
is(tok::colon)) {
2404 if (FormatTok->
is(tok::l_brace))
2405 tryToParseBracedList();
2407 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2411 if (FormatTok->
is(tok::semi))
2417bool UnwrappedLineParser::tryToParseBracedList() {
2419 calculateBraceTypes();
2428bool UnwrappedLineParser::tryToParseChildBlock() {
2430 assert(FormatTok->
is(TT_FatArrow));
2435 if (FormatTok->
isNot(tok::l_brace))
2441bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2442 assert(!IsAngleBracket || !IsEnum);
2443 bool HasError =
false;
2448 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2449 tryToParseChildBlock()) {
2454 tryToParseJSFunction();
2457 if (FormatTok->
is(tok::l_brace)) {
2459 if (tryToParseBracedList())
2464 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2485 if (FormatTok->
is(tok::l_brace))
2500 parseBracedList(
true);
2534bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2535 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2536 auto *LeftParen = FormatTok;
2537 bool SeenComma =
false;
2538 bool SeenEqual =
false;
2539 bool MightBeFoldExpr =
false;
2540 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2545 if (parseParens(AmpAmpTokenType))
2550 case tok::r_paren: {
2551 const auto *Prev = LeftParen->Previous;
2552 if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
2554 const auto *Next = Tokens->peekNextToken();
2555 const bool DoubleParens =
2556 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2557 const bool CommaSeparated =
2558 !DoubleParens && Prev && Prev->isOneOf(tok::l_paren, tok::comma) &&
2559 Next && Next->isOneOf(tok::comma, tok::r_paren);
2560 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2561 const bool Excluded =
2563 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2566 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2567 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2568 const bool ReturnParens =
2570 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2571 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2572 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2573 Next->is(tok::semi);
2574 if ((DoubleParens && !Excluded) || (CommaSeparated && !SeenComma) ||
2576 LeftParen->Optional =
true;
2580 if (Prev && Prev->is(TT_TypenameMacro)) {
2581 LeftParen->setFinalizedType(TT_TypeDeclarationParen);
2594 if (!tryToParseBracedList())
2599 if (FormatTok->
is(tok::l_brace)) {
2609 MightBeFoldExpr =
true;
2614 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2615 tryToParseChildBlock();
2625 case tok::identifier:
2627 tryToParseJSFunction();
2631 case tok::kw_switch:
2634 case tok::kw_requires: {
2635 auto RequiresToken = FormatTok;
2637 parseRequiresExpression(RequiresToken);
2641 if (AmpAmpTokenType != TT_Unknown)
2652void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2653 if (!LambdaIntroducer) {
2654 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2655 if (tryToParseLambda())
2672 case tok::l_brace: {
2673 if (!tryToParseBracedList())
2679 if (FormatTok->
is(tok::l_brace)) {
2691void UnwrappedLineParser::keepAncestorBraces() {
2695 const int MaxNestingLevels = 2;
2696 const int Size = NestedTooDeep.size();
2697 if (Size >= MaxNestingLevels)
2698 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2699 NestedTooDeep.push_back(
false);
2703 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2710void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2711 FormatToken *Tok =
nullptr;
2713 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2714 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2717 : Line->Tokens.back().Tok;
2719 if (Tok->BraceCount < 0) {
2720 assert(Tok->BraceCount == -1);
2723 Tok->BraceCount = -1;
2729 ++Line->UnbracedBodyLevel;
2730 parseStructuralElement();
2731 --Line->UnbracedBodyLevel;
2734 assert(!Line->InPPDirective);
2736 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2738 Tok = L.Tokens.back().Tok;
2746 if (CheckEOF && eof())
2756 assert(LeftBrace->
is(tok::l_brace));
2764 assert(RightBrace->
is(tok::r_brace));
2772void UnwrappedLineParser::handleAttributes() {
2776 else if (FormatTok->
is(tok::l_square))
2777 handleCppAttributes();
2780bool UnwrappedLineParser::handleCppAttributes() {
2782 assert(FormatTok->
is(tok::l_square));
2783 if (!tryToParseSimpleAttribute())
2790bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2794 : Tok.is(tok::l_brace);
2797FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2799 bool IsVerilogAssert) {
2800 assert((FormatTok->
is(tok::kw_if) ||
2807 if (IsVerilogAssert) {
2811 if (FormatTok->
is(tok::numeric_constant))
2828 if (FormatTok->
is(tok::exclaim))
2831 bool KeepIfBraces =
true;
2832 if (FormatTok->
is(tok::kw_consteval)) {
2836 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2838 if (FormatTok->
is(tok::l_paren)) {
2845 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2851 bool NeedsUnwrappedLine =
false;
2852 keepAncestorBraces();
2854 FormatToken *IfLeftBrace =
nullptr;
2855 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2857 if (isBlockBegin(*FormatTok)) {
2859 IfLeftBrace = FormatTok;
2861 parseBlock(
false, 1u,
2862 true, KeepIfBraces, &IfBlockKind);
2863 setPreviousRBraceType(TT_ControlStatementRBrace);
2867 NeedsUnwrappedLine =
true;
2868 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2871 parseUnbracedBody();
2875 assert(!NestedTooDeep.empty());
2876 KeepIfBraces = KeepIfBraces ||
2877 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2878 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2879 IfBlockKind == IfStmtKind::IfElseIf;
2882 bool KeepElseBraces = KeepIfBraces;
2883 FormatToken *ElseLeftBrace =
nullptr;
2884 IfStmtKind
Kind = IfStmtKind::IfOnly;
2886 if (FormatTok->
is(tok::kw_else)) {
2888 NestedTooDeep.back() =
false;
2889 Kind = IfStmtKind::IfElse;
2893 if (isBlockBegin(*FormatTok)) {
2894 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2896 ElseLeftBrace = FormatTok;
2898 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2899 FormatToken *IfLBrace =
2900 parseBlock(
false, 1u,
2901 true, KeepElseBraces, &ElseBlockKind);
2902 setPreviousRBraceType(TT_ElseRBrace);
2903 if (FormatTok->
is(tok::kw_else)) {
2904 KeepElseBraces = KeepElseBraces ||
2905 ElseBlockKind == IfStmtKind::IfOnly ||
2906 ElseBlockKind == IfStmtKind::IfElseIf;
2907 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2908 KeepElseBraces =
true;
2909 assert(ElseLeftBrace->MatchingParen);
2913 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2914 const FormatToken *
Previous = Tokens->getPreviousToken();
2916 const bool IsPrecededByComment =
Previous->is(tok::comment);
2917 if (IsPrecededByComment) {
2921 bool TooDeep =
true;
2923 Kind = IfStmtKind::IfElseIf;
2924 TooDeep = NestedTooDeep.pop_back_val();
2926 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2928 NestedTooDeep.push_back(TooDeep);
2929 if (IsPrecededByComment)
2932 parseUnbracedBody(
true);
2935 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2936 if (NeedsUnwrappedLine)
2943 assert(!NestedTooDeep.empty());
2944 KeepElseBraces = KeepElseBraces ||
2945 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2946 NestedTooDeep.back();
2948 NestedTooDeep.pop_back();
2950 if (!KeepIfBraces && !KeepElseBraces) {
2953 }
else if (IfLeftBrace) {
2954 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2956 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2957 assert(!IfLeftBrace->Optional);
2958 assert(!IfRightBrace->Optional);
2959 IfLeftBrace->MatchingParen =
nullptr;
2960 IfRightBrace->MatchingParen =
nullptr;
2970void UnwrappedLineParser::parseTryCatch() {
2971 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2973 bool NeedsUnwrappedLine =
false;
2974 bool HasCtorInitializer =
false;
2975 if (FormatTok->
is(tok::colon)) {
2976 auto *Colon = FormatTok;
2979 if (FormatTok->
is(tok::identifier)) {
2980 HasCtorInitializer =
true;
2981 Colon->setFinalizedType(TT_CtorInitializerColon);
2986 while (FormatTok->
is(tok::comma))
2989 while (FormatTok->
is(tok::identifier)) {
2991 if (FormatTok->
is(tok::l_paren)) {
2993 }
else if (FormatTok->
is(tok::l_brace)) {
3000 while (FormatTok->
is(tok::comma))
3008 keepAncestorBraces();
3010 if (FormatTok->
is(tok::l_brace)) {
3011 if (HasCtorInitializer)
3018 NeedsUnwrappedLine =
true;
3019 }
else if (FormatTok->
isNot(tok::kw_catch)) {
3025 parseStructuralElement();
3029 if (FormatTok->
is(tok::at))
3032 tok::kw___finally) ||
3040 while (FormatTok->
isNot(tok::l_brace)) {
3041 if (FormatTok->
is(tok::l_paren)) {
3045 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
3047 NestedTooDeep.pop_back();
3052 NeedsUnwrappedLine =
false;
3053 Line->MustBeDeclaration =
false;
3059 NeedsUnwrappedLine =
true;
3063 NestedTooDeep.pop_back();
3065 if (NeedsUnwrappedLine)
3069void UnwrappedLineParser::parseNamespace() {
3070 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3071 "'namespace' expected");
3073 const FormatToken &InitialToken = *FormatTok;
3075 if (InitialToken.is(TT_NamespaceMacro)) {
3078 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3079 tok::l_square, tok::period, tok::l_paren) ||
3080 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3081 if (FormatTok->
is(tok::l_square))
3083 else if (FormatTok->
is(tok::l_paren))
3089 if (FormatTok->
is(tok::l_brace)) {
3095 unsigned AddLevels =
3098 DeclarationScopeStack.size() > 1)
3101 bool ManageWhitesmithsBraces =
3107 if (ManageWhitesmithsBraces)
3112 parseBlock(
true, AddLevels,
true,
3114 ManageWhitesmithsBraces);
3116 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3118 if (ManageWhitesmithsBraces)
3124void UnwrappedLineParser::parseNew() {
3125 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3131 if (FormatTok->
is(tok::l_paren))
3135 if (FormatTok->
is(tok::l_brace))
3138 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3151 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3155 if (FormatTok->
is(tok::l_paren)) {
3159 if (FormatTok->
is(tok::l_brace))
3167void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3168 keepAncestorBraces();
3170 if (isBlockBegin(*FormatTok)) {
3172 FormatToken *LeftBrace = FormatTok;
3174 parseBlock(
false, 1u,
3176 setPreviousRBraceType(TT_ControlStatementRBrace);
3178 assert(!NestedTooDeep.empty());
3179 if (!NestedTooDeep.back())
3185 parseUnbracedBody();
3189 NestedTooDeep.pop_back();
3192void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3193 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3200 "'for', 'while' or foreach macro expected");
3202 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3208 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3210 if (HasParens && FormatTok->
is(tok::l_paren)) {
3221 parseVerilogSensitivityList();
3223 Tokens->getPreviousToken()->is(tok::r_paren)) {
3230 parseLoopBody(KeepBraces,
true);
3233void UnwrappedLineParser::parseDoWhile() {
3234 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3240 if (FormatTok->
isNot(tok::kw_while)) {
3253 parseStructuralElement();
3256void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3258 unsigned OldLineLevel = Line->Level;
3262 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3266 FormatTok->
is(tok::l_brace)) {
3272 if (FormatTok->
is(tok::kw_break)) {
3281 parseStructuralElement();
3285 if (FormatTok->
is(tok::semi))
3289 Line->Level = OldLineLevel;
3290 if (FormatTok->
isNot(tok::l_brace)) {
3291 parseStructuralElement();
3296void UnwrappedLineParser::parseCaseLabel() {
3297 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3298 auto *Case = FormatTok;
3303 if (FormatTok->
is(tok::colon)) {
3309 Case->setFinalizedType(TT_SwitchExpressionLabel);
3316void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3317 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3319 if (FormatTok->
is(tok::l_paren))
3322 keepAncestorBraces();
3324 if (FormatTok->
is(tok::l_brace)) {
3327 : TT_ControlStatementLBrace);
3332 setPreviousRBraceType(TT_ControlStatementRBrace);
3338 parseStructuralElement();
3343 NestedTooDeep.pop_back();
3353 case tok::caretequal:
3357 case tok::equalequal:
3359 case tok::exclaimequal:
3361 case tok::greaterequal:
3362 case tok::greatergreater:
3363 case tok::greatergreaterequal:
3367 case tok::lessequal:
3369 case tok::lesslessequal:
3371 case tok::minusequal:
3372 case tok::minusminus:
3374 case tok::percentequal:
3377 case tok::pipeequal:
3380 case tok::plusequal:
3388 case tok::slashequal:
3390 case tok::starequal:
3397void UnwrappedLineParser::parseAccessSpecifier() {
3398 FormatToken *AccessSpecifierCandidate = FormatTok;
3404 if (FormatTok->
is(tok::colon)) {
3407 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3411 }
else if (AccessSpecifierCandidate) {
3413 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3420bool UnwrappedLineParser::parseRequires() {
3421 assert(FormatTok->
is(tok::kw_requires) &&
"'requires' expected");
3422 auto RequiresToken = FormatTok;
3431 parseRequiresExpression(RequiresToken);
3438 parseRequiresClause(RequiresToken);
3449 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3451 if (!PreviousNonComment ||
3452 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3455 parseRequiresClause(RequiresToken);
3459 switch (PreviousNonComment->Tok.getKind()) {
3462 case tok::kw_noexcept:
3465 parseRequiresClause(RequiresToken);
3475 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3476 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3477 parseRequiresClause(RequiresToken);
3483 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3485 parseRequiresClause(RequiresToken);
3489 parseRequiresExpression(RequiresToken);
3499 unsigned StoredPosition = Tokens->getPosition();
3500 FormatToken *NextToken = Tokens->getNextToken();
3502 auto PeekNext = [&Lookahead, &NextToken,
this] {
3504 NextToken = Tokens->getNextToken();
3507 bool FoundType =
false;
3508 bool LastWasColonColon =
false;
3511 for (; Lookahead < 50; PeekNext()) {
3512 switch (NextToken->Tok.getKind()) {
3513 case tok::kw_volatile:
3516 if (OpenAngles == 0) {
3517 FormatTok = Tokens->setPosition(StoredPosition);
3518 parseRequiresExpression(RequiresToken);
3526 case tok::coloncolon:
3527 LastWasColonColon =
true;
3529 case tok::kw_decltype:
3530 case tok::identifier:
3531 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3532 FormatTok = Tokens->setPosition(StoredPosition);
3533 parseRequiresExpression(RequiresToken);
3537 LastWasColonColon =
false;
3546 if (NextToken->isTypeName(LangOpts)) {
3547 FormatTok = Tokens->setPosition(StoredPosition);
3548 parseRequiresExpression(RequiresToken);
3555 FormatTok = Tokens->setPosition(StoredPosition);
3556 parseRequiresClause(RequiresToken);
3567void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3569 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3574 bool InRequiresExpression =
3575 !RequiresToken->Previous ||
3576 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3578 RequiresToken->setFinalizedType(InRequiresExpression
3579 ? TT_RequiresClauseInARequiresExpression
3580 : TT_RequiresClause);
3584 parseConstraintExpression();
3586 if (!InRequiresExpression)
3597void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3599 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3601 RequiresToken->setFinalizedType(TT_RequiresExpression);
3603 if (FormatTok->
is(tok::l_paren)) {
3608 if (FormatTok->
is(tok::l_brace)) {
3618void UnwrappedLineParser::parseConstraintExpression() {
3625 bool LambdaNextTimeAllowed =
true;
3635 bool TopLevelParensAllowed =
true;
3638 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3641 case tok::kw_requires: {
3642 auto RequiresToken = FormatTok;
3644 parseRequiresExpression(RequiresToken);
3649 if (!TopLevelParensAllowed)
3651 parseParens(TT_BinaryOperator);
3652 TopLevelParensAllowed =
false;
3656 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3663 case tok::kw_struct:
3675 LambdaNextTimeAllowed =
true;
3676 TopLevelParensAllowed =
true;
3681 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3685 case tok::kw_sizeof:
3687 case tok::greaterequal:
3688 case tok::greatergreater:
3690 case tok::lessequal:
3692 case tok::equalequal:
3694 case tok::exclaimequal:
3699 LambdaNextTimeAllowed =
true;
3700 TopLevelParensAllowed =
true;
3705 case tok::numeric_constant:
3706 case tok::coloncolon:
3709 TopLevelParensAllowed =
false;
3714 case tok::kw_static_cast:
3715 case tok::kw_const_cast:
3716 case tok::kw_reinterpret_cast:
3717 case tok::kw_dynamic_cast:
3719 if (FormatTok->
isNot(tok::less))
3723 parseBracedList(
true);
3739 case tok::coloncolon:
3743 case tok::kw_requires:
3752 if (FormatTok->
is(tok::less)) {
3754 parseBracedList(
true);
3756 TopLevelParensAllowed =
false;
3762bool UnwrappedLineParser::parseEnum() {
3763 const FormatToken &InitialToken = *FormatTok;
3766 if (FormatTok->
is(tok::kw_enum))
3781 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3783 while (FormatTok->
is(tok::l_square))
3784 if (!handleCppAttributes())
3789 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3790 tok::greater, tok::comma, tok::question,
3796 while (FormatTok->
is(tok::l_square))
3802 if (FormatTok->
is(tok::l_paren))
3804 if (FormatTok->
is(tok::identifier)) {
3808 if (IsCpp && FormatTok->
is(tok::identifier))
3814 if (FormatTok->
isNot(tok::l_brace))
3821 parseJavaEnumBody();
3839 bool HasError = !parseBracedList(
false,
true);
3843 if (FormatTok->
is(tok::semi))
3847 setPreviousRBraceType(TT_EnumRBrace);
3855bool UnwrappedLineParser::parseStructLike() {
3862 if (FormatTok->
is(tok::semi))
3873class ScopedTokenPosition {
3874 unsigned StoredPosition;
3875 FormatTokenSource *Tokens;
3878 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3879 assert(Tokens &&
"Tokens expected to not be null");
3880 StoredPosition = Tokens->getPosition();
3883 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3889bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3890 ScopedTokenPosition AutoPosition(Tokens);
3891 FormatToken *Tok = Tokens->getNextToken();
3893 if (Tok->isNot(tok::l_square))
3897 while (Tok->isNot(tok::eof)) {
3898 if (Tok->is(tok::r_square))
3900 Tok = Tokens->getNextToken();
3902 if (Tok->is(tok::eof))
3904 Tok = Tokens->getNextToken();
3905 if (Tok->isNot(tok::r_square))
3907 Tok = Tokens->getNextToken();
3908 if (Tok->is(tok::semi))
3913void UnwrappedLineParser::parseJavaEnumBody() {
3914 assert(FormatTok->
is(tok::l_brace));
3915 const FormatToken *OpeningBrace = FormatTok;
3920 unsigned StoredPosition = Tokens->getPosition();
3921 bool IsSimple =
true;
3922 FormatToken *Tok = Tokens->getNextToken();
3923 while (Tok->isNot(tok::eof)) {
3924 if (Tok->is(tok::r_brace))
3926 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3932 Tok = Tokens->getNextToken();
3934 FormatTok = Tokens->setPosition(StoredPosition);
3951 if (FormatTok->
is(tok::l_brace)) {
3953 parseBlock(
true, 1u,
3955 }
else if (FormatTok->
is(tok::l_paren)) {
3957 }
else if (FormatTok->
is(tok::comma)) {
3960 }
else if (FormatTok->
is(tok::semi)) {
3964 }
else if (FormatTok->
is(tok::r_brace)) {
3973 parseLevel(OpeningBrace);
3979void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
3980 const FormatToken &InitialToken = *FormatTok;
3983 const FormatToken *ClassName =
nullptr;
3984 bool IsDerived =
false;
3985 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
3986 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
3991 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3992 tok::kw_alignas, tok::l_square) ||
3995 FormatTok->
isOneOf(tok::period, tok::comma))) {
4002 if (FormatTok->
is(tok::l_brace)) {
4003 tryToParseBracedList();
4007 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
4014 if (!IsNonMacroIdentifier(
Previous) ||
4016 Previous->Previous == &InitialToken) {
4020 case tok::coloncolon:
4023 if (!ClassName &&
Previous->is(tok::identifier) &&
4024 Previous->isNot(TT_AttributeMacro)) {
4030 auto IsListInitialization = [&] {
4031 if (!ClassName || IsDerived)
4033 assert(FormatTok->
is(tok::l_brace));
4036 return Prev != ClassName && Prev->is(tok::identifier) &&
4037 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
4040 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
4041 int AngleNestingLevel = 0;
4043 if (FormatTok->
is(tok::less))
4044 ++AngleNestingLevel;
4045 else if (FormatTok->
is(tok::greater))
4046 --AngleNestingLevel;
4048 if (AngleNestingLevel == 0) {
4049 if (FormatTok->
is(tok::colon)) {
4051 }
else if (FormatTok->
is(tok::identifier) &&
4053 ClassName = FormatTok;
4054 }
else if (FormatTok->
is(tok::l_paren) &&
4055 IsNonMacroIdentifier(FormatTok->
Previous)) {
4059 if (FormatTok->
is(tok::l_brace)) {
4060 if (AngleNestingLevel == 0 && IsListInitialization())
4062 calculateBraceTypes(
true);
4063 if (!tryToParseBracedList())
4066 if (FormatTok->
is(tok::l_square)) {
4069 !
Previous->isTypeOrIdentifier(LangOpts))) {
4072 if (!tryToParseLambda())
4079 if (FormatTok->
is(tok::semi))
4084 parseCSharpGenericTypeConstraint();
4091 auto GetBraceTypes =
4092 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4093 switch (RecordTok.Tok.getKind()) {
4095 return {TT_ClassLBrace, TT_ClassRBrace};
4096 case tok::kw_struct:
4097 return {TT_StructLBrace, TT_StructRBrace};
4099 return {TT_UnionLBrace, TT_UnionRBrace};
4102 return {TT_RecordLBrace, TT_RecordRBrace};
4105 if (FormatTok->
is(tok::l_brace)) {
4106 if (IsListInitialization())
4108 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4117 parseBlock(
true, AddLevels,
false);
4119 setPreviousRBraceType(ClosingBraceType);
4126void UnwrappedLineParser::parseObjCMethod() {
4127 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4128 "'(' or identifier expected.");
4130 if (FormatTok->
is(tok::semi)) {
4134 }
else if (FormatTok->
is(tok::l_brace)) {
4146void UnwrappedLineParser::parseObjCProtocolList() {
4147 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4151 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4155 }
while (!eof() && FormatTok->
isNot(tok::greater));
4159void UnwrappedLineParser::parseObjCUntilAtEnd() {
4166 if (FormatTok->
is(tok::l_brace)) {
4170 }
else if (FormatTok->
is(tok::r_brace)) {
4174 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4178 parseStructuralElement();
4183void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4191 if (FormatTok->
is(tok::less))
4192 parseObjCLightweightGenerics();
4193 if (FormatTok->
is(tok::colon)) {
4197 if (FormatTok->
is(tok::less))
4198 parseObjCLightweightGenerics();
4199 }
else if (FormatTok->
is(tok::l_paren)) {
4204 if (FormatTok->
is(tok::less))
4205 parseObjCProtocolList();
4207 if (FormatTok->
is(tok::l_brace)) {
4217 parseObjCUntilAtEnd();
4220void UnwrappedLineParser::parseObjCLightweightGenerics() {
4221 assert(FormatTok->
is(tok::less));
4229 unsigned NumOpenAngles = 1;
4233 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4237 if (FormatTok->
is(tok::less)) {
4239 }
else if (FormatTok->
is(tok::greater)) {
4240 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4243 }
while (!eof() && NumOpenAngles != 0);
4249bool UnwrappedLineParser::parseObjCProtocol() {
4253 if (FormatTok->
is(tok::l_paren)) {
4265 if (FormatTok->
is(tok::less))
4266 parseObjCProtocolList();
4269 if (FormatTok->
is(tok::semi)) {
4276 parseObjCUntilAtEnd();
4280void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4281 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4282 assert(IsImport || FormatTok->
is(tok::kw_export));
4286 if (FormatTok->
is(tok::kw_default))
4303 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4306 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4311 if (FormatTok->
is(tok::semi))
4313 if (Line->Tokens.empty()) {
4318 if (FormatTok->
is(tok::l_brace)) {
4328void UnwrappedLineParser::parseStatementMacro() {
4330 if (FormatTok->
is(tok::l_paren))
4332 if (FormatTok->
is(tok::semi))
4337void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4340 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4341 tok::coloncolon, tok::hash) ||
4344 }
else if (FormatTok->
is(tok::l_square)) {
4352void UnwrappedLineParser::parseVerilogSensitivityList() {
4353 if (FormatTok->
isNot(tok::at))
4357 if (FormatTok->
is(tok::at))
4367 parseVerilogHierarchyIdentifier();
4372unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4373 unsigned AddLevels = 0;
4379 parseVerilogSensitivityList();
4380 if (FormatTok->
is(tok::semi))
4388 if (FormatTok->
is(tok::l_paren)) {
4401 if (FormatTok->
is(tok::l_square)) {
4416 Line->IsContinuation =
true;
4423 parseVerilogHierarchyIdentifier();
4424 if (FormatTok->
is(tok::semi))
4432 if (FormatTok->
is(tok::l_paren)) {
4437 if (FormatTok->
is(tok::l_paren)) {
4447 parseVerilogHierarchyIdentifier();
4448 if (FormatTok->
is(tok::l_paren))
4455 parseVerilogHierarchyIdentifier();
4456 }
while (FormatTok->
is(tok::comma));
4460 if (FormatTok->
is(tok::at)) {
4462 parseVerilogSensitivityList();
4465 if (FormatTok->
is(tok::semi))
4473void UnwrappedLineParser::parseVerilogTable() {
4478 auto InitialLevel = Line->Level++;
4480 FormatToken *Tok = FormatTok;
4482 if (Tok->is(tok::semi))
4484 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4485 Tok->setFinalizedType(TT_VerilogTableItem);
4487 Line->Level = InitialLevel;
4492void UnwrappedLineParser::parseVerilogCaseLabel() {
4498 auto OrigLevel = Line->Level;
4499 auto FirstLine = CurrentLines->size();
4500 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4504 parseStructuralElement();
4507 if (CurrentLines->size() > FirstLine)
4508 (*CurrentLines)[FirstLine].Level = OrigLevel;
4509 Line->Level = OrigLevel;
4512bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4513 for (
const auto &N : Line.Tokens) {
4514 if (N.Tok->MacroCtx)
4516 for (
const UnwrappedLine &Child : N.Children)
4517 if (containsExpansion(Child))
4523void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4524 if (Line->Tokens.empty())
4527 if (!parsingPPDirective()) {
4528 llvm::dbgs() <<
"Adding unwrapped line:\n";
4529 printDebugInfo(*Line);
4537 bool ClosesWhitesmithsBlock =
4544 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4546 Reconstruct.emplace(Line->Level, Unexpanded);
4547 Reconstruct->addLine(*Line);
4552 CurrentExpandedLines.push_back(std::move(*Line));
4554 if (Reconstruct->finished()) {
4555 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4556 assert(!Reconstructed.Tokens.empty() &&
4557 "Reconstructed must at least contain the macro identifier.");
4558 assert(!parsingPPDirective());
4560 llvm::dbgs() <<
"Adding unexpanded line:\n";
4561 printDebugInfo(Reconstructed);
4563 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4564 Lines.push_back(std::move(Reconstructed));
4565 CurrentExpandedLines.clear();
4566 Reconstruct.reset();
4571 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4572 CurrentLines->push_back(std::move(*Line));
4574 Line->Tokens.clear();
4576 Line->FirstStartColumn = 0;
4577 Line->IsContinuation =
false;
4578 Line->SeenDecltypeAuto =
false;
4580 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4582 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4583 CurrentLines->append(
4584 std::make_move_iterator(PreprocessorDirectives.begin()),
4585 std::make_move_iterator(PreprocessorDirectives.end()));
4586 PreprocessorDirectives.clear();
4592bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4594bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4595 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4596 FormatTok.NewlinesBefore > 0;
4604 const llvm::Regex &CommentPragmasRegex) {
4605 if (
Line.Tokens.empty())
4608 StringRef IndentContent = FormatTok.
TokenText;
4609 if (FormatTok.
TokenText.starts_with(
"//") ||
4610 FormatTok.
TokenText.starts_with(
"/*")) {
4611 IndentContent = FormatTok.
TokenText.substr(2);
4613 if (CommentPragmasRegex.match(IndentContent))
4688 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4690 MinColumnToken = PreviousToken;
4693 PreviousToken =
Node.Tok;
4696 if (
Node.Tok->NewlinesBefore > 0)
4697 MinColumnToken =
Node.Tok;
4699 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4700 MinColumnToken = PreviousToken;
4706void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4707 bool JustComments = Line->Tokens.empty();
4708 for (FormatToken *Tok : CommentsBeforeNextToken) {
4717 Tok->ContinuesLineCommentSection =
4719 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4723 if (NewlineBeforeNext && JustComments)
4725 CommentsBeforeNextToken.clear();
4728void UnwrappedLineParser::nextToken(
int LevelDifference) {
4731 flushComments(isOnNewLine(*FormatTok));
4732 pushToken(FormatTok);
4735 readToken(LevelDifference);
4737 readTokenWithJavaScriptASI();
4747 FormatTok->Tok.setKind(tok::r_brace);
4751void UnwrappedLineParser::distributeComments(
4752 const SmallVectorImpl<FormatToken *> &Comments,
4753 const FormatToken *NextTok) {
4772 if (Comments.empty())
4774 bool ShouldPushCommentsInCurrentLine =
true;
4775 bool HasTrailAlignedWithNextToken =
false;
4776 unsigned StartOfTrailAlignedWithNextToken = 0;
4779 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4780 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4781 HasTrailAlignedWithNextToken =
true;
4782 StartOfTrailAlignedWithNextToken = i;
4786 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4787 FormatToken *FormatTok = Comments[i];
4788 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4789 FormatTok->ContinuesLineCommentSection =
false;
4791 FormatTok->ContinuesLineCommentSection =
4794 if (!FormatTok->ContinuesLineCommentSection &&
4795 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4796 ShouldPushCommentsInCurrentLine =
false;
4798 if (ShouldPushCommentsInCurrentLine)
4799 pushToken(FormatTok);
4801 CommentsBeforeNextToken.push_back(FormatTok);
4805void UnwrappedLineParser::readToken(
int LevelDifference) {
4806 SmallVector<FormatToken *, 1> Comments;
4807 bool PreviousWasComment =
false;
4808 bool FirstNonCommentOnLine =
false;
4810 FormatTok = Tokens->getNextToken();
4812 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4813 TT_ConflictAlternative)) {
4814 if (FormatTok->is(TT_ConflictStart))
4815 conditionalCompilationStart(
false);
4816 else if (FormatTok->is(TT_ConflictAlternative))
4817 conditionalCompilationAlternative();
4818 else if (FormatTok->is(TT_ConflictEnd))
4819 conditionalCompilationEnd();
4820 FormatTok = Tokens->getNextToken();
4821 FormatTok->MustBreakBefore =
true;
4822 FormatTok->MustBreakBeforeFinalized =
true;
4825 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4826 const FormatToken &Tok,
4827 bool PreviousWasComment) {
4828 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4829 return Tok.HasUnescapedNewline || Tok.IsFirst;
4834 if (PreviousWasComment)
4835 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4836 return IsFirstOnLine(Tok);
4839 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4840 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4841 PreviousWasComment = FormatTok->is(tok::comment);
4843 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4846 FirstNonCommentOnLine) {
4847 distributeComments(Comments, FormatTok);
4851 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4853 assert((LevelDifference >= 0 ||
4854 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4855 "LevelDifference makes Line->Level negative");
4856 Line->Level += LevelDifference;
4861 PPBranchLevel > 0) {
4862 Line->Level += PPBranchLevel;
4864 assert(Line->Level >= Line->UnbracedBodyLevel);
4865 Line->Level -= Line->UnbracedBodyLevel;
4866 flushComments(isOnNewLine(*FormatTok));
4868 PreviousWasComment = FormatTok->is(tok::comment);
4869 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4870 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4873 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4874 !Line->InPPDirective) {
4878 if (FormatTok->is(tok::identifier) &&
4879 Macros.
defined(FormatTok->TokenText) &&
4881 !Line->InPPDirective) {
4882 FormatToken *
ID = FormatTok;
4883 unsigned Position = Tokens->getPosition();
4887 auto PreCall = std::move(Line);
4888 Line.reset(
new UnwrappedLine);
4889 bool OldInExpansion = InExpansion;
4892 auto Args = parseMacroCall();
4893 InExpansion = OldInExpansion;
4894 assert(Line->Tokens.front().Tok ==
ID);
4896 auto UnexpandedLine = std::move(Line);
4898 Line = std::move(PreCall);
4901 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4903 llvm::dbgs() <<
"(";
4904 for (
const auto &Arg : Args.value())
4905 for (
const auto &
T : Arg)
4906 llvm::dbgs() <<
T->TokenText <<
" ";
4907 llvm::dbgs() <<
")";
4909 llvm::dbgs() <<
"\n";
4912 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4918 LLVM_DEBUG(llvm::dbgs()
4919 <<
"Macro \"" <<
ID->TokenText
4920 <<
"\" not overloaded for arity " << Args->size()
4921 <<
"or not function-like, using object-like overload.");
4923 UnexpandedLine->Tokens.resize(1);
4924 Tokens->setPosition(Position);
4929 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4932 Unexpanded[
ID] = std::move(UnexpandedLine);
4933 SmallVector<FormatToken *, 8> Expansion =
4934 Macros.
expand(
ID, std::move(Args));
4935 if (!Expansion.empty())
4936 FormatTok = Tokens->insertTokens(Expansion);
4939 llvm::dbgs() <<
"Expanded: ";
4940 for (
const auto &
T : Expansion)
4941 llvm::dbgs() <<
T->TokenText <<
" ";
4942 llvm::dbgs() <<
"\n";
4946 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4947 <<
"\", because it was used ";
4949 llvm::dbgs() <<
"with " << Args->size();
4951 llvm::dbgs() <<
"without";
4952 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4954 Tokens->setPosition(Position);
4959 if (FormatTok->isNot(tok::comment)) {
4960 distributeComments(Comments, FormatTok);
4965 Comments.push_back(FormatTok);
4968 distributeComments(Comments,
nullptr);
4973template <
typename Iterator>
4974void pushTokens(Iterator
Begin, Iterator End,
4976 for (
auto I =
Begin; I != End; ++I) {
4977 Into.push_back(I->Tok);
4978 for (
const auto &Child : I->Children)
4979 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
4984std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
4985UnwrappedLineParser::parseMacroCall() {
4986 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
4987 assert(Line->Tokens.empty());
4989 if (FormatTok->isNot(tok::l_paren))
4991 unsigned Position = Tokens->getPosition();
4992 FormatToken *Tok = FormatTok;
4995 auto ArgStart = std::prev(Line->Tokens.end());
4999 switch (FormatTok->Tok.getKind()) {
5004 case tok::r_paren: {
5010 Args->push_back({});
5011 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5020 Args->push_back({});
5021 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5023 ArgStart = std::prev(Line->Tokens.end());
5031 Line->Tokens.resize(1);
5032 Tokens->setPosition(Position);
5037void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5038 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5039 if (MustBreakBeforeNextToken) {
5040 Line->Tokens.back().Tok->MustBreakBefore =
true;
5041 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
5042 MustBreakBeforeNextToken =
false;
enum clang::sema::@1655::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.