21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/Debug.h"
24#include "llvm/Support/raw_os_ostream.h"
25#include "llvm/Support/raw_ostream.h"
29#define DEBUG_TYPE "format-parser"
36void printLine(llvm::raw_ostream &OS,
const UnwrappedLine &
Line,
37 StringRef Prefix =
"",
bool PrintText =
false) {
38 OS << Prefix <<
"Line(" <<
Line.Level <<
", FSC=" <<
Line.FirstStartColumn
39 <<
")" << (
Line.InPPDirective ?
" MACRO" :
"") <<
": ";
41 for (std::list<UnwrappedLineNode>::const_iterator I =
Line.Tokens.begin(),
42 E =
Line.Tokens.end();
48 OS << I->Tok->Tok.getName() <<
"["
49 <<
"T=" << (
unsigned)I->Tok->getType()
50 <<
", OC=" << I->Tok->OriginalColumn <<
", \"" << I->Tok->TokenText
52 for (
const auto *CI = I->Children.begin(), *CE = I->Children.end();
55 printLine(OS, *CI, (Prefix +
" ").str());
63[[maybe_unused]]
static void printDebugInfo(
const UnwrappedLine &
Line) {
64 printLine(llvm::dbgs(),
Line);
67class ScopedDeclarationState {
69 ScopedDeclarationState(UnwrappedLine &
Line, llvm::BitVector &Stack,
70 bool MustBeDeclaration)
72 Line.MustBeDeclaration = MustBeDeclaration;
73 Stack.push_back(MustBeDeclaration);
75 ~ScopedDeclarationState() {
78 Line.MustBeDeclaration = Stack.back();
80 Line.MustBeDeclaration =
true;
85 llvm::BitVector &Stack;
91 llvm::raw_os_ostream OS(Stream);
100 bool SwitchToPreprocessorLines =
false,
101 bool DiscardLines =
false)
102 : Parser(Parser), OriginalLines(Parser.CurrentLines),
103 DiscardLines(DiscardLines) {
104 if (SwitchToPreprocessorLines)
105 Parser.CurrentLines = &Parser.PreprocessorDirectives;
106 else if (!Parser.Line->Tokens.empty())
107 Parser.CurrentLines = &Parser.Line->Tokens.back().Children;
108 OriginalNumLines = Parser.CurrentLines->size();
109 PreBlockLine = std::move(Parser.Line);
110 Parser.Line = std::make_unique<UnwrappedLine>();
111 Parser.Line->Level = PreBlockLine->Level;
112 Parser.Line->PPLevel = PreBlockLine->PPLevel;
113 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
114 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
115 Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel;
119 if (!Parser.Line->Tokens.empty())
120 Parser.addUnwrappedLine();
121 assert(Parser.Line->Tokens.empty());
123 Parser.CurrentLines->truncate(OriginalNumLines);
124 Parser.Line = std::move(PreBlockLine);
125 if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
126 Parser.PP.AtEndOfPPLine =
true;
127 Parser.CurrentLines = OriginalLines;
133 std::unique_ptr<UnwrappedLine> PreBlockLine;
135 size_t OriginalNumLines;
144 Style.BraceWrapping.AfterControlStatement ==
146 Style.BraceWrapping.IndentBraces) {}
148 bool WrapBrace,
bool IndentBrace)
149 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
151 Parser->addUnwrappedLine();
159 unsigned OldLineLevel;
166 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
168 : Line(new
UnwrappedLine), CurrentLines(&Lines), Style(Style),
170 Keywords(Keywords), CommentPragmasRegex(Style.CommentPragmas),
171 Tokens(
nullptr), Callback(Callback), AllTokens(Tokens),
172 PP(getIncludeGuardState(Style.IndentPPDirectives)),
173 FirstStartColumn(FirstStartColumn),
174 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}
176void UnwrappedLineParser::reset() {
178 PP.IncludeGuard = getIncludeGuardState(Style.IndentPPDirectives);
179 PP.IncludeGuardToken =
nullptr;
180 ParsedPPDirectives.clear();
182 CommentsBeforeNextToken.clear();
184 PP.AtEndOfPPLine =
false;
185 IsDecltypeAutoFunction =
false;
186 PreprocessorDirectives.clear();
187 CurrentLines = &Lines;
188 DeclarationScopeStack.clear();
189 NestedTooDeep.clear();
190 NestedLambdas.clear();
192 Line->FirstStartColumn = FirstStartColumn;
194 if (!Unexpanded.empty())
196 Token->MacroCtx.reset();
197 CurrentExpandedLines.clear();
198 ExpandedLines.clear();
206 Line->FirstStartColumn = FirstStartColumn;
208 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
210 Tokens = &TokenSource;
218 if (PP.IncludeGuard == IG_Found) {
219 for (
auto &Line : Lines)
220 if (Line.InPPDirective && Line.Level > 0)
226 pushToken(FormatTok);
231 if (!ExpandedLines.empty()) {
232 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
233 for (
const auto &Line : Lines) {
234 if (!Line.Tokens.empty()) {
235 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
236 if (it != ExpandedLines.end()) {
237 for (
const auto &Expanded : it->second) {
238 LLVM_DEBUG(printDebugInfo(Expanded));
239 Callback.consumeUnwrappedLine(Expanded);
244 LLVM_DEBUG(printDebugInfo(Line));
245 Callback.consumeUnwrappedLine(Line);
247 Callback.finishRun();
250 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
252 LLVM_DEBUG(printDebugInfo(Line));
253 Callback.consumeUnwrappedLine(Line);
255 Callback.finishRun();
257 while (!PP.LevelBranchIndex.empty() &&
258 PP.LevelBranchIndex.back() + 1 >= PP.LevelBranchCount.back()) {
259 PP.LevelBranchIndex.resize(PP.LevelBranchIndex.size() - 1);
260 PP.LevelBranchCount.resize(PP.LevelBranchCount.size() - 1);
262 if (!PP.LevelBranchIndex.empty()) {
263 ++PP.LevelBranchIndex.back();
264 assert(PP.LevelBranchIndex.size() == PP.LevelBranchCount.size());
265 assert(PP.LevelBranchIndex.back() <= PP.LevelBranchCount.back());
267 }
while (!PP.LevelBranchIndex.empty());
270void UnwrappedLineParser::parseFile() {
273 bool MustBeDeclaration = !
Line->InPPDirective && !Style.isJavaScript();
274 ScopedDeclarationState DeclarationState(*
Line, DeclarationScopeStack,
276 if (Style.isTextProto() || (Style.isJson() && FormatTok->
IsFirst))
290 if (Style.isTextProto() && !CommentsBeforeNextToken.empty())
296void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
306 parseCSharpGenericTypeConstraint();
315void UnwrappedLineParser::parseCSharpAttribute() {
316 int UnpairedSquareBrackets = 1;
318 switch (FormatTok->Tok.getKind()) {
321 --UnpairedSquareBrackets;
322 if (UnpairedSquareBrackets == 0) {
328 ++UnpairedSquareBrackets;
338bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
339 if (!Lines.empty() && Lines.back().InPPDirective)
353bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
356 const bool InRequiresExpression =
357 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
358 const bool IsPrecededByCommentOrPPDirective =
359 !Style.RemoveBracesLLVM || precededByCommentOrPPDirective();
361 bool HasDoWhile =
false;
362 bool HasLabel =
false;
363 unsigned StatementCount = 0;
364 bool SwitchLabelEncountered =
false;
367 if (FormatTok->isAttribute()) {
369 if (FormatTok->is(tok::l_paren))
374 if (FormatTok->is(TT_MacroBlockBegin))
376 else if (FormatTok->is(TT_MacroBlockEnd))
379 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
380 &HasLabel, &StatementCount] {
381 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
382 HasDoWhile ?
nullptr : &HasDoWhile,
383 HasLabel ?
nullptr : &HasLabel);
385 assert(StatementCount > 0 &&
"StatementCount overflow!");
394 if (InRequiresExpression) {
395 FormatTok->setFinalizedType(TT_CompoundRequirementLBrace);
396 }
else if (FormatTok->Previous &&
397 FormatTok->Previous->ClosesRequiresClause) {
403 if (!InRequiresExpression && FormatTok->isNot(TT_MacroBlockBegin)) {
404 if (tryToParseBracedList())
406 FormatTok->setFinalizedType(TT_BlockLBrace);
410 assert(StatementCount > 0 &&
"StatementCount overflow!");
415 if (!Style.RemoveBracesLLVM || Line->InPPDirective ||
416 OpeningBrace->isNoneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
419 if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
420 HasDoWhile || IsPrecededByCommentOrPPDirective ||
421 precededByCommentOrPPDirective()) {
425 if (
Next->is(tok::comment) &&
Next->NewlinesBefore == 0)
428 *IfLeftBrace = IfLBrace;
434 case tok::kw_default: {
435 unsigned StoredPosition = Tokens->getPosition();
436 auto *
Next = Tokens->getNextNonComment();
437 FormatTok = Tokens->setPosition(StoredPosition);
438 if (
Next->isNoneOf(tok::colon, tok::arrow)) {
441 parseStructuralElement();
449 (Style.isJavaScript() && Line->MustBeDeclaration)) {
457 if (!SwitchLabelEncountered &&
458 (Style.IndentCaseLabels ||
459 (OpeningBrace && OpeningBrace->is(TT_SwitchExpressionLBrace)) ||
460 (Line->InPPDirective && Line->Level == 1))) {
463 SwitchLabelEncountered =
true;
464 parseStructuralElement();
467 if (Style.isCSharp()) {
469 parseCSharpAttribute();
472 if (handleCppAttributes())
484void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
489 unsigned StoredPosition = Tokens->getPosition();
499 SmallVector<StackEntry, 8> LBraceStack;
500 assert(
Tok->is(tok::l_brace));
503 auto *NextTok = Tokens->getNextNonComment();
505 if (!Line->InMacroBody && !Style.isTableGen()) {
507 while (NextTok->is(tok::hash)) {
508 NextTok = Tokens->getNextToken();
509 if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))
512 NextTok = Tokens->getNextToken();
513 }
while (!NextTok->HasUnescapedNewline && NextTok->isNot(tok::eof));
515 while (NextTok->is(tok::comment))
516 NextTok = Tokens->getNextToken();
520 switch (
Tok->Tok.getKind()) {
522 if (Style.isJavaScript() && PrevTok) {
523 if (PrevTok->isOneOf(tok::colon, tok::less)) {
534 }
else if (PrevTok->is(tok::r_paren)) {
538 }
else if (Style.isJava() && PrevTok && PrevTok->is(tok::arrow)) {
543 LBraceStack.push_back({
Tok, PrevTok});
546 if (LBraceStack.empty())
548 if (
auto *LBrace = LBraceStack.back().Tok; LBrace->is(
BK_Unknown)) {
549 bool ProbablyBracedList =
false;
551 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
552 }
else if (LBrace->isNot(TT_EnumLBrace)) {
555 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
556 NextTok->OriginalColumn == 0;
566 ProbablyBracedList = LBrace->is(TT_BracedListLBrace);
568 ProbablyBracedList = ProbablyBracedList ||
569 (Style.isJavaScript() &&
570 NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
573 ProbablyBracedList ||
574 (IsCpp && (PrevTok->Tok.isLiteral() ||
575 NextTok->isOneOf(tok::l_paren, tok::arrow)));
582 ProbablyBracedList ||
583 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
584 tok::r_paren, tok::r_square, tok::ellipsis);
589 ProbablyBracedList ||
590 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
591 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
595 ProbablyBracedList ||
596 (NextTok->is(tok::identifier) &&
597 PrevTok->isNoneOf(tok::semi, tok::r_brace, tok::l_brace));
599 ProbablyBracedList = ProbablyBracedList ||
600 (NextTok->is(tok::semi) &&
601 (!ExpectClassBody || LBraceStack.size() != 1));
604 ProbablyBracedList ||
605 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
607 if (!Style.isCSharp() && NextTok->is(tok::l_square)) {
610 NextTok = Tokens->getNextToken();
611 ProbablyBracedList = NextTok->isNot(tok::l_square);
615 if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
616 !FormatTok->Previous && NextTok->is(tok::eof) &&
620 PrevTok->isNoneOf(tok::semi,
BK_Block, tok::colon)) {
621 ProbablyBracedList =
true;
625 Tok->setBlockKind(BlockKind);
626 LBrace->setBlockKind(BlockKind);
628 LBraceStack.pop_back();
630 case tok::identifier:
631 if (
Tok->isNot(TT_StatementMacro))
642 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
643 LBraceStack.back().Tok->setBlockKind(
BK_Block);
651 }
while (
Tok->isNot(tok::eof) && !LBraceStack.empty());
654 for (
const auto &Entry : LBraceStack)
658 FormatTok = Tokens->setPosition(StoredPosition);
662void UnwrappedLineParser::setPreviousRBraceType(
TokenType Type) {
663 if (
auto Prev = FormatTok->getPreviousNonComment();
664 Prev && Prev->is(tok::r_brace)) {
665 Prev->setFinalizedType(
Type);
672 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
675size_t UnwrappedLineParser::computePPHash()
const {
677 for (
const auto &i : PP.Stack) {
688bool UnwrappedLineParser::mightFitOnOneLine(
690 const auto ColumnLimit = Style.ColumnLimit;
691 if (ColumnLimit == 0)
694 auto &Tokens = ParsedLine.Tokens;
695 assert(!Tokens.empty());
697 const auto *LastToken = Tokens.back().Tok;
700 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
703 for (
const auto &Token : Tokens) {
705 auto &SavedToken = SavedTokens[Index++];
707 SavedToken.Tok->copyFrom(*Token.Tok);
708 SavedToken.Children = std::move(Token.Children);
711 AnnotatedLine
Line(ParsedLine);
712 assert(Line.Last == LastToken);
714 TokenAnnotator Annotator(Style, Keywords);
715 Annotator.annotate(Line);
716 Annotator.calculateFormattingInformation(Line);
718 auto Length = LastToken->TotalLength;
720 assert(OpeningBrace != Tokens.front().Tok);
721 if (
auto Prev = OpeningBrace->Previous;
722 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
723 Length -= ColumnLimit;
725 Length -= OpeningBrace->TokenText.size() + 1;
728 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
729 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
730 Length -= FirstToken->TokenText.size() + 1;
734 for (
auto &Token : Tokens) {
735 const auto &SavedToken = SavedTokens[Index++];
736 Token.Tok->copyFrom(*SavedToken.Tok);
737 Token.Children = std::move(SavedToken.Children);
738 delete SavedToken.Tok;
742 assert(!Line.InMacroBody);
743 assert(!Line.InPPDirective);
744 return Line.Level * Style.IndentWidth + Length <= ColumnLimit;
747FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
748 unsigned AddLevels,
bool MunchSemi,
751 bool UnindentWhitesmithsBraces) {
752 auto HandleVerilogBlockLabel = [
this]() {
754 if (Style.isVerilog() && FormatTok->is(tok::colon)) {
756 if (Keywords.isVerilogIdentifier(*FormatTok))
763 const bool VerilogHierarchy =
764 Style.isVerilog() && Keywords.isVerilogHierarchy(*FormatTok);
765 assert((FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
766 (Style.isVerilog() &&
767 (Keywords.isVerilogBegin(*FormatTok) || VerilogHierarchy))) &&
768 "'{' or macro block token expected");
770 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
771 auto Index = CurrentLines->size();
772 const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);
775 const bool IsWhitesmiths =
780 if (!VerilogHierarchy && AddLevels > 0 && IsWhitesmiths)
783 size_t PPStartHash = computePPHash();
785 const unsigned InitialLevel = Line->Level;
786 if (VerilogHierarchy) {
787 AddLevels += parseVerilogHierarchyHeader();
789 nextToken(AddLevels);
790 HandleVerilogBlockLabel();
794 if (Line->Level > 300)
797 if (MacroBlock && FormatTok->is(tok::l_paren))
800 size_t NbPreprocessorDirectives =
801 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
803 size_t OpeningLineIndex =
804 CurrentLines->empty()
806 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
811 if (UnindentWhitesmithsBraces)
814 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
820 Line->Level += AddLevels - (IsWhitesmiths ? 1 : 0);
823 const bool SimpleBlock = parseLevel(
Tok, IfKind, &IfLBrace);
828 if (MacroBlock ? FormatTok->isNot(TT_MacroBlockEnd)
829 : FormatTok->isNot(tok::r_brace)) {
830 Line->Level = InitialLevel;
831 FormatTok->setBlockKind(BK_Block);
835 if (FormatTok->is(tok::r_brace)) {
836 FormatTok->setBlockKind(BK_Block);
837 if (Tok->is(TT_NamespaceLBrace))
838 FormatTok->setFinalizedType(TT_NamespaceRBrace);
841 const bool IsFunctionRBrace =
842 FormatTok->is(tok::r_brace) &&
Tok->is(TT_FunctionLBrace);
844 auto RemoveBraces = [=]()
mutable {
847 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
848 assert(FormatTok->is(tok::r_brace));
849 const bool WrappedOpeningBrace = !Tok->Previous;
850 if (WrappedOpeningBrace && FollowedByComment)
852 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
853 if (KeepBraces && !HasRequiredIfBraces)
855 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
856 const FormatToken *Previous = Tokens->getPreviousToken();
858 if (Previous->is(tok::r_brace) && !Previous->Optional)
861 assert(!CurrentLines->empty());
862 auto &LastLine = CurrentLines->back();
863 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
865 if (
Tok->is(TT_ElseLBrace))
867 if (WrappedOpeningBrace) {
872 return mightFitOnOneLine((*CurrentLines)[Index],
Tok);
874 if (RemoveBraces()) {
875 Tok->MatchingParen = FormatTok;
876 FormatTok->MatchingParen =
Tok;
879 size_t PPEndHash = computePPHash();
882 nextToken(-AddLevels);
887 if (Style.RemoveSemicolon && IsFunctionRBrace) {
888 while (FormatTok->is(tok::semi)) {
889 FormatTok->Optional =
true;
894 HandleVerilogBlockLabel();
896 if (MacroBlock && FormatTok->is(tok::l_paren))
899 Line->Level = InitialLevel;
901 if (FormatTok->is(tok::kw_noexcept)) {
906 if (FormatTok->is(tok::arrow)) {
910 parseStructuralElement();
913 if (MunchSemi && FormatTok->is(tok::semi))
916 if (PPStartHash == PPEndHash) {
917 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
920 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
921 CurrentLines->size() - 1;
931 if (
Line.Tokens.size() < 4)
933 auto I =
Line.Tokens.begin();
934 if (I->Tok->TokenText !=
"goog")
937 if (I->Tok->isNot(tok::period))
940 if (I->Tok->TokenText !=
"scope")
943 return I->Tok->is(tok::l_paren);
952 if (
Line.Tokens.size() < 3)
954 auto I =
Line.Tokens.begin();
955 if (I->Tok->isNot(tok::l_paren))
961 return I->Tok->is(tok::l_paren);
967 bool IsJavaRecord =
false) {
969 return Style.BraceWrapping.AfterClass;
972 if (InitialToken.
is(TT_NamespaceMacro))
973 Kind = tok::kw_namespace;
975 const bool WrapRecordAllowed =
978 Style.BraceWrapping.SplitEmptyRecord;
981 case tok::kw_namespace:
982 return Style.BraceWrapping.AfterNamespace;
984 return Style.BraceWrapping.AfterClass && WrapRecordAllowed;
986 return Style.BraceWrapping.AfterUnion && WrapRecordAllowed;
988 return Style.BraceWrapping.AfterStruct && WrapRecordAllowed;
990 return Style.BraceWrapping.AfterEnum;
996void UnwrappedLineParser::parseChildBlock() {
997 assert(FormatTok->is(tok::l_brace));
998 FormatTok->setBlockKind(BK_Block);
1002 bool SkipIndent = (Style.isJavaScript() &&
1003 (isGoogScope(*
Line) || isIIFE(*
Line, Keywords)));
1004 ScopedLineState LineState(*
this);
1005 ScopedDeclarationState DeclarationState(*
Line, DeclarationScopeStack,
1007 Line->Level += SkipIndent ? 0 : 1;
1008 parseLevel(OpeningBrace);
1009 flushComments(isOnNewLine(*FormatTok));
1010 Line->Level -= SkipIndent ? 0 : 1;
1015void UnwrappedLineParser::parsePPDirective() {
1016 assert(FormatTok->is(tok::hash) &&
"'#' expected");
1017 ScopedMacroState MacroState(*
Line, Tokens, FormatTok);
1021 if (!FormatTok->Tok.getIdentifierInfo()) {
1026 switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {
1027 case tok::pp_define:
1034 case tok::pp_ifndef:
1038 case tok::pp_elifdef:
1039 case tok::pp_elifndef:
1046 case tok::pp_pragma:
1050 case tok::pp_warning:
1052 if (!
eof() && Style.isCpp())
1053 FormatTok->setFinalizedType(TT_AfterPPDirective);
1061void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1062 size_t Line = CurrentLines->size();
1063 if (CurrentLines == &PreprocessorDirectives)
1064 Line += Lines.size();
1067 (!PP.Stack.empty() && PP.Stack.back().Kind == PP_Unreachable)) {
1068 PP.Stack.push_back({PP_Unreachable,
Line});
1070 PP.Stack.push_back({PP_Conditional,
Line});
1074void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1076 assert(PP.BranchLevel >= 0 &&
1077 PP.BranchLevel <= (
int)PP.LevelBranchIndex.size());
1078 if (PP.BranchLevel == (
int)PP.LevelBranchIndex.size()) {
1079 PP.LevelBranchIndex.push_back(0);
1080 PP.LevelBranchCount.push_back(0);
1082 PP.ChainBranchIndex.push(Unreachable ? -1 : 0);
1083 bool Skip = PP.LevelBranchIndex[PP.BranchLevel] > 0;
1084 conditionalCompilationCondition(Unreachable ||
Skip);
1087void UnwrappedLineParser::conditionalCompilationAlternative() {
1088 if (!PP.Stack.empty())
1089 PP.Stack.pop_back();
1090 assert(PP.BranchLevel < (
int)PP.LevelBranchIndex.size());
1091 if (!PP.ChainBranchIndex.empty())
1092 ++PP.ChainBranchIndex.top();
1093 conditionalCompilationCondition(
1094 PP.BranchLevel >= 0 && !PP.ChainBranchIndex.empty() &&
1095 PP.LevelBranchIndex[PP.BranchLevel] != PP.ChainBranchIndex.top());
1098void UnwrappedLineParser::conditionalCompilationEnd() {
1099 assert(PP.BranchLevel < (
int)PP.LevelBranchIndex.size());
1100 if (PP.BranchLevel >= 0 && !PP.ChainBranchIndex.empty()) {
1101 if (PP.ChainBranchIndex.top() + 1 > PP.LevelBranchCount[PP.BranchLevel])
1102 PP.LevelBranchCount[PP.BranchLevel] = PP.ChainBranchIndex.top() + 1;
1105 if (PP.BranchLevel > -1)
1107 if (!PP.ChainBranchIndex.empty())
1108 PP.ChainBranchIndex.pop();
1109 if (!PP.Stack.empty())
1110 PP.Stack.pop_back();
1113void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1114 bool IfNDef = FormatTok->is(tok::pp_ifndef);
1116 bool Unreachable =
false;
1117 if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText ==
"0"))
1119 if (IfDef && !IfNDef && FormatTok->TokenText ==
"SWIG")
1121 conditionalCompilationStart(Unreachable);
1125 bool MaybeIncludeGuard = IfNDef;
1126 if (PP.IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1127 for (
auto &
Line : Lines) {
1128 if (
Line.Tokens.front().Tok->isNot(tok::comment)) {
1129 MaybeIncludeGuard =
false;
1130 PP.IncludeGuard = IG_Rejected;
1138 if (PP.IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1139 PP.IncludeGuard = IG_IfNdefed;
1140 PP.IncludeGuardToken = IfCondition;
1144void UnwrappedLineParser::parsePPElse() {
1146 if (PP.IncludeGuard == IG_Defined && PP.BranchLevel == 0)
1147 PP.IncludeGuard = IG_Rejected;
1149 assert(PP.BranchLevel >= -1);
1150 if (PP.BranchLevel == -1)
1151 conditionalCompilationStart(
true);
1152 conditionalCompilationAlternative();
1158void UnwrappedLineParser::parsePPEndIf() {
1159 conditionalCompilationEnd();
1163void UnwrappedLineParser::parsePPDefine() {
1166 if (!FormatTok->Tok.getIdentifierInfo()) {
1167 PP.IncludeGuard = IG_Rejected;
1168 PP.IncludeGuardToken =
nullptr;
1173 bool MaybeIncludeGuard =
false;
1174 if (PP.IncludeGuard == IG_IfNdefed &&
1175 PP.IncludeGuardToken->TokenText == FormatTok->TokenText) {
1176 PP.IncludeGuard = IG_Defined;
1177 PP.IncludeGuardToken =
nullptr;
1178 for (
auto &
Line : Lines) {
1179 if (
Line.Tokens.front().Tok->isNoneOf(tok::comment, tok::hash)) {
1180 PP.IncludeGuard = IG_Rejected;
1184 MaybeIncludeGuard = PP.IncludeGuard == IG_Defined;
1192 FormatTok->Tok.setKind(tok::identifier);
1193 FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);
1197 if (MaybeIncludeGuard && !
eof())
1198 PP.IncludeGuard = IG_Rejected;
1200 if (FormatTok->is(tok::l_paren) && !FormatTok->hasWhitespaceBefore())
1203 Line->Level += PP.BranchLevel + 1;
1207 Line->PPLevel = PP.BranchLevel + (PP.IncludeGuard == IG_Defined ? 0 : 1);
1208 assert((
int)
Line->PPLevel >= 0);
1213 Line->InMacroBody =
true;
1215 if (!Style.SkipMacroDefinitionBody) {
1225 for (
auto *Comment : CommentsBeforeNextToken)
1226 Comment->Finalized =
true;
1229 FormatTok->Finalized =
true;
1230 FormatTok = Tokens->getNextToken();
1236void UnwrappedLineParser::parsePPPragma() {
1237 Line->InPragmaDirective =
true;
1241void UnwrappedLineParser::parsePPUnknown() {
1245 Line->Level += PP.BranchLevel + 1;
1255 return Tok.isNoneOf(tok::semi, tok::l_brace,
1258 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1259 tok::less, tok::greater, tok::slash, tok::percent,
1260 tok::lessless, tok::greatergreater, tok::equal,
1261 tok::plusequal, tok::minusequal, tok::starequal,
1262 tok::slashequal, tok::percentequal, tok::ampequal,
1263 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1276 return FormatTok->
is(tok::identifier) &&
1291 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1302 tok::kw_if, tok::kw_else,
1304 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1306 tok::kw_switch, tok::kw_case,
1308 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1310 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1318 return Tok.isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1319 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1336 if (FuncName->
isNot(tok::identifier))
1344 Tok->isNoneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1348 if (
Next->isNot(tok::star) && !
Next->Tok.getIdentifierInfo())
1352 if (!
Tok ||
Tok->isNot(tok::r_paren))
1356 if (!
Tok ||
Tok->isNot(tok::identifier))
1359 return Tok->Previous &&
Tok->Previous->isOneOf(tok::l_paren, tok::comma);
1362bool UnwrappedLineParser::parseModuleDecl() {
1364 assert(FormatTok->is(Keywords.kw_module));
1372 if (FormatTok->isNot(tok::identifier))
1375 for (nextToken(); FormatTok->isNoneOf(tok::semi, tok::eof); nextToken())
1376 if (FormatTok->is(tok::colon))
1377 FormatTok->setFinalizedType(TT_ModulePartitionColon);
1380 Line->IsModuleOrImportDecl =
true;
1385bool UnwrappedLineParser::parseImportDecl() {
1387 assert(FormatTok->is(Keywords.kw_import) &&
"'import' expected");
1395 if (FormatTok->is(tok::colon)) {
1396 FormatTok->setFinalizedType(TT_ModulePartitionColon);
1399 if (FormatTok->isNoneOf(tok::identifier, tok::less, tok::string_literal))
1402 for (; FormatTok->isNoneOf(tok::semi, tok::eof); nextToken()) {
1404 if (FormatTok->is(tok::less)) {
1405 for (nextToken(); FormatTok->isNoneOf(tok::greater, tok::semi, tok::eof);
1409 FormatTok->setFinalizedType(TT_ImplicitStringLiteral);
1415 Line->IsModuleOrImportDecl =
true;
1427void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1433 CommentsBeforeNextToken.empty()
1434 ?
Next->NewlinesBefore == 0
1435 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1440 bool PreviousStartsTemplateExpr =
1442 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1445 bool HasAt = llvm::any_of(
Line->Tokens, [](UnwrappedLineNode &LineNode) {
1446 return LineNode.Tok->is(tok::at);
1451 if (
Next->is(tok::exclaim) && PreviousMustBeValue)
1452 return addUnwrappedLine();
1454 bool NextEndsTemplateExpr =
1455 Next->is(TT_TemplateString) &&
Next->TokenText.starts_with(
"}");
1456 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1457 (PreviousMustBeValue ||
1458 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1459 tok::minusminus))) {
1460 return addUnwrappedLine();
1462 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1464 return addUnwrappedLine();
1468void UnwrappedLineParser::parseStructuralElement(
1469 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1470 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1471 if (Style.isTableGen() && FormatTok->is(tok::pp_include)) {
1473 if (FormatTok->is(tok::string_literal))
1480 while (FormatTok->is(tok::l_square) && handleCppAttributes()) {
1482 }
else if (Style.isVerilog()) {
1484 while (FormatTok->is(tok::l_paren) &&
1485 Tokens->peekNextToken()->is(tok::star)) {
1488 skipVerilogQualifiers();
1490 if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
1491 Keywords.kw_unique0)) {
1495 if (Keywords.isVerilogStructuredProcedure(*FormatTok)) {
1496 parseForOrWhileLoop(
false);
1499 if (FormatTok->isOneOf(Keywords.kw_foreach, Keywords.kw_repeat)) {
1500 parseForOrWhileLoop();
1503 if (FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,
1504 Keywords.kw_assume, Keywords.kw_cover)) {
1505 parseIfThenElse(IfKind,
false,
true);
1511 if (FormatTok->isAccessSpecifierKeyword()) {
1512 if (Style.isJava() || Style.isJavaScript() || Style.isCSharp())
1515 parseAccessSpecifier();
1518 switch (FormatTok->Tok.getKind()) {
1523 bool DoNotFormat =
false;
1528 FormatTok->isOneOf(tok::kw_volatile, tok::kw_inline, tok::kw_goto)) {
1533 if (FormatTok->is(tok::l_brace)) {
1534 FormatTok->setFinalizedType(TT_InlineASMBrace);
1535 OpenType = tok::l_brace;
1536 CloseType = tok::r_brace;
1538 }
else if (FormatTok->is(tok::l_paren)) {
1539 OpenType = tok::l_paren;
1540 CloseType = tok::r_paren;
1541 FormatTok->setFinalizedType(TT_InlineASMParen);
1549 while (FormatTok && !
eof()) {
1550 if (FormatTok->is(OpenType)) {
1552 }
else if (FormatTok->is(CloseType)) {
1554 if (NestLevel < 1) {
1555 FormatTok->setFinalizedType(OpenTok->getType());
1561 FormatTok->Finalized =
true;
1567 case tok::kw_namespace:
1571 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1582 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1586 parseForOrWhileLoop();
1589 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1597 case tok::kw_switch:
1598 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1604 case tok::kw_default: {
1606 if (Style.isVerilog())
1608 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1614 if (FormatTok->is(tok::colon)) {
1615 FormatTok->setFinalizedType(TT_CaseLabelColon);
1619 if (FormatTok->is(tok::arrow)) {
1620 FormatTok->setFinalizedType(TT_CaseLabelArrow);
1621 Default->setFinalizedType(TT_SwitchExpressionLabel);
1634 if (Style.isVerilog()) {
1639 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1648 if (FormatTok->is(tok::kw_case))
1653 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
1659 case tok::kw_extern:
1660 if (Style.isVerilog()) {
1663 parseVerilogExtern();
1667 if (FormatTok->is(tok::string_literal)) {
1669 if (FormatTok->is(tok::l_brace)) {
1670 if (Style.BraceWrapping.AfterExternBlock)
1674 unsigned AddLevels =
1676 (Style.BraceWrapping.AfterExternBlock &&
1677 Style.IndentExternBlock ==
1681 parseBlock(
true, AddLevels);
1687 case tok::kw_export:
1690 if (FormatTok->is(tok::kw_namespace)) {
1694 if (FormatTok->is(tok::l_brace)) {
1695 parseCppExportBlock();
1698 if (FormatTok->is(Keywords.kw_module) && parseModuleDecl())
1700 if (FormatTok->is(Keywords.kw_import) && parseImportDecl())
1704 if (Style.isJavaScript()) {
1705 parseJavaScriptEs6ImportExport();
1708 if (Style.isVerilog()) {
1709 parseVerilogExtern();
1713 case tok::kw_inline:
1715 if (FormatTok->is(tok::kw_namespace)) {
1720 case tok::identifier:
1721 if (FormatTok->is(TT_ForEachMacro)) {
1722 parseForOrWhileLoop();
1725 if (FormatTok->is(TT_MacroBlockBegin)) {
1726 parseBlock(
false, 1u,
1730 if (FormatTok->is(Keywords.kw_import)) {
1731 if (IsCpp && parseImportDecl())
1733 if (Style.isJavaScript()) {
1734 parseJavaScriptEs6ImportExport();
1739 if (FormatTok->is(tok::kw_public))
1741 if (FormatTok->isNot(tok::string_literal))
1744 if (FormatTok->is(tok::semi))
1749 if (Style.isVerilog()) {
1750 parseVerilogExtern();
1755 if (FormatTok->is(Keywords.kw_module) && parseModuleDecl())
1757 if (FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
1758 Keywords.kw_slots, Keywords.kw_qslots)) {
1760 if (FormatTok->is(tok::colon)) {
1766 if (FormatTok->is(TT_StatementMacro)) {
1767 parseStatementMacro();
1770 if (FormatTok->is(TT_NamespaceMacro)) {
1779 if (!Style.isJavaScript() && !Style.isVerilog() && !Style.isTableGen() &&
1780 Tokens->peekNextToken()->is(tok::colon) && !
Line->MustBeDeclaration) {
1782 if (!
Line->InMacroBody || CurrentLines->size() > 1)
1783 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1784 FormatTok->setFinalizedType(TT_GotoLabelColon);
1790 if (Style.isJava() && FormatTok->is(Keywords.kw_record)) {
1791 parseRecord(
false,
true);
1801 bool SeenEqual =
false;
1802 for (
const bool InRequiresExpression =
1803 OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
1804 TT_CompoundRequirementLBrace);
1807 switch (FormatTok->Tok.getKind()) {
1810 if (FormatTok->is(tok::l_brace)) {
1815 if (Style.isJava() && FormatTok->is(Keywords.kw_interface)) {
1819 switch (
bool IsAutoRelease =
false; FormatTok->Tok.getObjCKeywordID()) {
1820 case tok::objc_public:
1821 case tok::objc_protected:
1822 case tok::objc_package:
1823 case tok::objc_private:
1824 return parseAccessSpecifier();
1825 case tok::objc_interface:
1826 case tok::objc_implementation:
1827 return parseObjCInterfaceOrImplementation();
1828 case tok::objc_protocol:
1829 if (parseObjCProtocol())
1834 case tok::objc_optional:
1835 case tok::objc_required:
1839 case tok::objc_autoreleasepool:
1840 IsAutoRelease =
true;
1842 case tok::objc_synchronized:
1844 if (!IsAutoRelease && FormatTok->is(tok::l_paren)) {
1848 if (FormatTok->is(tok::l_brace)) {
1849 if (Style.BraceWrapping.AfterControlStatement ==
1866 case tok::kw_requires: {
1868 bool ParsedClause = parseRequires(SeenEqual);
1889 if (!IsCpp && !Style.isVerilog()) {
1894 case tok::kw_typedef:
1896 if (FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
1897 Keywords.kw_CF_ENUM, Keywords.kw_CF_OPTIONS,
1898 Keywords.kw_CF_CLOSED_ENUM,
1899 Keywords.kw_NS_CLOSED_ENUM)) {
1904 if (Style.isVerilog()) {
1909 if (Style.isTableGen()) {
1916 case tok::kw_struct:
1918 if (parseStructLike())
1921 case tok::kw_decltype:
1923 if (FormatTok->is(tok::l_paren)) {
1925 if (FormatTok->Previous &&
1926 FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,
1928 Line->SeenDecltypeAuto =
true;
1935 if (Style.isJava() && FormatTok && FormatTok->is(tok::kw_class))
1937 if (Style.isJavaScript() && FormatTok &&
1938 FormatTok->Tok.getIdentifierInfo()) {
1951 case tok::string_literal:
1952 if (Style.isVerilog() && FormatTok->is(TT_VerilogProtected)) {
1953 FormatTok->Finalized =
true;
1960 case tok::l_paren: {
1967 Tokens->peekNextToken(
true),
1974 case tok::kw_operator:
1976 if (FormatTok->isBinaryOperator())
1980 const auto *Prev = FormatTok->getPreviousNonComment();
1982 if (Prev && Prev->is(tok::identifier))
1985 if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName(LangOpts)) {
1988 if (FormatTok->is(tok::less)) {
1990 parseBracedList(
true);
1993 while (FormatTok->is(tok::star))
1997 if (FormatTok->is(tok::l_paren))
2000 if (FormatTok->is(tok::l_brace))
2005 if (InRequiresExpression)
2006 FormatTok->setFinalizedType(TT_BracedListLBrace);
2007 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
2008 IsDecltypeAutoFunction =
Line->SeenDecltypeAuto;
2013 if (Style.isJava() &&
2014 Line->Tokens.front().Tok->is(Keywords.kw_synchronized)) {
2017 if (Style.BraceWrapping.AfterControlStatement ==
2021 }
else if (Style.BraceWrapping.AfterFunction) {
2025 FormatTok->setFinalizedType(TT_FunctionLBrace);
2027 IsDecltypeAutoFunction =
false;
2035 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
2041 if (Style.BraceWrapping.AfterFunction)
2045 case tok::identifier: {
2046 if (Style.isCSharp() && FormatTok->is(Keywords.kw_where) &&
2047 Line->MustBeDeclaration) {
2049 parseCSharpGenericTypeConstraint();
2052 if (FormatTok->is(TT_MacroBlockEnd)) {
2061 size_t TokenCount =
Line->Tokens.size();
2062 if (Style.isJavaScript() && FormatTok->is(Keywords.kw_function) &&
2065 Line->Tokens.front().Tok->isNot(Keywords.kw_async)))) {
2066 tryToParseJSFunction();
2069 if ((Style.isJavaScript() || Style.isJava()) &&
2070 FormatTok->is(Keywords.kw_interface)) {
2071 if (Style.isJavaScript()) {
2076 unsigned StoredPosition = Tokens->getPosition();
2078 FormatTok = Tokens->setPosition(StoredPosition);
2089 if (Style.isVerilog()) {
2090 if (FormatTok->is(Keywords.kw_table)) {
2091 parseVerilogTable();
2094 if (Keywords.isVerilogBegin(*FormatTok) ||
2095 Keywords.isVerilogHierarchy(*FormatTok)) {
2102 if (!IsCpp && FormatTok->is(Keywords.kw_interface)) {
2103 if (parseStructLike())
2108 if (IsCpp && FormatTok->is(TT_StatementMacro)) {
2109 parseStatementMacro();
2114 StringRef
Text = FormatTok->TokenText;
2121 if (Style.isJavaScript())
2124 auto OneTokenSoFar = [&]() {
2125 auto I =
Line->Tokens.begin(), E =
Line->Tokens.end();
2126 while (I != E && I->Tok->is(tok::comment))
2128 if (Style.isVerilog())
2129 while (I != E && I->Tok->is(tok::hash))
2131 return I != E && (++I == E);
2133 if (OneTokenSoFar()) {
2136 bool FunctionLike = FormatTok->is(tok::l_paren);
2140 bool FollowedByNewline =
2141 CommentsBeforeNextToken.empty()
2142 ? FormatTok->NewlinesBefore > 0
2143 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
2145 if (FollowedByNewline &&
2146 (
Text.size() >= 5 ||
2147 (FunctionLike && FormatTok->isNot(tok::l_paren))) &&
2149 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
2150 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
2158 if ((Style.isJavaScript() || Style.isCSharp()) &&
2159 FormatTok->is(TT_FatArrow)) {
2160 tryToParseChildBlock();
2166 if (FormatTok->is(tok::l_brace)) {
2170 if (!Style.isJavaScript())
2171 FormatTok->setBlockKind(BK_BracedInit);
2174 if (Style.isTableGen() &&
2175 Line->Tokens.begin()->Tok->is(Keywords.kw_defset)) {
2176 FormatTok->setFinalizedType(TT_FunctionLBrace);
2177 parseBlock(
false, 1u,
2185 FormatTok->is(tok::less)) {
2187 parseBracedList(
true);
2194 if (Style.isCSharp() &&
2195 (Tokens->peekNextToken()->isAccessSpecifierKeyword() ||
2202 case tok::kw_switch:
2215 if (Style.isVerilog()) {
2220 if (Style.isJavaScript() &&
Line->MustBeDeclaration) {
2227 case tok::kw_default:
2229 if (Style.isVerilog()) {
2230 if (FormatTok->is(tok::colon)) {
2234 if (FormatTok->is(Keywords.kw_clocking)) {
2240 parseVerilogCaseLabel();
2246 if (Style.isVerilog()) {
2247 parseVerilogCaseLabel();
2253 if (FormatTok->is(tok::l_brace))
2254 FormatTok->Previous->setFinalizedType(TT_TemplateCloser);
2263bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2264 assert(FormatTok->is(tok::l_brace));
2265 if (!Style.isCSharp())
2268 if (!FormatTok->Previous || FormatTok->Previous->isNot(tok::identifier))
2276 unsigned int StoredPosition = Tokens->getPosition();
2282 bool HasSpecialAccessor =
false;
2283 bool IsTrivialPropertyAccessor =
true;
2286 if (
const bool IsAccessorKeyword =
2287 Tok->
isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set);
2288 IsAccessorKeyword ||
Tok->isAccessSpecifierKeyword() ||
2289 Tok->
isOneOf(tok::l_square, tok::semi, Keywords.kw_internal)) {
2290 if (IsAccessorKeyword)
2291 HasSpecialAccessor =
true;
2292 else if (
Tok->
is(tok::l_square))
2294 Tok = Tokens->getNextToken();
2298 IsTrivialPropertyAccessor =
false;
2303 Tokens->setPosition(StoredPosition);
2309 Tokens->setPosition(StoredPosition);
2310 if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction)
2314 switch (FormatTok->Tok.getKind()) {
2317 if (FormatTok->is(tok::equal)) {
2318 while (!
eof() && FormatTok->isNot(tok::semi))
2331 if (FormatTok->is(TT_FatArrow)) {
2335 }
while (!
eof() && FormatTok->isNot(tok::semi));
2344 if (FormatTok->isOneOf(Keywords.kw_get, Keywords.kw_init,
2346 !IsTrivialPropertyAccessor) {
2358bool UnwrappedLineParser::tryToParseLambda() {
2359 assert(FormatTok->is(tok::l_square));
2365 if (!tryToParseLambdaIntroducer())
2369 bool InTemplateParameterList =
false;
2371 while (FormatTok->isNot(tok::l_brace)) {
2372 if (FormatTok->isTypeName(LangOpts) || FormatTok->isAttribute()) {
2376 switch (FormatTok->Tok.getKind()) {
2380 parseParens(TT_PointerOrReference);
2386 assert(FormatTok->Previous);
2387 if (FormatTok->Previous->is(tok::r_square))
2388 InTemplateParameterList =
true;
2393 case tok::kw_struct:
2395 case tok::kw_template:
2396 case tok::kw_typename:
2400 case tok::kw_constexpr:
2401 case tok::kw_consteval:
2404 case tok::identifier:
2405 case tok::numeric_constant:
2406 case tok::coloncolon:
2407 case tok::kw_mutable:
2408 case tok::kw_noexcept:
2409 case tok::kw_static:
2434 case tok::equalequal:
2435 case tok::exclaimequal:
2436 case tok::greaterequal:
2437 case tok::lessequal:
2443 if (Arrow || InTemplateParameterList) {
2452 case tok::kw_requires:
2453 parseRequiresClause();
2456 if (!InTemplateParameterList)
2465 FormatTok->setFinalizedType(TT_LambdaLBrace);
2466 LSquare.setFinalizedType(TT_LambdaLSquare);
2469 Arrow->setFinalizedType(TT_LambdaArrow);
2471 NestedLambdas.push_back(
Line->SeenDecltypeAuto);
2473 assert(!NestedLambdas.empty());
2474 NestedLambdas.pop_back();
2479bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2484 const auto *PrevPrev =
Previous->getPreviousNonComment();
2485 if (
Previous->is(tok::star) && PrevPrev && PrevPrev->isTypeName(LangOpts))
2493 if (!PrevPrev || PrevPrev->isNoneOf(tok::greater, tok::r_paren))
2497 Previous->isNoneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
2498 tok::kw_co_return)) {
2502 if (LeftSquare->isCppStructuredBinding(IsCpp))
2504 if (FormatTok->is(tok::l_square) ||
tok::isLiteral(FormatTok->Tok.getKind()))
2506 if (FormatTok->is(tok::r_square)) {
2508 if (
Next->is(tok::greater))
2515void UnwrappedLineParser::tryToParseJSFunction() {
2516 assert(FormatTok->is(Keywords.kw_function));
2517 if (FormatTok->is(Keywords.kw_async))
2523 if (FormatTok->is(tok::star)) {
2524 FormatTok->setFinalizedType(TT_OverloadedOperator);
2529 if (FormatTok->is(tok::identifier))
2532 if (FormatTok->isNot(tok::l_paren))
2538 if (FormatTok->is(tok::colon)) {
2544 if (FormatTok->is(tok::l_brace))
2545 tryToParseBracedList();
2547 while (FormatTok->isNoneOf(tok::l_brace, tok::semi) && !
eof())
2551 if (FormatTok->is(tok::semi))
2557bool UnwrappedLineParser::tryToParseBracedList() {
2558 if (FormatTok->is(BK_Unknown))
2559 calculateBraceTypes();
2560 assert(FormatTok->isNot(BK_Unknown));
2561 if (FormatTok->is(BK_Block))
2568bool UnwrappedLineParser::tryToParseChildBlock() {
2569 assert(Style.isJavaScript() || Style.isCSharp());
2570 assert(FormatTok->is(TT_FatArrow));
2575 if (FormatTok->isNot(tok::l_brace))
2581bool UnwrappedLineParser::parseBracedList(
bool IsAngleBracket,
bool IsEnum) {
2582 assert(!IsAngleBracket || !IsEnum);
2583 bool HasError =
false;
2588 if (Style.isCSharp() && FormatTok->is(TT_FatArrow) &&
2589 tryToParseChildBlock()) {
2592 if (Style.isJavaScript()) {
2593 if (FormatTok->is(Keywords.kw_function)) {
2594 tryToParseJSFunction();
2597 if (FormatTok->is(tok::l_brace)) {
2599 if (tryToParseBracedList())
2604 if (FormatTok->is(IsAngleBracket ? tok::greater : tok::r_brace)) {
2606 FormatTok->setBlockKind(BK_Block);
2607 if (!Style.AllowShortEnumsOnASingleLine)
2613 switch (FormatTok->Tok.getKind()) {
2615 if (Style.isCSharp())
2624 if (Style.isJavaScript()) {
2625 if (FormatTok->is(tok::l_brace))
2633 FormatTok->setBlockKind(BK_BracedInit);
2634 if (!IsAngleBracket) {
2635 auto *Prev = FormatTok->Previous;
2636 if (Prev && Prev->is(tok::greater))
2637 Prev->setFinalizedType(TT_TemplateCloser);
2645 parseBracedList(
true);
2652 if (Style.isJavaScript()) {
2663 if (IsEnum && !Style.AllowShortEnumsOnASingleLine)
2666 case tok::kw_requires:
2667 parseRequiresExpression();
2684bool UnwrappedLineParser::parseParens(TokenType StarAndAmpTokenType,
2686 assert(FormatTok->is(tok::l_paren) &&
"'(' expected.");
2687 auto *LParen = FormatTok;
2688 auto *Prev = FormatTok->Previous;
2689 bool SeenComma =
false;
2690 bool SeenEqual =
false;
2691 bool MightBeFoldExpr =
false;
2692 unsigned ExcessLess = 0;
2694 const bool MightBeStmtExpr = FormatTok->is(tok::l_brace);
2695 if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro))
2698 switch (FormatTok->Tok.getKind()) {
2700 if (parseParens(ExcessLess == 0 ? StarAndAmpTokenType : TT_Unknown,
2704 if (Style.isJava() && FormatTok->is(tok::l_brace))
2707 case tok::r_paren: {
2708 auto *RParen = FormatTok;
2711 auto OptionalParens = [&] {
2713 MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall ||
2714 Line->InMacroBody || RParen->getPreviousNonComment() == LParen) {
2717 const bool DoubleParens =
2718 Prev->is(tok::l_paren) && FormatTok->is(tok::r_paren);
2720 const auto *PrevPrev = Prev->getPreviousNonComment();
2721 const bool Excluded =
2723 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2725 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2726 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2730 const bool CommaSeparated =
2731 Prev->isOneOf(tok::l_paren, tok::comma) &&
2732 FormatTok->isOneOf(tok::comma, tok::r_paren);
2733 if (CommaSeparated &&
2735 !Prev->endsSequence(tok::comma, tok::ellipsis) &&
2737 !(FormatTok->is(tok::comma) &&
2738 Tokens->peekNextToken()->is(tok::ellipsis))) {
2741 const bool ReturnParens =
2743 ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
2744 (!NestedLambdas.empty() && !NestedLambdas.back())) &&
2745 Prev->isOneOf(tok::kw_return, tok::kw_co_return) &&
2746 FormatTok->is(tok::semi);
2752 if (OptionalParens()) {
2753 LParen->Optional =
true;
2754 RParen->Optional =
true;
2755 }
else if (Prev->is(TT_TypenameMacro)) {
2756 LParen->setFinalizedType(TT_TypeDeclarationParen);
2757 RParen->setFinalizedType(TT_TypeDeclarationParen);
2758 }
else if (Prev->is(tok::greater) && RParen->Previous == LParen) {
2759 Prev->setFinalizedType(TT_TemplateCloser);
2760 }
else if (FormatTok->is(tok::l_brace) && Prev->is(tok::amp) &&
2762 FormatTok->setBlockKind(BK_BracedInit);
2774 if (!tryToParseBracedList())
2779 if (FormatTok->is(tok::l_brace)) {
2789 MightBeFoldExpr =
true;
2794 if (Style.isCSharp() && FormatTok->is(TT_FatArrow))
2795 tryToParseChildBlock();
2800 if (Style.isJavaScript())
2805 case tok::identifier:
2806 if (Style.isJavaScript() && (FormatTok->is(Keywords.kw_function)))
2807 tryToParseJSFunction();
2811 case tok::kw_switch:
2817 case tok::kw_requires:
2818 parseRequiresExpression();
2834 if (StarAndAmpTokenType != TT_Unknown && ExcessLess == 0)
2835 FormatTok->setFinalizedType(StarAndAmpTokenType);
2847 assert(FormatTok->is(tok::l_square) &&
"'[' expected.");
2848 if (tryToParseLambda())
2852 switch (FormatTok->Tok.getKind()) {
2865 case tok::l_brace: {
2866 if (!tryToParseBracedList())
2873 if (FormatTok->is(tok::l_brace)) {
2885void UnwrappedLineParser::keepAncestorBraces() {
2886 if (!Style.RemoveBracesLLVM)
2889 const int MaxNestingLevels = 2;
2890 const int Size = NestedTooDeep.size();
2891 if (Size >= MaxNestingLevels)
2892 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2893 NestedTooDeep.push_back(
false);
2897 for (
const auto &
Token : llvm::reverse(
Line.Tokens))
2904void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2907 if (Style.InsertBraces && !
Line->InPPDirective && !
Line->Tokens.empty() &&
2908 PreprocessorDirectives.empty() && FormatTok->isNot(tok::semi)) {
2910 ? getLastNonComment(*
Line)
2913 if (
Tok->BraceCount < 0) {
2914 assert(
Tok->BraceCount == -1);
2917 Tok->BraceCount = -1;
2923 ++
Line->UnbracedBodyLevel;
2924 parseStructuralElement();
2925 --
Line->UnbracedBodyLevel;
2928 assert(!
Line->InPPDirective);
2930 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2932 Tok = L.Tokens.back().Tok;
2940 if (CheckEOF &&
eof())
2950 assert(LeftBrace->
is(tok::l_brace));
2958 assert(RightBrace->
is(tok::r_brace));
2966void UnwrappedLineParser::handleAttributes() {
2968 if (FormatTok->isAttribute())
2970 else if (FormatTok->is(tok::l_square))
2971 handleCppAttributes();
2974bool UnwrappedLineParser::handleCppAttributes() {
2976 assert(FormatTok->is(tok::l_square));
2977 if (!tryToParseSimpleAttribute())
2984bool UnwrappedLineParser::isBlockBegin(
const FormatToken &
Tok)
const {
2987 return Style.isVerilog() ? Keywords.isVerilogBegin(
Tok)
2988 :
Tok.
is(tok::l_brace);
2991FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2993 bool IsVerilogAssert) {
2994 assert((FormatTok->is(tok::kw_if) ||
2995 (Style.isVerilog() &&
2996 FormatTok->isOneOf(tok::kw_restrict, Keywords.kw_assert,
2997 Keywords.kw_assume, Keywords.kw_cover))) &&
3001 if (IsVerilogAssert) {
3003 if (FormatTok->is(Keywords.kw_verilogHash)) {
3005 if (FormatTok->is(tok::numeric_constant))
3007 }
else if (FormatTok->isOneOf(Keywords.kw_final, Keywords.kw_property,
3008 Keywords.kw_sequence)) {
3014 if (Style.isTableGen()) {
3015 while (!
eof() && FormatTok->isNot(Keywords.kw_then)) {
3022 if (FormatTok->is(tok::exclaim))
3025 bool KeepIfBraces =
true;
3026 if (FormatTok->is(tok::kw_consteval)) {
3029 KeepIfBraces = !Style.RemoveBracesLLVM || KeepBraces;
3030 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
3032 if (FormatTok->is(tok::l_paren)) {
3033 FormatTok->setFinalizedType(TT_ConditionLParen);
3039 if (IsVerilogAssert && FormatTok->is(tok::semi)) {
3045 bool NeedsUnwrappedLine =
false;
3046 keepAncestorBraces();
3049 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
3051 if (isBlockBegin(*FormatTok)) {
3052 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3053 IfLeftBrace = FormatTok;
3054 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3055 parseBlock(
false, 1u,
3056 true, KeepIfBraces, &IfBlockKind);
3057 setPreviousRBraceType(TT_ControlStatementRBrace);
3058 if (Style.BraceWrapping.BeforeElse)
3061 NeedsUnwrappedLine =
true;
3062 }
else if (IsVerilogAssert && FormatTok->is(tok::kw_else)) {
3065 parseUnbracedBody();
3068 if (Style.RemoveBracesLLVM) {
3069 assert(!NestedTooDeep.empty());
3070 KeepIfBraces = KeepIfBraces ||
3071 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
3072 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
3073 IfBlockKind == IfStmtKind::IfElseIf;
3076 bool KeepElseBraces = KeepIfBraces;
3078 IfStmtKind
Kind = IfStmtKind::IfOnly;
3080 if (FormatTok->is(tok::kw_else)) {
3081 if (Style.RemoveBracesLLVM) {
3082 NestedTooDeep.back() =
false;
3083 Kind = IfStmtKind::IfElse;
3087 if (isBlockBegin(*FormatTok)) {
3088 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
3089 FormatTok->setFinalizedType(TT_ElseLBrace);
3090 ElseLeftBrace = FormatTok;
3091 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3092 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
3094 parseBlock(
false, 1u,
3095 true, KeepElseBraces, &ElseBlockKind);
3096 setPreviousRBraceType(TT_ElseRBrace);
3097 if (FormatTok->is(tok::kw_else)) {
3098 KeepElseBraces = KeepElseBraces ||
3099 ElseBlockKind == IfStmtKind::IfOnly ||
3100 ElseBlockKind == IfStmtKind::IfElseIf;
3101 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
3102 KeepElseBraces =
true;
3103 assert(ElseLeftBrace->MatchingParen);
3107 }
else if (!IsVerilogAssert && FormatTok->is(tok::kw_if)) {
3110 const bool IsPrecededByComment =
Previous->is(tok::comment);
3111 if (IsPrecededByComment) {
3115 bool TooDeep =
true;
3116 if (Style.RemoveBracesLLVM) {
3117 Kind = IfStmtKind::IfElseIf;
3118 TooDeep = NestedTooDeep.pop_back_val();
3120 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
3121 if (Style.RemoveBracesLLVM)
3122 NestedTooDeep.push_back(TooDeep);
3123 if (IsPrecededByComment)
3126 parseUnbracedBody(
true);
3129 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
3130 if (NeedsUnwrappedLine)
3134 if (!Style.RemoveBracesLLVM)
3137 assert(!NestedTooDeep.empty());
3138 KeepElseBraces = KeepElseBraces ||
3139 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
3140 NestedTooDeep.back();
3142 NestedTooDeep.pop_back();
3144 if (!KeepIfBraces && !KeepElseBraces) {
3147 }
else if (IfLeftBrace) {
3148 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
3150 assert(IfRightBrace->MatchingParen == IfLeftBrace);
3151 assert(!IfLeftBrace->Optional);
3152 assert(!IfRightBrace->Optional);
3153 IfLeftBrace->MatchingParen =
nullptr;
3154 IfRightBrace->MatchingParen =
nullptr;
3164void UnwrappedLineParser::parseTryCatch() {
3165 assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
3167 bool NeedsUnwrappedLine =
false;
3168 bool HasCtorInitializer =
false;
3169 if (FormatTok->is(tok::colon)) {
3170 auto *Colon = FormatTok;
3173 if (FormatTok->is(tok::identifier)) {
3174 HasCtorInitializer =
true;
3175 Colon->setFinalizedType(TT_CtorInitializerColon);
3180 while (FormatTok->is(tok::comma))
3183 while (FormatTok->is(tok::identifier)) {
3185 if (FormatTok->is(tok::l_paren)) {
3187 }
else if (FormatTok->is(tok::l_brace)) {
3194 while (FormatTok->is(tok::comma))
3199 if (Style.isJava() && FormatTok->is(tok::l_paren))
3202 keepAncestorBraces();
3204 if (FormatTok->is(tok::l_brace)) {
3205 if (HasCtorInitializer)
3206 FormatTok->setFinalizedType(TT_FunctionLBrace);
3207 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3209 if (Style.BraceWrapping.BeforeCatch)
3212 NeedsUnwrappedLine =
true;
3213 }
else if (FormatTok->isNot(tok::kw_catch)) {
3219 parseStructuralElement();
3222 for (
bool SeenCatch =
false;;) {
3223 if (FormatTok->is(tok::at))
3225 if (FormatTok->isNoneOf(tok::kw_catch, Keywords.kw___except,
3226 tok::kw___finally, tok::objc_catch,
3227 tok::objc_finally) &&
3228 !((Style.isJava() || Style.isJavaScript()) &&
3229 FormatTok->is(Keywords.kw_finally))) {
3232 if (FormatTok->is(tok::kw_catch))
3235 while (FormatTok->isNot(tok::l_brace)) {
3236 if (FormatTok->is(tok::l_paren)) {
3240 if (FormatTok->isOneOf(tok::semi, tok::r_brace) ||
eof()) {
3241 if (Style.RemoveBracesLLVM)
3242 NestedTooDeep.pop_back();
3248 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3251 NeedsUnwrappedLine =
false;
3252 Line->MustBeDeclaration =
false;
3253 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3255 if (Style.BraceWrapping.BeforeCatch)
3258 NeedsUnwrappedLine =
true;
3261 if (Style.RemoveBracesLLVM)
3262 NestedTooDeep.pop_back();
3264 if (NeedsUnwrappedLine)
3268void UnwrappedLineParser::parseNamespaceOrExportBlock(
unsigned AddLevels) {
3269 bool ManageWhitesmithsBraces =
3274 if (ManageWhitesmithsBraces)
3279 parseBlock(
true, AddLevels,
true,
3280 true,
nullptr, ManageWhitesmithsBraces);
3282 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
3284 if (ManageWhitesmithsBraces)
3288void UnwrappedLineParser::parseNamespace() {
3289 assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
3290 "'namespace' expected");
3294 if (InitialToken.is(TT_NamespaceMacro)) {
3297 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
3298 tok::l_square, tok::period, tok::l_paren) ||
3299 (Style.isCSharp() && FormatTok->is(tok::kw_union))) {
3300 if (FormatTok->is(tok::l_square))
3302 else if (FormatTok->is(tok::l_paren))
3308 if (FormatTok->is(tok::l_brace)) {
3309 FormatTok->setFinalizedType(TT_NamespaceLBrace);
3312 Tokens->peekNextToken()->is(tok::r_brace))) {
3316 unsigned AddLevels =
3319 DeclarationScopeStack.size() > 1)
3322 parseNamespaceOrExportBlock(AddLevels);
3327void UnwrappedLineParser::parseCppExportBlock() {
3328 if (FormatTok->is(tok::l_brace)) {
3329 FormatTok->setFinalizedType(TT_ExportLBrace);
3330 if (Style.BraceWrapping.AfterExportBlock)
3333 parseNamespaceOrExportBlock(Style.IndentExportBlock ? 1 : 0);
3336void UnwrappedLineParser::parseNew() {
3337 assert(FormatTok->is(tok::kw_new) &&
"'new' expected");
3340 if (Style.isCSharp()) {
3343 if (FormatTok->is(tok::l_paren))
3347 if (FormatTok->is(tok::l_brace))
3350 if (FormatTok->isOneOf(tok::semi, tok::comma))
3357 if (!Style.isJava())
3363 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3367 if (FormatTok->is(tok::l_paren)) {
3371 if (FormatTok->is(tok::l_brace))
3379void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3380 keepAncestorBraces();
3382 if (isBlockBegin(*FormatTok)) {
3383 FormatTok->setFinalizedType(TT_ControlStatementLBrace);
3385 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3386 parseBlock(
false, 1u,
3388 setPreviousRBraceType(TT_ControlStatementRBrace);
3390 assert(!NestedTooDeep.empty());
3391 if (!NestedTooDeep.back())
3397 parseUnbracedBody();
3401 NestedTooDeep.pop_back();
3404void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3405 assert((FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3406 (Style.isVerilog() &&
3407 FormatTok->isOneOf(Keywords.kw_always, Keywords.kw_always_comb,
3408 Keywords.kw_always_ff, Keywords.kw_always_latch,
3409 Keywords.kw_final, Keywords.kw_initial,
3410 Keywords.kw_foreach, Keywords.kw_forever,
3411 Keywords.kw_repeat))) &&
3412 "'for', 'while' or foreach macro expected");
3413 const bool KeepBraces = !Style.RemoveBracesLLVM ||
3414 FormatTok->isNoneOf(tok::kw_for, tok::kw_while);
3418 if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
3420 if (IsCpp && FormatTok->is(tok::kw_co_await))
3422 if (HasParens && FormatTok->is(tok::l_paren)) {
3426 if (Style.isVerilog())
3427 FormatTok->setFinalizedType(TT_ConditionLParen);
3431 if (Style.isVerilog()) {
3433 parseVerilogSensitivityList();
3434 }
else if (Style.AllowShortLoopsOnASingleLine && FormatTok->is(tok::semi) &&
3435 Tokens->getPreviousToken()->is(tok::r_paren)) {
3442 parseLoopBody(KeepBraces,
true);
3445void UnwrappedLineParser::parseDoWhile() {
3446 assert(FormatTok->is(tok::kw_do) &&
"'do' expected");
3449 parseLoopBody(
true, Style.BraceWrapping.BeforeWhile);
3452 if (FormatTok->isNot(tok::kw_while)) {
3457 FormatTok->setFinalizedType(TT_DoWhile);
3465 parseStructuralElement();
3468void UnwrappedLineParser::parseLabel(
bool IsGotoLabel) {
3471 const auto IndentGotoLabel = Style.IndentGotoLabels;
3472 const auto OldLineLevel =
Line->Level;
3479 if (OldLineLevel > 1 || (!
Line->InPPDirective && OldLineLevel > 0))
3483 if (!IsGotoLabel && !Style.IndentCaseBlocks &&
3484 CommentsBeforeNextToken.empty() && FormatTok->is(tok::l_brace)) {
3485 CompoundStatementIndenter Indenter(
this,
Level,
3486 Style.BraceWrapping.AfterCaseLabel,
3487 Style.BraceWrapping.IndentBraces);
3489 if (FormatTok->is(tok::kw_break)) {
3490 if (Style.BraceWrapping.AfterControlStatement ==
3493 if (!Style.IndentCaseBlocks &&
3498 parseStructuralElement();
3502 if (FormatTok->is(tok::semi))
3507 Level = OldLineLevel;
3509 if (FormatTok->isNot(tok::l_brace)) {
3510 parseStructuralElement();
3515void UnwrappedLineParser::parseCaseLabel() {
3516 assert(FormatTok->is(tok::kw_case) &&
"'case' expected");
3517 auto *Case = FormatTok;
3522 if (FormatTok->is(tok::colon)) {
3523 FormatTok->setFinalizedType(TT_CaseLabelColon);
3526 if (Style.isJava() && FormatTok->is(tok::arrow)) {
3527 FormatTok->setFinalizedType(TT_CaseLabelArrow);
3528 Case->setFinalizedType(TT_SwitchExpressionLabel);
3535void UnwrappedLineParser::parseSwitch(
bool IsExpr) {
3536 assert(FormatTok->is(tok::kw_switch) &&
"'switch' expected");
3538 if (FormatTok->is(tok::l_paren))
3541 keepAncestorBraces();
3543 if (FormatTok->is(tok::l_brace)) {
3544 CompoundStatementIndenter Indenter(
this, Style,
Line->Level);
3545 FormatTok->setFinalizedType(IsExpr ? TT_SwitchExpressionLBrace
3546 : TT_ControlStatementLBrace);
3551 setPreviousRBraceType(TT_ControlStatementRBrace);
3557 parseStructuralElement();
3561 if (Style.RemoveBracesLLVM)
3562 NestedTooDeep.pop_back();
3565void UnwrappedLineParser::parseAccessSpecifier() {
3568 if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
3571 if (FormatTok->is(tok::colon))
3579bool UnwrappedLineParser::parseRequires(
bool SeenEqual) {
3580 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3584 switch (Tokens->peekNextToken(
true)->Tok.getKind()) {
3587 parseRequiresExpression();
3594 parseRequiresClause();
3605 auto *PreviousNonComment = FormatTok->getPreviousNonComment();
3607 if (!PreviousNonComment ||
3608 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3611 parseRequiresClause();
3615 switch (PreviousNonComment->Tok.getKind()) {
3618 case tok::kw_noexcept:
3623 parseRequiresClause();
3632 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3633 if ((PrevPrev && PrevPrev->is(tok::kw_const)) || !SeenEqual) {
3634 parseRequiresClause();
3640 if (PreviousNonComment->isTypeOrIdentifier(LangOpts)) {
3642 parseRequiresClause();
3646 parseRequiresExpression();
3656 unsigned StoredPosition = Tokens->getPosition();
3659 auto PeekNext = [&Lookahead, &NextToken,
this] {
3661 NextToken = Tokens->getNextToken();
3664 bool FoundType =
false;
3665 bool LastWasColonColon =
false;
3668 for (; Lookahead < 50; PeekNext()) {
3669 switch (NextToken->Tok.getKind()) {
3670 case tok::kw_volatile:
3673 if (OpenAngles == 0) {
3674 FormatTok = Tokens->setPosition(StoredPosition);
3675 parseRequiresExpression();
3683 case tok::coloncolon:
3684 LastWasColonColon =
true;
3686 case tok::kw_decltype:
3687 case tok::identifier:
3688 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3689 FormatTok = Tokens->setPosition(StoredPosition);
3690 parseRequiresExpression();
3694 LastWasColonColon =
false;
3703 if (NextToken->isTypeName(LangOpts)) {
3704 FormatTok = Tokens->setPosition(StoredPosition);
3705 parseRequiresExpression();
3712 FormatTok = Tokens->setPosition(StoredPosition);
3713 parseRequiresClause();
3722void UnwrappedLineParser::parseRequiresClause() {
3723 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3728 bool InRequiresExpression =
3729 !FormatTok->Previous ||
3730 FormatTok->Previous->is(TT_RequiresExpressionLBrace);
3732 FormatTok->setFinalizedType(InRequiresExpression
3733 ? TT_RequiresClauseInARequiresExpression
3734 : TT_RequiresClause);
3739 parseConstraintExpression();
3741 if (!InRequiresExpression && FormatTok->Previous)
3742 FormatTok->Previous->ClosesRequiresClause =
true;
3750void UnwrappedLineParser::parseRequiresExpression() {
3751 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3753 FormatTok->setFinalizedType(TT_RequiresExpression);
3756 if (FormatTok->is(tok::l_paren)) {
3757 FormatTok->setFinalizedType(TT_RequiresExpressionLParen);
3761 if (FormatTok->is(tok::l_brace)) {
3762 FormatTok->setFinalizedType(TT_RequiresExpressionLBrace);
3771void UnwrappedLineParser::parseConstraintExpression() {
3778 bool LambdaNextTimeAllowed =
true;
3788 bool TopLevelParensAllowed =
true;
3791 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3793 switch (FormatTok->Tok.getKind()) {
3794 case tok::kw_requires:
3795 parseRequiresExpression();
3799 if (!TopLevelParensAllowed)
3801 parseParens(TT_BinaryOperator);
3802 TopLevelParensAllowed =
false;
3806 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3813 case tok::kw_struct:
3823 FormatTok->setFinalizedType(TT_BinaryOperator);
3825 LambdaNextTimeAllowed =
true;
3826 TopLevelParensAllowed =
true;
3831 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3835 case tok::kw_sizeof:
3837 case tok::greaterequal:
3838 case tok::greatergreater:
3840 case tok::lessequal:
3842 case tok::equalequal:
3844 case tok::exclaimequal:
3849 LambdaNextTimeAllowed =
true;
3850 TopLevelParensAllowed =
true;
3855 case tok::numeric_constant:
3856 case tok::coloncolon:
3859 TopLevelParensAllowed =
false;
3864 case tok::kw_static_cast:
3865 case tok::kw_const_cast:
3866 case tok::kw_reinterpret_cast:
3867 case tok::kw_dynamic_cast:
3869 if (FormatTok->isNot(tok::less))
3873 parseBracedList(
true);
3877 if (!FormatTok->Tok.getIdentifierInfo()) {
3887 assert(FormatTok->Previous);
3888 switch (FormatTok->Previous->Tok.getKind()) {
3889 case tok::coloncolon:
3893 case tok::kw_requires:
3895 case tok::kw_template:
3903 if (FormatTok->is(tok::less)) {
3905 parseBracedList(
true);
3907 TopLevelParensAllowed =
false;
3913bool UnwrappedLineParser::parseEnum() {
3917 if (FormatTok->is(tok::kw_enum))
3923 if (Style.isJavaScript() && FormatTok->isOneOf(tok::colon, tok::question))
3932 if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))
3934 while (FormatTok->is(tok::l_square))
3935 if (!handleCppAttributes())
3939 while (FormatTok->Tok.getIdentifierInfo() ||
3940 FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
3941 tok::greater, tok::comma, tok::question,
3943 if (FormatTok->is(tok::colon))
3944 FormatTok->setFinalizedType(TT_EnumUnderlyingTypeColon);
3945 if (Style.isVerilog()) {
3946 FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);
3949 while (FormatTok->is(tok::l_square))
3955 if (FormatTok->is(tok::l_paren))
3957 if (FormatTok->is(tok::identifier)) {
3961 if (IsCpp && FormatTok->is(tok::identifier))
3967 if (FormatTok->isNot(tok::l_brace))
3969 FormatTok->setFinalizedType(TT_EnumLBrace);
3970 FormatTok->setBlockKind(BK_Block);
3972 if (Style.isJava()) {
3974 parseJavaEnumBody();
3982 const bool ManageWhitesmithsBraces =
3985 if (!Style.AllowShortEnumsOnASingleLine &&
3987 Tokens->peekNextToken()->is(tok::r_brace))) {
3992 if (ManageWhitesmithsBraces)
3997 if (!Style.AllowShortEnumsOnASingleLine) {
3999 if (!ManageWhitesmithsBraces)
4002 const auto OpeningLineIndex = CurrentLines->empty()
4003 ? UnwrappedLine::kInvalidIndex
4004 : CurrentLines->size() - 1;
4005 bool HasError = !parseBracedList(
false,
true);
4006 if (!Style.AllowShortEnumsOnASingleLine && !ManageWhitesmithsBraces)
4009 if (FormatTok->is(tok::semi))
4013 setPreviousRBraceType(TT_EnumRBrace);
4014 if (ManageWhitesmithsBraces)
4015 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
4023bool UnwrappedLineParser::parseStructLike() {
4028 if (Style.isJava() || Style.isJavaScript() || Style.isCSharp()) {
4029 if (FormatTok->is(tok::semi))
4040class ScopedTokenPosition {
4041 unsigned StoredPosition;
4042 FormatTokenSource *Tokens;
4045 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
4046 assert(Tokens &&
"Tokens expected to not be null");
4047 StoredPosition = Tokens->getPosition();
4050 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
4056bool UnwrappedLineParser::tryToParseSimpleAttribute() {
4057 ScopedTokenPosition AutoPosition(Tokens);
4065 if (
Tok->
is(tok::r_square))
4067 Tok = Tokens->getNextToken();
4069 if (
Tok->
is(tok::eof))
4071 Tok = Tokens->getNextToken();
4074 Tok = Tokens->getNextToken();
4075 if (
Tok->
is(tok::semi))
4080void UnwrappedLineParser::parseJavaEnumBody() {
4081 assert(FormatTok->is(tok::l_brace));
4087 unsigned StoredPosition = Tokens->getPosition();
4088 bool IsSimple =
true;
4091 if (
Tok->
is(tok::r_brace))
4099 Tok = Tokens->getNextToken();
4101 FormatTok = Tokens->setPosition(StoredPosition);
4118 if (FormatTok->is(tok::l_brace)) {
4120 parseBlock(
true, 1u,
4122 }
else if (FormatTok->is(tok::l_paren)) {
4124 }
else if (FormatTok->is(tok::comma)) {
4127 }
else if (FormatTok->is(tok::semi)) {
4131 }
else if (FormatTok->is(tok::r_brace)) {
4140 parseLevel(OpeningBrace);
4146void UnwrappedLineParser::parseRecord(
bool ParseAsExpr,
bool IsJavaRecord) {
4147 assert(!IsJavaRecord || FormatTok->is(Keywords.kw_record));
4152 IsJavaRecord && FormatTok->is(tok::identifier) ? FormatTok :
nullptr;
4153 bool IsDerived =
false;
4155 return Tok->
is(tok::identifier) &&
Tok->TokenText !=
Tok->TokenText.upper();
4159 bool JSPastExtendsOrImplements =
false;
4163 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
4164 tok::kw_alignas, tok::l_square) ||
4165 FormatTok->isAttribute() ||
4166 ((Style.isJava() || Style.isJavaScript()) &&
4167 FormatTok->isOneOf(tok::period, tok::comma)) ||
4168 (Style.isVerilog() &&
4169 FormatTok->isOneOf(tok::kw_signed, tok::kw_unsigned))) {
4170 if (Style.isJavaScript() &&
4171 FormatTok->isOneOf(Keywords.kw_extends, Keywords.kw_implements)) {
4172 JSPastExtendsOrImplements =
true;
4177 if (FormatTok->is(tok::l_brace)) {
4178 tryToParseBracedList();
4182 if (FormatTok->is(tok::l_square) && handleCppAttributes())
4186 switch (FormatTok->Tok.getKind()) {
4189 if (IsJavaRecord || !IsNonMacroIdentifier(
Previous) ||
4191 Previous->Previous == &InitialToken) {
4195 case tok::coloncolon:
4199 if (JSPastExtendsOrImplements || ClassName ||
4210 auto IsListInitialization = [&] {
4211 if (!ClassName || IsDerived || JSPastExtendsOrImplements)
4213 assert(FormatTok->is(tok::l_brace));
4214 const auto *Prev = FormatTok->getPreviousNonComment();
4216 return Prev != ClassName && Prev->is(tok::identifier) &&
4217 Prev->isNot(Keywords.kw_final) && tryToParseBracedList();
4220 if (FormatTok->isOneOf(tok::colon, tok::less)) {
4221 int AngleNestingLevel = 0;
4223 if (FormatTok->is(tok::less))
4224 ++AngleNestingLevel;
4225 else if (FormatTok->is(tok::greater))
4226 --AngleNestingLevel;
4228 if (AngleNestingLevel == 0) {
4229 if (FormatTok->is(tok::colon)) {
4231 }
else if (!IsDerived && FormatTok->is(tok::identifier) &&
4232 FormatTok->Previous->is(tok::coloncolon)) {
4233 ClassName = FormatTok;
4234 }
else if (FormatTok->is(tok::l_paren) &&
4235 IsNonMacroIdentifier(FormatTok->Previous)) {
4239 if (FormatTok->is(tok::l_brace)) {
4240 if (AngleNestingLevel == 0 && IsListInitialization())
4242 calculateBraceTypes(
true);
4243 if (!tryToParseBracedList())
4246 if (FormatTok->is(tok::l_square)) {
4249 !
Previous->isTypeOrIdentifier(LangOpts))) {
4252 if (!tryToParseLambda())
4259 if (FormatTok->is(tok::semi))
4261 if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) {
4264 parseCSharpGenericTypeConstraint();
4271 auto GetBraceTypes =
4272 [](
const FormatToken &RecordTok) -> std::pair<TokenType, TokenType> {
4273 switch (RecordTok.Tok.getKind()) {
4275 return {TT_ClassLBrace, TT_ClassRBrace};
4276 case tok::kw_struct:
4277 return {TT_StructLBrace, TT_StructRBrace};
4279 return {TT_UnionLBrace, TT_UnionRBrace};
4282 return {TT_RecordLBrace, TT_RecordRBrace};
4285 if (FormatTok->is(tok::l_brace)) {
4286 if (IsListInitialization())
4289 ClassName->setFinalizedType(TT_ClassHeadName);
4290 auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
4291 FormatTok->setFinalizedType(OpenBraceType);
4296 Tokens->peekNextToken()->is(tok::r_brace),
4301 unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;
4302 parseBlock(
true, AddLevels,
false);
4304 setPreviousRBraceType(ClosingBraceType);
4311void UnwrappedLineParser::parseObjCMethod() {
4312 assert(FormatTok->isOneOf(tok::l_paren, tok::identifier) &&
4313 "'(' or identifier expected.");
4315 if (FormatTok->is(tok::semi)) {
4319 }
else if (FormatTok->is(tok::l_brace)) {
4320 if (Style.BraceWrapping.AfterFunction)
4331void UnwrappedLineParser::parseObjCProtocolList() {
4332 assert(FormatTok->is(tok::less) &&
"'<' expected.");
4336 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))
4338 }
while (!
eof() && FormatTok->isNot(tok::greater));
4342void UnwrappedLineParser::parseObjCUntilAtEnd() {
4344 if (FormatTok->is(tok::objc_end)) {
4349 if (FormatTok->is(tok::l_brace)) {
4353 }
else if (FormatTok->is(tok::r_brace)) {
4357 }
else if (FormatTok->isOneOf(tok::minus, tok::plus)) {
4359 if (FormatTok->isOneOf(tok::l_paren, tok::identifier))
4362 parseStructuralElement();
4367void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
4368 assert(FormatTok->isOneOf(tok::objc_interface, tok::objc_implementation));
4374 if (FormatTok->is(tok::less))
4375 parseObjCLightweightGenerics();
4376 if (FormatTok->is(tok::colon)) {
4380 if (FormatTok->is(tok::less))
4381 parseObjCLightweightGenerics();
4382 }
else if (FormatTok->is(tok::l_paren)) {
4387 if (FormatTok->is(tok::less))
4388 parseObjCProtocolList();
4390 if (FormatTok->is(tok::l_brace)) {
4391 if (Style.BraceWrapping.AfterObjCDeclaration)
4400 parseObjCUntilAtEnd();
4403void UnwrappedLineParser::parseObjCLightweightGenerics() {
4404 assert(FormatTok->is(tok::less));
4412 unsigned NumOpenAngles = 1;
4416 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))
4418 if (FormatTok->is(tok::less)) {
4420 }
else if (FormatTok->is(tok::greater)) {
4421 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4424 }
while (!
eof() && NumOpenAngles != 0);
4430bool UnwrappedLineParser::parseObjCProtocol() {
4431 assert(FormatTok->is(tok::objc_protocol));
4434 if (FormatTok->is(tok::l_paren)) {
4446 if (FormatTok->is(tok::less))
4447 parseObjCProtocolList();
4450 if (FormatTok->is(tok::semi)) {
4457 parseObjCUntilAtEnd();
4461void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4462 bool IsImport = FormatTok->is(Keywords.kw_import);
4463 assert(IsImport || FormatTok->is(tok::kw_export));
4467 if (FormatTok->is(tok::kw_default))
4473 if (FormatTok->is(Keywords.kw_async))
4475 if (FormatTok->is(Keywords.kw_function)) {
4484 if (!IsImport && FormatTok->isNoneOf(tok::l_brace, tok::star) &&
4485 !FormatTok->isStringLiteral() &&
4486 !(FormatTok->is(Keywords.kw_type) &&
4487 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4492 if (FormatTok->is(tok::semi))
4494 if (
Line->Tokens.empty()) {
4499 if (FormatTok->is(tok::l_brace)) {
4500 FormatTok->setBlockKind(BK_Block);
4509void UnwrappedLineParser::parseStatementMacro() {
4511 if (FormatTok->is(tok::l_paren))
4513 if (FormatTok->is(tok::semi))
4518void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4521 if (FormatTok->isOneOf(tok::star, tok::period, tok::periodstar,
4522 tok::coloncolon, tok::hash) ||
4523 Keywords.isVerilogIdentifier(*FormatTok)) {
4525 }
else if (FormatTok->is(tok::l_square)) {
4533void UnwrappedLineParser::parseVerilogSensitivityList() {
4534 if (FormatTok->isNot(tok::at))
4538 if (FormatTok->is(tok::at))
4540 switch (FormatTok->Tok.getKind()) {
4548 parseVerilogHierarchyIdentifier();
4553unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4554 unsigned AddLevels = 0;
4556 if (FormatTok->is(Keywords.kw_clocking)) {
4558 if (Keywords.isVerilogIdentifier(*FormatTok))
4560 parseVerilogSensitivityList();
4561 if (FormatTok->is(tok::semi))
4563 }
else if (FormatTok->isOneOf(tok::kw_case, Keywords.kw_casex,
4564 Keywords.kw_casez, Keywords.kw_randcase,
4565 Keywords.kw_randsequence)) {
4566 if (Style.IndentCaseLabels)
4569 if (FormatTok->is(tok::l_paren)) {
4570 FormatTok->setFinalizedType(TT_ConditionLParen);
4573 if (FormatTok->isOneOf(Keywords.kw_inside, Keywords.kw_matches))
4582 if (FormatTok->is(tok::l_square)) {
4583 auto Prev = FormatTok->getPreviousNonComment();
4584 if (Prev && Keywords.isVerilogIdentifier(*Prev))
4585 Prev->setFinalizedType(TT_VerilogDimensionedTypeName);
4587 }
else if (Keywords.isVerilogIdentifier(*FormatTok) ||
4588 FormatTok->isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
4589 Keywords.kw_automatic, tok::kw_static)) {
4596 auto NewLine = [
this]() {
4598 Line->IsContinuation =
true;
4602 while (FormatTok->is(Keywords.kw_import)) {
4605 parseVerilogHierarchyIdentifier();
4606 if (FormatTok->is(tok::semi))
4611 if (FormatTok->is(Keywords.kw_verilogHash)) {
4614 if (FormatTok->is(tok::l_paren)) {
4615 FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
4619 if (FormatTok->is(tok::l_paren)) {
4621 FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
4626 if (FormatTok->is(Keywords.kw_extends)) {
4629 parseVerilogHierarchyIdentifier();
4630 if (FormatTok->is(tok::l_paren))
4633 if (FormatTok->is(Keywords.kw_implements)) {
4637 parseVerilogHierarchyIdentifier();
4638 }
while (FormatTok->is(tok::comma));
4642 if (FormatTok->is(tok::at)) {
4644 parseVerilogSensitivityList();
4647 if (FormatTok->is(tok::semi))
4655void UnwrappedLineParser::parseVerilogTable() {
4656 assert(FormatTok->is(Keywords.kw_table));
4660 auto InitialLevel =
Line->Level++;
4661 while (!
eof() && !Keywords.isVerilogEnd(*FormatTok)) {
4664 if (
Tok->
is(tok::semi))
4666 else if (
Tok->
isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4667 Tok->setFinalizedType(TT_VerilogTableItem);
4669 Line->Level = InitialLevel;
4674void UnwrappedLineParser::parseVerilogCaseLabel() {
4680 auto OrigLevel =
Line->Level;
4681 auto FirstLine = CurrentLines->size();
4682 if (
Line->Level == 0 || (
Line->InPPDirective &&
Line->Level <= 1))
4684 else if (!Style.IndentCaseBlocks && Keywords.isVerilogBegin(*FormatTok))
4686 parseStructuralElement();
4689 if (CurrentLines->size() > FirstLine)
4690 (*CurrentLines)[FirstLine].Level = OrigLevel;
4691 Line->Level = OrigLevel;
4694void UnwrappedLineParser::parseVerilogExtern() {
4696 FormatTok->isOneOf(tok::kw_extern, tok::kw_export, Keywords.kw_import));
4699 if (FormatTok->is(tok::string_literal))
4701 skipVerilogQualifiers();
4702 if (Keywords.isVerilogIdentifier(*FormatTok))
4704 if (FormatTok->is(tok::equal))
4706 if (Keywords.isVerilogHierarchy(*FormatTok))
4707 parseVerilogHierarchyHeader();
4710void UnwrappedLineParser::skipVerilogQualifiers() {
4711 while (FormatTok->isOneOf(tok::kw_protected, tok::kw_virtual, tok::kw_static,
4712 Keywords.kw_rand, Keywords.kw_context,
4713 Keywords.kw_pure, Keywords.kw_randc,
4714 Keywords.kw_local)) {
4719bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &
Line)
const {
4720 for (
const auto &N :
Line.Tokens) {
4721 if (N.Tok->MacroCtx)
4723 for (
const UnwrappedLine &Child : N.Children)
4724 if (containsExpansion(Child))
4730void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4731 if (
Line->Tokens.empty())
4734 if (!parsingPPDirective()) {
4735 llvm::dbgs() <<
"Adding unwrapped line:\n";
4736 printDebugInfo(*
Line);
4744 bool ClosesWhitesmithsBlock =
4745 Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex &&
4751 if (!parsingPPDirective() && !InExpansion && containsExpansion(*
Line)) {
4753 Reconstruct.emplace(
Line->Level, Unexpanded);
4754 Reconstruct->addLine(*
Line);
4759 CurrentExpandedLines.push_back(std::move(*
Line));
4761 if (Reconstruct->finished()) {
4762 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4763 assert(!Reconstructed.Tokens.empty() &&
4764 "Reconstructed must at least contain the macro identifier.");
4765 assert(!parsingPPDirective());
4767 llvm::dbgs() <<
"Adding unexpanded line:\n";
4768 printDebugInfo(Reconstructed);
4770 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4771 Lines.push_back(std::move(Reconstructed));
4772 CurrentExpandedLines.clear();
4773 Reconstruct.reset();
4778 assert(!Reconstruct || (CurrentLines != &Lines) || !PP.Stack.empty());
4779 CurrentLines->push_back(std::move(*
Line));
4781 Line->Tokens.clear();
4782 Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;
4783 Line->FirstStartColumn = 0;
4784 Line->IsContinuation =
false;
4785 Line->SeenDecltypeAuto =
false;
4786 Line->IsModuleOrImportDecl =
false;
4788 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4790 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4791 CurrentLines->append(
4792 std::make_move_iterator(PreprocessorDirectives.begin()),
4793 std::make_move_iterator(PreprocessorDirectives.end()));
4794 PreprocessorDirectives.clear();
4797 FormatTok->Previous =
nullptr;
4800bool UnwrappedLineParser::eof()
const {
return FormatTok->is(tok::eof); }
4802bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4803 return (
Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4804 FormatTok.NewlinesBefore > 0;
4812 const llvm::Regex &CommentPragmasRegex) {
4816 StringRef IndentContent = FormatTok.
TokenText;
4817 if (FormatTok.
TokenText.starts_with(
"//") ||
4818 FormatTok.
TokenText.starts_with(
"/*")) {
4819 IndentContent = FormatTok.
TokenText.substr(2);
4821 if (CommentPragmasRegex.match(IndentContent))
4896 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4898 MinColumnToken = PreviousToken;
4901 PreviousToken = Node.
Tok;
4905 MinColumnToken = Node.
Tok;
4907 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4908 MinColumnToken = PreviousToken;
4914void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4915 bool JustComments =
Line->Tokens.empty();
4925 Tok->ContinuesLineCommentSection =
4926 continuesLineCommentSection(*
Tok, *
Line, Style, CommentPragmasRegex);
4927 if (isOnNewLine(*
Tok) && JustComments && !
Tok->ContinuesLineCommentSection)
4931 if (NewlineBeforeNext && JustComments)
4933 CommentsBeforeNextToken.clear();
4936void UnwrappedLineParser::nextToken(
int LevelDifference) {
4939 flushComments(isOnNewLine(*FormatTok));
4940 pushToken(FormatTok);
4942 if (!Style.isJavaScript())
4943 readToken(LevelDifference);
4945 readTokenWithJavaScriptASI();
4947 if (Style.isVerilog()) {
4954 if (Keywords.isVerilogEnd(*FormatTok))
4955 FormatTok->Tok.setKind(tok::r_brace);
4959void UnwrappedLineParser::distributeComments(
4979 if (Comments.empty())
4981 bool ShouldPushCommentsInCurrentLine =
true;
4982 bool HasTrailAlignedWithNextToken =
false;
4983 unsigned StartOfTrailAlignedWithNextToken = 0;
4986 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4988 HasTrailAlignedWithNextToken =
true;
4989 StartOfTrailAlignedWithNextToken = i;
4993 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4995 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4996 FormatTok->ContinuesLineCommentSection =
false;
4999 *FormatTok, *
Line, Style, CommentPragmasRegex);
5001 if (!FormatTok->ContinuesLineCommentSection &&
5002 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
5003 ShouldPushCommentsInCurrentLine =
false;
5005 if (ShouldPushCommentsInCurrentLine)
5006 pushToken(FormatTok);
5008 CommentsBeforeNextToken.push_back(FormatTok);
5012void UnwrappedLineParser::readToken(
int LevelDifference) {
5014 bool PreviousWasComment =
false;
5015 bool FirstNonCommentOnLine =
false;
5017 FormatTok = Tokens->getNextToken();
5019 while (FormatTok->isOneOf(TT_ConflictStart, TT_ConflictEnd,
5020 TT_ConflictAlternative)) {
5021 if (FormatTok->is(TT_ConflictStart))
5022 conditionalCompilationStart(
false);
5023 else if (FormatTok->is(TT_ConflictAlternative))
5024 conditionalCompilationAlternative();
5025 else if (FormatTok->is(TT_ConflictEnd))
5026 conditionalCompilationEnd();
5027 FormatTok = Tokens->getNextToken();
5028 FormatTok->MustBreakBefore =
true;
5029 FormatTok->MustBreakBeforeFinalized =
true;
5032 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
5034 bool PreviousWasComment) {
5036 return Tok.HasUnescapedNewline ||
Tok.IsFirst;
5041 if (PreviousWasComment)
5042 return FirstNonCommentOnLine || IsFirstOnLine(
Tok);
5043 return IsFirstOnLine(
Tok);
5046 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
5047 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
5048 PreviousWasComment = FormatTok->is(tok::comment);
5050 while (!
Line->InPPDirective && FormatTok->is(tok::hash) &&
5051 FirstNonCommentOnLine) {
5054 const auto *
Next = Tokens->peekNextToken();
5055 if ((Style.isVerilog() && !Keywords.isVerilogPPDirective(*
Next)) ||
5056 (Style.isTableGen() &&
5057 Next->isNoneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,
5058 tok::pp_ifndef, tok::pp_endif))) {
5061 distributeComments(Comments, FormatTok);
5066 const bool ParsedBefore = !ParsedPPDirectives.insert(FormatTok).second;
5069 bool SwitchToPreprocessorLines = !
Line->Tokens.empty();
5070 ScopedLineState BlockState(*
this, SwitchToPreprocessorLines,
5072 assert((LevelDifference >= 0 ||
5073 static_cast<unsigned>(-LevelDifference) <=
Line->Level) &&
5074 "LevelDifference makes Line->Level negative");
5075 Line->Level += LevelDifference;
5080 PP.BranchLevel > 0) {
5081 Line->Level += PP.BranchLevel;
5083 assert(
Line->Level >=
Line->UnbracedBodyLevel);
5084 Line->Level -=
Line->UnbracedBodyLevel;
5085 flushComments(isOnNewLine(*FormatTok));
5086 const bool IsEndIf = Tokens->peekNextToken()->is(tok::pp_endif);
5088 PreviousWasComment = FormatTok->is(tok::comment);
5089 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
5090 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
5093 if (IsEndIf && PP.IncludeGuard == IG_Defined && PP.BranchLevel == -1 &&
5094 getIncludeGuardState(Style.IndentPPDirectives) == IG_Inited &&
5096 (PreviousWasComment &&
5097 Tokens->peekNextToken(
true)->is(tok::eof)))) {
5098 PP.IncludeGuard = IG_Found;
5102 if (!PP.Stack.empty() && (PP.Stack.back().Kind == PP_Unreachable) &&
5103 !
Line->InPPDirective) {
5107 if (FormatTok->is(tok::identifier) &&
5108 Macros.defined(FormatTok->TokenText) &&
5110 !
Line->InPPDirective) {
5112 unsigned Position = Tokens->getPosition();
5117 const auto SavedPPState = PP;
5121 auto PreCall = std::move(
Line);
5122 Line.reset(
new UnwrappedLine);
5123 bool OldInExpansion = InExpansion;
5126 auto Args = parseMacroCall(SavedPPState);
5127 InExpansion = OldInExpansion;
5128 assert(
Line->Tokens.front().Tok == ID);
5130 auto UnexpandedLine = std::move(
Line);
5132 Line = std::move(PreCall);
5135 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
5137 llvm::dbgs() <<
"(";
5138 for (
const auto &Arg : Args.value())
5139 for (
const auto &
T : Arg)
5140 llvm::dbgs() <<
T->TokenText <<
" ";
5141 llvm::dbgs() <<
")";
5143 llvm::dbgs() <<
"\n";
5145 if (
Macros.objectLike(
ID->TokenText) && Args &&
5146 !
Macros.hasArity(
ID->TokenText, Args->size())) {
5152 LLVM_DEBUG(llvm::dbgs()
5153 <<
"Macro \"" <<
ID->TokenText
5154 <<
"\" not overloaded for arity " << Args->size()
5155 <<
"or not function-like, using object-like overload.");
5157 UnexpandedLine->Tokens.resize(1);
5158 Tokens->setPosition(Position);
5160 FormatTok = Tokens->getNextToken();
5162 assert(!Args &&
Macros.objectLike(
ID->TokenText));
5164 if ((!Args &&
Macros.objectLike(
ID->TokenText)) ||
5165 (Args &&
Macros.hasArity(
ID->TokenText, Args->size()))) {
5168 Unexpanded[
ID] = std::move(UnexpandedLine);
5170 Macros.expand(ID, std::move(Args));
5171 if (!Expansion.empty())
5172 FormatTok = Tokens->insertTokens(Expansion);
5175 llvm::dbgs() <<
"Expanded: ";
5176 for (
const auto &
T : Expansion)
5177 llvm::dbgs() <<
T->TokenText <<
" ";
5178 llvm::dbgs() <<
"\n";
5182 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
5183 <<
"\", because it was used ";
5185 llvm::dbgs() <<
"with " << Args->size();
5187 llvm::dbgs() <<
"without";
5188 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
5190 Tokens->setPosition(Position);
5196 if (FormatTok->isNot(tok::comment)) {
5197 distributeComments(Comments, FormatTok);
5202 Comments.push_back(FormatTok);
5205 distributeComments(Comments,
nullptr);
5210template <
typename Iterator>
5211void pushTokens(Iterator Begin, Iterator End,
5213 for (
auto I = Begin; I != End; ++I) {
5214 Into.push_back(I->Tok);
5215 for (
const auto &Child : I->Children)
5216 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
5221std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
5222UnwrappedLineParser::parseMacroCall(
const PPState &SavedPPState) {
5223 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
5224 assert(
Line->Tokens.empty());
5227 auto ConsumeLastTokenOfCall = [
this] {
5228 flushComments(isOnNewLine(*FormatTok));
5229 pushToken(FormatTok);
5230 FormatTok = Tokens->getNextToken();
5232 if (Tokens->peekNextToken(
true)->isNot(tok::l_paren)) {
5233 ConsumeLastTokenOfCall();
5237 assert(FormatTok->is(tok::l_paren));
5238 unsigned Position = Tokens->getPosition();
5242 auto ArgStart = std::prev(
Line->Tokens.end());
5246 switch (FormatTok->Tok.getKind()) {
5251 case tok::r_paren: {
5257 Args->push_back({});
5258 pushTokens(std::next(ArgStart),
Line->Tokens.end(), Args->back());
5259 ConsumeLastTokenOfCall();
5267 Args->push_back({});
5268 pushTokens(std::next(ArgStart),
Line->Tokens.end(), Args->back());
5270 ArgStart = std::prev(
Line->Tokens.end());
5278 Line->Tokens.resize(1);
5279 Tokens->setPosition(Position);
5286 Line->Tokens.push_back(UnwrappedLineNode(
Tok));
5287 if (PP.AtEndOfPPLine) {
5288 auto &
Tok = *
Line->Tokens.back().Tok;
5289 Tok.MustBreakBefore =
true;
5290 Tok.MustBreakBeforeFinalized =
true;
5291 Tok.FirstAfterPPLine =
true;
5292 PP.AtEndOfPPLine =
false;
This file contains the main building blocks of macro support in clang-format.
static bool HasAttribute(const QualType &T)
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...
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 isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isOneOf(Ts... Ks) const
bool isNot(tok::TokenKind K) const
@ Macros
Canonicalize -D and -U options.
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.
Top level wrappers for InstallAPI frontend operations.
bool isLineComment(const FormatToken &FormatTok)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Default
Set to the current date and time.
const FunctionProtoType * T
@ Type
The name was classified as a type.
bool continuesLineComment(const FormatToken &FormatTok, const FormatToken *Previous, const FormatToken *MinColumnToken)
@ Parens
New-expression has a C++98 paren-delimited initializer.
Encapsulates keywords that are context sensitive or for languages not properly supported by Clang's l...
IdentifierInfo * kw_instanceof
IdentifierInfo * kw_implements
IdentifierInfo * kw_override
IdentifierInfo * kw_await
IdentifierInfo * kw_extends
IdentifierInfo * kw_async
IdentifierInfo * kw_abstract
IdentifierInfo * kw_interface
IdentifierInfo * kw_function
IdentifierInfo * kw_yield
IdentifierInfo * kw_where
IdentifierInfo * kw_throws
IdentifierInfo * kw_import
IdentifierInfo * kw_finally
Represents a complete lambda introducer.