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 SeenEqual =
false;
2538 bool MightBeFoldExpr =
false;
2539 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2544 if (parseParens(AmpAmpTokenType))
2549 case tok::r_paren: {
2550 const auto *Prev = LeftParen->Previous;
2551 if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
2553 const auto *Next = Tokens->peekNextToken();
2554 const bool DoubleParens =
2555 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2556 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2557 const bool Blacklisted =
2559 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2561 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2562 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2563 const bool ReturnParens =
2565 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2566 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2567 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2568 Next->is(tok::semi);
2569 if ((DoubleParens && !Blacklisted) || ReturnParens) {
2570 LeftParen->Optional =
true;
2574 if (Prev && Prev->is(TT_TypenameMacro)) {
2575 LeftParen->setFinalizedType(TT_TypeDeclarationParen);
2588 if (!tryToParseBracedList())
2593 if (FormatTok->
is(tok::l_brace)) {
2599 MightBeFoldExpr =
true;
2604 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2605 tryToParseChildBlock();
2615 case tok::identifier:
2617 tryToParseJSFunction();
2621 case tok::kw_switch:
2624 case tok::kw_requires: {
2625 auto RequiresToken = FormatTok;
2627 parseRequiresExpression(RequiresToken);
2631 if (AmpAmpTokenType != TT_Unknown)
2642void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2643 if (!LambdaIntroducer) {
2644 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2645 if (tryToParseLambda())
2662 case tok::l_brace: {
2663 if (!tryToParseBracedList())
2669 if (FormatTok->
is(tok::l_brace)) {
2681void UnwrappedLineParser::keepAncestorBraces() {
2685 const int MaxNestingLevels = 2;
2686 const int Size = NestedTooDeep.size();
2687 if (Size >= MaxNestingLevels)
2688 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2689 NestedTooDeep.push_back(
false);
2693 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2700void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2701 FormatToken *Tok =
nullptr;
2703 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2704 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2707 : Line->Tokens.back().Tok;
2709 if (Tok->BraceCount < 0) {
2710 assert(Tok->BraceCount == -1);
2713 Tok->BraceCount = -1;
2719 ++Line->UnbracedBodyLevel;
2720 parseStructuralElement();
2721 --Line->UnbracedBodyLevel;
2724 assert(!Line->InPPDirective);
2726 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2728 Tok = L.Tokens.back().Tok;
2736 if (CheckEOF && eof())
2746 assert(LeftBrace->
is(tok::l_brace));
2754 assert(RightBrace->
is(tok::r_brace));
2762void UnwrappedLineParser::handleAttributes() {
2766 else if (FormatTok->
is(tok::l_square))
2767 handleCppAttributes();
2770bool UnwrappedLineParser::handleCppAttributes() {
2772 assert(FormatTok->
is(tok::l_square));
2773 if (!tryToParseSimpleAttribute())
2780bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2784 : Tok.is(tok::l_brace);
2787FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2789 bool IsVerilogAssert) {
2790 assert((FormatTok->
is(tok::kw_if) ||
2797 if (IsVerilogAssert) {
2801 if (FormatTok->
is(tok::numeric_constant))
2818 if (FormatTok->
is(tok::exclaim))
2821 bool KeepIfBraces =
true;
2822 if (FormatTok->
is(tok::kw_consteval)) {
2826 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2828 if (FormatTok->
is(tok::l_paren)) {
2835 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2841 bool NeedsUnwrappedLine =
false;
2842 keepAncestorBraces();
2844 FormatToken *IfLeftBrace =
nullptr;
2845 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2847 if (isBlockBegin(*FormatTok)) {
2849 IfLeftBrace = FormatTok;
2851 parseBlock(
false, 1u,
2852 true, KeepIfBraces, &IfBlockKind);
2853 setPreviousRBraceType(TT_ControlStatementRBrace);
2857 NeedsUnwrappedLine =
true;
2858 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2861 parseUnbracedBody();
2865 assert(!NestedTooDeep.empty());
2866 KeepIfBraces = KeepIfBraces ||
2867 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2868 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2869 IfBlockKind == IfStmtKind::IfElseIf;
2872 bool KeepElseBraces = KeepIfBraces;
2873 FormatToken *ElseLeftBrace =
nullptr;
2874 IfStmtKind
Kind = IfStmtKind::IfOnly;
2876 if (FormatTok->
is(tok::kw_else)) {
2878 NestedTooDeep.back() =
false;
2879 Kind = IfStmtKind::IfElse;
2883 if (isBlockBegin(*FormatTok)) {
2884 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2886 ElseLeftBrace = FormatTok;
2888 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2889 FormatToken *IfLBrace =
2890 parseBlock(
false, 1u,
2891 true, KeepElseBraces, &ElseBlockKind);
2892 setPreviousRBraceType(TT_ElseRBrace);
2893 if (FormatTok->
is(tok::kw_else)) {
2894 KeepElseBraces = KeepElseBraces ||
2895 ElseBlockKind == IfStmtKind::IfOnly ||
2896 ElseBlockKind == IfStmtKind::IfElseIf;
2897 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2898 KeepElseBraces =
true;
2899 assert(ElseLeftBrace->MatchingParen);
2903 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2904 const FormatToken *
Previous = Tokens->getPreviousToken();
2906 const bool IsPrecededByComment =
Previous->is(tok::comment);
2907 if (IsPrecededByComment) {
2911 bool TooDeep =
true;
2913 Kind = IfStmtKind::IfElseIf;
2914 TooDeep = NestedTooDeep.pop_back_val();
2916 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2918 NestedTooDeep.push_back(TooDeep);
2919 if (IsPrecededByComment)
2922 parseUnbracedBody(
true);
2925 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2926 if (NeedsUnwrappedLine)
2933 assert(!NestedTooDeep.empty());
2934 KeepElseBraces = KeepElseBraces ||
2935 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2936 NestedTooDeep.back();
2938 NestedTooDeep.pop_back();
2940 if (!KeepIfBraces && !KeepElseBraces) {
2943 }
else if (IfLeftBrace) {
2944 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2946 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2947 assert(!IfLeftBrace->Optional);
2948 assert(!IfRightBrace->Optional);
2949 IfLeftBrace->MatchingParen =
nullptr;
2950 IfRightBrace->MatchingParen =
nullptr;
2960void UnwrappedLineParser::parseTryCatch() {
2961 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2963 bool NeedsUnwrappedLine =
false;
2964 bool HasCtorInitializer =
false;
2965 if (FormatTok->
is(tok::colon)) {
2966 auto *Colon = FormatTok;
2969 if (FormatTok->
is(tok::identifier)) {
2970 HasCtorInitializer =
true;
2971 Colon->setFinalizedType(TT_CtorInitializerColon);
2976 while (FormatTok->
is(tok::comma))
2979 while (FormatTok->
is(tok::identifier)) {
2981 if (FormatTok->
is(tok::l_paren)) {
2983 }
else if (FormatTok->
is(tok::l_brace)) {
2990 while (FormatTok->
is(tok::comma))
2998 keepAncestorBraces();
3000 if (FormatTok->
is(tok::l_brace)) {
3001 if (HasCtorInitializer)
3008 NeedsUnwrappedLine =
true;
3009 }
else if (FormatTok->
isNot(tok::kw_catch)) {
3015 parseStructuralElement();
3019 if (FormatTok->
is(tok::at))
3022 tok::kw___finally) ||
3030 while (FormatTok->
isNot(tok::l_brace)) {
3031 if (FormatTok->
is(tok::l_paren)) {
3035 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
3037 NestedTooDeep.pop_back();
3042 NeedsUnwrappedLine =
false;
3043 Line->MustBeDeclaration =
false;
3049 NeedsUnwrappedLine =
true;
3053 NestedTooDeep.pop_back();
3055 if (NeedsUnwrappedLine)
3059void UnwrappedLineParser::parseNamespace() {
3060 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3061 "'namespace' expected");
3063 const FormatToken &InitialToken = *FormatTok;
3065 if (InitialToken.is(TT_NamespaceMacro)) {
3068 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3069 tok::l_square, tok::period, tok::l_paren) ||
3070 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3071 if (FormatTok->
is(tok::l_square))
3073 else if (FormatTok->
is(tok::l_paren))
3079 if (FormatTok->
is(tok::l_brace)) {
3085 unsigned AddLevels =
3088 DeclarationScopeStack.size() > 1)
3091 bool ManageWhitesmithsBraces =
3097 if (ManageWhitesmithsBraces)
3102 parseBlock(
true, AddLevels,
true,
3104 ManageWhitesmithsBraces);
3106 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3108 if (ManageWhitesmithsBraces)
3114void UnwrappedLineParser::parseNew() {
3115 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3121 if (FormatTok->
is(tok::l_paren))
3125 if (FormatTok->
is(tok::l_brace))
3128 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3141 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3145 if (FormatTok->
is(tok::l_paren)) {
3149 if (FormatTok->
is(tok::l_brace))
3157void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3158 keepAncestorBraces();
3160 if (isBlockBegin(*FormatTok)) {
3162 FormatToken *LeftBrace = FormatTok;
3164 parseBlock(
false, 1u,
3166 setPreviousRBraceType(TT_ControlStatementRBrace);
3168 assert(!NestedTooDeep.empty());
3169 if (!NestedTooDeep.back())
3175 parseUnbracedBody();
3179 NestedTooDeep.pop_back();
3182void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3183 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3190 "'for', 'while' or foreach macro expected");
3192 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3198 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3200 if (HasParens && FormatTok->
is(tok::l_paren)) {
3211 parseVerilogSensitivityList();
3213 Tokens->getPreviousToken()->is(tok::r_paren)) {
3220 parseLoopBody(KeepBraces,
true);
3223void UnwrappedLineParser::parseDoWhile() {
3224 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3230 if (FormatTok->
isNot(tok::kw_while)) {
3243 parseStructuralElement();
3246void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3248 unsigned OldLineLevel = Line->Level;
3252 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3256 FormatTok->
is(tok::l_brace)) {
3262 if (FormatTok->
is(tok::kw_break)) {
3271 parseStructuralElement();
3275 if (FormatTok->
is(tok::semi))
3279 Line->Level = OldLineLevel;
3280 if (FormatTok->
isNot(tok::l_brace)) {
3281 parseStructuralElement();
3286void UnwrappedLineParser::parseCaseLabel() {
3287 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3288 auto *Case = FormatTok;
3293 if (FormatTok->
is(tok::colon)) {
3299 Case->setFinalizedType(TT_SwitchExpressionLabel);
3306void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3307 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3309 if (FormatTok->
is(tok::l_paren))
3312 keepAncestorBraces();
3314 if (FormatTok->
is(tok::l_brace)) {
3317 : TT_ControlStatementLBrace);
3322 setPreviousRBraceType(TT_ControlStatementRBrace);
3328 parseStructuralElement();
3333 NestedTooDeep.pop_back();
3343 case tok::caretequal:
3347 case tok::equalequal:
3349 case tok::exclaimequal:
3351 case tok::greaterequal:
3352 case tok::greatergreater:
3353 case tok::greatergreaterequal:
3357 case tok::lessequal:
3359 case tok::lesslessequal:
3361 case tok::minusequal:
3362 case tok::minusminus:
3364 case tok::percentequal:
3367 case tok::pipeequal:
3370 case tok::plusequal:
3378 case tok::slashequal:
3380 case tok::starequal:
3387void UnwrappedLineParser::parseAccessSpecifier() {
3388 FormatToken *AccessSpecifierCandidate = FormatTok;
3394 if (FormatTok->
is(tok::colon)) {
3397 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3401 }
else if (AccessSpecifierCandidate) {
3403 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3410bool UnwrappedLineParser::parseRequires() {
3411 assert(FormatTok->
is(tok::kw_requires) &&
"'requires' expected");
3412 auto RequiresToken = FormatTok;
3421 parseRequiresExpression(RequiresToken);
3428 parseRequiresClause(RequiresToken);
3439 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3441 if (!PreviousNonComment ||
3442 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3445 parseRequiresClause(RequiresToken);
3449 switch (PreviousNonComment->Tok.getKind()) {
3452 case tok::kw_noexcept:
3455 parseRequiresClause(RequiresToken);
3465 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3466 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3467 parseRequiresClause(RequiresToken);
3473 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3475 parseRequiresClause(RequiresToken);
3479 parseRequiresExpression(RequiresToken);
3489 unsigned StoredPosition = Tokens->getPosition();
3490 FormatToken *NextToken = Tokens->getNextToken();
3492 auto PeekNext = [&Lookahead, &NextToken,
this] {
3494 NextToken = Tokens->getNextToken();
3497 bool FoundType =
false;
3498 bool LastWasColonColon =
false;
3501 for (; Lookahead < 50; PeekNext()) {
3502 switch (NextToken->Tok.getKind()) {
3503 case tok::kw_volatile:
3506 if (OpenAngles == 0) {
3507 FormatTok = Tokens->setPosition(StoredPosition);
3508 parseRequiresExpression(RequiresToken);
3516 case tok::coloncolon:
3517 LastWasColonColon =
true;
3519 case tok::kw_decltype:
3520 case tok::identifier:
3521 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3522 FormatTok = Tokens->setPosition(StoredPosition);
3523 parseRequiresExpression(RequiresToken);
3527 LastWasColonColon =
false;
3536 if (NextToken->isTypeName(LangOpts)) {
3537 FormatTok = Tokens->setPosition(StoredPosition);
3538 parseRequiresExpression(RequiresToken);
3545 FormatTok = Tokens->setPosition(StoredPosition);
3546 parseRequiresClause(RequiresToken);
3557void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3559 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3564 bool InRequiresExpression =
3565 !RequiresToken->Previous ||
3566 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3568 RequiresToken->setFinalizedType(InRequiresExpression
3569 ? TT_RequiresClauseInARequiresExpression
3570 : TT_RequiresClause);
3574 parseConstraintExpression();
3576 if (!InRequiresExpression)
3587void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3589 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3591 RequiresToken->setFinalizedType(TT_RequiresExpression);
3593 if (FormatTok->
is(tok::l_paren)) {
3598 if (FormatTok->
is(tok::l_brace)) {
3608void UnwrappedLineParser::parseConstraintExpression() {
3615 bool LambdaNextTimeAllowed =
true;
3625 bool TopLevelParensAllowed =
true;
3628 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3631 case tok::kw_requires: {
3632 auto RequiresToken = FormatTok;
3634 parseRequiresExpression(RequiresToken);
3639 if (!TopLevelParensAllowed)
3641 parseParens(TT_BinaryOperator);
3642 TopLevelParensAllowed =
false;
3646 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3653 case tok::kw_struct:
3665 LambdaNextTimeAllowed =
true;
3666 TopLevelParensAllowed =
true;
3671 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3675 case tok::kw_sizeof:
3677 case tok::greaterequal:
3678 case tok::greatergreater:
3680 case tok::lessequal:
3682 case tok::equalequal:
3684 case tok::exclaimequal:
3689 LambdaNextTimeAllowed =
true;
3690 TopLevelParensAllowed =
true;
3695 case tok::numeric_constant:
3696 case tok::coloncolon:
3699 TopLevelParensAllowed =
false;
3704 case tok::kw_static_cast:
3705 case tok::kw_const_cast:
3706 case tok::kw_reinterpret_cast:
3707 case tok::kw_dynamic_cast:
3709 if (FormatTok->
isNot(tok::less))
3713 parseBracedList(
true);
3729 case tok::coloncolon:
3733 case tok::kw_requires:
3742 if (FormatTok->
is(tok::less)) {
3744 parseBracedList(
true);
3746 TopLevelParensAllowed =
false;
3752bool UnwrappedLineParser::parseEnum() {
3753 const FormatToken &InitialToken = *FormatTok;
3756 if (FormatTok->
is(tok::kw_enum))
3771 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3773 while (FormatTok->
is(tok::l_square))
3774 if (!handleCppAttributes())
3779 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3780 tok::greater, tok::comma, tok::question,
3786 while (FormatTok->
is(tok::l_square))
3792 if (FormatTok->
is(tok::l_paren))
3794 if (FormatTok->
is(tok::identifier)) {
3798 if (IsCpp && FormatTok->
is(tok::identifier))
3804 if (FormatTok->
isNot(tok::l_brace))
3811 parseJavaEnumBody();
3829 bool HasError = !parseBracedList(
false,
true);
3833 if (FormatTok->
is(tok::semi))
3837 setPreviousRBraceType(TT_EnumRBrace);
3845bool UnwrappedLineParser::parseStructLike() {
3852 if (FormatTok->
is(tok::semi))
3863class ScopedTokenPosition {
3864 unsigned StoredPosition;
3865 FormatTokenSource *Tokens;
3868 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3869 assert(Tokens &&
"Tokens expected to not be null");
3870 StoredPosition = Tokens->getPosition();
3873 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3879bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3880 ScopedTokenPosition AutoPosition(Tokens);
3881 FormatToken *Tok = Tokens->getNextToken();
3883 if (Tok->isNot(tok::l_square))
3887 while (Tok->isNot(tok::eof)) {
3888 if (Tok->is(tok::r_square))
3890 Tok = Tokens->getNextToken();
3892 if (Tok->is(tok::eof))
3894 Tok = Tokens->getNextToken();
3895 if (Tok->isNot(tok::r_square))
3897 Tok = Tokens->getNextToken();
3898 if (Tok->is(tok::semi))
3903void UnwrappedLineParser::parseJavaEnumBody() {
3904 assert(FormatTok->
is(tok::l_brace));
3905 const FormatToken *OpeningBrace = FormatTok;
3910 unsigned StoredPosition = Tokens->getPosition();
3911 bool IsSimple =
true;
3912 FormatToken *Tok = Tokens->getNextToken();
3913 while (Tok->isNot(tok::eof)) {
3914 if (Tok->is(tok::r_brace))
3916 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3922 Tok = Tokens->getNextToken();
3924 FormatTok = Tokens->setPosition(StoredPosition);
3941 if (FormatTok->
is(tok::l_brace)) {
3943 parseBlock(
true, 1u,
3945 }
else if (FormatTok->
is(tok::l_paren)) {
3947 }
else if (FormatTok->
is(tok::comma)) {
3950 }
else if (FormatTok->
is(tok::semi)) {
3954 }
else if (FormatTok->
is(tok::r_brace)) {
3963 parseLevel(OpeningBrace);
3969void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
3970 const FormatToken &InitialToken = *FormatTok;
3973 const FormatToken *ClassName =
nullptr;
3974 bool IsDerived =
false;
3975 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
3976 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
3981 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3982 tok::kw_alignas, tok::l_square) ||
3985 FormatTok->
isOneOf(tok::period, tok::comma))) {
3992 if (FormatTok->
is(tok::l_brace)) {
3993 tryToParseBracedList();
3997 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
4004 if (!IsNonMacroIdentifier(
Previous) ||
4006 Previous->Previous == &InitialToken) {
4010 case tok::coloncolon:
4013 if (!ClassName &&
Previous->is(tok::identifier) &&
4014 Previous->isNot(TT_AttributeMacro)) {
4020 auto IsListInitialization = [&] {
4021 if (!ClassName || IsDerived)
4023 assert(FormatTok->
is(tok::l_brace));
4026 return Prev != ClassName && Prev->is(tok::identifier) &&
4027 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
4030 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
4031 int AngleNestingLevel = 0;
4033 if (FormatTok->
is(tok::less))
4034 ++AngleNestingLevel;
4035 else if (FormatTok->
is(tok::greater))
4036 --AngleNestingLevel;
4038 if (AngleNestingLevel == 0) {
4039 if (FormatTok->
is(tok::colon)) {
4041 }
else if (FormatTok->
is(tok::identifier) &&
4043 ClassName = FormatTok;
4044 }
else if (FormatTok->
is(tok::l_paren) &&
4045 IsNonMacroIdentifier(FormatTok->
Previous)) {
4049 if (FormatTok->
is(tok::l_brace)) {
4050 if (AngleNestingLevel == 0 && IsListInitialization())
4052 calculateBraceTypes(
true);
4053 if (!tryToParseBracedList())
4056 if (FormatTok->
is(tok::l_square)) {
4059 !
Previous->isTypeOrIdentifier(LangOpts))) {
4062 if (!tryToParseLambda())
4069 if (FormatTok->
is(tok::semi))
4074 parseCSharpGenericTypeConstraint();
4081 auto GetBraceTypes =
4082 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4083 switch (RecordTok.Tok.getKind()) {
4085 return {TT_ClassLBrace, TT_ClassRBrace};
4086 case tok::kw_struct:
4087 return {TT_StructLBrace, TT_StructRBrace};
4089 return {TT_UnionLBrace, TT_UnionRBrace};
4092 return {TT_RecordLBrace, TT_RecordRBrace};
4095 if (FormatTok->
is(tok::l_brace)) {
4096 if (IsListInitialization())
4098 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4107 parseBlock(
true, AddLevels,
false);
4109 setPreviousRBraceType(ClosingBraceType);
4116void UnwrappedLineParser::parseObjCMethod() {
4117 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4118 "'(' or identifier expected.");
4120 if (FormatTok->
is(tok::semi)) {
4124 }
else if (FormatTok->
is(tok::l_brace)) {
4136void UnwrappedLineParser::parseObjCProtocolList() {
4137 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4141 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4145 }
while (!eof() && FormatTok->
isNot(tok::greater));
4149void UnwrappedLineParser::parseObjCUntilAtEnd() {
4156 if (FormatTok->
is(tok::l_brace)) {
4160 }
else if (FormatTok->
is(tok::r_brace)) {
4164 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4168 parseStructuralElement();
4173void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4181 if (FormatTok->
is(tok::less))
4182 parseObjCLightweightGenerics();
4183 if (FormatTok->
is(tok::colon)) {
4187 if (FormatTok->
is(tok::less))
4188 parseObjCLightweightGenerics();
4189 }
else if (FormatTok->
is(tok::l_paren)) {
4194 if (FormatTok->
is(tok::less))
4195 parseObjCProtocolList();
4197 if (FormatTok->
is(tok::l_brace)) {
4207 parseObjCUntilAtEnd();
4210void UnwrappedLineParser::parseObjCLightweightGenerics() {
4211 assert(FormatTok->
is(tok::less));
4219 unsigned NumOpenAngles = 1;
4223 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4227 if (FormatTok->
is(tok::less)) {
4229 }
else if (FormatTok->
is(tok::greater)) {
4230 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4233 }
while (!eof() && NumOpenAngles != 0);
4239bool UnwrappedLineParser::parseObjCProtocol() {
4243 if (FormatTok->
is(tok::l_paren)) {
4255 if (FormatTok->
is(tok::less))
4256 parseObjCProtocolList();
4259 if (FormatTok->
is(tok::semi)) {
4266 parseObjCUntilAtEnd();
4270void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4271 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4272 assert(IsImport || FormatTok->
is(tok::kw_export));
4276 if (FormatTok->
is(tok::kw_default))
4293 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4296 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4301 if (FormatTok->
is(tok::semi))
4303 if (Line->Tokens.empty()) {
4308 if (FormatTok->
is(tok::l_brace)) {
4318void UnwrappedLineParser::parseStatementMacro() {
4320 if (FormatTok->
is(tok::l_paren))
4322 if (FormatTok->
is(tok::semi))
4327void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4330 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4331 tok::coloncolon, tok::hash) ||
4334 }
else if (FormatTok->
is(tok::l_square)) {
4342void UnwrappedLineParser::parseVerilogSensitivityList() {
4343 if (FormatTok->
isNot(tok::at))
4347 if (FormatTok->
is(tok::at))
4357 parseVerilogHierarchyIdentifier();
4362unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4363 unsigned AddLevels = 0;
4369 parseVerilogSensitivityList();
4370 if (FormatTok->
is(tok::semi))
4378 if (FormatTok->
is(tok::l_paren)) {
4391 if (FormatTok->
is(tok::l_square)) {
4406 Line->IsContinuation =
true;
4413 parseVerilogHierarchyIdentifier();
4414 if (FormatTok->
is(tok::semi))
4422 if (FormatTok->
is(tok::l_paren)) {
4427 if (FormatTok->
is(tok::l_paren)) {
4437 parseVerilogHierarchyIdentifier();
4438 if (FormatTok->
is(tok::l_paren))
4445 parseVerilogHierarchyIdentifier();
4446 }
while (FormatTok->
is(tok::comma));
4450 if (FormatTok->
is(tok::at)) {
4452 parseVerilogSensitivityList();
4455 if (FormatTok->
is(tok::semi))
4463void UnwrappedLineParser::parseVerilogTable() {
4468 auto InitialLevel = Line->Level++;
4470 FormatToken *Tok = FormatTok;
4472 if (Tok->is(tok::semi))
4474 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4475 Tok->setFinalizedType(TT_VerilogTableItem);
4477 Line->Level = InitialLevel;
4482void UnwrappedLineParser::parseVerilogCaseLabel() {
4488 auto OrigLevel = Line->Level;
4489 auto FirstLine = CurrentLines->size();
4490 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4494 parseStructuralElement();
4497 if (CurrentLines->size() > FirstLine)
4498 (*CurrentLines)[FirstLine].Level = OrigLevel;
4499 Line->Level = OrigLevel;
4502bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4503 for (
const auto &N : Line.Tokens) {
4504 if (N.Tok->MacroCtx)
4506 for (
const UnwrappedLine &Child : N.Children)
4507 if (containsExpansion(Child))
4513void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4514 if (Line->Tokens.empty())
4517 if (!parsingPPDirective()) {
4518 llvm::dbgs() <<
"Adding unwrapped line:\n";
4519 printDebugInfo(*Line);
4527 bool ClosesWhitesmithsBlock =
4534 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4536 Reconstruct.emplace(Line->Level, Unexpanded);
4537 Reconstruct->addLine(*Line);
4542 CurrentExpandedLines.push_back(std::move(*Line));
4544 if (Reconstruct->finished()) {
4545 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4546 assert(!Reconstructed.Tokens.empty() &&
4547 "Reconstructed must at least contain the macro identifier.");
4548 assert(!parsingPPDirective());
4550 llvm::dbgs() <<
"Adding unexpanded line:\n";
4551 printDebugInfo(Reconstructed);
4553 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4554 Lines.push_back(std::move(Reconstructed));
4555 CurrentExpandedLines.clear();
4556 Reconstruct.reset();
4561 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4562 CurrentLines->push_back(std::move(*Line));
4564 Line->Tokens.clear();
4566 Line->FirstStartColumn = 0;
4567 Line->IsContinuation =
false;
4568 Line->SeenDecltypeAuto =
false;
4570 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4572 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4573 CurrentLines->append(
4574 std::make_move_iterator(PreprocessorDirectives.begin()),
4575 std::make_move_iterator(PreprocessorDirectives.end()));
4576 PreprocessorDirectives.clear();
4582bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4584bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4585 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4586 FormatTok.NewlinesBefore > 0;
4594 const llvm::Regex &CommentPragmasRegex) {
4595 if (
Line.Tokens.empty())
4598 StringRef IndentContent = FormatTok.
TokenText;
4599 if (FormatTok.
TokenText.starts_with(
"//") ||
4600 FormatTok.
TokenText.starts_with(
"/*")) {
4601 IndentContent = FormatTok.
TokenText.substr(2);
4603 if (CommentPragmasRegex.match(IndentContent))
4678 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4680 MinColumnToken = PreviousToken;
4683 PreviousToken =
Node.Tok;
4686 if (
Node.Tok->NewlinesBefore > 0)
4687 MinColumnToken =
Node.Tok;
4689 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4690 MinColumnToken = PreviousToken;
4696void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4697 bool JustComments = Line->Tokens.empty();
4698 for (FormatToken *Tok : CommentsBeforeNextToken) {
4707 Tok->ContinuesLineCommentSection =
4709 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4713 if (NewlineBeforeNext && JustComments)
4715 CommentsBeforeNextToken.clear();
4718void UnwrappedLineParser::nextToken(
int LevelDifference) {
4721 flushComments(isOnNewLine(*FormatTok));
4722 pushToken(FormatTok);
4725 readToken(LevelDifference);
4727 readTokenWithJavaScriptASI();
4737 FormatTok->Tok.setKind(tok::r_brace);
4741void UnwrappedLineParser::distributeComments(
4742 const SmallVectorImpl<FormatToken *> &Comments,
4743 const FormatToken *NextTok) {
4762 if (Comments.empty())
4764 bool ShouldPushCommentsInCurrentLine =
true;
4765 bool HasTrailAlignedWithNextToken =
false;
4766 unsigned StartOfTrailAlignedWithNextToken = 0;
4769 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4770 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4771 HasTrailAlignedWithNextToken =
true;
4772 StartOfTrailAlignedWithNextToken = i;
4776 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4777 FormatToken *FormatTok = Comments[i];
4778 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4779 FormatTok->ContinuesLineCommentSection =
false;
4781 FormatTok->ContinuesLineCommentSection =
4784 if (!FormatTok->ContinuesLineCommentSection &&
4785 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4786 ShouldPushCommentsInCurrentLine =
false;
4788 if (ShouldPushCommentsInCurrentLine)
4789 pushToken(FormatTok);
4791 CommentsBeforeNextToken.push_back(FormatTok);
4795void UnwrappedLineParser::readToken(
int LevelDifference) {
4796 SmallVector<FormatToken *, 1> Comments;
4797 bool PreviousWasComment =
false;
4798 bool FirstNonCommentOnLine =
false;
4800 FormatTok = Tokens->getNextToken();
4802 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4803 TT_ConflictAlternative)) {
4804 if (FormatTok->is(TT_ConflictStart))
4805 conditionalCompilationStart(
false);
4806 else if (FormatTok->is(TT_ConflictAlternative))
4807 conditionalCompilationAlternative();
4808 else if (FormatTok->is(TT_ConflictEnd))
4809 conditionalCompilationEnd();
4810 FormatTok = Tokens->getNextToken();
4811 FormatTok->MustBreakBefore =
true;
4812 FormatTok->MustBreakBeforeFinalized =
true;
4815 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4816 const FormatToken &Tok,
4817 bool PreviousWasComment) {
4818 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4819 return Tok.HasUnescapedNewline || Tok.IsFirst;
4824 if (PreviousWasComment)
4825 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4826 return IsFirstOnLine(Tok);
4829 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4830 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4831 PreviousWasComment = FormatTok->is(tok::comment);
4833 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4836 FirstNonCommentOnLine) {
4837 distributeComments(Comments, FormatTok);
4841 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4843 assert((LevelDifference >= 0 ||
4844 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4845 "LevelDifference makes Line->Level negative");
4846 Line->Level += LevelDifference;
4851 PPBranchLevel > 0) {
4852 Line->Level += PPBranchLevel;
4854 assert(Line->Level >= Line->UnbracedBodyLevel);
4855 Line->Level -= Line->UnbracedBodyLevel;
4856 flushComments(isOnNewLine(*FormatTok));
4858 PreviousWasComment = FormatTok->is(tok::comment);
4859 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4860 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4863 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4864 !Line->InPPDirective) {
4868 if (FormatTok->is(tok::identifier) &&
4869 Macros.
defined(FormatTok->TokenText) &&
4871 !Line->InPPDirective) {
4872 FormatToken *
ID = FormatTok;
4873 unsigned Position = Tokens->getPosition();
4877 auto PreCall = std::move(Line);
4878 Line.reset(
new UnwrappedLine);
4879 bool OldInExpansion = InExpansion;
4882 auto Args = parseMacroCall();
4883 InExpansion = OldInExpansion;
4884 assert(Line->Tokens.front().Tok ==
ID);
4886 auto UnexpandedLine = std::move(Line);
4888 Line = std::move(PreCall);
4891 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4893 llvm::dbgs() <<
"(";
4894 for (
const auto &Arg : Args.value())
4895 for (
const auto &
T : Arg)
4896 llvm::dbgs() <<
T->TokenText <<
" ";
4897 llvm::dbgs() <<
")";
4899 llvm::dbgs() <<
"\n";
4902 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4908 LLVM_DEBUG(llvm::dbgs()
4909 <<
"Macro \"" <<
ID->TokenText
4910 <<
"\" not overloaded for arity " << Args->size()
4911 <<
"or not function-like, using object-like overload.");
4913 UnexpandedLine->Tokens.resize(1);
4914 Tokens->setPosition(Position);
4919 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4922 Unexpanded[
ID] = std::move(UnexpandedLine);
4923 SmallVector<FormatToken *, 8> Expansion =
4924 Macros.
expand(
ID, std::move(Args));
4925 if (!Expansion.empty())
4926 FormatTok = Tokens->insertTokens(Expansion);
4929 llvm::dbgs() <<
"Expanded: ";
4930 for (
const auto &
T : Expansion)
4931 llvm::dbgs() <<
T->TokenText <<
" ";
4932 llvm::dbgs() <<
"\n";
4936 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4937 <<
"\", because it was used ";
4939 llvm::dbgs() <<
"with " << Args->size();
4941 llvm::dbgs() <<
"without";
4942 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4944 Tokens->setPosition(Position);
4949 if (FormatTok->isNot(tok::comment)) {
4950 distributeComments(Comments, FormatTok);
4955 Comments.push_back(FormatTok);
4958 distributeComments(Comments,
nullptr);
4963template <
typename Iterator>
4964void pushTokens(Iterator
Begin, Iterator End,
4966 for (
auto I =
Begin; I != End; ++I) {
4967 Into.push_back(I->Tok);
4968 for (
const auto &Child : I->Children)
4969 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
4974std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
4975UnwrappedLineParser::parseMacroCall() {
4976 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
4977 assert(Line->Tokens.empty());
4979 if (FormatTok->isNot(tok::l_paren))
4981 unsigned Position = Tokens->getPosition();
4982 FormatToken *Tok = FormatTok;
4985 auto ArgStart = std::prev(Line->Tokens.end());
4989 switch (FormatTok->Tok.getKind()) {
4994 case tok::r_paren: {
5000 Args->push_back({});
5001 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5010 Args->push_back({});
5011 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
5013 ArgStart = std::prev(Line->Tokens.end());
5021 Line->Tokens.resize(1);
5022 Tokens->setPosition(Position);
5027void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5028 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5029 if (MustBreakBeforeNextToken) {
5030 Line->Tokens.back().Tok->MustBreakBefore =
true;
5031 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
5032 MustBreakBeforeNextToken =
false;
enum clang::sema::@1651::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.