22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/raw_os_ostream.h"
26#include "llvm/Support/raw_ostream.h"
31#define DEBUG_TYPE "format-parser"
38void printLine(llvm::raw_ostream &OS,
const UnwrappedLine &
Line,
39 StringRef Prefix =
"",
bool PrintText =
false) {
40 OS << Prefix <<
"Line(" <<
Line.Level <<
", FSC=" <<
Line.FirstStartColumn
41 <<
")" << (
Line.InPPDirective ?
" MACRO" :
"") <<
": ";
43 for (std::list<UnwrappedLineNode>::const_iterator I =
Line.Tokens.begin(),
44 E =
Line.Tokens.end();
50 OS << I->Tok->Tok.getName() <<
"[" <<
"T=" << (
unsigned)I->Tok->getType()
51 <<
", OC=" << I->Tok->OriginalColumn <<
", \"" << I->Tok->TokenText
53 for (SmallVectorImpl<UnwrappedLine>::const_iterator
54 CI = I->Children.begin(),
55 CE = I->Children.end();
58 printLine(OS, *CI, (Prefix +
" ").str());
66LLVM_ATTRIBUTE_UNUSED
static void printDebugInfo(
const UnwrappedLine &
Line) {
67 printLine(llvm::dbgs(),
Line);
70class ScopedDeclarationState {
72 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
73 bool MustBeDeclaration)
74 : Line(Line), Stack(Stack) {
75 Line.MustBeDeclaration = MustBeDeclaration;
76 Stack.push_back(MustBeDeclaration);
78 ~ScopedDeclarationState() {
81 Line.MustBeDeclaration = Stack.back();
83 Line.MustBeDeclaration =
true;
88 llvm::BitVector &Stack;
94 llvm::raw_os_ostream OS(Stream);
102 bool SwitchToPreprocessorLines =
false)
104 if (SwitchToPreprocessorLines)
106 else if (!
Parser.Line->Tokens.empty())
107 Parser.CurrentLines = &
Parser.Line->Tokens.back().Children;
108 PreBlockLine = std::move(
Parser.Line);
109 Parser.Line = std::make_unique<UnwrappedLine>();
110 Parser.Line->Level = PreBlockLine->Level;
111 Parser.Line->PPLevel = PreBlockLine->PPLevel;
112 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
113 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
117 if (!
Parser.Line->Tokens.empty())
118 Parser.addUnwrappedLine();
119 assert(
Parser.Line->Tokens.empty());
120 Parser.Line = std::move(PreBlockLine);
121 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
122 Parser.MustBreakBeforeNextToken =
true;
123 Parser.CurrentLines = OriginalLines;
129 std::unique_ptr<UnwrappedLine> PreBlockLine;
138 Style.BraceWrapping.AfterControlStatement,
139 Style.BraceWrapping.IndentBraces) {}
141 bool WrapBrace,
bool IndentBrace)
142 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
144 Parser->addUnwrappedLine();
152 unsigned OldLineLevel;
159 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
162 CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()),
163 Keywords(Keywords), CommentPragmasRegex(Style.CommentPragmas),
164 Tokens(nullptr), Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
165 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
168 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
169 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}
171void UnwrappedLineParser::reset() {
176 IncludeGuardToken =
nullptr;
178 CommentsBeforeNextToken.clear();
180 MustBreakBeforeNextToken =
false;
181 IsDecltypeAutoFunction =
false;
182 PreprocessorDirectives.clear();
183 CurrentLines = &Lines;
184 DeclarationScopeStack.clear();
185 NestedTooDeep.clear();
186 NestedLambdas.clear();
188 Line->FirstStartColumn = FirstStartColumn;
190 if (!Unexpanded.empty())
192 Token->MacroCtx.reset();
193 CurrentExpandedLines.clear();
194 ExpandedLines.clear();
202 Line->FirstStartColumn = FirstStartColumn;
204 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
206 Tokens = &TokenSource;
214 if (IncludeGuard == IG_Found) {
215 for (
auto &Line : Lines)
216 if (Line.InPPDirective && Line.Level > 0)
222 pushToken(FormatTok);
227 if (!ExpandedLines.empty()) {
228 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
229 for (
const auto &Line : Lines) {
230 if (!Line.Tokens.empty()) {
231 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
232 if (it != ExpandedLines.end()) {
233 for (
const auto &Expanded : it->second) {
234 LLVM_DEBUG(printDebugInfo(Expanded));
240 LLVM_DEBUG(printDebugInfo(Line));
246 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
248 LLVM_DEBUG(printDebugInfo(Line));
253 while (!PPLevelBranchIndex.empty() &&
254 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
255 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
256 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
258 if (!PPLevelBranchIndex.empty()) {
259 ++PPLevelBranchIndex.back();
260 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
261 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
263 }
while (!PPLevelBranchIndex.empty());
266void UnwrappedLineParser::parseFile() {
269 bool MustBeDeclaration = !Line->InPPDirective && !Style.
isJavaScript();
270 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
287 !CommentsBeforeNextToken.empty()) {
294void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
303 parseCSharpGenericTypeConstraint();
312void UnwrappedLineParser::parseCSharpAttribute() {
313 int UnpairedSquareBrackets = 1;
318 --UnpairedSquareBrackets;
319 if (UnpairedSquareBrackets == 0) {
325 ++UnpairedSquareBrackets;
335bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
336 if (!Lines.empty() && Lines.back().InPPDirective)
350bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
352 FormatToken **IfLeftBrace) {
353 const bool InRequiresExpression =
354 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
355 const bool IsPrecededByCommentOrPPDirective =
357 FormatToken *IfLBrace =
nullptr;
358 bool HasDoWhile =
false;
359 bool HasLabel =
false;
360 unsigned StatementCount = 0;
361 bool SwitchLabelEncountered =
false;
369 if (FormatTok->
is(TT_MacroBlockBegin))
371 else if (FormatTok->
is(TT_MacroBlockEnd))
374 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
375 &HasLabel, &StatementCount] {
376 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
377 HasDoWhile ?
nullptr : &HasDoWhile,
378 HasLabel ?
nullptr : &HasLabel);
380 assert(StatementCount > 0 &&
"StatementCount overflow!");
389 if (InRequiresExpression) {
398 if (!InRequiresExpression && FormatTok->
isNot(TT_MacroBlockBegin)) {
399 if (tryToParseBracedList())
405 assert(StatementCount > 0 &&
"StatementCount overflow!");
411 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
414 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
415 HasDoWhile || IsPrecededByCommentOrPPDirective ||
416 precededByCommentOrPPDirective()) {
420 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
423 *IfLeftBrace = IfLBrace;
429 case tok::kw_default: {
433 if (Next->isNot(tok::colon)) {
436 parseStructuralElement();
452 if (!SwitchLabelEncountered &&
454 (Line->InPPDirective && Line->Level == 1))) {
457 SwitchLabelEncountered =
true;
458 parseStructuralElement();
463 parseCSharpAttribute();
466 if (handleCppAttributes())
478void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
484 FormatToken *Tok = FormatTok;
485 const FormatToken *PrevTok = Tok->
Previous;
491 const FormatToken *PrevTok;
493 SmallVector<StackEntry, 8> LBraceStack;
494 assert(Tok->is(tok::l_brace));
499 if (!Line->InMacroBody && !Style.
isTableGen()) {
501 while (NextTok->is(tok::hash)) {
504 }
while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof));
506 while (NextTok->is(tok::comment))
511 switch (Tok->Tok.getKind()) {
514 if (PrevTok->isOneOf(tok::colon, tok::less)) {
525 }
else if (PrevTok->is(tok::r_paren)) {
532 LBraceStack.push_back({Tok, PrevTok});
535 if (LBraceStack.empty())
537 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
538 bool ProbablyBracedList =
false;
540 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
541 }
else if (LBrace->isNot(TT_EnumLBrace)) {
544 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
545 NextTok->OriginalColumn == 0;
555 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
557 ProbablyBracedList = ProbablyBracedList ||
559 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
562 ProbablyBracedList || (IsCpp && NextTok->is(tok::l_paren));
569 ProbablyBracedList ||
570 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
571 tok::r_paren, tok::r_square, tok::ellipsis);
576 ProbablyBracedList ||
577 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
578 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
582 ProbablyBracedList ||
583 (NextTok->is(tok::identifier) &&
584 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
586 ProbablyBracedList = ProbablyBracedList ||
587 (NextTok->is(tok::semi) &&
588 (!ExpectClassBody || LBraceStack.size() != 1));
591 ProbablyBracedList ||
592 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
594 if (!Style.
isCSharp() && NextTok->is(tok::l_square)) {
598 ProbablyBracedList = NextTok->
isNot(tok::l_square);
602 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
603 !FormatTok->
Previous && NextTok->
is(tok::eof) &&
607 !PrevTok->isOneOf(tok::semi,
BK_Block, tok::colon)) {
608 ProbablyBracedList =
true;
612 Tok->setBlockKind(BlockKind);
613 LBrace->setBlockKind(BlockKind);
615 LBraceStack.pop_back();
617 case tok::identifier:
618 if (Tok->isNot(TT_StatementMacro))
629 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
630 LBraceStack.back().Tok->setBlockKind(
BK_Block);
638 }
while (Tok->isNot(tok::eof) && !LBraceStack.empty());
641 for (
const auto &Entry : LBraceStack)
649void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
651 Prev && Prev->
is(tok::r_brace)) {
659 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
662size_t UnwrappedLineParser::computePPHash()
const {
664 for (
const auto &i : PPStack) {
675bool UnwrappedLineParser::mightFitOnOneLine(
676 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
678 if (ColumnLimit == 0)
681 auto &Tokens = ParsedLine.Tokens;
682 assert(!Tokens.empty());
684 const auto *LastToken = Tokens.back().Tok;
687 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
690 for (
const auto &Token : Tokens) {
692 auto &SavedToken = SavedTokens[Index++];
693 SavedToken.Tok =
new FormatToken;
694 SavedToken.Tok->copyFrom(*Token.Tok);
695 SavedToken.Children = std::move(Token.Children);
698 AnnotatedLine Line(ParsedLine);
699 assert(Line.Last == LastToken);
701 TokenAnnotator Annotator(Style, Keywords);
702 Annotator.annotate(Line);
703 Annotator.calculateFormattingInformation(Line);
705 auto Length = LastToken->TotalLength;
707 assert(OpeningBrace != Tokens.front().Tok);
708 if (
auto Prev = OpeningBrace->Previous;
709 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
710 Length -= ColumnLimit;
712 Length -= OpeningBrace->TokenText.size() + 1;
715 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
716 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
717 Length -= FirstToken->TokenText.size() + 1;
721 for (
auto &Token : Tokens) {
722 const auto &SavedToken = SavedTokens[Index++];
723 Token.Tok->copyFrom(*SavedToken.Tok);
724 Token.Children = std::move(SavedToken.Children);
725 delete SavedToken.Tok;
729 assert(!Line.InMacroBody);
730 assert(!Line.InPPDirective);
731 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
734FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
735 unsigned AddLevels,
bool MunchSemi,
738 bool UnindentWhitesmithsBraces) {
739 auto HandleVerilogBlockLabel = [
this]() {
741 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
750 const bool VerilogHierarchy =
752 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
755 "'{' or macro block token expected");
756 FormatToken *Tok = FormatTok;
757 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
758 auto Index = CurrentLines->size();
759 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
764 if (!VerilogHierarchy && AddLevels > 0 &&
769 size_t PPStartHash = computePPHash();
771 const unsigned InitialLevel = Line->Level;
772 if (VerilogHierarchy) {
773 AddLevels += parseVerilogHierarchyHeader();
775 nextToken(AddLevels);
776 HandleVerilogBlockLabel();
780 if (Line->Level > 300)
783 if (MacroBlock && FormatTok->
is(tok::l_paren))
786 size_t NbPreprocessorDirectives =
787 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
789 size_t OpeningLineIndex =
790 CurrentLines->empty()
792 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
797 if (UnindentWhitesmithsBraces)
800 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
803 Line->Level += AddLevels;
805 FormatToken *IfLBrace =
nullptr;
806 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
811 if (MacroBlock ? FormatTok->
isNot(TT_MacroBlockEnd)
812 : FormatTok->
isNot(tok::r_brace)) {
813 Line->Level = InitialLevel;
818 if (FormatTok->
is(tok::r_brace)) {
820 if (Tok->is(TT_NamespaceLBrace))
824 const bool IsFunctionRBrace =
825 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
827 auto RemoveBraces = [=]()
mutable {
830 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
831 assert(FormatTok->
is(tok::r_brace));
832 const bool WrappedOpeningBrace = !Tok->Previous;
833 if (WrappedOpeningBrace && FollowedByComment)
835 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
836 if (KeepBraces && !HasRequiredIfBraces)
838 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
839 const FormatToken *
Previous = Tokens->getPreviousToken();
844 assert(!CurrentLines->empty());
845 auto &LastLine = CurrentLines->back();
846 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
848 if (Tok->is(TT_ElseLBrace))
850 if (WrappedOpeningBrace) {
855 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
857 if (RemoveBraces()) {
858 Tok->MatchingParen = FormatTok;
862 size_t PPEndHash = computePPHash();
865 nextToken(-AddLevels);
871 while (FormatTok->
is(tok::semi)) {
877 HandleVerilogBlockLabel();
879 if (MacroBlock && FormatTok->
is(tok::l_paren))
882 Line->Level = InitialLevel;
884 if (FormatTok->
is(tok::kw_noexcept)) {
889 if (FormatTok->
is(tok::arrow)) {
893 parseStructuralElement();
896 if (MunchSemi && FormatTok->
is(tok::semi))
899 if (PPStartHash == PPEndHash) {
900 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
903 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
904 CurrentLines->size() - 1;
914 if (
Line.Tokens.size() < 4)
916 auto I =
Line.Tokens.begin();
917 if (I->Tok->TokenText !=
"goog")
920 if (I->Tok->isNot(tok::period))
923 if (I->Tok->TokenText !=
"scope")
926 return I->Tok->is(tok::l_paren);
935 if (
Line.Tokens.size() < 3)
937 auto I =
Line.Tokens.begin();
938 if (I->Tok->isNot(tok::l_paren))
944 return I->Tok->is(tok::l_paren);
950 if (InitialToken.
is(TT_NamespaceMacro))
951 Kind = tok::kw_namespace;
954 case tok::kw_namespace:
969void UnwrappedLineParser::parseChildBlock() {
970 assert(FormatTok->
is(tok::l_brace));
972 const FormatToken *OpeningBrace = FormatTok;
978 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
980 Line->Level += SkipIndent ? 0 : 1;
981 parseLevel(OpeningBrace);
982 flushComments(isOnNewLine(*FormatTok));
983 Line->Level -= SkipIndent ? 0 : 1;
988void UnwrappedLineParser::parsePPDirective() {
989 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
990 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
1000 case tok::pp_define:
1007 case tok::pp_ifndef:
1011 case tok::pp_elifdef:
1012 case tok::pp_elifndef:
1019 case tok::pp_pragma:
1028void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1029 size_t Line = CurrentLines->size();
1030 if (CurrentLines == &PreprocessorDirectives)
1031 Line += Lines.size();
1034 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1035 PPStack.push_back({PP_Unreachable, Line});
1037 PPStack.push_back({PP_Conditional, Line});
1041void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1043 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1044 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1045 PPLevelBranchIndex.push_back(0);
1046 PPLevelBranchCount.push_back(0);
1048 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1049 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1050 conditionalCompilationCondition(Unreachable || Skip);
1053void UnwrappedLineParser::conditionalCompilationAlternative() {
1054 if (!PPStack.empty())
1056 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1057 if (!PPChainBranchIndex.empty())
1058 ++PPChainBranchIndex.top();
1059 conditionalCompilationCondition(
1060 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1061 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1064void UnwrappedLineParser::conditionalCompilationEnd() {
1065 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1066 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1067 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1068 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1071 if (PPBranchLevel > -1)
1073 if (!PPChainBranchIndex.empty())
1074 PPChainBranchIndex.pop();
1075 if (!PPStack.empty())
1079void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1080 bool IfNDef = FormatTok->
is(tok::pp_ifndef);
1082 bool Unreachable =
false;
1083 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1085 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1087 conditionalCompilationStart(Unreachable);
1088 FormatToken *IfCondition = FormatTok;
1091 bool MaybeIncludeGuard = IfNDef;
1092 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1093 for (
auto &Line : Lines) {
1094 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1095 MaybeIncludeGuard =
false;
1096 IncludeGuard = IG_Rejected;
1104 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1105 IncludeGuard = IG_IfNdefed;
1106 IncludeGuardToken = IfCondition;
1110void UnwrappedLineParser::parsePPElse() {
1112 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1113 IncludeGuard = IG_Rejected;
1115 assert(PPBranchLevel >= -1);
1116 if (PPBranchLevel == -1)
1117 conditionalCompilationStart(
true);
1118 conditionalCompilationAlternative();
1124void UnwrappedLineParser::parsePPEndIf() {
1125 conditionalCompilationEnd();
1129 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1131 IncludeGuard = IG_Found;
1135void UnwrappedLineParser::parsePPDefine() {
1139 IncludeGuard = IG_Rejected;
1140 IncludeGuardToken =
nullptr;
1145 if (IncludeGuard == IG_IfNdefed &&
1147 IncludeGuard = IG_Defined;
1148 IncludeGuardToken =
nullptr;
1149 for (
auto &Line : Lines) {
1150 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1151 IncludeGuard = IG_Rejected;
1165 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1170 Line->Level += PPBranchLevel + 1;
1174 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1175 assert((
int)Line->PPLevel >= 0);
1176 Line->InMacroBody =
true;
1187 if (FormatTok->
is(tok::identifier) &&
1188 Tokens->peekNextToken()->is(tok::colon)) {
1201void UnwrappedLineParser::parsePPPragma() {
1202 Line->InPragmaDirective =
true;
1206void UnwrappedLineParser::parsePPUnknown() {
1211 Line->Level += PPBranchLevel + 1;
1221 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1224 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1225 tok::less, tok::greater, tok::slash, tok::percent,
1226 tok::lessless, tok::greatergreater, tok::equal,
1227 tok::plusequal, tok::minusequal, tok::starequal,
1228 tok::slashequal, tok::percentequal, tok::ampequal,
1229 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1242 return FormatTok->
is(tok::identifier) &&
1257 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1268 tok::kw_if, tok::kw_else,
1270 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1272 tok::kw_switch, tok::kw_case,
1274 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1276 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1284 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1285 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1302 if (FuncName->
isNot(tok::identifier))
1310 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1314 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1318 if (!Tok || Tok->
isNot(tok::r_paren))
1322 if (!Tok || Tok->
isNot(tok::identifier))
1328bool UnwrappedLineParser::parseModuleImport() {
1329 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1331 if (
auto Token = Tokens->peekNextToken(
true);
1333 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1339 if (FormatTok->
is(tok::colon)) {
1343 else if (FormatTok->
is(tok::less)) {
1345 while (!FormatTok->
isOneOf(tok::semi, tok::greater, tok::eof)) {
1348 if (FormatTok->
isNot(tok::comment) &&
1349 !FormatTok->
TokenText.starts_with(
"//")) {
1355 if (FormatTok->
is(tok::semi)) {
1373void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1376 FormatToken *Next = FormatTok;
1379 CommentsBeforeNextToken.empty()
1380 ? Next->NewlinesBefore == 0
1381 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1386 bool PreviousStartsTemplateExpr =
1388 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1391 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1392 return LineNode.Tok->is(tok::at);
1397 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1398 return addUnwrappedLine();
1400 bool NextEndsTemplateExpr =
1401 Next->is(TT_TemplateString) && Next->TokenText.starts_with(
"}");
1402 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1403 (PreviousMustBeValue ||
1404 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1405 tok::minusminus))) {
1406 return addUnwrappedLine();
1408 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1410 return addUnwrappedLine();
1414void UnwrappedLineParser::parseStructuralElement(
1415 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1416 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1418 FormatTok->
is(tok::pp_include)) {
1420 if (FormatTok->
is(tok::string_literal))
1427 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1431 parseForOrWhileLoop(
false);
1435 parseForOrWhileLoop();
1440 parseIfThenElse(IfKind,
false,
true);
1449 }
else if (FormatTok->
is(tok::l_paren) &&
1450 Tokens->peekNextToken()->is(tok::star)) {
1462 if (FormatTok->
is(tok::l_brace)) {
1465 while (FormatTok && !eof()) {
1466 if (FormatTok->
is(tok::r_brace)) {
1477 case tok::kw_namespace:
1480 case tok::kw_public:
1481 case tok::kw_protected:
1482 case tok::kw_private:
1487 parseAccessSpecifier();
1495 FormatToken *Tok = parseIfThenElse(IfKind);
1506 parseForOrWhileLoop();
1517 case tok::kw_switch:
1524 case tok::kw_default:
1533 if (FormatTok->
is(tok::colon)) {
1566 case tok::kw_extern:
1572 parseVerilogHierarchyHeader();
1575 }
else if (FormatTok->
is(tok::string_literal)) {
1577 if (FormatTok->
is(tok::l_brace)) {
1582 unsigned AddLevels =
1589 parseBlock(
true, AddLevels);
1595 case tok::kw_export:
1597 parseJavaScriptEs6ImportExport();
1602 if (FormatTok->
is(tok::kw_namespace)) {
1606 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1610 case tok::kw_inline:
1612 if (FormatTok->
is(tok::kw_namespace)) {
1617 case tok::identifier:
1618 if (FormatTok->
is(TT_ForEachMacro)) {
1619 parseForOrWhileLoop();
1622 if (FormatTok->
is(TT_MacroBlockBegin)) {
1623 parseBlock(
false, 1u,
1629 parseJavaScriptEs6ImportExport();
1634 if (FormatTok->
is(tok::kw_public))
1636 if (FormatTok->
isNot(tok::string_literal))
1639 if (FormatTok->
is(tok::semi))
1644 if (IsCpp && parseModuleImport())
1650 if (FormatTok->
is(tok::colon)) {
1656 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1657 parseStatementMacro();
1660 if (IsCpp && FormatTok->
is(TT_NamespaceMacro)) {
1669 Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
1671 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1684 const bool InRequiresExpression =
1685 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
1691 if (FormatTok->
is(tok::l_brace)) {
1701 case tok::objc_public:
1702 case tok::objc_protected:
1703 case tok::objc_package:
1704 case tok::objc_private:
1705 return parseAccessSpecifier();
1706 case tok::objc_interface:
1707 case tok::objc_implementation:
1708 return parseObjCInterfaceOrImplementation();
1709 case tok::objc_protocol:
1710 if (parseObjCProtocol())
1715 case tok::objc_optional:
1716 case tok::objc_required:
1720 case tok::objc_autoreleasepool:
1722 if (FormatTok->
is(tok::l_brace)) {
1731 case tok::objc_synchronized:
1733 if (FormatTok->
is(tok::l_paren)) {
1737 if (FormatTok->
is(tok::l_brace)) {
1755 case tok::kw_requires: {
1757 bool ParsedClause = parseRequires();
1782 case tok::kw_typedef:
1804 case tok::kw_struct:
1806 if (parseStructLike())
1809 case tok::kw_decltype:
1811 if (FormatTok->
is(tok::l_paren)) {
1816 Line->SeenDecltypeAuto =
true;
1824 FormatTok->
is(tok::kw_class)) {
1841 case tok::l_paren: {
1845 if (OpeningBrace || !IsCpp || !
Previous || eof())
1848 Tokens->peekNextToken(
true),
1855 case tok::kw_operator:
1866 while (FormatTok->
is(tok::star))
1870 if (FormatTok->
is(tok::l_paren))
1873 if (FormatTok->
is(tok::l_brace))
1877 if (InRequiresExpression)
1879 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1880 IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
1898 IsDecltypeAutoFunction =
false;
1916 case tok::identifier: {
1918 Line->MustBeDeclaration) {
1920 parseCSharpGenericTypeConstraint();
1923 if (FormatTok->
is(TT_MacroBlockEnd)) {
1932 size_t TokenCount = Line->Tokens.size();
1936 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1937 tryToParseJSFunction();
1947 unsigned StoredPosition = Tokens->getPosition();
1948 FormatToken *Next = Tokens->getNextToken();
1949 FormatTok = Tokens->setPosition(StoredPosition);
1962 parseVerilogTable();
1974 if (parseStructLike())
1979 if (IsCpp && FormatTok->
is(TT_StatementMacro)) {
1980 parseStatementMacro();
1987 FormatToken *PreviousToken = FormatTok;
1995 auto OneTokenSoFar = [&]() {
1996 auto I = Line->Tokens.begin(), E = Line->Tokens.end();
1997 while (I != E && I->Tok->is(tok::comment))
2000 while (I != E && I->Tok->is(tok::hash))
2002 return I != E && (++I == E);
2004 if (OneTokenSoFar()) {
2007 bool FunctionLike = FormatTok->
is(tok::l_paren);
2011 bool FollowedByNewline =
2012 CommentsBeforeNextToken.empty()
2014 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2016 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
2018 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2019 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2028 FormatTok->
is(TT_FatArrow)) {
2029 tryToParseChildBlock();
2034 if (FormatTok->
is(tok::l_brace)) {
2043 Line->Tokens.begin()->Tok->is(Keywords.
kw_defset)) {
2045 parseBlock(
false, 1u,
2053 FormatTok->
is(tok::less)) {
2055 parseBracedList(
true);
2083 case tok::kw_default:
2086 if (FormatTok->
is(tok::colon)) {
2096 parseVerilogCaseLabel();
2103 parseVerilogCaseLabel();
2114bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2115 assert(FormatTok->
is(tok::l_brace));
2127 unsigned int StoredPosition = Tokens->getPosition();
2128 FormatToken *Tok = Tokens->getNextToken();
2133 bool HasSpecialAccessor =
false;
2134 bool IsTrivialPropertyAccessor =
true;
2136 if (Tok->isOneOf(tok::semi, tok::kw_public, tok::kw_private,
2140 HasSpecialAccessor =
true;
2141 Tok = Tokens->getNextToken();
2144 if (Tok->isNot(tok::r_brace))
2145 IsTrivialPropertyAccessor =
false;
2149 if (!HasSpecialAccessor) {
2150 Tokens->setPosition(StoredPosition);
2156 Tokens->setPosition(StoredPosition);
2164 if (FormatTok->
is(tok::equal)) {
2165 while (!eof() && FormatTok->
isNot(tok::semi))
2178 if (FormatTok->
is(TT_FatArrow)) {
2182 }
while (!eof() && FormatTok->
isNot(tok::semi));
2193 !IsTrivialPropertyAccessor) {
2205bool UnwrappedLineParser::tryToParseLambda() {
2206 assert(FormatTok->
is(tok::l_square));
2211 FormatToken &LSquare = *FormatTok;
2212 if (!tryToParseLambdaIntroducer())
2215 bool SeenArrow =
false;
2216 bool InTemplateParameterList =
false;
2218 while (FormatTok->
isNot(tok::l_brace)) {
2227 parseParens(TT_PointerOrReference);
2235 InTemplateParameterList =
true;
2240 case tok::kw_template:
2241 case tok::kw_typename:
2245 case tok::kw_constexpr:
2246 case tok::kw_consteval:
2249 case tok::identifier:
2250 case tok::numeric_constant:
2251 case tok::coloncolon:
2252 case tok::kw_mutable:
2253 case tok::kw_noexcept:
2254 case tok::kw_static:
2279 case tok::equalequal:
2280 case tok::exclaimequal:
2281 case tok::greaterequal:
2282 case tok::lessequal:
2288 if (SeenArrow || InTemplateParameterList) {
2301 case tok::kw_requires: {
2302 auto *RequiresToken = FormatTok;
2304 parseRequiresClause(RequiresToken);
2308 if (!InTemplateParameterList)
2318 LSquare.setFinalizedType(TT_LambdaLSquare);
2320 NestedLambdas.push_back(Line->SeenDecltypeAuto);
2322 assert(!NestedLambdas.empty());
2323 NestedLambdas.pop_back();
2328bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2330 const FormatToken *LeftSquare = FormatTok;
2333 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2334 tok::kw_co_yield, tok::kw_co_return)) ||
2336 LeftSquare->isCppStructuredBinding(IsCpp)) {
2341 if (FormatTok->
is(tok::r_square)) {
2342 const FormatToken *Next = Tokens->peekNextToken(
true);
2343 if (Next->is(tok::greater))
2350void UnwrappedLineParser::tryToParseJSFunction() {
2358 if (FormatTok->
is(tok::star)) {
2364 if (FormatTok->
is(tok::identifier))
2367 if (FormatTok->
isNot(tok::l_paren))
2373 if (FormatTok->
is(tok::colon)) {
2379 if (FormatTok->
is(tok::l_brace))
2380 tryToParseBracedList();
2382 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2386 if (FormatTok->
is(tok::semi))
2392bool UnwrappedLineParser::tryToParseBracedList() {
2394 calculateBraceTypes();
2403bool UnwrappedLineParser::tryToParseChildBlock() {
2405 assert(FormatTok->
is(TT_FatArrow));
2410 if (FormatTok->
isNot(tok::l_brace))
2416bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2417 assert(!IsAngleBracket || !IsEnum);
2418 bool HasError =
false;
2423 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2424 tryToParseChildBlock()) {
2429 tryToParseJSFunction();
2432 if (FormatTok->
is(tok::l_brace)) {
2434 if (tryToParseBracedList())
2439 if (FormatTok->
is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2460 if (FormatTok->
is(tok::l_brace))
2475 parseBracedList(
true);
2509bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2510 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2511 auto *LeftParen = FormatTok;
2512 bool SeenEqual =
false;
2513 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2518 if (parseParens(AmpAmpTokenType))
2524 if (!MightBeStmtExpr && !Line->InMacroBody &&
2526 const auto *Prev = LeftParen->Previous;
2527 const auto *Next = Tokens->peekNextToken();
2528 const bool DoubleParens =
2529 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2530 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2531 const bool Blacklisted =
2533 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2535 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2536 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2537 const bool ReturnParens =
2539 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2540 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2541 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2542 Next->is(tok::semi);
2543 if ((DoubleParens && !Blacklisted) || ReturnParens) {
2544 LeftParen->Optional =
true;
2557 if (!tryToParseBracedList())
2562 if (FormatTok->
is(tok::l_brace)) {
2569 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2570 tryToParseChildBlock();
2580 case tok::identifier:
2582 tryToParseJSFunction();
2586 case tok::kw_requires: {
2587 auto RequiresToken = FormatTok;
2589 parseRequiresExpression(RequiresToken);
2593 if (AmpAmpTokenType != TT_Unknown)
2604void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2605 if (!LambdaIntroducer) {
2606 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2607 if (tryToParseLambda())
2624 case tok::l_brace: {
2625 if (!tryToParseBracedList())
2631 if (FormatTok->
is(tok::l_brace)) {
2643void UnwrappedLineParser::keepAncestorBraces() {
2647 const int MaxNestingLevels = 2;
2648 const int Size = NestedTooDeep.size();
2649 if (Size >= MaxNestingLevels)
2650 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2651 NestedTooDeep.push_back(
false);
2655 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2662void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2663 FormatToken *Tok =
nullptr;
2665 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2666 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2669 : Line->Tokens.back().Tok;
2671 if (Tok->BraceCount < 0) {
2672 assert(Tok->BraceCount == -1);
2675 Tok->BraceCount = -1;
2681 parseStructuralElement();
2684 assert(!Line->InPPDirective);
2686 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2688 Tok = L.Tokens.back().Tok;
2696 if (CheckEOF && eof())
2706 assert(LeftBrace->
is(tok::l_brace));
2714 assert(RightBrace->
is(tok::r_brace));
2722void UnwrappedLineParser::handleAttributes() {
2726 else if (FormatTok->
is(tok::l_square))
2727 handleCppAttributes();
2730bool UnwrappedLineParser::handleCppAttributes() {
2732 assert(FormatTok->
is(tok::l_square));
2733 if (!tryToParseSimpleAttribute())
2740bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2744 : Tok.is(tok::l_brace);
2747FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2749 bool IsVerilogAssert) {
2750 assert((FormatTok->
is(tok::kw_if) ||
2757 if (IsVerilogAssert) {
2761 if (FormatTok->
is(tok::numeric_constant))
2778 if (FormatTok->
is(tok::exclaim))
2781 bool KeepIfBraces =
true;
2782 if (FormatTok->
is(tok::kw_consteval)) {
2786 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2788 if (FormatTok->
is(tok::l_paren)) {
2795 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2801 bool NeedsUnwrappedLine =
false;
2802 keepAncestorBraces();
2804 FormatToken *IfLeftBrace =
nullptr;
2805 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2807 if (isBlockBegin(*FormatTok)) {
2809 IfLeftBrace = FormatTok;
2811 parseBlock(
false, 1u,
2812 true, KeepIfBraces, &IfBlockKind);
2813 setPreviousRBraceType(TT_ControlStatementRBrace);
2817 NeedsUnwrappedLine =
true;
2818 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2821 parseUnbracedBody();
2825 assert(!NestedTooDeep.empty());
2826 KeepIfBraces = KeepIfBraces ||
2827 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2828 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2829 IfBlockKind == IfStmtKind::IfElseIf;
2832 bool KeepElseBraces = KeepIfBraces;
2833 FormatToken *ElseLeftBrace =
nullptr;
2834 IfStmtKind
Kind = IfStmtKind::IfOnly;
2836 if (FormatTok->
is(tok::kw_else)) {
2838 NestedTooDeep.back() =
false;
2839 Kind = IfStmtKind::IfElse;
2843 if (isBlockBegin(*FormatTok)) {
2844 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2846 ElseLeftBrace = FormatTok;
2848 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2849 FormatToken *IfLBrace =
2850 parseBlock(
false, 1u,
2851 true, KeepElseBraces, &ElseBlockKind);
2852 setPreviousRBraceType(TT_ElseRBrace);
2853 if (FormatTok->
is(tok::kw_else)) {
2854 KeepElseBraces = KeepElseBraces ||
2855 ElseBlockKind == IfStmtKind::IfOnly ||
2856 ElseBlockKind == IfStmtKind::IfElseIf;
2857 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2858 KeepElseBraces =
true;
2859 assert(ElseLeftBrace->MatchingParen);
2863 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2864 const FormatToken *
Previous = Tokens->getPreviousToken();
2866 const bool IsPrecededByComment =
Previous->is(tok::comment);
2867 if (IsPrecededByComment) {
2871 bool TooDeep =
true;
2873 Kind = IfStmtKind::IfElseIf;
2874 TooDeep = NestedTooDeep.pop_back_val();
2876 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2878 NestedTooDeep.push_back(TooDeep);
2879 if (IsPrecededByComment)
2882 parseUnbracedBody(
true);
2885 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2886 if (NeedsUnwrappedLine)
2893 assert(!NestedTooDeep.empty());
2894 KeepElseBraces = KeepElseBraces ||
2895 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2896 NestedTooDeep.back();
2898 NestedTooDeep.pop_back();
2900 if (!KeepIfBraces && !KeepElseBraces) {
2903 }
else if (IfLeftBrace) {
2904 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2906 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2907 assert(!IfLeftBrace->Optional);
2908 assert(!IfRightBrace->Optional);
2909 IfLeftBrace->MatchingParen =
nullptr;
2910 IfRightBrace->MatchingParen =
nullptr;
2920void UnwrappedLineParser::parseTryCatch() {
2921 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2923 bool NeedsUnwrappedLine =
false;
2924 if (FormatTok->
is(tok::colon)) {
2930 while (FormatTok->
is(tok::comma))
2933 while (FormatTok->
is(tok::identifier)) {
2935 if (FormatTok->
is(tok::l_paren))
2938 FormatTok->
is(tok::l_brace)) {
2941 }
while (FormatTok->
isNot(tok::r_brace));
2947 while (FormatTok->
is(tok::comma))
2955 keepAncestorBraces();
2957 if (FormatTok->
is(tok::l_brace)) {
2963 NeedsUnwrappedLine =
true;
2964 }
else if (FormatTok->
isNot(tok::kw_catch)) {
2970 parseStructuralElement();
2974 if (FormatTok->
is(tok::at))
2977 tok::kw___finally) ||
2985 while (FormatTok->
isNot(tok::l_brace)) {
2986 if (FormatTok->
is(tok::l_paren)) {
2990 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
2992 NestedTooDeep.pop_back();
2997 NeedsUnwrappedLine =
false;
2998 Line->MustBeDeclaration =
false;
3004 NeedsUnwrappedLine =
true;
3008 NestedTooDeep.pop_back();
3010 if (NeedsUnwrappedLine)
3014void UnwrappedLineParser::parseNamespace() {
3015 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3016 "'namespace' expected");
3018 const FormatToken &InitialToken = *FormatTok;
3020 if (InitialToken.is(TT_NamespaceMacro)) {
3023 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3024 tok::l_square, tok::period, tok::l_paren) ||
3025 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
3026 if (FormatTok->
is(tok::l_square))
3028 else if (FormatTok->
is(tok::l_paren))
3034 if (FormatTok->
is(tok::l_brace)) {
3040 unsigned AddLevels =
3043 DeclarationScopeStack.size() > 1)
3046 bool ManageWhitesmithsBraces =
3052 if (ManageWhitesmithsBraces)
3057 parseBlock(
true, AddLevels,
true,
3059 ManageWhitesmithsBraces);
3061 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3063 if (ManageWhitesmithsBraces)
3069void UnwrappedLineParser::parseNew() {
3070 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
3076 if (FormatTok->
is(tok::l_paren))
3080 if (FormatTok->
is(tok::l_brace))
3083 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3096 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3100 if (FormatTok->
is(tok::l_paren)) {
3104 if (FormatTok->
is(tok::l_brace))
3112void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3113 keepAncestorBraces();
3115 if (isBlockBegin(*FormatTok)) {
3117 FormatToken *LeftBrace = FormatTok;
3119 parseBlock(
false, 1u,
3121 setPreviousRBraceType(TT_ControlStatementRBrace);
3123 assert(!NestedTooDeep.empty());
3124 if (!NestedTooDeep.back())
3130 parseUnbracedBody();
3134 NestedTooDeep.pop_back();
3137void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3138 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3145 "'for', 'while' or foreach macro expected");
3147 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3153 if (IsCpp && FormatTok->
is(tok::kw_co_await))
3155 if (HasParens && FormatTok->
is(tok::l_paren)) {
3166 parseVerilogSensitivityList();
3168 Tokens->getPreviousToken()->is(tok::r_paren)) {
3175 parseLoopBody(KeepBraces,
true);
3178void UnwrappedLineParser::parseDoWhile() {
3179 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3185 if (FormatTok->
isNot(tok::kw_while)) {
3198 parseStructuralElement();
3201void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3203 unsigned OldLineLevel = Line->Level;
3204 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3210 FormatTok->
is(tok::l_brace)) {
3216 if (FormatTok->
is(tok::kw_break)) {
3225 parseStructuralElement();
3229 if (FormatTok->
is(tok::semi))
3233 Line->Level = OldLineLevel;
3234 if (FormatTok->
isNot(tok::l_brace)) {
3235 parseStructuralElement();
3240void UnwrappedLineParser::parseCaseLabel() {
3241 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3246 if (FormatTok->
is(tok::colon)) {
3254void UnwrappedLineParser::parseSwitch() {
3255 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3257 if (FormatTok->
is(tok::l_paren))
3260 keepAncestorBraces();
3262 if (FormatTok->
is(tok::l_brace)) {
3266 setPreviousRBraceType(TT_ControlStatementRBrace);
3271 parseStructuralElement();
3276 NestedTooDeep.pop_back();
3286 case tok::caretequal:
3290 case tok::equalequal:
3292 case tok::exclaimequal:
3294 case tok::greaterequal:
3295 case tok::greatergreater:
3296 case tok::greatergreaterequal:
3300 case tok::lessequal:
3302 case tok::lesslessequal:
3304 case tok::minusequal:
3305 case tok::minusminus:
3307 case tok::percentequal:
3310 case tok::pipeequal:
3313 case tok::plusequal:
3321 case tok::slashequal:
3323 case tok::starequal:
3330void UnwrappedLineParser::parseAccessSpecifier() {
3331 FormatToken *AccessSpecifierCandidate = FormatTok;
3337 if (FormatTok->
is(tok::colon)) {
3340 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3344 }
else if (AccessSpecifierCandidate) {
3346 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3353bool clang::format::UnwrappedLineParser::parseRequires() {
3354 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3355 auto RequiresToken = FormatTok;
3361 switch (FormatTok->Tok.getKind()) {
3364 parseRequiresExpression(RequiresToken);
3371 parseRequiresClause(RequiresToken);
3382 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3384 if (!PreviousNonComment ||
3385 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3388 parseRequiresClause(RequiresToken);
3392 switch (PreviousNonComment->Tok.getKind()) {
3395 case tok::kw_noexcept:
3398 parseRequiresClause(RequiresToken);
3408 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3409 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3410 parseRequiresClause(RequiresToken);
3416 if (PreviousNonComment->isTypeOrIdentifier(IsCpp)) {
3418 parseRequiresClause(RequiresToken);
3422 parseRequiresExpression(RequiresToken);
3435 auto PeekNext = [&Lookahead, &NextToken,
this] {
3440 bool FoundType =
false;
3441 bool LastWasColonColon =
false;
3444 for (; Lookahead < 50; PeekNext()) {
3445 switch (NextToken->Tok.getKind()) {
3446 case tok::kw_volatile:
3449 if (OpenAngles == 0) {
3451 parseRequiresExpression(RequiresToken);
3459 case tok::coloncolon:
3460 LastWasColonColon =
true;
3462 case tok::kw_decltype:
3463 case tok::identifier:
3464 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3466 parseRequiresExpression(RequiresToken);
3470 LastWasColonColon =
false;
3479 if (NextToken->isTypeName(IsCpp)) {
3481 parseRequiresExpression(RequiresToken);
3489 parseRequiresClause(RequiresToken);
3500void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3502 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3507 bool InRequiresExpression =
3508 !RequiresToken->Previous ||
3509 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3511 RequiresToken->setFinalizedType(InRequiresExpression
3512 ? TT_RequiresClauseInARequiresExpression
3513 : TT_RequiresClause);
3517 parseConstraintExpression();
3519 if (!InRequiresExpression)
3530void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3532 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3534 RequiresToken->setFinalizedType(TT_RequiresExpression);
3536 if (FormatTok->
is(tok::l_paren)) {
3541 if (FormatTok->
is(tok::l_brace)) {
3551void UnwrappedLineParser::parseConstraintExpression() {
3558 bool LambdaNextTimeAllowed =
true;
3568 bool TopLevelParensAllowed =
true;
3571 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3574 case tok::kw_requires: {
3575 auto RequiresToken = FormatTok;
3577 parseRequiresExpression(RequiresToken);
3582 if (!TopLevelParensAllowed)
3584 parseParens(TT_BinaryOperator);
3585 TopLevelParensAllowed =
false;
3589 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3596 case tok::kw_struct:
3608 LambdaNextTimeAllowed =
true;
3609 TopLevelParensAllowed =
true;
3614 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3618 case tok::kw_sizeof:
3620 case tok::greaterequal:
3621 case tok::greatergreater:
3623 case tok::lessequal:
3625 case tok::equalequal:
3627 case tok::exclaimequal:
3632 LambdaNextTimeAllowed =
true;
3633 TopLevelParensAllowed =
true;
3638 case tok::numeric_constant:
3639 case tok::coloncolon:
3642 TopLevelParensAllowed =
false;
3647 case tok::kw_static_cast:
3648 case tok::kw_const_cast:
3649 case tok::kw_reinterpret_cast:
3650 case tok::kw_dynamic_cast:
3652 if (FormatTok->
isNot(tok::less))
3656 parseBracedList(
true);
3672 case tok::coloncolon:
3676 case tok::kw_requires:
3685 if (FormatTok->
is(tok::less)) {
3687 parseBracedList(
true);
3689 TopLevelParensAllowed =
false;
3695bool UnwrappedLineParser::parseEnum() {
3696 const FormatToken &InitialToken = *FormatTok;
3699 if (FormatTok->
is(tok::kw_enum))
3714 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3716 while (FormatTok->
is(tok::l_square))
3717 if (!handleCppAttributes())
3722 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3723 tok::greater, tok::comma, tok::question,
3729 while (FormatTok->
is(tok::l_square))
3735 if (FormatTok->
is(tok::l_paren))
3737 if (FormatTok->
is(tok::identifier)) {
3741 if (IsCpp && FormatTok->
is(tok::identifier))
3747 if (FormatTok->
isNot(tok::l_brace))
3754 parseJavaEnumBody();
3772 bool HasError = !parseBracedList(
false,
true);
3776 if (FormatTok->
is(tok::semi))
3780 setPreviousRBraceType(TT_EnumRBrace);
3788bool UnwrappedLineParser::parseStructLike() {
3795 if (FormatTok->
is(tok::semi))
3806class ScopedTokenPosition {
3807 unsigned StoredPosition;
3808 FormatTokenSource *Tokens;
3811 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3812 assert(Tokens &&
"Tokens expected to not be null");
3813 StoredPosition = Tokens->getPosition();
3816 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3822bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3823 ScopedTokenPosition AutoPosition(Tokens);
3824 FormatToken *Tok = Tokens->getNextToken();
3826 if (Tok->isNot(tok::l_square))
3830 while (Tok->isNot(tok::eof)) {
3831 if (Tok->is(tok::r_square))
3833 Tok = Tokens->getNextToken();
3835 if (Tok->is(tok::eof))
3837 Tok = Tokens->getNextToken();
3838 if (Tok->isNot(tok::r_square))
3840 Tok = Tokens->getNextToken();
3841 if (Tok->is(tok::semi))
3846void UnwrappedLineParser::parseJavaEnumBody() {
3847 assert(FormatTok->
is(tok::l_brace));
3848 const FormatToken *OpeningBrace = FormatTok;
3853 unsigned StoredPosition = Tokens->getPosition();
3854 bool IsSimple =
true;
3855 FormatToken *Tok = Tokens->getNextToken();
3856 while (Tok->isNot(tok::eof)) {
3857 if (Tok->is(tok::r_brace))
3859 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3865 Tok = Tokens->getNextToken();
3867 FormatTok = Tokens->setPosition(StoredPosition);
3884 if (FormatTok->
is(tok::l_brace)) {
3886 parseBlock(
true, 1u,
3888 }
else if (FormatTok->
is(tok::l_paren)) {
3890 }
else if (FormatTok->
is(tok::comma)) {
3893 }
else if (FormatTok->
is(tok::semi)) {
3897 }
else if (FormatTok->
is(tok::r_brace)) {
3906 parseLevel(OpeningBrace);
3912void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
3913 const FormatToken &InitialToken = *FormatTok;
3916 const FormatToken *ClassName =
nullptr;
3917 bool IsDerived =
false;
3918 auto IsNonMacroIdentifier = [](
const FormatToken *Tok) {
3919 return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
3924 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3925 tok::kw_alignas, tok::l_square) ||
3928 FormatTok->
isOneOf(tok::period, tok::comma))) {
3935 if (FormatTok->
is(tok::l_brace)) {
3936 tryToParseBracedList();
3940 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
3947 if (!IsNonMacroIdentifier(
Previous))
3950 case tok::coloncolon:
3953 if (!ClassName &&
Previous->is(tok::identifier))
3958 auto IsListInitialization = [&] {
3959 if (!ClassName || IsDerived)
3961 assert(FormatTok->
is(tok::l_brace));
3964 return Prev != ClassName && Prev->is(tok::identifier) &&
3965 Prev->isNot(Keywords.
kw_final) && tryToParseBracedList();
3968 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
3969 if (FormatTok->
is(tok::colon))
3971 int AngleNestingLevel = 0;
3973 if (FormatTok->
is(tok::less))
3974 ++AngleNestingLevel;
3975 else if (FormatTok->
is(tok::greater))
3976 --AngleNestingLevel;
3978 if (AngleNestingLevel == 0 && FormatTok->
is(tok::l_paren) &&
3979 IsNonMacroIdentifier(FormatTok->
Previous)) {
3982 if (FormatTok->
is(tok::l_brace)) {
3983 if (AngleNestingLevel == 0 && IsListInitialization())
3985 calculateBraceTypes(
true);
3986 if (!tryToParseBracedList())
3989 if (FormatTok->
is(tok::l_square)) {
3992 !
Previous->isTypeOrIdentifier(IsCpp))) {
3995 if (!tryToParseLambda())
4002 if (FormatTok->
is(tok::semi))
4007 parseCSharpGenericTypeConstraint();
4014 auto GetBraceTypes =
4015 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4016 switch (RecordTok.Tok.getKind()) {
4018 return {TT_ClassLBrace, TT_ClassRBrace};
4019 case tok::kw_struct:
4020 return {TT_StructLBrace, TT_StructRBrace};
4022 return {TT_UnionLBrace, TT_UnionRBrace};
4025 return {TT_RecordLBrace, TT_RecordRBrace};
4028 if (FormatTok->
is(tok::l_brace)) {
4029 if (IsListInitialization())
4031 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4040 parseBlock(
true, AddLevels,
false);
4042 setPreviousRBraceType(ClosingBraceType);
4049void UnwrappedLineParser::parseObjCMethod() {
4050 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
4051 "'(' or identifier expected.");
4053 if (FormatTok->
is(tok::semi)) {
4057 }
else if (FormatTok->
is(tok::l_brace)) {
4069void UnwrappedLineParser::parseObjCProtocolList() {
4070 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
4074 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4078 }
while (!eof() && FormatTok->
isNot(tok::greater));
4082void UnwrappedLineParser::parseObjCUntilAtEnd() {
4089 if (FormatTok->
is(tok::l_brace)) {
4093 }
else if (FormatTok->
is(tok::r_brace)) {
4097 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
4101 parseStructuralElement();
4106void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4114 if (FormatTok->
is(tok::less))
4115 parseObjCLightweightGenerics();
4116 if (FormatTok->
is(tok::colon)) {
4120 if (FormatTok->
is(tok::less))
4121 parseObjCLightweightGenerics();
4122 }
else if (FormatTok->
is(tok::l_paren)) {
4127 if (FormatTok->
is(tok::less))
4128 parseObjCProtocolList();
4130 if (FormatTok->
is(tok::l_brace)) {
4140 parseObjCUntilAtEnd();
4143void UnwrappedLineParser::parseObjCLightweightGenerics() {
4144 assert(FormatTok->
is(tok::less));
4152 unsigned NumOpenAngles = 1;
4156 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4160 if (FormatTok->
is(tok::less)) {
4162 }
else if (FormatTok->
is(tok::greater)) {
4163 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4166 }
while (!eof() && NumOpenAngles != 0);
4172bool UnwrappedLineParser::parseObjCProtocol() {
4176 if (FormatTok->
is(tok::l_paren)) {
4188 if (FormatTok->
is(tok::less))
4189 parseObjCProtocolList();
4192 if (FormatTok->
is(tok::semi)) {
4199 parseObjCUntilAtEnd();
4203void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4204 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4205 assert(IsImport || FormatTok->
is(tok::kw_export));
4209 if (FormatTok->
is(tok::kw_default))
4226 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4229 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4234 if (FormatTok->
is(tok::semi))
4236 if (Line->Tokens.empty()) {
4241 if (FormatTok->
is(tok::l_brace)) {
4251void UnwrappedLineParser::parseStatementMacro() {
4253 if (FormatTok->
is(tok::l_paren))
4255 if (FormatTok->
is(tok::semi))
4260void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4263 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4264 tok::coloncolon, tok::hash) ||
4267 }
else if (FormatTok->
is(tok::l_square)) {
4275void UnwrappedLineParser::parseVerilogSensitivityList() {
4276 if (FormatTok->
isNot(tok::at))
4280 if (FormatTok->
is(tok::at))
4290 parseVerilogHierarchyIdentifier();
4295unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4296 unsigned AddLevels = 0;
4302 parseVerilogSensitivityList();
4303 if (FormatTok->
is(tok::semi))
4311 if (FormatTok->
is(tok::l_paren)) {
4324 if (FormatTok->
is(tok::l_square)) {
4339 Line->IsContinuation =
true;
4346 parseVerilogHierarchyIdentifier();
4347 if (FormatTok->
is(tok::semi))
4355 if (FormatTok->
is(tok::l_paren)) {
4360 if (FormatTok->
is(tok::l_paren)) {
4370 parseVerilogHierarchyIdentifier();
4371 if (FormatTok->
is(tok::l_paren))
4378 parseVerilogHierarchyIdentifier();
4379 }
while (FormatTok->
is(tok::comma));
4383 if (FormatTok->
is(tok::at)) {
4385 parseVerilogSensitivityList();
4388 if (FormatTok->
is(tok::semi))
4396void UnwrappedLineParser::parseVerilogTable() {
4401 auto InitialLevel = Line->Level++;
4403 FormatToken *Tok = FormatTok;
4405 if (Tok->is(tok::semi))
4407 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4408 Tok->setFinalizedType(TT_VerilogTableItem);
4410 Line->Level = InitialLevel;
4415void UnwrappedLineParser::parseVerilogCaseLabel() {
4421 auto OrigLevel = Line->Level;
4422 auto FirstLine = CurrentLines->size();
4423 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4427 parseStructuralElement();
4430 if (CurrentLines->size() > FirstLine)
4431 (*CurrentLines)[FirstLine].Level = OrigLevel;
4432 Line->Level = OrigLevel;
4435bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4436 for (
const auto &N : Line.Tokens) {
4437 if (N.Tok->MacroCtx)
4439 for (
const UnwrappedLine &Child : N.Children)
4440 if (containsExpansion(Child))
4446void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4447 if (Line->Tokens.empty())
4450 if (!parsingPPDirective()) {
4451 llvm::dbgs() <<
"Adding unwrapped line:\n";
4452 printDebugInfo(*Line);
4460 bool ClosesWhitesmithsBlock =
4467 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4469 Reconstruct.emplace(Line->Level, Unexpanded);
4470 Reconstruct->addLine(*Line);
4475 CurrentExpandedLines.push_back(std::move(*Line));
4477 if (Reconstruct->finished()) {
4478 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4479 assert(!Reconstructed.Tokens.empty() &&
4480 "Reconstructed must at least contain the macro identifier.");
4481 assert(!parsingPPDirective());
4483 llvm::dbgs() <<
"Adding unexpanded line:\n";
4484 printDebugInfo(Reconstructed);
4486 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4487 Lines.push_back(std::move(Reconstructed));
4488 CurrentExpandedLines.clear();
4489 Reconstruct.reset();
4494 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4495 CurrentLines->push_back(std::move(*Line));
4497 Line->Tokens.clear();
4499 Line->FirstStartColumn = 0;
4500 Line->IsContinuation =
false;
4501 Line->SeenDecltypeAuto =
false;
4503 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4505 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4506 CurrentLines->append(
4507 std::make_move_iterator(PreprocessorDirectives.begin()),
4508 std::make_move_iterator(PreprocessorDirectives.end()));
4509 PreprocessorDirectives.clear();
4515bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4517bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4518 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4519 FormatTok.NewlinesBefore > 0;
4527 const llvm::Regex &CommentPragmasRegex) {
4528 if (
Line.Tokens.empty())
4531 StringRef IndentContent = FormatTok.
TokenText;
4532 if (FormatTok.
TokenText.starts_with(
"//") ||
4533 FormatTok.
TokenText.starts_with(
"/*")) {
4534 IndentContent = FormatTok.
TokenText.substr(2);
4536 if (CommentPragmasRegex.match(IndentContent))
4611 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4613 MinColumnToken = PreviousToken;
4616 PreviousToken =
Node.Tok;
4619 if (
Node.Tok->NewlinesBefore > 0)
4620 MinColumnToken =
Node.Tok;
4622 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4623 MinColumnToken = PreviousToken;
4629void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4630 bool JustComments = Line->Tokens.empty();
4631 for (FormatToken *Tok : CommentsBeforeNextToken) {
4640 Tok->ContinuesLineCommentSection =
4642 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4646 if (NewlineBeforeNext && JustComments)
4648 CommentsBeforeNextToken.clear();
4651void UnwrappedLineParser::nextToken(
int LevelDifference) {
4654 flushComments(isOnNewLine(*FormatTok));
4655 pushToken(FormatTok);
4658 readToken(LevelDifference);
4660 readTokenWithJavaScriptASI();
4670 FormatTok->Tok.setKind(tok::r_brace);
4674void UnwrappedLineParser::distributeComments(
4675 const SmallVectorImpl<FormatToken *> &Comments,
4676 const FormatToken *NextTok) {
4695 if (Comments.empty())
4697 bool ShouldPushCommentsInCurrentLine =
true;
4698 bool HasTrailAlignedWithNextToken =
false;
4699 unsigned StartOfTrailAlignedWithNextToken = 0;
4702 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4703 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4704 HasTrailAlignedWithNextToken =
true;
4705 StartOfTrailAlignedWithNextToken = i;
4709 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4710 FormatToken *FormatTok = Comments[i];
4711 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4712 FormatTok->ContinuesLineCommentSection =
false;
4714 FormatTok->ContinuesLineCommentSection =
4717 if (!FormatTok->ContinuesLineCommentSection &&
4718 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4719 ShouldPushCommentsInCurrentLine =
false;
4721 if (ShouldPushCommentsInCurrentLine)
4722 pushToken(FormatTok);
4724 CommentsBeforeNextToken.push_back(FormatTok);
4728void UnwrappedLineParser::readToken(
int LevelDifference) {
4729 SmallVector<FormatToken *, 1> Comments;
4730 bool PreviousWasComment =
false;
4731 bool FirstNonCommentOnLine =
false;
4733 FormatTok = Tokens->getNextToken();
4735 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
4736 TT_ConflictAlternative)) {
4737 if (FormatTok->is(TT_ConflictStart))
4738 conditionalCompilationStart(
false);
4739 else if (FormatTok->is(TT_ConflictAlternative))
4740 conditionalCompilationAlternative();
4741 else if (FormatTok->is(TT_ConflictEnd))
4742 conditionalCompilationEnd();
4743 FormatTok = Tokens->getNextToken();
4744 FormatTok->MustBreakBefore =
true;
4745 FormatTok->MustBreakBeforeFinalized =
true;
4748 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4749 const FormatToken &Tok,
4750 bool PreviousWasComment) {
4751 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4752 return Tok.HasUnescapedNewline || Tok.IsFirst;
4757 if (PreviousWasComment)
4758 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4759 return IsFirstOnLine(Tok);
4762 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4763 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4764 PreviousWasComment = FormatTok->is(tok::comment);
4766 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4769 FirstNonCommentOnLine) {
4770 distributeComments(Comments, FormatTok);
4774 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4776 assert((LevelDifference >= 0 ||
4777 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4778 "LevelDifference makes Line->Level negative");
4779 Line->Level += LevelDifference;
4784 PPBranchLevel > 0) {
4785 Line->Level += PPBranchLevel;
4787 flushComments(isOnNewLine(*FormatTok));
4789 PreviousWasComment = FormatTok->is(tok::comment);
4790 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4791 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4794 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4795 !Line->InPPDirective) {
4799 if (FormatTok->is(tok::identifier) &&
4800 Macros.
defined(FormatTok->TokenText) &&
4802 !Line->InPPDirective) {
4803 FormatToken *
ID = FormatTok;
4804 unsigned Position = Tokens->getPosition();
4808 auto PreCall = std::move(Line);
4809 Line.reset(
new UnwrappedLine);
4810 bool OldInExpansion = InExpansion;
4813 auto Args = parseMacroCall();
4814 InExpansion = OldInExpansion;
4815 assert(Line->Tokens.front().Tok ==
ID);
4817 auto UnexpandedLine = std::move(Line);
4819 Line = std::move(PreCall);
4822 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4824 llvm::dbgs() <<
"(";
4825 for (
const auto &Arg : Args.value())
4826 for (
const auto &
T : Arg)
4827 llvm::dbgs() <<
T->TokenText <<
" ";
4828 llvm::dbgs() <<
")";
4830 llvm::dbgs() <<
"\n";
4833 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4839 LLVM_DEBUG(llvm::dbgs()
4840 <<
"Macro \"" <<
ID->TokenText
4841 <<
"\" not overloaded for arity " << Args->size()
4842 <<
"or not function-like, using object-like overload.");
4844 UnexpandedLine->Tokens.resize(1);
4845 Tokens->setPosition(Position);
4850 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4853 Unexpanded[
ID] = std::move(UnexpandedLine);
4854 SmallVector<FormatToken *, 8> Expansion =
4855 Macros.
expand(
ID, std::move(Args));
4856 if (!Expansion.empty())
4857 FormatTok = Tokens->insertTokens(Expansion);
4860 llvm::dbgs() <<
"Expanded: ";
4861 for (
const auto &
T : Expansion)
4862 llvm::dbgs() <<
T->TokenText <<
" ";
4863 llvm::dbgs() <<
"\n";
4867 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4868 <<
"\", because it was used ";
4870 llvm::dbgs() <<
"with " << Args->size();
4872 llvm::dbgs() <<
"without";
4873 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4875 Tokens->setPosition(Position);
4880 if (FormatTok->isNot(tok::comment)) {
4881 distributeComments(Comments, FormatTok);
4886 Comments.push_back(FormatTok);
4889 distributeComments(Comments,
nullptr);
4894template <
typename Iterator>
4895void pushTokens(Iterator
Begin, Iterator End,
4897 for (
auto I =
Begin; I != End; ++I) {
4898 Into.push_back(I->Tok);
4899 for (
const auto &Child : I->Children)
4900 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
4905std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
4906UnwrappedLineParser::parseMacroCall() {
4907 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
4908 assert(Line->Tokens.empty());
4910 if (FormatTok->isNot(tok::l_paren))
4912 unsigned Position = Tokens->getPosition();
4913 FormatToken *Tok = FormatTok;
4916 auto ArgStart = std::prev(Line->Tokens.end());
4920 switch (FormatTok->Tok.getKind()) {
4925 case tok::r_paren: {
4931 Args->push_back({});
4932 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4941 Args->push_back({});
4942 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4944 ArgStart = std::prev(Line->Tokens.end());
4952 Line->Tokens.resize(1);
4953 Tokens->setPosition(Position);
4958void UnwrappedLineParser::pushToken(FormatToken *Tok) {
4959 Line->Tokens.push_back(UnwrappedLineNode(Tok));
4960 if (MustBreakBeforeNextToken) {
4961 Line->Tokens.back().Tok->MustBreakBefore =
true;
4962 Line->Tokens.back().Tok->MustBreakBeforeFinalized =
true;
4963 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.
IdentifierInfo * getIdentifierInfo() const
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
void setKind(tok::TokenKind K)
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
tok::TokenKind getKind() const
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
void setIdentifierInfo(IdentifierInfo *II)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isLiteral(TokenKind K)
Return true if this is a "literal" kind, like a numeric constant, string, etc.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
@ Parens
New-expression has a C++98 paren-delimited initializer.