18#include "llvm/Support/raw_os_ostream.h"
20#define DEBUG_TYPE "format-parser"
27void printLine(llvm::raw_ostream &OS,
const UnwrappedLine &
Line,
28 StringRef Prefix =
"",
bool PrintText =
false) {
29 OS << Prefix <<
"Line(" <<
Line.Level <<
", FSC=" <<
Line.FirstStartColumn
30 <<
")" << (
Line.InPPDirective ?
" MACRO" :
"") <<
": ";
32 for (std::list<UnwrappedLineNode>::const_iterator I =
Line.Tokens.begin(),
33 E =
Line.Tokens.end();
39 OS << I->Tok->Tok.getName() <<
"[" <<
"T=" << (
unsigned)I->Tok->getType()
40 <<
", OC=" << I->Tok->OriginalColumn <<
", \"" << I->Tok->TokenText
42 for (SmallVectorImpl<UnwrappedLine>::const_iterator
43 CI = I->Children.begin(),
44 CE = I->Children.end();
47 printLine(OS, *CI, (Prefix +
" ").str());
55LLVM_ATTRIBUTE_UNUSED
static void printDebugInfo(
const UnwrappedLine &
Line) {
56 printLine(llvm::dbgs(),
Line);
59class ScopedDeclarationState {
61 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
62 bool MustBeDeclaration)
63 : Line(Line), Stack(Stack) {
64 Line.MustBeDeclaration = MustBeDeclaration;
65 Stack.push_back(MustBeDeclaration);
67 ~ScopedDeclarationState() {
70 Line.MustBeDeclaration = Stack.back();
72 Line.MustBeDeclaration =
true;
77 llvm::BitVector &Stack;
83 llvm::raw_os_ostream OS(Stream);
91 bool SwitchToPreprocessorLines =
false)
93 if (SwitchToPreprocessorLines)
95 else if (!
Parser.Line->Tokens.empty())
96 Parser.CurrentLines = &
Parser.Line->Tokens.back().Children;
97 PreBlockLine = std::move(
Parser.Line);
98 Parser.Line = std::make_unique<UnwrappedLine>();
99 Parser.Line->Level = PreBlockLine->Level;
100 Parser.Line->PPLevel = PreBlockLine->PPLevel;
101 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
102 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
106 if (!
Parser.Line->Tokens.empty())
107 Parser.addUnwrappedLine();
108 assert(
Parser.Line->Tokens.empty());
109 Parser.Line = std::move(PreBlockLine);
110 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
111 Parser.MustBreakBeforeNextToken =
true;
112 Parser.CurrentLines = OriginalLines;
118 std::unique_ptr<UnwrappedLine> PreBlockLine;
127 Style.BraceWrapping.AfterControlStatement,
128 Style.BraceWrapping.IndentBraces) {}
130 bool WrapBrace,
bool IndentBrace)
131 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
133 Parser->addUnwrappedLine();
141 unsigned OldLineLevel;
148 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
151 CurrentLines(&Lines), Style(Style), Keywords(Keywords),
152 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
153 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
154 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
157 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
158 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {
159 assert(
IsCpp == Style.isCpp());
162void UnwrappedLineParser::reset() {
167 IncludeGuardToken =
nullptr;
169 CommentsBeforeNextToken.clear();
171 MustBreakBeforeNextToken =
false;
172 IsDecltypeAutoFunction =
false;
173 PreprocessorDirectives.clear();
174 CurrentLines = &Lines;
175 DeclarationScopeStack.clear();
176 NestedTooDeep.clear();
177 NestedLambdas.clear();
179 Line->FirstStartColumn = FirstStartColumn;
181 if (!Unexpanded.empty())
183 Token->MacroCtx.reset();
184 CurrentExpandedLines.clear();
185 ExpandedLines.clear();
193 Line->FirstStartColumn = FirstStartColumn;
195 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
197 Tokens = &TokenSource;
205 if (IncludeGuard == IG_Found) {
206 for (
auto &Line : Lines)
207 if (Line.InPPDirective && Line.Level > 0)
213 pushToken(FormatTok);
218 if (!ExpandedLines.empty()) {
219 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
220 for (
const auto &Line : Lines) {
221 if (!Line.Tokens.empty()) {
222 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
223 if (it != ExpandedLines.end()) {
224 for (
const auto &Expanded : it->second) {
225 LLVM_DEBUG(printDebugInfo(Expanded));
231 LLVM_DEBUG(printDebugInfo(Line));
237 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
239 LLVM_DEBUG(printDebugInfo(Line));
244 while (!PPLevelBranchIndex.empty() &&
245 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
246 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
247 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
249 if (!PPLevelBranchIndex.empty()) {
250 ++PPLevelBranchIndex.back();
251 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
252 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
254 }
while (!PPLevelBranchIndex.empty());
257void UnwrappedLineParser::parseFile() {
260 bool MustBeDeclaration = !Line->InPPDirective && !Style.
isJavaScript();
261 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
278 !CommentsBeforeNextToken.empty()) {
285void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
294 parseCSharpGenericTypeConstraint();
303void UnwrappedLineParser::parseCSharpAttribute() {
304 int UnpairedSquareBrackets = 1;
309 --UnpairedSquareBrackets;
310 if (UnpairedSquareBrackets == 0) {
316 ++UnpairedSquareBrackets;
326bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
327 if (!Lines.empty() && Lines.back().InPPDirective)
341bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
343 FormatToken **IfLeftBrace) {
344 const bool InRequiresExpression =
345 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
346 const bool IsPrecededByCommentOrPPDirective =
348 FormatToken *IfLBrace =
nullptr;
349 bool HasDoWhile =
false;
350 bool HasLabel =
false;
351 unsigned StatementCount = 0;
352 bool SwitchLabelEncountered =
false;
360 if (FormatTok->
getType() == TT_MacroBlockBegin)
362 else if (FormatTok->
getType() == TT_MacroBlockEnd)
365 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
366 &HasLabel, &StatementCount] {
367 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
368 HasDoWhile ?
nullptr : &HasDoWhile,
369 HasLabel ?
nullptr : &HasLabel);
371 assert(StatementCount > 0 &&
"StatementCount overflow!");
380 if (InRequiresExpression) {
389 if (!InRequiresExpression && FormatTok->
isNot(TT_MacroBlockBegin) &&
390 tryToParseBracedList()) {
395 assert(StatementCount > 0 &&
"StatementCount overflow!");
401 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
404 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
405 HasDoWhile || IsPrecededByCommentOrPPDirective ||
406 precededByCommentOrPPDirective()) {
410 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
413 *IfLeftBrace = IfLBrace;
419 case tok::kw_default: {
425 }
while (Next->is(tok::comment));
427 if (Next->isNot(tok::colon)) {
430 parseStructuralElement();
446 if (!SwitchLabelEncountered &&
448 (Line->InPPDirective && Line->Level == 1))) {
451 SwitchLabelEncountered =
true;
452 parseStructuralElement();
457 parseCSharpAttribute();
460 if (handleCppAttributes())
472void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
478 FormatToken *Tok = FormatTok;
479 const FormatToken *PrevTok = Tok->
Previous;
485 const FormatToken *PrevTok;
487 SmallVector<StackEntry, 8> LBraceStack;
488 assert(Tok->is(tok::l_brace));
491 FormatToken *NextTok;
494 }
while (NextTok->is(tok::comment));
497 while (NextTok->is(tok::hash) && !Line->InMacroBody) {
501 }
while (NextTok->is(tok::comment) ||
502 (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof)));
506 switch (Tok->Tok.getKind()) {
509 if (PrevTok->isOneOf(tok::colon, tok::less)) {
520 }
else if (PrevTok->is(tok::r_paren)) {
527 LBraceStack.push_back({Tok, PrevTok});
530 if (LBraceStack.empty())
533 bool ProbablyBracedList =
false;
535 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
540 while (NextTok->is(tok::hash)) {
541 ScopedMacroState MacroState(*Line, Tokens, NextTok);
544 }
while (NextTok->isNot(tok::eof));
549 bool NextIsObjCMethod = NextTok->
isOneOf(tok::plus, tok::minus) &&
550 NextTok->OriginalColumn == 0;
560 ProbablyBracedList = LBraceStack.back().Tok->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);
606 if (ProbablyBracedList) {
611 LBraceStack.back().Tok->setBlockKind(
BK_Block);
614 LBraceStack.pop_back();
616 case tok::identifier:
617 if (Tok->isNot(TT_StatementMacro))
628 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
629 LBraceStack.back().Tok->setBlockKind(
BK_Block);
636 }
while (Tok->isNot(tok::eof) && !LBraceStack.empty());
639 for (
const auto &Entry : LBraceStack)
647void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
649 Prev && Prev->
is(tok::r_brace)) {
657 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
660size_t UnwrappedLineParser::computePPHash()
const {
662 for (
const auto &i : PPStack) {
673bool UnwrappedLineParser::mightFitOnOneLine(
674 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
676 if (ColumnLimit == 0)
679 auto &Tokens = ParsedLine.Tokens;
680 assert(!Tokens.empty());
682 const auto *LastToken = Tokens.back().Tok;
685 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
688 for (
const auto &Token : Tokens) {
690 auto &SavedToken = SavedTokens[Index++];
691 SavedToken.Tok =
new FormatToken;
692 SavedToken.Tok->copyFrom(*Token.Tok);
693 SavedToken.Children = std::move(Token.Children);
696 AnnotatedLine Line(ParsedLine);
697 assert(Line.Last == LastToken);
699 TokenAnnotator Annotator(Style, Keywords);
700 Annotator.annotate(Line);
701 Annotator.calculateFormattingInformation(Line);
703 auto Length = LastToken->TotalLength;
705 assert(OpeningBrace != Tokens.front().Tok);
706 if (
auto Prev = OpeningBrace->Previous;
707 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
708 Length -= ColumnLimit;
710 Length -= OpeningBrace->TokenText.size() + 1;
713 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
714 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
715 Length -= FirstToken->TokenText.size() + 1;
719 for (
auto &Token : Tokens) {
720 const auto &SavedToken = SavedTokens[Index++];
721 Token.Tok->copyFrom(*SavedToken.Tok);
722 Token.Children = std::move(SavedToken.Children);
723 delete SavedToken.Tok;
727 assert(!Line.InMacroBody);
728 assert(!Line.InPPDirective);
729 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
732FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
733 unsigned AddLevels,
bool MunchSemi,
736 bool UnindentWhitesmithsBraces) {
737 auto HandleVerilogBlockLabel = [
this]() {
739 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
748 const bool VerilogHierarchy =
750 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
753 "'{' or macro block token expected");
754 FormatToken *Tok = FormatTok;
755 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
756 auto Index = CurrentLines->size();
757 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
762 if (!VerilogHierarchy && AddLevels > 0 &&
767 size_t PPStartHash = computePPHash();
769 const unsigned InitialLevel = Line->Level;
770 if (VerilogHierarchy) {
771 AddLevels += parseVerilogHierarchyHeader();
773 nextToken(AddLevels);
774 HandleVerilogBlockLabel();
778 if (Line->Level > 300)
781 if (MacroBlock && FormatTok->
is(tok::l_paren))
784 size_t NbPreprocessorDirectives =
785 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
787 size_t OpeningLineIndex =
788 CurrentLines->empty()
790 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
795 if (UnindentWhitesmithsBraces)
798 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
801 Line->Level += AddLevels;
803 FormatToken *IfLBrace =
nullptr;
804 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
809 if (MacroBlock ? FormatTok->
isNot(TT_MacroBlockEnd)
810 : FormatTok->
isNot(tok::r_brace)) {
811 Line->Level = InitialLevel;
816 if (FormatTok->
is(tok::r_brace) && Tok->is(TT_NamespaceLBrace))
819 const bool IsFunctionRBrace =
820 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
822 auto RemoveBraces = [=]()
mutable {
825 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
826 assert(FormatTok->
is(tok::r_brace));
827 const bool WrappedOpeningBrace = !Tok->Previous;
828 if (WrappedOpeningBrace && FollowedByComment)
830 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
831 if (KeepBraces && !HasRequiredIfBraces)
833 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
834 const FormatToken *
Previous = Tokens->getPreviousToken();
839 assert(!CurrentLines->empty());
840 auto &LastLine = CurrentLines->back();
841 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
843 if (Tok->is(TT_ElseLBrace))
845 if (WrappedOpeningBrace) {
850 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
852 if (RemoveBraces()) {
853 Tok->MatchingParen = FormatTok;
857 size_t PPEndHash = computePPHash();
860 nextToken(-AddLevels);
866 while (FormatTok->
is(tok::semi)) {
872 HandleVerilogBlockLabel();
874 if (MacroBlock && FormatTok->
is(tok::l_paren))
877 Line->Level = InitialLevel;
879 if (FormatTok->
is(tok::kw_noexcept)) {
884 if (FormatTok->
is(tok::arrow)) {
888 parseStructuralElement();
891 if (MunchSemi && FormatTok->
is(tok::semi))
894 if (PPStartHash == PPEndHash) {
895 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
898 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
899 CurrentLines->size() - 1;
909 if (
Line.Tokens.size() < 4)
911 auto I =
Line.Tokens.begin();
912 if (I->Tok->TokenText !=
"goog")
915 if (I->Tok->isNot(tok::period))
918 if (I->Tok->TokenText !=
"scope")
921 return I->Tok->is(tok::l_paren);
930 if (
Line.Tokens.size() < 3)
932 auto I =
Line.Tokens.begin();
933 if (I->Tok->isNot(tok::l_paren))
939 return I->Tok->is(tok::l_paren);
945 if (InitialToken.
is(TT_NamespaceMacro))
946 Kind = tok::kw_namespace;
949 case tok::kw_namespace:
964void UnwrappedLineParser::parseChildBlock() {
965 assert(FormatTok->
is(tok::l_brace));
967 const FormatToken *OpeningBrace = FormatTok;
973 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
975 Line->Level += SkipIndent ? 0 : 1;
976 parseLevel(OpeningBrace);
977 flushComments(isOnNewLine(*FormatTok));
978 Line->Level -= SkipIndent ? 0 : 1;
983void UnwrappedLineParser::parsePPDirective() {
984 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
985 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
1002 case tok::pp_ifndef:
1006 case tok::pp_elifdef:
1007 case tok::pp_elifndef:
1014 case tok::pp_pragma:
1023void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1024 size_t Line = CurrentLines->size();
1025 if (CurrentLines == &PreprocessorDirectives)
1026 Line += Lines.size();
1029 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1030 PPStack.push_back({PP_Unreachable, Line});
1032 PPStack.push_back({PP_Conditional, Line});
1036void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1038 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1039 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1040 PPLevelBranchIndex.push_back(0);
1041 PPLevelBranchCount.push_back(0);
1043 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1044 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1045 conditionalCompilationCondition(Unreachable || Skip);
1048void UnwrappedLineParser::conditionalCompilationAlternative() {
1049 if (!PPStack.empty())
1051 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1052 if (!PPChainBranchIndex.empty())
1053 ++PPChainBranchIndex.top();
1054 conditionalCompilationCondition(
1055 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1056 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1059void UnwrappedLineParser::conditionalCompilationEnd() {
1060 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1061 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1062 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1063 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1066 if (PPBranchLevel > -1)
1068 if (!PPChainBranchIndex.empty())
1069 PPChainBranchIndex.pop();
1070 if (!PPStack.empty())
1074void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1075 bool IfNDef = FormatTok->
is(tok::pp_ifndef);
1077 bool Unreachable =
false;
1078 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1080 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1082 conditionalCompilationStart(Unreachable);
1083 FormatToken *IfCondition = FormatTok;
1086 bool MaybeIncludeGuard = IfNDef;
1087 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1088 for (
auto &Line : Lines) {
1089 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1090 MaybeIncludeGuard =
false;
1091 IncludeGuard = IG_Rejected;
1099 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1100 IncludeGuard = IG_IfNdefed;
1101 IncludeGuardToken = IfCondition;
1105void UnwrappedLineParser::parsePPElse() {
1107 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1108 IncludeGuard = IG_Rejected;
1110 assert(PPBranchLevel >= -1);
1111 if (PPBranchLevel == -1)
1112 conditionalCompilationStart(
true);
1113 conditionalCompilationAlternative();
1119void UnwrappedLineParser::parsePPEndIf() {
1120 conditionalCompilationEnd();
1124 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1126 IncludeGuard = IG_Found;
1130void UnwrappedLineParser::parsePPDefine() {
1134 IncludeGuard = IG_Rejected;
1135 IncludeGuardToken =
nullptr;
1140 if (IncludeGuard == IG_IfNdefed &&
1142 IncludeGuard = IG_Defined;
1143 IncludeGuardToken =
nullptr;
1144 for (
auto &Line : Lines) {
1145 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1146 IncludeGuard = IG_Rejected;
1160 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1165 Line->Level += PPBranchLevel + 1;
1169 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1170 assert((
int)Line->PPLevel >= 0);
1171 Line->InMacroBody =
true;
1182 if (FormatTok->
is(tok::identifier) &&
1183 Tokens->peekNextToken()->is(tok::colon)) {
1196void UnwrappedLineParser::parsePPPragma() {
1197 Line->InPragmaDirective =
true;
1201void UnwrappedLineParser::parsePPUnknown() {
1206 Line->Level += PPBranchLevel + 1;
1216 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1219 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1220 tok::less, tok::greater, tok::slash, tok::percent,
1221 tok::lessless, tok::greatergreater, tok::equal,
1222 tok::plusequal, tok::minusequal, tok::starequal,
1223 tok::slashequal, tok::percentequal, tok::ampequal,
1224 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1237 return FormatTok->
is(tok::identifier) &&
1252 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1263 tok::kw_if, tok::kw_else,
1265 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1267 tok::kw_switch, tok::kw_case,
1269 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1271 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1279 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1280 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1297 if (FuncName->
isNot(tok::identifier))
1305 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1309 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1313 if (!Tok || Tok->
isNot(tok::r_paren))
1317 if (!Tok || Tok->
isNot(tok::identifier))
1323bool UnwrappedLineParser::parseModuleImport() {
1324 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1326 if (
auto Token = Tokens->peekNextToken(
true);
1328 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1334 if (FormatTok->
is(tok::colon)) {
1338 else if (FormatTok->
is(tok::less)) {
1340 while (!FormatTok->
isOneOf(tok::semi, tok::greater, tok::eof)) {
1343 if (FormatTok->
isNot(tok::comment) &&
1344 !FormatTok->
TokenText.starts_with(
"//")) {
1350 if (FormatTok->
is(tok::semi)) {
1368void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1371 FormatToken *Next = FormatTok;
1374 CommentsBeforeNextToken.empty()
1375 ? Next->NewlinesBefore == 0
1376 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1381 bool PreviousStartsTemplateExpr =
1383 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1386 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1387 return LineNode.Tok->is(tok::at);
1392 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1393 return addUnwrappedLine();
1395 bool NextEndsTemplateExpr =
1396 Next->is(TT_TemplateString) && Next->TokenText.starts_with(
"}");
1397 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1398 (PreviousMustBeValue ||
1399 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1400 tok::minusminus))) {
1401 return addUnwrappedLine();
1403 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1405 return addUnwrappedLine();
1409void UnwrappedLineParser::parseStructuralElement(
1410 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1411 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1413 FormatTok->
is(tok::pp_include)) {
1415 if (FormatTok->
is(tok::string_literal))
1422 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1426 parseForOrWhileLoop(
false);
1430 parseForOrWhileLoop();
1435 parseIfThenElse(IfKind,
false,
true);
1444 }
else if (FormatTok->
is(tok::l_paren) &&
1445 Tokens->peekNextToken()->is(tok::star)) {
1457 if (FormatTok->
is(tok::l_brace)) {
1460 while (FormatTok && !eof()) {
1461 if (FormatTok->
is(tok::r_brace)) {
1472 case tok::kw_namespace:
1475 case tok::kw_public:
1476 case tok::kw_protected:
1477 case tok::kw_private:
1482 parseAccessSpecifier();
1490 FormatToken *Tok = parseIfThenElse(IfKind);
1501 parseForOrWhileLoop();
1512 case tok::kw_switch:
1519 case tok::kw_default:
1528 if (FormatTok->
is(tok::colon)) {
1561 case tok::kw_extern:
1567 parseVerilogHierarchyHeader();
1570 }
else if (FormatTok->
is(tok::string_literal)) {
1572 if (FormatTok->
is(tok::l_brace)) {
1577 unsigned AddLevels =
1584 parseBlock(
true, AddLevels);
1590 case tok::kw_export:
1592 parseJavaScriptEs6ImportExport();
1597 if (FormatTok->
is(tok::kw_namespace)) {
1601 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1605 case tok::kw_inline:
1607 if (FormatTok->
is(tok::kw_namespace)) {
1612 case tok::identifier:
1613 if (FormatTok->
is(TT_ForEachMacro)) {
1614 parseForOrWhileLoop();
1617 if (FormatTok->
is(TT_MacroBlockBegin)) {
1618 parseBlock(
false, 1u,
1624 parseJavaScriptEs6ImportExport();
1629 if (FormatTok->
is(tok::kw_public))
1631 if (FormatTok->
isNot(tok::string_literal))
1634 if (FormatTok->
is(tok::semi))
1639 if (
IsCpp && parseModuleImport())
1645 if (FormatTok->
is(tok::colon)) {
1651 if (
IsCpp && FormatTok->
is(TT_StatementMacro)) {
1652 parseStatementMacro();
1655 if (
IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1664 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1666 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1679 const bool InRequiresExpression =
1680 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
1686 if (FormatTok->
is(tok::l_brace)) {
1696 case tok::objc_public:
1697 case tok::objc_protected:
1698 case tok::objc_package:
1699 case tok::objc_private:
1700 return parseAccessSpecifier();
1701 case tok::objc_interface:
1702 case tok::objc_implementation:
1703 return parseObjCInterfaceOrImplementation();
1704 case tok::objc_protocol:
1705 if (parseObjCProtocol())
1710 case tok::objc_optional:
1711 case tok::objc_required:
1715 case tok::objc_autoreleasepool:
1717 if (FormatTok->
is(tok::l_brace)) {
1726 case tok::objc_synchronized:
1728 if (FormatTok->
is(tok::l_paren)) {
1732 if (FormatTok->
is(tok::l_brace)) {
1750 case tok::kw_requires: {
1752 bool ParsedClause = parseRequires();
1777 case tok::kw_typedef:
1799 case tok::kw_struct:
1801 if (parseStructLike())
1804 case tok::kw_decltype:
1806 if (FormatTok->
is(tok::l_paren)) {
1811 Line->SeenDecltypeAuto =
true;
1819 FormatTok->
is(tok::kw_class)) {
1836 case tok::l_paren: {
1843 Tokens->peekNextToken(
true),
1850 case tok::kw_operator:
1861 while (FormatTok->
is(tok::star))
1865 if (FormatTok->
is(tok::l_paren))
1868 if (FormatTok->
is(tok::l_brace))
1872 if (InRequiresExpression)
1874 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1875 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1893 IsDecltypeAutoFunction =
false;
1911 case tok::identifier: {
1913 Line->MustBeDeclaration) {
1915 parseCSharpGenericTypeConstraint();
1918 if (FormatTok->
is(TT_MacroBlockEnd)) {
1927 size_t TokenCount = Line->Tokens.size();
1931 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1932 tryToParseJSFunction();
1942 unsigned StoredPosition = Tokens->getPosition();
1943 FormatToken *Next = Tokens->getNextToken();
1944 FormatTok = Tokens->setPosition(StoredPosition);
1957 parseVerilogTable();
1969 if (parseStructLike())
1974 if (
IsCpp && FormatTok->
is(TT_StatementMacro)) {
1975 parseStatementMacro();
1982 FormatToken *PreviousToken = FormatTok;
1990 auto OneTokenSoFar = [&]() {
1991 auto I = Line->Tokens.begin(), E = Line->Tokens.end();
1992 while (I != E && I->Tok->is(tok::comment))
1995 while (I != E && I->Tok->is(tok::hash))
1997 return I != E && (++I == E);
1999 if (OneTokenSoFar()) {
2002 bool FunctionLike = FormatTok->
is(tok::l_paren);
2006 bool FollowedByNewline =
2007 CommentsBeforeNextToken.empty()
2009 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2011 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
2013 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2014 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2023 FormatTok->
is(TT_FatArrow)) {
2024 tryToParseChildBlock();
2029 if (FormatTok->
is(tok::l_brace)) {
2038 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2040 parseBlock(
false, 1u,
2048 FormatTok->
is(tok::less)) {
2050 parseBracedList(
true);
2078 case tok::kw_default:
2081 if (FormatTok->
is(tok::colon)) {
2091 parseVerilogCaseLabel();
2098 parseVerilogCaseLabel();
2109bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2110 assert(FormatTok->
is(tok::l_brace));
2122 unsigned int StoredPosition = Tokens->getPosition();
2123 FormatToken *Tok = Tokens->getNextToken();
2128 bool HasSpecialAccessor =
false;
2129 bool IsTrivialPropertyAccessor =
true;
2131 if (Tok->isOneOf(tok::semi, tok::kw_public, tok::kw_private,
2135 HasSpecialAccessor =
true;
2136 Tok = Tokens->getNextToken();
2139 if (Tok->isNot(tok::r_brace))
2140 IsTrivialPropertyAccessor =
false;
2144 if (!HasSpecialAccessor) {
2145 Tokens->setPosition(StoredPosition);
2151 Tokens->setPosition(StoredPosition);
2159 if (FormatTok->
is(tok::equal)) {
2160 while (!eof() && FormatTok->
isNot(tok::semi))
2173 if (FormatTok->
is(TT_FatArrow)) {
2177 }
while (!eof() && FormatTok->
isNot(tok::semi));
2188 !IsTrivialPropertyAccessor) {
2200bool UnwrappedLineParser::tryToParseLambda() {
2201 assert(FormatTok->
is(tok::l_square));
2206 FormatToken &LSquare = *FormatTok;
2207 if (!tryToParseLambdaIntroducer())
2210 bool SeenArrow =
false;
2211 bool InTemplateParameterList =
false;
2213 while (FormatTok->
isNot(tok::l_brace)) {
2222 parseParens(TT_PointerOrReference);
2230 InTemplateParameterList =
true;
2235 case tok::kw_template:
2236 case tok::kw_typename:
2240 case tok::kw_constexpr:
2241 case tok::kw_consteval:
2244 case tok::identifier:
2245 case tok::numeric_constant:
2246 case tok::coloncolon:
2247 case tok::kw_mutable:
2248 case tok::kw_noexcept:
2249 case tok::kw_static:
2274 case tok::equalequal:
2275 case tok::exclaimequal:
2276 case tok::greaterequal:
2277 case tok::lessequal:
2283 if (SeenArrow || InTemplateParameterList) {
2296 case tok::kw_requires: {
2297 auto *RequiresToken = FormatTok;
2299 parseRequiresClause(RequiresToken);
2303 if (!InTemplateParameterList)
2313 LSquare.setFinalizedType(TT_LambdaLSquare);
2315 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2317 assert(!NestedLambdas.empty());
2318 NestedLambdas.pop_back();
2323bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2325 const FormatToken *LeftSquare = FormatTok;
2328 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2329 tok::kw_co_yield, tok::kw_co_return)) ||
2331 LeftSquare->isCppStructuredBinding()) {
2336 if (FormatTok->
is(tok::r_square)) {
2337 const FormatToken *Next = Tokens->peekNextToken(
true);
2338 if (Next->is(tok::greater))
2345void UnwrappedLineParser::tryToParseJSFunction() {
2353 if (FormatTok->
is(tok::star)) {
2359 if (FormatTok->
is(tok::identifier))
2362 if (FormatTok->
isNot(tok::l_paren))
2368 if (FormatTok->
is(tok::colon)) {
2374 if (FormatTok->
is(tok::l_brace))
2375 tryToParseBracedList();
2377 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2381 if (FormatTok->
is(tok::semi))
2387bool UnwrappedLineParser::tryToParseBracedList() {
2389 calculateBraceTypes();
2398bool UnwrappedLineParser::tryToParseChildBlock() {
2400 assert(FormatTok->
is(TT_FatArrow));
2405 if (FormatTok->
isNot(tok::l_brace))
2411bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2412 bool HasError =
false;
2417 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2418 tryToParseChildBlock()) {
2423 tryToParseJSFunction();
2426 if (FormatTok->
is(tok::l_brace)) {
2428 if (tryToParseBracedList())
2433 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2451 if (FormatTok->
is(tok::l_brace))
2466 parseBracedList(
true);
2500bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2501 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2502 auto *LeftParen = FormatTok;
2503 bool SeenEqual =
false;
2504 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2509 if (parseParens(AmpAmpTokenType))
2515 if (!MightBeStmtExpr && !Line->InMacroBody &&
2517 const auto *Prev = LeftParen->Previous;
2518 const auto *Next = Tokens->peekNextToken();
2519 const bool DoubleParens =
2520 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2521 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2522 const bool Blacklisted =
2524 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2526 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2527 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2528 const bool ReturnParens =
2530 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2531 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2532 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2533 Next->is(tok::semi);
2534 if ((DoubleParens && !Blacklisted) || ReturnParens) {
2535 LeftParen->Optional =
true;
2548 if (!tryToParseBracedList())
2553 if (FormatTok->
is(tok::l_brace)) {
2560 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2561 tryToParseChildBlock();
2571 case tok::identifier:
2573 tryToParseJSFunction();
2577 case tok::kw_requires: {
2578 auto RequiresToken = FormatTok;
2580 parseRequiresExpression(RequiresToken);
2584 if (AmpAmpTokenType != TT_Unknown)
2595void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2596 if (!LambdaIntroducer) {
2597 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2598 if (tryToParseLambda())
2615 case tok::l_brace: {
2616 if (!tryToParseBracedList())
2622 if (FormatTok->
is(tok::l_brace)) {
2634void UnwrappedLineParser::keepAncestorBraces() {
2638 const int MaxNestingLevels = 2;
2639 const int Size = NestedTooDeep.size();
2640 if (Size >= MaxNestingLevels)
2641 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2642 NestedTooDeep.push_back(
false);
2646 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2653void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2654 FormatToken *Tok =
nullptr;
2656 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2657 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2660 : Line->Tokens.back().Tok;
2662 if (Tok->BraceCount < 0) {
2663 assert(Tok->BraceCount == -1);
2666 Tok->BraceCount = -1;
2672 parseStructuralElement();
2675 assert(!Line->InPPDirective);
2677 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2679 Tok = L.Tokens.back().Tok;
2687 if (CheckEOF && eof())
2697 assert(LeftBrace->
is(tok::l_brace));
2705 assert(RightBrace->
is(tok::r_brace));
2713void UnwrappedLineParser::handleAttributes() {
2717 else if (FormatTok->
is(tok::l_square))
2718 handleCppAttributes();
2721bool UnwrappedLineParser::handleCppAttributes() {
2723 assert(FormatTok->
is(tok::l_square));
2724 if (!tryToParseSimpleAttribute())
2731bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2735 : Tok.is(tok::l_brace);
2738FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2740 bool IsVerilogAssert) {
2741 assert((FormatTok->
is(tok::kw_if) ||
2748 if (IsVerilogAssert) {
2752 if (FormatTok->
is(tok::numeric_constant))
2769 if (FormatTok->
is(tok::exclaim))
2772 bool KeepIfBraces =
true;
2773 if (FormatTok->
is(tok::kw_consteval)) {
2777 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2779 if (FormatTok->
is(tok::l_paren)) {
2786 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2792 bool NeedsUnwrappedLine =
false;
2793 keepAncestorBraces();
2795 FormatToken *IfLeftBrace =
nullptr;
2796 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2798 if (isBlockBegin(*FormatTok)) {
2800 IfLeftBrace = FormatTok;
2802 parseBlock(
false, 1u,
2803 true, KeepIfBraces, &IfBlockKind);
2804 setPreviousRBraceType(TT_ControlStatementRBrace);
2808 NeedsUnwrappedLine =
true;
2809 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2812 parseUnbracedBody();
2816 assert(!NestedTooDeep.empty());
2817 KeepIfBraces = KeepIfBraces ||
2818 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2819 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2820 IfBlockKind == IfStmtKind::IfElseIf;
2823 bool KeepElseBraces = KeepIfBraces;
2824 FormatToken *ElseLeftBrace =
nullptr;
2825 IfStmtKind
Kind = IfStmtKind::IfOnly;
2827 if (FormatTok->
is(tok::kw_else)) {
2829 NestedTooDeep.back() =
false;
2830 Kind = IfStmtKind::IfElse;
2834 if (isBlockBegin(*FormatTok)) {
2835 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2837 ElseLeftBrace = FormatTok;
2839 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2840 FormatToken *IfLBrace =
2841 parseBlock(
false, 1u,
2842 true, KeepElseBraces, &ElseBlockKind);
2843 setPreviousRBraceType(TT_ElseRBrace);
2844 if (FormatTok->
is(tok::kw_else)) {
2845 KeepElseBraces = KeepElseBraces ||
2846 ElseBlockKind == IfStmtKind::IfOnly ||
2847 ElseBlockKind == IfStmtKind::IfElseIf;
2848 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2849 KeepElseBraces =
true;
2850 assert(ElseLeftBrace->MatchingParen);
2854 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2855 const FormatToken *
Previous = Tokens->getPreviousToken();
2857 const bool IsPrecededByComment =
Previous->is(tok::comment);
2858 if (IsPrecededByComment) {
2862 bool TooDeep =
true;
2864 Kind = IfStmtKind::IfElseIf;
2865 TooDeep = NestedTooDeep.pop_back_val();
2867 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2869 NestedTooDeep.push_back(TooDeep);
2870 if (IsPrecededByComment)
2873 parseUnbracedBody(
true);
2876 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2877 if (NeedsUnwrappedLine)
2884 assert(!NestedTooDeep.empty());
2885 KeepElseBraces = KeepElseBraces ||
2886 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2887 NestedTooDeep.back();
2889 NestedTooDeep.pop_back();
2891 if (!KeepIfBraces && !KeepElseBraces) {
2894 }
else if (IfLeftBrace) {
2895 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2897 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2898 assert(!IfLeftBrace->Optional);
2899 assert(!IfRightBrace->Optional);
2900 IfLeftBrace->MatchingParen =
nullptr;
2901 IfRightBrace->MatchingParen =
nullptr;
2911void UnwrappedLineParser::parseTryCatch() {
2912 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2914 bool NeedsUnwrappedLine =
false;
2915 if (FormatTok->
is(tok::colon)) {
2921 while (FormatTok->
is(tok::comma))
2924 while (FormatTok->
is(tok::identifier)) {
2926 if (FormatTok->
is(tok::l_paren))
2929 FormatTok->
is(tok::l_brace)) {
2932 }
while (FormatTok->
isNot(tok::r_brace));
2938 while (FormatTok->
is(tok::comma))
2946 keepAncestorBraces();
2948 if (FormatTok->
is(tok::l_brace)) {
2954 NeedsUnwrappedLine =
true;
2955 }
else if (FormatTok->
isNot(tok::kw_catch)) {
2961 parseStructuralElement();
2965 if (FormatTok->
is(tok::at))
2968 tok::kw___finally) ||
2976 while (FormatTok->
isNot(tok::l_brace)) {
2977 if (FormatTok->
is(tok::l_paren)) {
2981 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
2983 NestedTooDeep.pop_back();
2988 NeedsUnwrappedLine =
false;
2989 Line->MustBeDeclaration =
false;
2995 NeedsUnwrappedLine =
true;
2999 NestedTooDeep.pop_back();
3001 if (NeedsUnwrappedLine)
3005void UnwrappedLineParser::parseNamespace() {
3006 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3007 "'namespace' expected");
3009 const FormatToken &InitialToken = *FormatTok;
3011 if (InitialToken.is(TT_NamespaceMacro)) {
3014 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3015 tok::l_square, tok::period, tok::l_paren) ||
3016 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3017 if (FormatTok->
is(tok::l_square))
3019 else if (FormatTok->
is(tok::l_paren))
3025 if (FormatTok->
is(tok::l_brace)) {
3031 unsigned AddLevels =
3034 DeclarationScopeStack.size() > 1)
3037 bool ManageWhitesmithsBraces =
3043 if (ManageWhitesmithsBraces)
3048 parseBlock(
true, AddLevels,
true,
3050 ManageWhitesmithsBraces);
3052 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3054 if (ManageWhitesmithsBraces)
3060void UnwrappedLineParser::parseNew() {
3061 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3067 if (FormatTok->
is(tok::l_paren))
3071 if (FormatTok->
is(tok::l_brace))
3074 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3087 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3091 if (FormatTok->
is(tok::l_paren)) {
3095 if (FormatTok->
is(tok::l_brace))
3103void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3104 keepAncestorBraces();
3106 if (isBlockBegin(*FormatTok)) {
3108 FormatToken *LeftBrace = FormatTok;
3110 parseBlock(
false, 1u,
3112 setPreviousRBraceType(TT_ControlStatementRBrace);
3114 assert(!NestedTooDeep.empty());
3115 if (!NestedTooDeep.back())
3121 parseUnbracedBody();
3125 NestedTooDeep.pop_back();
3128void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3129 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3136 "'for', 'while' or foreach macro expected");
3138 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3144 if (
IsCpp && FormatTok->
is(tok::kw_co_await))
3146 if (HasParens && FormatTok->
is(tok::l_paren)) {
3157 parseVerilogSensitivityList();
3159 Tokens->getPreviousToken()->is(tok::r_paren)) {
3166 parseLoopBody(KeepBraces,
true);
3169void UnwrappedLineParser::parseDoWhile() {
3170 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3176 if (FormatTok->
isNot(tok::kw_while)) {
3189 parseStructuralElement();
3192void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3194 unsigned OldLineLevel = Line->Level;
3195 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3201 FormatTok->
is(tok::l_brace)) {
3207 if (FormatTok->
is(tok::kw_break)) {
3216 parseStructuralElement();
3220 if (FormatTok->
is(tok::semi))
3224 Line->Level = OldLineLevel;
3225 if (FormatTok->
isNot(tok::l_brace)) {
3226 parseStructuralElement();
3231void UnwrappedLineParser::parseCaseLabel() {
3232 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3237 if (FormatTok->
is(tok::colon)) {
3245void UnwrappedLineParser::parseSwitch() {
3246 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3248 if (FormatTok->
is(tok::l_paren))
3251 keepAncestorBraces();
3253 if (FormatTok->
is(tok::l_brace)) {
3257 setPreviousRBraceType(TT_ControlStatementRBrace);
3262 parseStructuralElement();
3267 NestedTooDeep.pop_back();
3277 case tok::caretequal:
3281 case tok::equalequal:
3283 case tok::exclaimequal:
3285 case tok::greaterequal:
3286 case tok::greatergreater:
3287 case tok::greatergreaterequal:
3291 case tok::lessequal:
3293 case tok::lesslessequal:
3295 case tok::minusequal:
3296 case tok::minusminus:
3298 case tok::percentequal:
3301 case tok::pipeequal:
3304 case tok::plusequal:
3312 case tok::slashequal:
3314 case tok::starequal:
3321void UnwrappedLineParser::parseAccessSpecifier() {
3322 FormatToken *AccessSpecifierCandidate = FormatTok;
3328 if (FormatTok->
is(tok::colon)) {
3331 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3335 }
else if (AccessSpecifierCandidate) {
3337 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3344bool clang::format::UnwrappedLineParser::parseRequires() {
3345 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3346 auto RequiresToken = FormatTok;
3352 switch (FormatTok->Tok.getKind()) {
3355 parseRequiresExpression(RequiresToken);
3362 parseRequiresClause(RequiresToken);
3373 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3375 if (!PreviousNonComment ||
3376 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3379 parseRequiresClause(RequiresToken);
3383 switch (PreviousNonComment->Tok.getKind()) {
3386 case tok::kw_noexcept:
3389 parseRequiresClause(RequiresToken);
3399 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3400 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3401 parseRequiresClause(RequiresToken);
3407 if (PreviousNonComment->isTypeOrIdentifier()) {
3409 parseRequiresClause(RequiresToken);
3413 parseRequiresExpression(RequiresToken);
3426 auto PeekNext = [&Lookahead, &NextToken,
this] {
3431 bool FoundType =
false;
3432 bool LastWasColonColon =
false;
3435 for (; Lookahead < 50; PeekNext()) {
3436 switch (NextToken->Tok.getKind()) {
3437 case tok::kw_volatile:
3440 if (OpenAngles == 0) {
3442 parseRequiresExpression(RequiresToken);
3450 case tok::coloncolon:
3451 LastWasColonColon =
true;
3453 case tok::kw_decltype:
3454 case tok::identifier:
3455 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3457 parseRequiresExpression(RequiresToken);
3461 LastWasColonColon =
false;
3470 if (NextToken->isTypeName()) {
3472 parseRequiresExpression(RequiresToken);
3480 parseRequiresClause(RequiresToken);
3491void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3493 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3498 bool InRequiresExpression =
3499 !RequiresToken->Previous ||
3500 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3502 RequiresToken->setFinalizedType(InRequiresExpression
3503 ? TT_RequiresClauseInARequiresExpression
3504 : TT_RequiresClause);
3508 parseConstraintExpression();
3510 if (!InRequiresExpression)
3521void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3523 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3525 RequiresToken->setFinalizedType(TT_RequiresExpression);
3527 if (FormatTok->
is(tok::l_paren)) {
3532 if (FormatTok->
is(tok::l_brace)) {
3542void UnwrappedLineParser::parseConstraintExpression() {
3549 bool LambdaNextTimeAllowed =
true;
3559 bool TopLevelParensAllowed =
true;
3562 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3565 case tok::kw_requires: {
3566 auto RequiresToken = FormatTok;
3568 parseRequiresExpression(RequiresToken);
3573 if (!TopLevelParensAllowed)
3575 parseParens(TT_BinaryOperator);
3576 TopLevelParensAllowed =
false;
3580 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3587 case tok::kw_struct:
3599 LambdaNextTimeAllowed =
true;
3600 TopLevelParensAllowed =
true;
3605 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3609 case tok::kw_sizeof:
3611 case tok::greaterequal:
3612 case tok::greatergreater:
3614 case tok::lessequal:
3616 case tok::equalequal:
3618 case tok::exclaimequal:
3623 LambdaNextTimeAllowed =
true;
3624 TopLevelParensAllowed =
true;
3629 case tok::numeric_constant:
3630 case tok::coloncolon:
3633 TopLevelParensAllowed =
false;
3638 case tok::kw_static_cast:
3639 case tok::kw_const_cast:
3640 case tok::kw_reinterpret_cast:
3641 case tok::kw_dynamic_cast:
3643 if (FormatTok->
isNot(tok::less))
3647 parseBracedList(
true);
3663 case tok::coloncolon:
3667 case tok::kw_requires:
3676 if (FormatTok->
is(tok::less)) {
3678 parseBracedList(
true);
3680 TopLevelParensAllowed =
false;
3686bool UnwrappedLineParser::parseEnum() {
3687 const FormatToken &InitialToken = *FormatTok;
3690 if (FormatTok->
is(tok::kw_enum))
3705 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3707 while (FormatTok->
is(tok::l_square))
3708 if (!handleCppAttributes())
3713 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3714 tok::greater, tok::comma, tok::question,
3720 while (FormatTok->
is(tok::l_square))
3726 if (FormatTok->
is(tok::l_paren))
3728 if (FormatTok->
is(tok::identifier)) {
3732 if (
IsCpp && FormatTok->
is(tok::identifier))
3738 if (FormatTok->
isNot(tok::l_brace))
3745 parseJavaEnumBody();
3763 bool HasError = !parseBracedList(
false,
true);
3767 if (FormatTok->
is(tok::semi))
3771 setPreviousRBraceType(TT_EnumRBrace);
3779bool UnwrappedLineParser::parseStructLike() {
3786 if (FormatTok->
is(tok::semi))
3797class ScopedTokenPosition {
3798 unsigned StoredPosition;
3799 FormatTokenSource *Tokens;
3802 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3803 assert(Tokens &&
"Tokens expected to not be null");
3804 StoredPosition = Tokens->getPosition();
3807 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3813bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3814 ScopedTokenPosition AutoPosition(Tokens);
3815 FormatToken *Tok = Tokens->getNextToken();
3817 if (Tok->isNot(tok::l_square))
3821 while (Tok->isNot(tok::eof)) {
3822 if (Tok->is(tok::r_square))
3824 Tok = Tokens->getNextToken();
3826 if (Tok->is(tok::eof))
3828 Tok = Tokens->getNextToken();
3829 if (Tok->isNot(tok::r_square))
3831 Tok = Tokens->getNextToken();
3832 if (Tok->is(tok::semi))
3837void UnwrappedLineParser::parseJavaEnumBody() {
3838 assert(FormatTok->
is(tok::l_brace));
3839 const FormatToken *OpeningBrace = FormatTok;
3844 unsigned StoredPosition = Tokens->getPosition();
3845 bool IsSimple =
true;
3846 FormatToken *Tok = Tokens->getNextToken();
3847 while (Tok->isNot(tok::eof)) {
3848 if (Tok->is(tok::r_brace))
3850 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3856 Tok = Tokens->getNextToken();
3858 FormatTok = Tokens->setPosition(StoredPosition);
3875 if (FormatTok->
is(tok::l_brace)) {
3877 parseBlock(
true, 1u,
3879 }
else if (FormatTok->
is(tok::l_paren)) {
3881 }
else if (FormatTok->
is(tok::comma)) {
3884 }
else if (FormatTok->
is(tok::semi)) {
3888 }
else if (FormatTok->
is(tok::r_brace)) {
3897 parseLevel(OpeningBrace);
3903void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
3904 const FormatToken &InitialToken = *FormatTok;
3907 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
3908 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
3913 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3914 tok::kw_alignas, tok::l_square) ||
3917 FormatTok->
isOneOf(tok::period, tok::comma))) {
3924 if (FormatTok->
is(tok::l_brace)) {
3925 tryToParseBracedList();
3929 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
3933 if (!IsNonMacroIdentifier(FormatTok->
Previous) &&
3934 FormatTok->
is(tok::l_paren)) {
3939 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
3940 int AngleNestingLevel = 0;
3942 if (FormatTok->
is(tok::less))
3943 ++AngleNestingLevel;
3944 else if (FormatTok->
is(tok::greater))
3945 --AngleNestingLevel;
3947 if (AngleNestingLevel == 0 && FormatTok->
is(tok::l_paren) &&
3948 IsNonMacroIdentifier(FormatTok->
Previous)) {
3951 if (FormatTok->
is(tok::l_brace)) {
3952 calculateBraceTypes(
true);
3953 if (!tryToParseBracedList())
3956 if (FormatTok->
is(tok::l_square)) {
3959 !
Previous->isTypeOrIdentifier())) {
3962 if (!tryToParseLambda())
3969 if (FormatTok->
is(tok::semi))
3974 parseCSharpGenericTypeConstraint();
3981 auto GetBraceTypes =
3982 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
3983 switch (RecordTok.Tok.getKind()) {
3985 return {TT_ClassLBrace, TT_ClassRBrace};
3986 case tok::kw_struct:
3987 return {TT_StructLBrace, TT_StructRBrace};
3989 return {TT_UnionLBrace, TT_UnionRBrace};
3992 return {TT_RecordLBrace, TT_RecordRBrace};
3995 if (FormatTok->
is(tok::l_brace)) {
3996 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4005 parseBlock(
true, AddLevels,
false);
4007 setPreviousRBraceType(ClosingBraceType);
4014void UnwrappedLineParser::parseObjCMethod() {
4015 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4016 "'(' or identifier expected.");
4018 if (FormatTok->
is(tok::semi)) {
4022 }
else if (FormatTok->
is(tok::l_brace)) {
4034void UnwrappedLineParser::parseObjCProtocolList() {
4035 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4039 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4043 }
while (!eof() && FormatTok->
isNot(tok::greater));
4047void UnwrappedLineParser::parseObjCUntilAtEnd() {
4054 if (FormatTok->
is(tok::l_brace)) {
4058 }
else if (FormatTok->
is(tok::r_brace)) {
4062 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4066 parseStructuralElement();
4071void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4079 if (FormatTok->
is(tok::less))
4080 parseObjCLightweightGenerics();
4081 if (FormatTok->
is(tok::colon)) {
4085 if (FormatTok->
is(tok::less))
4086 parseObjCLightweightGenerics();
4087 }
else if (FormatTok->
is(tok::l_paren)) {
4092 if (FormatTok->
is(tok::less))
4093 parseObjCProtocolList();
4095 if (FormatTok->
is(tok::l_brace)) {
4105 parseObjCUntilAtEnd();
4108void UnwrappedLineParser::parseObjCLightweightGenerics() {
4109 assert(FormatTok->
is(tok::less));
4117 unsigned NumOpenAngles = 1;
4121 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4125 if (FormatTok->
is(tok::less)) {
4127 }
else if (FormatTok->
is(tok::greater)) {
4128 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4131 }
while (!eof() && NumOpenAngles != 0);
4137bool UnwrappedLineParser::parseObjCProtocol() {
4141 if (FormatTok->
is(tok::l_paren)) {
4153 if (FormatTok->
is(tok::less))
4154 parseObjCProtocolList();
4157 if (FormatTok->
is(tok::semi)) {
4164 parseObjCUntilAtEnd();
4168void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4169 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4170 assert(IsImport || FormatTok->
is(tok::kw_export));
4174 if (FormatTok->
is(tok::kw_default))
4191 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4194 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4199 if (FormatTok->
is(tok::semi))
4201 if (Line->Tokens.empty()) {
4206 if (FormatTok->
is(tok::l_brace)) {
4216void UnwrappedLineParser::parseStatementMacro() {
4218 if (FormatTok->
is(tok::l_paren))
4220 if (FormatTok->
is(tok::semi))
4225void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4228 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4229 tok::coloncolon, tok::hash) ||
4232 }
else if (FormatTok->
is(tok::l_square)) {
4240void UnwrappedLineParser::parseVerilogSensitivityList() {
4241 if (FormatTok->
isNot(tok::at))
4245 if (FormatTok->
is(tok::at))
4255 parseVerilogHierarchyIdentifier();
4260unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4261 unsigned AddLevels = 0;
4267 parseVerilogSensitivityList();
4268 if (FormatTok->
is(tok::semi))
4276 if (FormatTok->
is(tok::l_paren)) {
4289 if (FormatTok->
is(tok::l_square)) {
4304 Line->IsContinuation =
true;
4311 parseVerilogHierarchyIdentifier();
4312 if (FormatTok->
is(tok::semi))
4320 if (FormatTok->
is(tok::l_paren)) {
4325 if (FormatTok->
is(tok::l_paren)) {
4335 parseVerilogHierarchyIdentifier();
4336 if (FormatTok->
is(tok::l_paren))
4343 parseVerilogHierarchyIdentifier();
4344 }
while (FormatTok->
is(tok::comma));
4348 if (FormatTok->
is(tok::at)) {
4350 parseVerilogSensitivityList();
4353 if (FormatTok->
is(tok::semi))
4361void UnwrappedLineParser::parseVerilogTable() {
4366 auto InitialLevel = Line->Level++;
4368 FormatToken *Tok = FormatTok;
4370 if (Tok->is(tok::semi))
4372 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4373 Tok->setFinalizedType(TT_VerilogTableItem);
4375 Line->Level = InitialLevel;
4380void UnwrappedLineParser::parseVerilogCaseLabel() {
4386 auto OrigLevel = Line->Level;
4387 auto FirstLine = CurrentLines->size();
4388 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4392 parseStructuralElement();
4395 if (CurrentLines->size() > FirstLine)
4396 (*CurrentLines)[FirstLine].Level = OrigLevel;
4397 Line->Level = OrigLevel;
4400bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4401 for (
const auto &N : Line.Tokens) {
4402 if (N.Tok->MacroCtx)
4404 for (
const UnwrappedLine &Child : N.Children)
4405 if (containsExpansion(Child))
4411void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4412 if (Line->Tokens.empty())
4415 if (!parsingPPDirective()) {
4416 llvm::dbgs() <<
"Adding unwrapped line:\n";
4417 printDebugInfo(*Line);
4425 bool ClosesWhitesmithsBlock =
4432 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4434 Reconstruct.emplace(Line->Level, Unexpanded);
4435 Reconstruct->addLine(*Line);
4440 CurrentExpandedLines.push_back(std::move(*Line));
4442 if (Reconstruct->finished()) {
4443 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4444 assert(!Reconstructed.Tokens.empty() &&
4445 "Reconstructed must at least contain the macro identifier.");
4446 assert(!parsingPPDirective());
4448 llvm::dbgs() <<
"Adding unexpanded line:\n";
4449 printDebugInfo(Reconstructed);
4451 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4452 Lines.push_back(std::move(Reconstructed));
4453 CurrentExpandedLines.clear();
4454 Reconstruct.reset();
4459 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4460 CurrentLines->push_back(std::move(*Line));
4462 Line->Tokens.clear();
4464 Line->FirstStartColumn = 0;
4465 Line->IsContinuation =
false;
4466 Line->SeenDecltypeAuto =
false;
4468 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4470 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4471 CurrentLines->append(
4472 std::make_move_iterator(PreprocessorDirectives.begin()),
4473 std::make_move_iterator(PreprocessorDirectives.end()));
4474 PreprocessorDirectives.clear();
4480bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4482bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4483 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4484 FormatTok.NewlinesBefore > 0;
4492 const llvm::Regex &CommentPragmasRegex) {
4493 if (
Line.Tokens.empty())
4496 StringRef IndentContent = FormatTok.
TokenText;
4497 if (FormatTok.
TokenText.starts_with(
"//") ||
4498 FormatTok.
TokenText.starts_with(
"/*")) {
4499 IndentContent = FormatTok.
TokenText.substr(2);
4501 if (CommentPragmasRegex.match(IndentContent))
4576 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4578 MinColumnToken = PreviousToken;
4581 PreviousToken =
Node.Tok;
4584 if (
Node.Tok->NewlinesBefore > 0)
4585 MinColumnToken =
Node.Tok;
4587 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4588 MinColumnToken = PreviousToken;
4594void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4595 bool JustComments = Line->Tokens.empty();
4596 for (FormatToken *Tok : CommentsBeforeNextToken) {
4605 Tok->ContinuesLineCommentSection =
4607 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4611 if (NewlineBeforeNext && JustComments)
4613 CommentsBeforeNextToken.clear();
4616void UnwrappedLineParser::nextToken(
int LevelDifference) {
4619 flushComments(isOnNewLine(*FormatTok));
4620 pushToken(FormatTok);
4623 readToken(LevelDifference);
4625 readTokenWithJavaScriptASI();
4635 FormatTok->Tok.setKind(tok::r_brace);
4639void UnwrappedLineParser::distributeComments(
4640 const SmallVectorImpl<FormatToken *> &Comments,
4641 const FormatToken *NextTok) {
4660 if (Comments.empty())
4662 bool ShouldPushCommentsInCurrentLine =
true;
4663 bool HasTrailAlignedWithNextToken =
false;
4664 unsigned StartOfTrailAlignedWithNextToken = 0;
4667 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4668 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4669 HasTrailAlignedWithNextToken =
true;
4670 StartOfTrailAlignedWithNextToken = i;
4674 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4675 FormatToken *FormatTok = Comments[i];
4676 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4677 FormatTok->ContinuesLineCommentSection =
false;
4679 FormatTok->ContinuesLineCommentSection =
4682 if (!FormatTok->ContinuesLineCommentSection &&
4683 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4684 ShouldPushCommentsInCurrentLine =
false;
4686 if (ShouldPushCommentsInCurrentLine)
4687 pushToken(FormatTok);
4689 CommentsBeforeNextToken.push_back(FormatTok);
4693void UnwrappedLineParser::readToken(
int LevelDifference) {
4694 SmallVector<FormatToken *, 1> Comments;
4695 bool PreviousWasComment =
false;
4696 bool FirstNonCommentOnLine =
false;
4698 FormatTok = Tokens->getNextToken();
4700 while (FormatTok->getType() == TT_ConflictStart ||
4701 FormatTok->getType() == TT_ConflictEnd ||
4702 FormatTok->getType() == TT_ConflictAlternative) {
4703 if (FormatTok->getType() == TT_ConflictStart)
4704 conditionalCompilationStart(
false);
4705 else if (FormatTok->getType() == TT_ConflictAlternative)
4706 conditionalCompilationAlternative();
4707 else if (FormatTok->getType() == TT_ConflictEnd)
4708 conditionalCompilationEnd();
4709 FormatTok = Tokens->getNextToken();
4710 FormatTok->MustBreakBefore =
true;
4711 FormatTok->MustBreakBeforeFinalized =
true;
4714 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4715 const FormatToken &Tok,
4716 bool PreviousWasComment) {
4717 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4718 return Tok.HasUnescapedNewline || Tok.IsFirst;
4723 if (PreviousWasComment)
4724 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4725 return IsFirstOnLine(Tok);
4728 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4729 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4730 PreviousWasComment = FormatTok->is(tok::comment);
4732 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4735 FirstNonCommentOnLine) {
4736 distributeComments(Comments, FormatTok);
4740 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4742 assert((LevelDifference >= 0 ||
4743 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4744 "LevelDifference makes Line->Level negative");
4745 Line->Level += LevelDifference;
4750 PPBranchLevel > 0) {
4751 Line->Level += PPBranchLevel;
4753 flushComments(isOnNewLine(*FormatTok));
4755 PreviousWasComment = FormatTok->is(tok::comment);
4756 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4757 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4760 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4761 !Line->InPPDirective) {
4765 if (FormatTok->is(tok::identifier) &&
4766 Macros.
defined(FormatTok->TokenText) &&
4768 !Line->InPPDirective) {
4769 FormatToken *
ID = FormatTok;
4770 unsigned Position = Tokens->getPosition();
4774 auto PreCall = std::move(Line);
4775 Line.reset(
new UnwrappedLine);
4776 bool OldInExpansion = InExpansion;
4779 auto Args = parseMacroCall();
4780 InExpansion = OldInExpansion;
4781 assert(Line->Tokens.front().Tok ==
ID);
4783 auto UnexpandedLine = std::move(Line);
4785 Line = std::move(PreCall);
4788 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4790 llvm::dbgs() <<
"(";
4791 for (
const auto &Arg : Args.value())
4792 for (
const auto &T : Arg)
4793 llvm::dbgs() << T->TokenText <<
" ";
4794 llvm::dbgs() <<
")";
4796 llvm::dbgs() <<
"\n";
4799 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4805 LLVM_DEBUG(llvm::dbgs()
4806 <<
"Macro \"" <<
ID->TokenText
4807 <<
"\" not overloaded for arity " << Args->size()
4808 <<
"or not function-like, using object-like overload.");
4810 UnexpandedLine->Tokens.resize(1);
4811 Tokens->setPosition(Position);
4816 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4819 Unexpanded[
ID] = std::move(UnexpandedLine);
4820 SmallVector<FormatToken *, 8> Expansion =
4821 Macros.
expand(
ID, std::move(Args));
4822 if (!Expansion.empty())
4823 FormatTok = Tokens->insertTokens(Expansion);
4826 llvm::dbgs() <<
"Expanded: ";
4827 for (
const auto &T : Expansion)
4828 llvm::dbgs() << T->TokenText <<
" ";
4829 llvm::dbgs() <<
"\n";
4833 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4834 <<
"\", because it was used ";
4836 llvm::dbgs() <<
"with " << Args->size();
4838 llvm::dbgs() <<
"without";
4839 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4841 Tokens->setPosition(Position);
4846 if (FormatTok->isNot(tok::comment)) {
4847 distributeComments(Comments, FormatTok);
4852 Comments.push_back(FormatTok);
4855 distributeComments(Comments,
nullptr);
4860template <
typename Iterator>
4861void pushTokens(Iterator
Begin, Iterator End,
4863 for (
auto I =
Begin; I != End; ++I) {
4864 Into.push_back(I->Tok);
4865 for (
const auto &Child : I->Children)
4866 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
4871std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
4872UnwrappedLineParser::parseMacroCall() {
4873 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
4874 assert(Line->Tokens.empty());
4876 if (FormatTok->isNot(tok::l_paren))
4878 unsigned Position = Tokens->getPosition();
4879 FormatToken *Tok = FormatTok;
4882 auto ArgStart = std::prev(Line->Tokens.end());
4886 switch (FormatTok->Tok.getKind()) {
4891 case tok::r_paren: {
4897 Args->push_back({});
4898 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4907 Args->push_back({});
4908 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4910 ArgStart = std::prev(Line->Tokens.end());
4918 Line->Tokens.resize(1);
4919 Tokens->setPosition(Position);
4924void UnwrappedLineParser::pushToken(FormatToken *Tok) {
4925 Line->Tokens.push_back(UnwrappedLineNode(Tok));
4926 if (MustBreakBeforeNextToken) {
4927 Line->Tokens.back().Tok->MustBreakBefore =
true;
4928 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
4929 MustBreakBeforeNextToken =
false;
This file implements a token annotator, i.e.
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)
unsigned kind
All of the diagnostics that can be emitted by the frontend.
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.
@ Parens
New-expression has a C++98 paren-delimited initializer.