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"
38 void printLine(llvm::raw_ostream &OS,
const UnwrappedLine &Line,
39 StringRef Prefix =
"",
bool PrintText =
false) {
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());
67 LLVM_ATTRIBUTE_UNUSED
static void printDebugInfo(
const UnwrappedLine &Line) {
68 printLine(llvm::dbgs(), Line);
71 class 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;
118 if (!
Parser.Line->Tokens.empty())
119 Parser.addUnwrappedLine();
120 assert(
Parser.Line->Tokens.empty());
121 Parser.Line = std::move(PreBlockLine);
122 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
123 Parser.MustBreakBeforeNextToken =
true;
124 Parser.CurrentLines = OriginalLines;
130 std::unique_ptr<UnwrappedLine> PreBlockLine;
139 Style.BraceWrapping.AfterControlStatement,
140 Style.BraceWrapping.IndentBraces) {}
142 bool WrapBrace,
bool IndentBrace)
143 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
145 Parser->addUnwrappedLine();
153 unsigned OldLineLevel;
160 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
163 CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()),
165 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
166 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
167 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
170 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
171 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {
172 assert(IsCpp == LangOpts.CXXOperatorNames);
175 void UnwrappedLineParser::reset() {
180 IncludeGuardToken =
nullptr;
182 CommentsBeforeNextToken.clear();
184 MustBreakBeforeNextToken =
false;
185 IsDecltypeAutoFunction =
false;
186 PreprocessorDirectives.clear();
187 CurrentLines = &Lines;
188 DeclarationScopeStack.clear();
189 NestedTooDeep.clear();
190 NestedLambdas.clear();
192 Line->FirstStartColumn = FirstStartColumn;
194 if (!Unexpanded.empty())
196 Token->MacroCtx.reset();
197 CurrentExpandedLines.clear();
198 ExpandedLines.clear();
206 Line->FirstStartColumn = FirstStartColumn;
208 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
210 Tokens = &TokenSource;
218 if (IncludeGuard == IG_Found) {
219 for (
auto &Line : Lines)
220 if (Line.InPPDirective && Line.Level > 0)
226 pushToken(FormatTok);
231 if (!ExpandedLines.empty()) {
232 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
233 for (
const auto &Line : Lines) {
234 if (!Line.Tokens.empty()) {
235 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
236 if (it != ExpandedLines.end()) {
237 for (
const auto &Expanded : it->second) {
238 LLVM_DEBUG(printDebugInfo(Expanded));
244 LLVM_DEBUG(printDebugInfo(Line));
250 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
252 LLVM_DEBUG(printDebugInfo(Line));
257 while (!PPLevelBranchIndex.empty() &&
258 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
259 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
260 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
262 if (!PPLevelBranchIndex.empty()) {
263 ++PPLevelBranchIndex.back();
264 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
265 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
267 }
while (!PPLevelBranchIndex.empty());
270 void UnwrappedLineParser::parseFile() {
273 bool MustBeDeclaration = !Line->InPPDirective && !Style.
isJavaScript();
274 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
291 !CommentsBeforeNextToken.empty()) {
298 void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
307 parseCSharpGenericTypeConstraint();
316 void UnwrappedLineParser::parseCSharpAttribute() {
317 int UnpairedSquareBrackets = 1;
322 --UnpairedSquareBrackets;
323 if (UnpairedSquareBrackets == 0) {
329 ++UnpairedSquareBrackets;
339 bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
340 if (!Lines.empty() && Lines.back().InPPDirective)
354 bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
356 FormatToken **IfLeftBrace) {
357 const bool InRequiresExpression =
358 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
359 const bool IsPrecededByCommentOrPPDirective =
361 FormatToken *IfLBrace =
nullptr;
362 bool HasDoWhile =
false;
363 bool HasLabel =
false;
364 unsigned StatementCount = 0;
365 bool SwitchLabelEncountered =
false;
373 if (FormatTok->
is(TT_MacroBlockBegin))
375 else if (FormatTok->
is(TT_MacroBlockEnd))
378 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
379 &HasLabel, &StatementCount] {
380 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
381 HasDoWhile ?
nullptr : &HasDoWhile,
382 HasLabel ?
nullptr : &HasLabel);
384 assert(StatementCount > 0 &&
"StatementCount overflow!");
393 if (InRequiresExpression) {
402 if (!InRequiresExpression && FormatTok->
isNot(TT_MacroBlockBegin)) {
403 if (tryToParseBracedList())
409 assert(StatementCount > 0 &&
"StatementCount overflow!");
415 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
418 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
419 HasDoWhile || IsPrecededByCommentOrPPDirective ||
420 precededByCommentOrPPDirective()) {
424 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
427 *IfLeftBrace = IfLBrace;
433 case tok::kw_default: {
437 if (!Next->isOneOf(tok::colon, tok::arrow)) {
440 parseStructuralElement();
456 if (!SwitchLabelEncountered &&
458 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
459 (Line->InPPDirective && Line->Level == 1))) {
462 SwitchLabelEncountered =
true;
463 parseStructuralElement();
468 parseCSharpAttribute();
471 if (handleCppAttributes())
483 void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
489 FormatToken *Tok = FormatTok;
490 const FormatToken *PrevTok = Tok->
Previous;
496 const FormatToken *PrevTok;
498 SmallVector<StackEntry, 8> LBraceStack;
499 assert(Tok->is(tok::l_brace));
504 if (!Line->InMacroBody && !Style.
isTableGen()) {
506 while (NextTok->is(tok::hash)) {
509 }
while (NextTok->NewlinesBefore == 0 && NextTok->isNot(
tok::eof));
511 while (NextTok->is(tok::comment))
516 switch (Tok->Tok.getKind()) {
519 if (PrevTok->isOneOf(tok::colon, tok::less)) {
530 }
else if (PrevTok->is(tok::r_paren)) {
537 LBraceStack.push_back({Tok, PrevTok});
540 if (LBraceStack.empty())
542 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
543 bool ProbablyBracedList =
false;
545 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
546 }
else if (LBrace->isNot(TT_EnumLBrace)) {
549 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
550 NextTok->OriginalColumn == 0;
560 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
562 ProbablyBracedList = ProbablyBracedList ||
564 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
567 ProbablyBracedList || (IsCpp && NextTok->is(tok::l_paren));
574 ProbablyBracedList ||
575 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
576 tok::r_paren, tok::r_square, tok::ellipsis);
581 ProbablyBracedList ||
582 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
583 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
587 ProbablyBracedList ||
588 (NextTok->is(tok::identifier) &&
589 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
591 ProbablyBracedList = ProbablyBracedList ||
592 (NextTok->is(tok::semi) &&
593 (!ExpectClassBody || LBraceStack.size() != 1));
596 ProbablyBracedList ||
597 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
599 if (!Style.
isCSharp() && NextTok->is(tok::l_square)) {
603 ProbablyBracedList = NextTok->
isNot(tok::l_square);
607 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
612 !PrevTok->isOneOf(tok::semi,
BK_Block, tok::colon)) {
613 ProbablyBracedList =
true;
617 Tok->setBlockKind(BlockKind);
618 LBrace->setBlockKind(BlockKind);
620 LBraceStack.pop_back();
622 case tok::identifier:
623 if (Tok->isNot(TT_StatementMacro))
634 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
635 LBraceStack.back().Tok->setBlockKind(
BK_Block);
643 }
while (Tok->isNot(
tok::eof) && !LBraceStack.empty());
646 for (
const auto &Entry : LBraceStack)
654 void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
656 Prev && Prev->
is(tok::r_brace)) {
664 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
667 size_t UnwrappedLineParser::computePPHash()
const {
669 for (
const auto &i : PPStack) {
680 bool UnwrappedLineParser::mightFitOnOneLine(
681 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
683 if (ColumnLimit == 0)
686 auto &Tokens = ParsedLine.Tokens;
687 assert(!Tokens.empty());
689 const auto *LastToken = Tokens.back().Tok;
692 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
695 for (
const auto &Token : Tokens) {
697 auto &SavedToken = SavedTokens[Index++];
698 SavedToken.Tok =
new FormatToken;
699 SavedToken.Tok->copyFrom(*Token.Tok);
700 SavedToken.Children = std::move(Token.Children);
703 AnnotatedLine Line(ParsedLine);
704 assert(Line.Last == LastToken);
706 TokenAnnotator Annotator(Style, Keywords);
707 Annotator.annotate(Line);
708 Annotator.calculateFormattingInformation(Line);
710 auto Length = LastToken->TotalLength;
712 assert(OpeningBrace != Tokens.front().Tok);
713 if (
auto Prev = OpeningBrace->Previous;
714 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
715 Length -= ColumnLimit;
717 Length -= OpeningBrace->TokenText.size() + 1;
720 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
721 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
722 Length -= FirstToken->TokenText.size() + 1;
726 for (
auto &Token : Tokens) {
727 const auto &SavedToken = SavedTokens[Index++];
728 Token.Tok->copyFrom(*SavedToken.Tok);
729 Token.Children = std::move(SavedToken.Children);
730 delete SavedToken.Tok;
734 assert(!Line.InMacroBody);
735 assert(!Line.InPPDirective);
736 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
739 FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
740 unsigned AddLevels,
bool MunchSemi,
743 bool UnindentWhitesmithsBraces) {
744 auto HandleVerilogBlockLabel = [
this]() {
746 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
755 const bool VerilogHierarchy =
757 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
760 "'{' or macro block token expected");
761 FormatToken *Tok = FormatTok;
762 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
763 auto Index = CurrentLines->size();
764 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
769 if (!VerilogHierarchy && AddLevels > 0 &&
774 size_t PPStartHash = computePPHash();
776 const unsigned InitialLevel = Line->Level;
777 if (VerilogHierarchy) {
778 AddLevels += parseVerilogHierarchyHeader();
780 nextToken(AddLevels);
781 HandleVerilogBlockLabel();
785 if (Line->Level > 300)
788 if (MacroBlock && FormatTok->
is(tok::l_paren))
791 size_t NbPreprocessorDirectives =
792 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
794 size_t OpeningLineIndex =
795 CurrentLines->empty()
797 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
802 if (UnindentWhitesmithsBraces)
805 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
808 Line->Level += AddLevels;
810 FormatToken *IfLBrace =
nullptr;
811 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
816 if (MacroBlock ? FormatTok->
isNot(TT_MacroBlockEnd)
817 : FormatTok->
isNot(tok::r_brace)) {
818 Line->Level = InitialLevel;
823 if (FormatTok->
is(tok::r_brace)) {
825 if (Tok->is(TT_NamespaceLBrace))
829 const bool IsFunctionRBrace =
830 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
832 auto RemoveBraces = [=]()
mutable {
835 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
836 assert(FormatTok->
is(tok::r_brace));
837 const bool WrappedOpeningBrace = !Tok->Previous;
838 if (WrappedOpeningBrace && FollowedByComment)
840 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
841 if (KeepBraces && !HasRequiredIfBraces)
843 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
844 const FormatToken *
Previous = Tokens->getPreviousToken();
849 assert(!CurrentLines->empty());
850 auto &LastLine = CurrentLines->back();
851 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
853 if (Tok->is(TT_ElseLBrace))
855 if (WrappedOpeningBrace) {
860 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
862 if (RemoveBraces()) {
863 Tok->MatchingParen = FormatTok;
867 size_t PPEndHash = computePPHash();
870 nextToken(-AddLevels);
876 while (FormatTok->
is(tok::semi)) {
882 HandleVerilogBlockLabel();
884 if (MacroBlock && FormatTok->
is(tok::l_paren))
887 Line->Level = InitialLevel;
889 if (FormatTok->
is(tok::kw_noexcept)) {
894 if (FormatTok->
is(tok::arrow)) {
898 parseStructuralElement();
901 if (MunchSemi && FormatTok->
is(tok::semi))
904 if (PPStartHash == PPEndHash) {
905 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
908 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
909 CurrentLines->size() - 1;
919 if (Line.Tokens.
size() < 4)
921 auto I = Line.Tokens.begin();
922 if (I->Tok->TokenText !=
"goog")
925 if (I->Tok->isNot(tok::period))
928 if (I->Tok->TokenText !=
"scope")
931 return I->Tok->is(tok::l_paren);
940 if (Line.Tokens.
size() < 3)
942 auto I = Line.Tokens.begin();
943 if (I->Tok->isNot(tok::l_paren))
949 return I->Tok->is(tok::l_paren);
955 if (InitialToken.
is(TT_NamespaceMacro))
956 Kind = tok::kw_namespace;
959 case tok::kw_namespace:
974 void UnwrappedLineParser::parseChildBlock() {
975 assert(FormatTok->
is(tok::l_brace));
977 const FormatToken *OpeningBrace = FormatTok;
983 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
985 Line->Level += SkipIndent ? 0 : 1;
986 parseLevel(OpeningBrace);
987 flushComments(isOnNewLine(*FormatTok));
988 Line->Level -= SkipIndent ? 0 : 1;
993 void UnwrappedLineParser::parsePPDirective() {
994 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
995 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
1024 case tok::pp_pragma:
1033 void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1034 size_t Line = CurrentLines->size();
1035 if (CurrentLines == &PreprocessorDirectives)
1036 Line += Lines.size();
1039 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1040 PPStack.push_back({PP_Unreachable, Line});
1042 PPStack.push_back({PP_Conditional, Line});
1046 void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1048 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1049 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1050 PPLevelBranchIndex.push_back(0);
1051 PPLevelBranchCount.push_back(0);
1053 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1054 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1055 conditionalCompilationCondition(Unreachable || Skip);
1058 void UnwrappedLineParser::conditionalCompilationAlternative() {
1059 if (!PPStack.empty())
1061 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1062 if (!PPChainBranchIndex.empty())
1063 ++PPChainBranchIndex.top();
1064 conditionalCompilationCondition(
1065 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1066 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1069 void UnwrappedLineParser::conditionalCompilationEnd() {
1070 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1071 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1072 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1073 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1076 if (PPBranchLevel > -1)
1078 if (!PPChainBranchIndex.empty())
1079 PPChainBranchIndex.pop();
1080 if (!PPStack.empty())
1084 void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1087 bool Unreachable =
false;
1088 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1090 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1092 conditionalCompilationStart(Unreachable);
1093 FormatToken *IfCondition = FormatTok;
1096 bool MaybeIncludeGuard = IfNDef;
1097 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1098 for (
auto &Line : Lines) {
1099 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1100 MaybeIncludeGuard =
false;
1101 IncludeGuard = IG_Rejected;
1109 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1110 IncludeGuard = IG_IfNdefed;
1111 IncludeGuardToken = IfCondition;
1115 void UnwrappedLineParser::parsePPElse() {
1117 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1118 IncludeGuard = IG_Rejected;
1120 assert(PPBranchLevel >= -1);
1121 if (PPBranchLevel == -1)
1122 conditionalCompilationStart(
true);
1123 conditionalCompilationAlternative();
1129 void UnwrappedLineParser::parsePPEndIf() {
1130 conditionalCompilationEnd();
1134 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1136 IncludeGuard = IG_Found;
1140 void UnwrappedLineParser::parsePPDefine() {
1144 IncludeGuard = IG_Rejected;
1145 IncludeGuardToken =
nullptr;
1150 if (IncludeGuard == IG_IfNdefed &&
1152 IncludeGuard = IG_Defined;
1153 IncludeGuardToken =
nullptr;
1154 for (
auto &Line : Lines) {
1155 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1156 IncludeGuard = IG_Rejected;
1170 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1175 Line->Level += PPBranchLevel + 1;
1179 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1180 assert((
int)Line->PPLevel >= 0);
1181 Line->InMacroBody =
true;
1200 void UnwrappedLineParser::parsePPPragma() {
1201 Line->InPragmaDirective =
true;
1205 void UnwrappedLineParser::parsePPUnknown() {
1210 Line->Level += PPBranchLevel + 1;
1220 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1223 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1224 tok::less, tok::greater, tok::slash, tok::percent,
1225 tok::lessless, tok::greatergreater, tok::equal,
1226 tok::plusequal, tok::minusequal, tok::starequal,
1227 tok::slashequal, tok::percentequal, tok::ampequal,
1228 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1241 return FormatTok->
is(tok::identifier) &&
1256 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1267 tok::kw_if, tok::kw_else,
1269 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1271 tok::kw_switch, tok::kw_case,
1273 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1275 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1283 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1284 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1301 if (FuncName->
isNot(tok::identifier))
1309 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1313 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1317 if (!Tok || Tok->
isNot(tok::r_paren))
1321 if (!Tok || Tok->
isNot(tok::identifier))
1327 bool UnwrappedLineParser::parseModuleImport() {
1328 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1330 if (
auto Token = Tokens->peekNextToken(
true);
1332 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1338 if (FormatTok->
is(tok::colon)) {
1342 else if (FormatTok->
is(tok::less)) {
1347 if (FormatTok->
isNot(tok::comment) &&
1348 !FormatTok->
TokenText.starts_with(
"//")) {
1354 if (FormatTok->
is(tok::semi)) {
1372 void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1375 FormatToken *Next = FormatTok;
1378 CommentsBeforeNextToken.empty()
1379 ? Next->NewlinesBefore == 0
1380 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1385 bool PreviousStartsTemplateExpr =
1387 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1390 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1391 return LineNode.Tok->is(tok::at);
1396 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1397 return addUnwrappedLine();
1399 bool NextEndsTemplateExpr =
1400 Next->is(TT_TemplateString) && Next->TokenText.starts_with(
"}");
1401 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1402 (PreviousMustBeValue ||
1403 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1404 tok::minusminus))) {
1405 return addUnwrappedLine();
1407 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1409 return addUnwrappedLine();
1415 Tok.
isOneOf(tok::ampamp, tok::ampequal, tok::amp, tok::pipe,
1416 tok::tilde, tok::exclaim, tok::exclaimequal, tok::pipepipe,
1417 tok::pipeequal, tok::caret, tok::caretequal);
1420 void UnwrappedLineParser::parseStructuralElement(
1421 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1422 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1426 if (FormatTok->
is(tok::string_literal))
1433 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1437 parseForOrWhileLoop(
false);
1441 parseForOrWhileLoop();
1446 parseIfThenElse(IfKind,
false,
true);
1455 }
else if (FormatTok->
is(tok::l_paren) &&
1456 Tokens->peekNextToken()->is(tok::star)) {
1468 if (FormatTok->
is(tok::l_brace)) {
1471 while (FormatTok && !eof()) {
1472 if (FormatTok->
is(tok::r_brace)) {
1483 case tok::kw_namespace:
1486 case tok::kw_public:
1487 case tok::kw_protected:
1488 case tok::kw_private:
1493 parseAccessSpecifier();
1501 FormatToken *Tok = parseIfThenElse(IfKind);
1512 parseForOrWhileLoop();
1523 case tok::kw_switch:
1530 case tok::kw_default: {
1540 if (FormatTok->
is(tok::colon)) {
1545 if (FormatTok->
is(tok::arrow)) {
1547 Default->setFinalizedType(TT_SwitchExpressionLabel);
1580 case tok::kw_extern:
1586 parseVerilogHierarchyHeader();
1589 }
else if (FormatTok->
is(tok::string_literal)) {
1591 if (FormatTok->
is(tok::l_brace)) {
1596 unsigned AddLevels =
1603 parseBlock(
true, AddLevels);
1609 case tok::kw_export:
1611 parseJavaScriptEs6ImportExport();
1616 if (FormatTok->
is(tok::kw_namespace)) {
1620 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1624 case tok::kw_inline:
1626 if (FormatTok->
is(tok::kw_namespace)) {
1631 case tok::identifier:
1632 if (FormatTok->
is(TT_ForEachMacro)) {
1633 parseForOrWhileLoop();
1636 if (FormatTok->
is(TT_MacroBlockBegin)) {
1637 parseBlock(
false, 1u,
1643 parseJavaScriptEs6ImportExport();
1648 if (FormatTok->
is(tok::kw_public))
1650 if (FormatTok->
isNot(tok::string_literal))
1653 if (FormatTok->
is(tok::semi))
1658 if (IsCpp && parseModuleImport())
1664 if (FormatTok->
is(tok::colon)) {
1670 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1671 parseStatementMacro();
1674 if (IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1683 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1685 if (!Line->InMacroBody || CurrentLines->size() > 1)
1686 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1699 for (
const bool InRequiresExpression =
1700 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
1703 if (
auto *Next = Tokens->peekNextToken(
true);
1704 Next && Next->isBinaryOperator()) {
1712 if (FormatTok->
is(tok::l_brace)) {
1722 case tok::objc_public:
1723 case tok::objc_protected:
1724 case tok::objc_package:
1725 case tok::objc_private:
1726 return parseAccessSpecifier();
1727 case tok::objc_interface:
1728 case tok::objc_implementation:
1729 return parseObjCInterfaceOrImplementation();
1730 case tok::objc_protocol:
1731 if (parseObjCProtocol())
1736 case tok::objc_optional:
1737 case tok::objc_required:
1741 case tok::objc_autoreleasepool:
1743 if (FormatTok->
is(tok::l_brace)) {
1752 case tok::objc_synchronized:
1754 if (FormatTok->
is(tok::l_paren)) {
1758 if (FormatTok->
is(tok::l_brace)) {
1776 case tok::kw_requires: {
1778 bool ParsedClause = parseRequires();
1804 case tok::kw_typedef:
1826 case tok::kw_struct:
1828 if (parseStructLike())
1831 case tok::kw_decltype:
1833 if (FormatTok->
is(tok::l_paren)) {
1838 Line->SeenDecltypeAuto =
true;
1846 FormatTok->
is(tok::kw_class)) {
1863 case tok::l_paren: {
1867 if (OpeningBrace || !IsCpp || !
Previous || eof())
1870 Tokens->peekNextToken(
true),
1877 case tok::kw_operator:
1888 while (FormatTok->
is(tok::star))
1892 if (FormatTok->
is(tok::l_paren))
1895 if (FormatTok->
is(tok::l_brace))
1899 if (InRequiresExpression)
1901 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1902 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1920 IsDecltypeAutoFunction =
false;
1938 case tok::identifier: {
1940 Line->MustBeDeclaration) {
1942 parseCSharpGenericTypeConstraint();
1945 if (FormatTok->
is(TT_MacroBlockEnd)) {
1954 size_t TokenCount = Line->Tokens.size();
1958 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1959 tryToParseJSFunction();
1969 unsigned StoredPosition = Tokens->getPosition();
1970 FormatToken *Next = Tokens->getNextToken();
1971 FormatTok = Tokens->setPosition(StoredPosition);
1984 parseVerilogTable();
1996 if (parseStructLike())
2001 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
2002 parseStatementMacro();
2009 FormatToken *PreviousToken = FormatTok;
2017 auto OneTokenSoFar = [&]() {
2018 auto I = Line->Tokens.begin(), E = Line->Tokens.end();
2019 while (I != E && I->Tok->is(tok::comment))
2022 while (I != E && I->Tok->is(tok::hash))
2024 return I != E && (++I == E);
2026 if (OneTokenSoFar()) {
2029 bool FunctionLike = FormatTok->
is(tok::l_paren);
2033 bool FollowedByNewline =
2034 CommentsBeforeNextToken.empty()
2036 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2038 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
2040 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2041 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2050 FormatTok->
is(TT_FatArrow)) {
2051 tryToParseChildBlock();
2056 if (FormatTok->
is(tok::l_brace)) {
2065 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2067 parseBlock(
false, 1u,
2075 FormatTok->
is(tok::less)) {
2077 parseBracedList(
true);
2086 case tok::kw_switch:
2110 case tok::kw_default:
2113 if (FormatTok->
is(tok::colon)) {
2123 parseVerilogCaseLabel();
2130 parseVerilogCaseLabel();
2141 bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2142 assert(FormatTok->
is(tok::l_brace));
2154 unsigned int StoredPosition = Tokens->getPosition();
2155 FormatToken *Tok = Tokens->getNextToken();
2160 bool HasSpecialAccessor =
false;
2161 bool IsTrivialPropertyAccessor =
true;
2163 if (Tok->isOneOf(tok::semi, tok::kw_public, tok::kw_private,
2167 HasSpecialAccessor =
true;
2168 Tok = Tokens->getNextToken();
2171 if (Tok->isNot(tok::r_brace))
2172 IsTrivialPropertyAccessor =
false;
2176 if (!HasSpecialAccessor) {
2177 Tokens->setPosition(StoredPosition);
2183 Tokens->setPosition(StoredPosition);
2191 if (FormatTok->
is(tok::equal)) {
2192 while (!eof() && FormatTok->
isNot(tok::semi))
2205 if (FormatTok->
is(TT_FatArrow)) {
2209 }
while (!eof() && FormatTok->
isNot(tok::semi));
2220 !IsTrivialPropertyAccessor) {
2232 bool UnwrappedLineParser::tryToParseLambda() {
2233 assert(FormatTok->
is(tok::l_square));
2238 FormatToken &LSquare = *FormatTok;
2239 if (!tryToParseLambdaIntroducer())
2242 bool SeenArrow =
false;
2243 bool InTemplateParameterList =
false;
2245 while (FormatTok->
isNot(tok::l_brace)) {
2254 parseParens(TT_PointerOrReference);
2262 InTemplateParameterList =
true;
2267 case tok::kw_template:
2268 case tok::kw_typename:
2272 case tok::kw_constexpr:
2273 case tok::kw_consteval:
2276 case tok::identifier:
2277 case tok::numeric_constant:
2278 case tok::coloncolon:
2279 case tok::kw_mutable:
2280 case tok::kw_noexcept:
2281 case tok::kw_static:
2306 case tok::equalequal:
2307 case tok::exclaimequal:
2308 case tok::greaterequal:
2309 case tok::lessequal:
2315 if (SeenArrow || InTemplateParameterList) {
2328 case tok::kw_requires: {
2329 auto *RequiresToken = FormatTok;
2331 parseRequiresClause(RequiresToken);
2335 if (!InTemplateParameterList)
2345 LSquare.setFinalizedType(TT_LambdaLSquare);
2347 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2349 assert(!NestedLambdas.empty());
2350 NestedLambdas.pop_back();
2355 bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2357 const FormatToken *LeftSquare = FormatTok;
2360 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2361 tok::kw_co_yield, tok::kw_co_return)) ||
2363 LeftSquare->isCppStructuredBinding(IsCpp)) {
2368 if (FormatTok->
is(tok::r_square)) {
2369 const FormatToken *Next = Tokens->peekNextToken(
true);
2370 if (Next->is(tok::greater))
2377 void UnwrappedLineParser::tryToParseJSFunction() {
2385 if (FormatTok->
is(tok::star)) {
2391 if (FormatTok->
is(tok::identifier))
2394 if (FormatTok->
isNot(tok::l_paren))
2400 if (FormatTok->
is(tok::colon)) {
2406 if (FormatTok->
is(tok::l_brace))
2407 tryToParseBracedList();
2409 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2413 if (FormatTok->
is(tok::semi))
2419 bool UnwrappedLineParser::tryToParseBracedList() {
2421 calculateBraceTypes();
2430 bool UnwrappedLineParser::tryToParseChildBlock() {
2432 assert(FormatTok->
is(TT_FatArrow));
2437 if (FormatTok->
isNot(tok::l_brace))
2443 bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2444 assert(!IsAngleBracket || !IsEnum);
2445 bool HasError =
false;
2450 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2451 tryToParseChildBlock()) {
2456 tryToParseJSFunction();
2459 if (FormatTok->
is(tok::l_brace)) {
2461 if (tryToParseBracedList())
2466 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2487 if (FormatTok->
is(tok::l_brace))
2502 parseBracedList(
true);
2536 bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2537 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2538 auto *LeftParen = FormatTok;
2539 bool SeenEqual =
false;
2540 bool MightBeFoldExpr =
false;
2541 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2546 if (parseParens(AmpAmpTokenType))
2552 if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
2554 const auto *Prev = LeftParen->Previous;
2555 const auto *Next = Tokens->peekNextToken();
2556 const bool DoubleParens =
2557 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2558 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2559 const bool Blacklisted =
2561 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2563 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2564 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2565 const bool ReturnParens =
2567 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2568 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2569 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2570 Next->is(tok::semi);
2571 if ((DoubleParens && !Blacklisted) || ReturnParens) {
2572 LeftParen->Optional =
true;
2585 if (!tryToParseBracedList())
2590 if (FormatTok->
is(tok::l_brace)) {
2596 MightBeFoldExpr =
true;
2601 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2602 tryToParseChildBlock();
2612 case tok::identifier:
2614 tryToParseJSFunction();
2618 case tok::kw_switch:
2621 case tok::kw_requires: {
2622 auto RequiresToken = FormatTok;
2624 parseRequiresExpression(RequiresToken);
2628 if (AmpAmpTokenType != TT_Unknown)
2639 void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2640 if (!LambdaIntroducer) {
2641 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2642 if (tryToParseLambda())
2659 case tok::l_brace: {
2660 if (!tryToParseBracedList())
2666 if (FormatTok->
is(tok::l_brace)) {
2678 void UnwrappedLineParser::keepAncestorBraces() {
2682 const int MaxNestingLevels = 2;
2683 const int Size = NestedTooDeep.size();
2684 if (Size >= MaxNestingLevels)
2685 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2686 NestedTooDeep.push_back(
false);
2690 for (
const auto &
Token : llvm::reverse(Line.Tokens))
2697 void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2698 FormatToken *Tok =
nullptr;
2700 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2701 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2704 : Line->Tokens.back().Tok;
2706 if (Tok->BraceCount < 0) {
2707 assert(Tok->BraceCount == -1);
2710 Tok->BraceCount = -1;
2716 parseStructuralElement();
2719 assert(!Line->InPPDirective);
2721 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2723 Tok = L.Tokens.back().Tok;
2731 if (CheckEOF && eof())
2741 assert(LeftBrace->
is(tok::l_brace));
2749 assert(RightBrace->
is(tok::r_brace));
2757 void UnwrappedLineParser::handleAttributes() {
2761 else if (FormatTok->
is(tok::l_square))
2762 handleCppAttributes();
2765 bool UnwrappedLineParser::handleCppAttributes() {
2767 assert(FormatTok->
is(tok::l_square));
2768 if (!tryToParseSimpleAttribute())
2775 bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2779 : Tok.is(tok::l_brace);
2782 FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2784 bool IsVerilogAssert) {
2785 assert((FormatTok->
is(tok::kw_if) ||
2792 if (IsVerilogAssert) {
2796 if (FormatTok->
is(tok::numeric_constant))
2813 if (FormatTok->
is(tok::exclaim))
2816 bool KeepIfBraces =
true;
2817 if (FormatTok->
is(tok::kw_consteval)) {
2821 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2823 if (FormatTok->
is(tok::l_paren)) {
2830 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2836 bool NeedsUnwrappedLine =
false;
2837 keepAncestorBraces();
2839 FormatToken *IfLeftBrace =
nullptr;
2840 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2842 if (isBlockBegin(*FormatTok)) {
2844 IfLeftBrace = FormatTok;
2846 parseBlock(
false, 1u,
2847 true, KeepIfBraces, &IfBlockKind);
2848 setPreviousRBraceType(TT_ControlStatementRBrace);
2852 NeedsUnwrappedLine =
true;
2853 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2856 parseUnbracedBody();
2860 assert(!NestedTooDeep.empty());
2861 KeepIfBraces = KeepIfBraces ||
2862 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2863 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2864 IfBlockKind == IfStmtKind::IfElseIf;
2867 bool KeepElseBraces = KeepIfBraces;
2868 FormatToken *ElseLeftBrace =
nullptr;
2869 IfStmtKind
Kind = IfStmtKind::IfOnly;
2871 if (FormatTok->
is(tok::kw_else)) {
2873 NestedTooDeep.back() =
false;
2874 Kind = IfStmtKind::IfElse;
2878 if (isBlockBegin(*FormatTok)) {
2879 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2881 ElseLeftBrace = FormatTok;
2883 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2884 FormatToken *IfLBrace =
2885 parseBlock(
false, 1u,
2886 true, KeepElseBraces, &ElseBlockKind);
2887 setPreviousRBraceType(TT_ElseRBrace);
2888 if (FormatTok->
is(tok::kw_else)) {
2889 KeepElseBraces = KeepElseBraces ||
2890 ElseBlockKind == IfStmtKind::IfOnly ||
2891 ElseBlockKind == IfStmtKind::IfElseIf;
2892 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2893 KeepElseBraces =
true;
2894 assert(ElseLeftBrace->MatchingParen);
2898 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2899 const FormatToken *
Previous = Tokens->getPreviousToken();
2901 const bool IsPrecededByComment =
Previous->is(tok::comment);
2902 if (IsPrecededByComment) {
2906 bool TooDeep =
true;
2908 Kind = IfStmtKind::IfElseIf;
2909 TooDeep = NestedTooDeep.pop_back_val();
2911 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2913 NestedTooDeep.push_back(TooDeep);
2914 if (IsPrecededByComment)
2917 parseUnbracedBody(
true);
2920 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2921 if (NeedsUnwrappedLine)
2928 assert(!NestedTooDeep.empty());
2929 KeepElseBraces = KeepElseBraces ||
2930 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2931 NestedTooDeep.back();
2933 NestedTooDeep.pop_back();
2935 if (!KeepIfBraces && !KeepElseBraces) {
2938 }
else if (IfLeftBrace) {
2939 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2941 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2942 assert(!IfLeftBrace->Optional);
2943 assert(!IfRightBrace->Optional);
2944 IfLeftBrace->MatchingParen =
nullptr;
2945 IfRightBrace->MatchingParen =
nullptr;
2955 void UnwrappedLineParser::parseTryCatch() {
2956 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2958 bool NeedsUnwrappedLine =
false;
2959 if (FormatTok->
is(tok::colon)) {
2965 while (FormatTok->
is(tok::comma))
2968 while (FormatTok->
is(tok::identifier)) {
2970 if (FormatTok->
is(tok::l_paren))
2973 FormatTok->
is(tok::l_brace)) {
2976 }
while (FormatTok->
isNot(tok::r_brace));
2982 while (FormatTok->
is(tok::comma))
2990 keepAncestorBraces();
2992 if (FormatTok->
is(tok::l_brace)) {
2998 NeedsUnwrappedLine =
true;
2999 }
else if (FormatTok->
isNot(tok::kw_catch)) {
3005 parseStructuralElement();
3009 if (FormatTok->
is(tok::at))
3012 tok::kw___finally) ||
3020 while (FormatTok->
isNot(tok::l_brace)) {
3021 if (FormatTok->
is(tok::l_paren)) {
3027 NestedTooDeep.pop_back();
3032 NeedsUnwrappedLine =
false;
3033 Line->MustBeDeclaration =
false;
3039 NeedsUnwrappedLine =
true;
3043 NestedTooDeep.pop_back();
3045 if (NeedsUnwrappedLine)
3049 void UnwrappedLineParser::parseNamespace() {
3050 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3051 "'namespace' expected");
3053 const FormatToken &InitialToken = *FormatTok;
3055 if (InitialToken.is(TT_NamespaceMacro)) {
3058 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3059 tok::l_square, tok::period, tok::l_paren) ||
3060 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3061 if (FormatTok->
is(tok::l_square))
3063 else if (FormatTok->
is(tok::l_paren))
3069 if (FormatTok->
is(tok::l_brace)) {
3075 unsigned AddLevels =
3078 DeclarationScopeStack.size() > 1)
3081 bool ManageWhitesmithsBraces =
3087 if (ManageWhitesmithsBraces)
3092 parseBlock(
true, AddLevels,
true,
3094 ManageWhitesmithsBraces);
3096 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3098 if (ManageWhitesmithsBraces)
3104 void UnwrappedLineParser::parseNew() {
3105 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3111 if (FormatTok->
is(tok::l_paren))
3115 if (FormatTok->
is(tok::l_brace))
3118 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3131 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3135 if (FormatTok->
is(tok::l_paren)) {
3139 if (FormatTok->
is(tok::l_brace))
3147 void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3148 keepAncestorBraces();
3150 if (isBlockBegin(*FormatTok)) {
3152 FormatToken *LeftBrace = FormatTok;
3154 parseBlock(
false, 1u,
3156 setPreviousRBraceType(TT_ControlStatementRBrace);
3158 assert(!NestedTooDeep.empty());
3159 if (!NestedTooDeep.back())
3165 parseUnbracedBody();
3169 NestedTooDeep.pop_back();
3172 void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3173 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3180 "'for', 'while' or foreach macro expected");
3182 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3188 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3190 if (HasParens && FormatTok->
is(tok::l_paren)) {
3201 parseVerilogSensitivityList();
3203 Tokens->getPreviousToken()->is(tok::r_paren)) {
3210 parseLoopBody(KeepBraces,
true);
3213 void UnwrappedLineParser::parseDoWhile() {
3214 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3220 if (FormatTok->
isNot(tok::kw_while)) {
3233 parseStructuralElement();
3236 void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3238 unsigned OldLineLevel = Line->Level;
3242 else if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3246 FormatTok->
is(tok::l_brace)) {
3252 if (FormatTok->
is(tok::kw_break)) {
3261 parseStructuralElement();
3265 if (FormatTok->
is(tok::semi))
3269 Line->Level = OldLineLevel;
3270 if (FormatTok->
isNot(tok::l_brace)) {
3271 parseStructuralElement();
3276 void UnwrappedLineParser::parseCaseLabel() {
3277 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3278 auto *Case = FormatTok;
3283 if (FormatTok->
is(tok::colon)) {
3289 Case->setFinalizedType(TT_SwitchExpressionLabel);
3296 void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3297 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3299 if (FormatTok->
is(tok::l_paren))
3302 keepAncestorBraces();
3304 if (FormatTok->
is(tok::l_brace)) {
3307 : TT_ControlStatementLBrace);
3312 setPreviousRBraceType(TT_ControlStatementRBrace);
3318 parseStructuralElement();
3323 NestedTooDeep.pop_back();
3333 case tok::caretequal:
3337 case tok::equalequal:
3339 case tok::exclaimequal:
3341 case tok::greaterequal:
3342 case tok::greatergreater:
3343 case tok::greatergreaterequal:
3347 case tok::lessequal:
3349 case tok::lesslessequal:
3351 case tok::minusequal:
3352 case tok::minusminus:
3354 case tok::percentequal:
3357 case tok::pipeequal:
3360 case tok::plusequal:
3368 case tok::slashequal:
3370 case tok::starequal:
3377 void UnwrappedLineParser::parseAccessSpecifier() {
3378 FormatToken *AccessSpecifierCandidate = FormatTok;
3384 if (FormatTok->
is(tok::colon)) {
3387 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3391 }
else if (AccessSpecifierCandidate) {
3393 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3400 bool UnwrappedLineParser::parseRequires() {
3401 assert(FormatTok->
is(tok::kw_requires) &&
"'requires' expected");
3402 auto RequiresToken = FormatTok;
3411 parseRequiresExpression(RequiresToken);
3418 parseRequiresClause(RequiresToken);
3429 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3431 if (!PreviousNonComment ||
3432 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3435 parseRequiresClause(RequiresToken);
3439 switch (PreviousNonComment->Tok.getKind()) {
3442 case tok::kw_noexcept:
3445 parseRequiresClause(RequiresToken);
3455 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3456 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3457 parseRequiresClause(RequiresToken);
3463 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3465 parseRequiresClause(RequiresToken);
3469 parseRequiresExpression(RequiresToken);
3479 unsigned StoredPosition = Tokens->getPosition();
3480 FormatToken *NextToken = Tokens->getNextToken();
3482 auto PeekNext = [&Lookahead, &NextToken,
this] {
3484 NextToken = Tokens->getNextToken();
3487 bool FoundType =
false;
3488 bool LastWasColonColon =
false;
3491 for (; Lookahead < 50; PeekNext()) {
3492 switch (NextToken->Tok.getKind()) {
3493 case tok::kw_volatile:
3496 if (OpenAngles == 0) {
3497 FormatTok = Tokens->setPosition(StoredPosition);
3498 parseRequiresExpression(RequiresToken);
3506 case tok::coloncolon:
3507 LastWasColonColon =
true;
3509 case tok::kw_decltype:
3510 case tok::identifier:
3511 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3512 FormatTok = Tokens->setPosition(StoredPosition);
3513 parseRequiresExpression(RequiresToken);
3517 LastWasColonColon =
false;
3526 if (NextToken->isTypeName(LangOpts)) {
3527 FormatTok = Tokens->setPosition(StoredPosition);
3528 parseRequiresExpression(RequiresToken);
3535 FormatTok = Tokens->setPosition(StoredPosition);
3536 parseRequiresClause(RequiresToken);
3547 void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3549 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3554 bool InRequiresExpression =
3555 !RequiresToken->Previous ||
3556 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3558 RequiresToken->setFinalizedType(InRequiresExpression
3559 ? TT_RequiresClauseInARequiresExpression
3560 : TT_RequiresClause);
3564 parseConstraintExpression();
3566 if (!InRequiresExpression)
3577 void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3579 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3581 RequiresToken->setFinalizedType(TT_RequiresExpression);
3583 if (FormatTok->
is(tok::l_paren)) {
3588 if (FormatTok->
is(tok::l_brace)) {
3598 void UnwrappedLineParser::parseConstraintExpression() {
3605 bool LambdaNextTimeAllowed =
true;
3615 bool TopLevelParensAllowed =
true;
3618 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3621 case tok::kw_requires: {
3622 auto RequiresToken = FormatTok;
3624 parseRequiresExpression(RequiresToken);
3629 if (!TopLevelParensAllowed)
3631 parseParens(TT_BinaryOperator);
3632 TopLevelParensAllowed =
false;
3636 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3643 case tok::kw_struct:
3655 LambdaNextTimeAllowed =
true;
3656 TopLevelParensAllowed =
true;
3661 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3665 case tok::kw_sizeof:
3667 case tok::greaterequal:
3668 case tok::greatergreater:
3670 case tok::lessequal:
3672 case tok::equalequal:
3674 case tok::exclaimequal:
3679 LambdaNextTimeAllowed =
true;
3680 TopLevelParensAllowed =
true;
3685 case tok::numeric_constant:
3686 case tok::coloncolon:
3689 TopLevelParensAllowed =
false;
3694 case tok::kw_static_cast:
3695 case tok::kw_const_cast:
3696 case tok::kw_reinterpret_cast:
3697 case tok::kw_dynamic_cast:
3699 if (FormatTok->
isNot(tok::less))
3703 parseBracedList(
true);
3719 case tok::coloncolon:
3723 case tok::kw_requires:
3732 if (FormatTok->
is(tok::less)) {
3734 parseBracedList(
true);
3736 TopLevelParensAllowed =
false;
3742 bool UnwrappedLineParser::parseEnum() {
3743 const FormatToken &InitialToken = *FormatTok;
3746 if (FormatTok->
is(tok::kw_enum))
3761 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3763 while (FormatTok->
is(tok::l_square))
3764 if (!handleCppAttributes())
3769 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3770 tok::greater, tok::comma, tok::question,
3776 while (FormatTok->
is(tok::l_square))
3782 if (FormatTok->
is(tok::l_paren))
3784 if (FormatTok->
is(tok::identifier)) {
3788 if (IsCpp && FormatTok->
is(tok::identifier))
3794 if (FormatTok->
isNot(tok::l_brace))
3801 parseJavaEnumBody();
3819 bool HasError = !parseBracedList(
false,
true);
3823 if (FormatTok->
is(tok::semi))
3827 setPreviousRBraceType(TT_EnumRBrace);
3835 bool UnwrappedLineParser::parseStructLike() {
3842 if (FormatTok->
is(tok::semi))
3853 class ScopedTokenPosition {
3854 unsigned StoredPosition;
3855 FormatTokenSource *Tokens;
3858 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3859 assert(Tokens &&
"Tokens expected to not be null");
3860 StoredPosition = Tokens->getPosition();
3863 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3869 bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3870 ScopedTokenPosition AutoPosition(Tokens);
3871 FormatToken *Tok = Tokens->getNextToken();
3873 if (Tok->isNot(tok::l_square))
3878 if (Tok->is(tok::r_square))
3880 Tok = Tokens->getNextToken();
3884 Tok = Tokens->getNextToken();
3885 if (Tok->isNot(tok::r_square))
3887 Tok = Tokens->getNextToken();
3888 if (Tok->is(tok::semi))
3893 void UnwrappedLineParser::parseJavaEnumBody() {
3894 assert(FormatTok->
is(tok::l_brace));
3895 const FormatToken *OpeningBrace = FormatTok;
3900 unsigned StoredPosition = Tokens->getPosition();
3901 bool IsSimple =
true;
3902 FormatToken *Tok = Tokens->getNextToken();
3904 if (Tok->is(tok::r_brace))
3906 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3912 Tok = Tokens->getNextToken();
3914 FormatTok = Tokens->setPosition(StoredPosition);
3931 if (FormatTok->
is(tok::l_brace)) {
3933 parseBlock(
true, 1u,
3935 }
else if (FormatTok->
is(tok::l_paren)) {
3937 }
else if (FormatTok->
is(tok::comma)) {
3940 }
else if (FormatTok->
is(tok::semi)) {
3944 }
else if (FormatTok->
is(tok::r_brace)) {
3953 parseLevel(OpeningBrace);
3959 void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
3960 const FormatToken &InitialToken = *FormatTok;
3963 const FormatToken *ClassName =
nullptr;
3964 bool IsDerived =
false;
3965 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
3966 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
3971 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3972 tok::kw_alignas, tok::l_square) ||
3975 FormatTok->
isOneOf(tok::period, tok::comma))) {
3982 if (FormatTok->
is(tok::l_brace)) {
3983 tryToParseBracedList();
3987 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
3994 if (!IsNonMacroIdentifier(
Previous) ||
3996 Previous->Previous == &InitialToken) {
4000 case tok::coloncolon:
4003 if (!ClassName &&
Previous->is(tok::identifier))
4008 auto IsListInitialization = [&] {
4009 if (!ClassName || IsDerived)
4011 assert(FormatTok->
is(tok::l_brace));
4014 return Prev != ClassName && Prev->is(tok::identifier) &&
4015 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
4018 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
4019 int AngleNestingLevel = 0;
4021 if (FormatTok->
is(tok::less))
4022 ++AngleNestingLevel;
4023 else if (FormatTok->
is(tok::greater))
4024 --AngleNestingLevel;
4026 if (AngleNestingLevel == 0) {
4027 if (FormatTok->
is(tok::colon)) {
4029 }
else if (FormatTok->
is(tok::l_paren) &&
4030 IsNonMacroIdentifier(FormatTok->
Previous)) {
4034 if (FormatTok->
is(tok::l_brace)) {
4035 if (AngleNestingLevel == 0 && IsListInitialization())
4037 calculateBraceTypes(
true);
4038 if (!tryToParseBracedList())
4041 if (FormatTok->
is(tok::l_square)) {
4044 !
Previous->isTypeOrIdentifier(LangOpts))) {
4047 if (!tryToParseLambda())
4054 if (FormatTok->
is(tok::semi))
4059 parseCSharpGenericTypeConstraint();
4066 auto GetBraceTypes =
4067 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4068 switch (RecordTok.Tok.getKind()) {
4070 return {TT_ClassLBrace, TT_ClassRBrace};
4071 case tok::kw_struct:
4072 return {TT_StructLBrace, TT_StructRBrace};
4074 return {TT_UnionLBrace, TT_UnionRBrace};
4077 return {TT_RecordLBrace, TT_RecordRBrace};
4080 if (FormatTok->
is(tok::l_brace)) {
4081 if (IsListInitialization())
4083 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4092 parseBlock(
true, AddLevels,
false);
4094 setPreviousRBraceType(ClosingBraceType);
4101 void UnwrappedLineParser::parseObjCMethod() {
4102 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4103 "'(' or identifier expected.");
4105 if (FormatTok->
is(tok::semi)) {
4109 }
else if (FormatTok->
is(tok::l_brace)) {
4121 void UnwrappedLineParser::parseObjCProtocolList() {
4122 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4126 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4130 }
while (!eof() && FormatTok->
isNot(tok::greater));
4134 void UnwrappedLineParser::parseObjCUntilAtEnd() {
4141 if (FormatTok->
is(tok::l_brace)) {
4145 }
else if (FormatTok->
is(tok::r_brace)) {
4149 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4153 parseStructuralElement();
4158 void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4166 if (FormatTok->
is(tok::less))
4167 parseObjCLightweightGenerics();
4168 if (FormatTok->
is(tok::colon)) {
4172 if (FormatTok->
is(tok::less))
4173 parseObjCLightweightGenerics();
4174 }
else if (FormatTok->
is(tok::l_paren)) {
4179 if (FormatTok->
is(tok::less))
4180 parseObjCProtocolList();
4182 if (FormatTok->
is(tok::l_brace)) {
4192 parseObjCUntilAtEnd();
4195 void UnwrappedLineParser::parseObjCLightweightGenerics() {
4196 assert(FormatTok->
is(tok::less));
4204 unsigned NumOpenAngles = 1;
4208 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4212 if (FormatTok->
is(tok::less)) {
4214 }
else if (FormatTok->
is(tok::greater)) {
4215 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4218 }
while (!eof() && NumOpenAngles != 0);
4224 bool UnwrappedLineParser::parseObjCProtocol() {
4228 if (FormatTok->
is(tok::l_paren)) {
4240 if (FormatTok->
is(tok::less))
4241 parseObjCProtocolList();
4244 if (FormatTok->
is(tok::semi)) {
4251 parseObjCUntilAtEnd();
4255 void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4256 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4257 assert(IsImport || FormatTok->
is(tok::kw_export));
4261 if (FormatTok->
is(tok::kw_default))
4278 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4281 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4286 if (FormatTok->
is(tok::semi))
4288 if (Line->Tokens.empty()) {
4293 if (FormatTok->
is(tok::l_brace)) {
4303 void UnwrappedLineParser::parseStatementMacro() {
4305 if (FormatTok->
is(tok::l_paren))
4307 if (FormatTok->
is(tok::semi))
4312 void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4315 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4316 tok::coloncolon, tok::hash) ||
4319 }
else if (FormatTok->
is(tok::l_square)) {
4327 void UnwrappedLineParser::parseVerilogSensitivityList() {
4328 if (FormatTok->
isNot(tok::at))
4332 if (FormatTok->
is(tok::at))
4342 parseVerilogHierarchyIdentifier();
4347 unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4348 unsigned AddLevels = 0;
4354 parseVerilogSensitivityList();
4355 if (FormatTok->
is(tok::semi))
4363 if (FormatTok->
is(tok::l_paren)) {
4376 if (FormatTok->
is(tok::l_square)) {
4391 Line->IsContinuation =
true;
4398 parseVerilogHierarchyIdentifier();
4399 if (FormatTok->
is(tok::semi))
4407 if (FormatTok->
is(tok::l_paren)) {
4412 if (FormatTok->
is(tok::l_paren)) {
4422 parseVerilogHierarchyIdentifier();
4423 if (FormatTok->
is(tok::l_paren))
4430 parseVerilogHierarchyIdentifier();
4431 }
while (FormatTok->
is(tok::comma));
4435 if (FormatTok->
is(tok::at)) {
4437 parseVerilogSensitivityList();
4440 if (FormatTok->
is(tok::semi))
4448 void UnwrappedLineParser::parseVerilogTable() {
4453 auto InitialLevel = Line->Level++;
4455 FormatToken *Tok = FormatTok;
4457 if (Tok->is(tok::semi))
4459 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4460 Tok->setFinalizedType(TT_VerilogTableItem);
4462 Line->Level = InitialLevel;
4467 void UnwrappedLineParser::parseVerilogCaseLabel() {
4473 auto OrigLevel = Line->Level;
4474 auto FirstLine = CurrentLines->size();
4475 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4479 parseStructuralElement();
4482 if (CurrentLines->size() > FirstLine)
4483 (*CurrentLines)[FirstLine].Level = OrigLevel;
4484 Line->Level = OrigLevel;
4487 bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &Line)
const {
4488 for (
const auto &N : Line.Tokens) {
4489 if (N.Tok->MacroCtx)
4491 for (
const UnwrappedLine &Child : N.Children)
4492 if (containsExpansion(Child))
4498 void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4499 if (Line->Tokens.empty())
4502 if (!parsingPPDirective()) {
4503 llvm::dbgs() <<
"Adding unwrapped line:\n";
4504 printDebugInfo(*Line);
4512 bool ClosesWhitesmithsBlock =
4519 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4521 Reconstruct.emplace(Line->Level, Unexpanded);
4522 Reconstruct->addLine(*Line);
4527 CurrentExpandedLines.push_back(std::move(*Line));
4529 if (Reconstruct->finished()) {
4530 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4531 assert(!Reconstructed.Tokens.empty() &&
4532 "Reconstructed must at least contain the macro identifier.");
4533 assert(!parsingPPDirective());
4535 llvm::dbgs() <<
"Adding unexpanded line:\n";
4536 printDebugInfo(Reconstructed);
4538 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4539 Lines.push_back(std::move(Reconstructed));
4540 CurrentExpandedLines.clear();
4541 Reconstruct.reset();
4546 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4547 CurrentLines->push_back(std::move(*Line));
4549 Line->Tokens.clear();
4551 Line->FirstStartColumn = 0;
4552 Line->IsContinuation =
false;
4553 Line->SeenDecltypeAuto =
false;
4555 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4557 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4558 CurrentLines->append(
4559 std::make_move_iterator(PreprocessorDirectives.begin()),
4560 std::make_move_iterator(PreprocessorDirectives.end()));
4561 PreprocessorDirectives.clear();
4567 bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(
tok::eof); }
4569 bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4570 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4571 FormatTok.NewlinesBefore > 0;
4579 const llvm::Regex &CommentPragmasRegex) {
4580 if (Line.Tokens.empty())
4583 StringRef IndentContent = FormatTok.
TokenText;
4584 if (FormatTok.
TokenText.starts_with(
"//") ||
4585 FormatTok.
TokenText.starts_with(
"/*")) {
4586 IndentContent = FormatTok.
TokenText.substr(2);
4588 if (CommentPragmasRegex.match(IndentContent))
4657 const FormatToken *MinColumnToken = Line.Tokens.front().Tok;
4663 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4665 MinColumnToken = PreviousToken;
4668 PreviousToken =
Node.Tok;
4671 if (
Node.Tok->NewlinesBefore > 0)
4672 MinColumnToken =
Node.Tok;
4674 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4675 MinColumnToken = PreviousToken;
4681 void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4682 bool JustComments = Line->Tokens.empty();
4683 for (FormatToken *Tok : CommentsBeforeNextToken) {
4692 Tok->ContinuesLineCommentSection =
4694 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4698 if (NewlineBeforeNext && JustComments)
4700 CommentsBeforeNextToken.clear();
4703 void UnwrappedLineParser::nextToken(
int LevelDifference) {
4706 flushComments(isOnNewLine(*FormatTok));
4707 pushToken(FormatTok);
4710 readToken(LevelDifference);
4712 readTokenWithJavaScriptASI();
4722 FormatTok->Tok.setKind(tok::r_brace);
4726 void UnwrappedLineParser::distributeComments(
4727 const SmallVectorImpl<FormatToken *> &Comments,
4728 const FormatToken *NextTok) {
4747 if (Comments.empty())
4749 bool ShouldPushCommentsInCurrentLine =
true;
4750 bool HasTrailAlignedWithNextToken =
false;
4751 unsigned StartOfTrailAlignedWithNextToken = 0;
4754 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4755 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4756 HasTrailAlignedWithNextToken =
true;
4757 StartOfTrailAlignedWithNextToken = i;
4761 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4762 FormatToken *FormatTok = Comments[i];
4763 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4764 FormatTok->ContinuesLineCommentSection =
false;
4766 FormatTok->ContinuesLineCommentSection =
4769 if (!FormatTok->ContinuesLineCommentSection &&
4770 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4771 ShouldPushCommentsInCurrentLine =
false;
4773 if (ShouldPushCommentsInCurrentLine)
4774 pushToken(FormatTok);
4776 CommentsBeforeNextToken.push_back(FormatTok);
4780 void UnwrappedLineParser::readToken(
int LevelDifference) {
4781 SmallVector<FormatToken *, 1> Comments;
4782 bool PreviousWasComment =
false;
4783 bool FirstNonCommentOnLine =
false;
4785 FormatTok = Tokens->getNextToken();
4787 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4788 TT_ConflictAlternative)) {
4789 if (FormatTok->is(TT_ConflictStart))
4790 conditionalCompilationStart(
false);
4791 else if (FormatTok->is(TT_ConflictAlternative))
4792 conditionalCompilationAlternative();
4793 else if (FormatTok->is(TT_ConflictEnd))
4794 conditionalCompilationEnd();
4795 FormatTok = Tokens->getNextToken();
4796 FormatTok->MustBreakBefore =
true;
4797 FormatTok->MustBreakBeforeFinalized =
true;
4800 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4801 const FormatToken &Tok,
4802 bool PreviousWasComment) {
4803 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4804 return Tok.HasUnescapedNewline || Tok.IsFirst;
4809 if (PreviousWasComment)
4810 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4811 return IsFirstOnLine(Tok);
4814 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4815 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4816 PreviousWasComment = FormatTok->is(tok::comment);
4818 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4821 FirstNonCommentOnLine) {
4822 distributeComments(Comments, FormatTok);
4826 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4828 assert((LevelDifference >= 0 ||
4829 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4830 "LevelDifference makes Line->Level negative");
4831 Line->Level += LevelDifference;
4836 PPBranchLevel > 0) {
4837 Line->Level += PPBranchLevel;
4839 flushComments(isOnNewLine(*FormatTok));
4841 PreviousWasComment = FormatTok->is(tok::comment);
4842 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4843 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4846 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4847 !Line->InPPDirective) {
4851 if (FormatTok->is(tok::identifier) &&
4852 Macros.
defined(FormatTok->TokenText) &&
4854 !Line->InPPDirective) {
4855 FormatToken *
ID = FormatTok;
4856 unsigned Position = Tokens->getPosition();
4860 auto PreCall = std::move(Line);
4861 Line.reset(
new UnwrappedLine);
4862 bool OldInExpansion = InExpansion;
4865 auto Args = parseMacroCall();
4866 InExpansion = OldInExpansion;
4867 assert(Line->Tokens.front().Tok ==
ID);
4869 auto UnexpandedLine = std::move(Line);
4871 Line = std::move(PreCall);
4874 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4876 llvm::dbgs() <<
"(";
4877 for (
const auto &Arg : Args.value())
4878 for (
const auto &
T : Arg)
4879 llvm::dbgs() <<
T->TokenText <<
" ";
4880 llvm::dbgs() <<
")";
4882 llvm::dbgs() <<
"\n";
4885 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4891 LLVM_DEBUG(llvm::dbgs()
4892 <<
"Macro \"" <<
ID->TokenText
4893 <<
"\" not overloaded for arity " << Args->size()
4894 <<
"or not function-like, using object-like overload.");
4896 UnexpandedLine->Tokens.resize(1);
4897 Tokens->setPosition(Position);
4902 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4905 Unexpanded[
ID] = std::move(UnexpandedLine);
4906 SmallVector<FormatToken *, 8> Expansion =
4907 Macros.
expand(
ID, std::move(Args));
4908 if (!Expansion.empty())
4909 FormatTok = Tokens->insertTokens(Expansion);
4912 llvm::dbgs() <<
"Expanded: ";
4913 for (
const auto &
T : Expansion)
4914 llvm::dbgs() <<
T->TokenText <<
" ";
4915 llvm::dbgs() <<
"\n";
4919 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4920 <<
"\", because it was used ";
4922 llvm::dbgs() <<
"with " << Args->size();
4924 llvm::dbgs() <<
"without";
4925 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4927 Tokens->setPosition(Position);
4932 if (FormatTok->isNot(tok::comment)) {
4933 distributeComments(Comments, FormatTok);
4938 Comments.push_back(FormatTok);
4941 distributeComments(Comments,
nullptr);
4946 template <
typename Iterator>
4947 void pushTokens(Iterator
Begin, Iterator
End,
4949 for (
auto I =
Begin; I !=
End; ++I) {
4950 Into.push_back(I->Tok);
4951 for (
const auto &Child : I->Children)
4952 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
4957 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
4958 UnwrappedLineParser::parseMacroCall() {
4959 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
4960 assert(Line->Tokens.empty());
4962 if (FormatTok->isNot(tok::l_paren))
4964 unsigned Position = Tokens->getPosition();
4965 FormatToken *Tok = FormatTok;
4968 auto ArgStart = std::prev(Line->Tokens.end());
4972 switch (FormatTok->Tok.getKind()) {
4977 case tok::r_paren: {
4983 Args->push_back({});
4984 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4993 Args->push_back({});
4994 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4996 ArgStart = std::prev(Line->Tokens.end());
5004 Line->Tokens.resize(1);
5005 Tokens->setPosition(Position);
5010 void UnwrappedLineParser::pushToken(FormatToken *Tok) {
5011 Line->Tokens.push_back(UnwrappedLineNode(Tok));
5012 if (MustBreakBeforeNextToken) {
5013 Line->Tokens.back().Tok->MustBreakBefore =
true;
5014 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
5015 MustBreakBeforeNextToken =
false;
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.
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
IdentifierInfo * getIdentifierInfo() 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.