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) {
43 for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
44 E = Line.Tokens.end();
50 OS << I->Tok->Tok.getName() <<
"["
51 <<
"T=" << (
unsigned)I->Tok->getType()
52 <<
", OC=" << I->Tok->OriginalColumn <<
", \"" << I->Tok->TokenText
54 for (SmallVectorImpl<UnwrappedLine>::const_iterator
55 CI = I->Children.begin(),
56 CE = I->Children.end();
59 printLine(OS, *CI, (Prefix +
" ").str());
67LLVM_ATTRIBUTE_UNUSED
static void printDebugInfo(
const UnwrappedLine &Line) {
68 printLine(llvm::dbgs(), Line);
71class ScopedDeclarationState {
73 ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
74 bool MustBeDeclaration)
75 : Line(Line), Stack(Stack) {
76 Line.MustBeDeclaration = MustBeDeclaration;
77 Stack.push_back(MustBeDeclaration);
79 ~ScopedDeclarationState() {
82 Line.MustBeDeclaration = Stack.back();
84 Line.MustBeDeclaration =
true;
89 llvm::BitVector &Stack;
97 bool SwitchToPreprocessorLines =
false)
99 if (SwitchToPreprocessorLines)
101 else if (!
Parser.Line->Tokens.empty())
102 Parser.CurrentLines = &
Parser.Line->Tokens.back().Children;
103 PreBlockLine = std::move(
Parser.Line);
104 Parser.Line = std::make_unique<UnwrappedLine>();
105 Parser.Line->Level = PreBlockLine->Level;
106 Parser.Line->PPLevel = PreBlockLine->PPLevel;
107 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
108 Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
112 if (!
Parser.Line->Tokens.empty())
113 Parser.addUnwrappedLine();
114 assert(
Parser.Line->Tokens.empty());
115 Parser.Line = std::move(PreBlockLine);
116 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
117 Parser.MustBreakBeforeNextToken =
true;
118 Parser.CurrentLines = OriginalLines;
124 std::unique_ptr<UnwrappedLine> PreBlockLine;
133 Style.BraceWrapping.AfterControlStatement,
134 Style.BraceWrapping.IndentBraces) {}
136 bool WrapBrace,
bool IndentBrace)
137 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
139 Parser->addUnwrappedLine();
147 unsigned OldLineLevel;
154 llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
157 CurrentLines(&Lines), Style(Style), Keywords(Keywords),
158 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
159 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
160 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
163 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
164 Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}
166void UnwrappedLineParser::reset() {
171 IncludeGuardToken =
nullptr;
173 CommentsBeforeNextToken.clear();
175 MustBreakBeforeNextToken =
false;
176 PreprocessorDirectives.clear();
177 CurrentLines = &Lines;
178 DeclarationScopeStack.clear();
179 NestedTooDeep.clear();
181 Line->FirstStartColumn = FirstStartColumn;
183 if (!Unexpanded.empty())
185 Token->MacroCtx.reset();
186 CurrentExpandedLines.clear();
187 ExpandedLines.clear();
195 Line->FirstStartColumn = FirstStartColumn;
197 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
199 Tokens = &TokenSource;
207 if (IncludeGuard == IG_Found) {
208 for (
auto &Line : Lines)
209 if (Line.InPPDirective && Line.Level > 0)
214 assert(FormatTok->
is(tok::eof));
215 pushToken(FormatTok);
220 if (!ExpandedLines.empty()) {
221 LLVM_DEBUG(llvm::dbgs() <<
"Expanded lines:\n");
222 for (
const auto &Line : Lines) {
223 if (!Line.Tokens.empty()) {
224 auto it = ExpandedLines.find(Line.Tokens.begin()->Tok);
225 if (it != ExpandedLines.end()) {
226 for (
const auto &Expanded : it->second) {
227 LLVM_DEBUG(printDebugInfo(Expanded));
233 LLVM_DEBUG(printDebugInfo(Line));
239 LLVM_DEBUG(llvm::dbgs() <<
"Unwrapped lines:\n");
241 LLVM_DEBUG(printDebugInfo(Line));
246 while (!PPLevelBranchIndex.empty() &&
247 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
248 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
249 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
251 if (!PPLevelBranchIndex.empty()) {
252 ++PPLevelBranchIndex.back();
253 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
254 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
256 }
while (!PPLevelBranchIndex.empty());
259void UnwrappedLineParser::parseFile() {
262 bool MustBeDeclaration = !Line->InPPDirective && !Style.
isJavaScript();
263 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
280 !CommentsBeforeNextToken.empty()) {
287void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
296 parseCSharpGenericTypeConstraint();
305void UnwrappedLineParser::parseCSharpAttribute() {
306 int UnpairedSquareBrackets = 1;
311 --UnpairedSquareBrackets;
312 if (UnpairedSquareBrackets == 0) {
318 ++UnpairedSquareBrackets;
328bool UnwrappedLineParser::precededByCommentOrPPDirective()
const {
329 if (!Lines.empty() && Lines.back().InPPDirective)
343bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
345 FormatToken **IfLeftBrace) {
346 const bool InRequiresExpression =
347 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
348 const bool IsPrecededByCommentOrPPDirective =
350 FormatToken *IfLBrace =
nullptr;
351 bool HasDoWhile =
false;
352 bool HasLabel =
false;
353 unsigned StatementCount = 0;
354 bool SwitchLabelEncountered =
false;
362 if (FormatTok->
getType() == TT_MacroBlockBegin)
364 else if (FormatTok->
getType() == TT_MacroBlockEnd)
367 auto ParseDefault = [
this, OpeningBrace, IfKind, &IfLBrace, &HasDoWhile,
368 &HasLabel, &StatementCount] {
369 parseStructuralElement(OpeningBrace, IfKind, &IfLBrace,
370 HasDoWhile ?
nullptr : &HasDoWhile,
371 HasLabel ?
nullptr : &HasLabel);
373 assert(StatementCount > 0 &&
"StatementCount overflow!");
382 if (InRequiresExpression) {
391 if (!InRequiresExpression && FormatTok->
isNot(TT_MacroBlockBegin) &&
392 tryToParseBracedList()) {
397 assert(StatementCount > 0 &&
"StatementCount overflow!");
403 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
406 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
407 HasDoWhile || IsPrecededByCommentOrPPDirective ||
408 precededByCommentOrPPDirective()) {
412 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
415 *IfLeftBrace = IfLBrace;
421 case tok::kw_default: {
427 }
while (Next->is(tok::comment));
429 if (Next->isNot(tok::colon)) {
432 parseStructuralElement();
448 if (!SwitchLabelEncountered &&
450 (Line->InPPDirective && Line->Level == 1))) {
453 SwitchLabelEncountered =
true;
454 parseStructuralElement();
459 parseCSharpAttribute();
462 if (handleCppAttributes())
474void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
480 FormatToken *Tok = FormatTok;
481 const FormatToken *PrevTok = Tok->
Previous;
487 const FormatToken *PrevTok;
489 SmallVector<StackEntry, 8> LBraceStack;
490 assert(Tok->is(tok::l_brace));
493 FormatToken *NextTok;
496 }
while (NextTok->is(tok::comment));
498 switch (Tok->Tok.getKind()) {
501 if (PrevTok->isOneOf(tok::colon, tok::less)) {
512 }
else if (PrevTok->is(tok::r_paren)) {
519 LBraceStack.push_back({Tok, PrevTok});
522 if (LBraceStack.empty())
525 bool ProbablyBracedList =
false;
527 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
532 while (NextTok->is(tok::hash)) {
533 ScopedMacroState MacroState(*Line, Tokens, NextTok);
536 }
while (NextTok->isNot(tok::eof));
541 bool NextIsObjCMethod = NextTok->
isOneOf(tok::plus, tok::minus) &&
542 NextTok->OriginalColumn == 0;
552 ProbablyBracedList = LBraceStack.back().Tok->is(TT_BracedListLBrace);
554 ProbablyBracedList = ProbablyBracedList ||
556 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
558 ProbablyBracedList = ProbablyBracedList ||
559 (Style.
isCpp() && NextTok->is(tok::l_paren));
566 ProbablyBracedList ||
567 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
568 tok::r_paren, tok::r_square, tok::ellipsis);
573 ProbablyBracedList ||
574 (NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
575 LBraceStack.back().PrevTok->isOneOf(tok::identifier,
579 ProbablyBracedList ||
580 (NextTok->is(tok::identifier) &&
581 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
583 ProbablyBracedList = ProbablyBracedList ||
584 (NextTok->is(tok::semi) &&
585 (!ExpectClassBody || LBraceStack.size() != 1));
588 ProbablyBracedList ||
589 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
591 if (!Style.
isCSharp() && NextTok->is(tok::l_square)) {
595 ProbablyBracedList = NextTok->
isNot(tok::l_square);
598 if (ProbablyBracedList) {
603 LBraceStack.back().Tok->setBlockKind(
BK_Block);
606 LBraceStack.pop_back();
608 case tok::identifier:
609 if (Tok->isNot(TT_StatementMacro))
613 if (PrevTok->is(tok::hash))
623 if (!LBraceStack.empty() && LBraceStack.back().Tok->is(
BK_Unknown))
624 LBraceStack.back().Tok->setBlockKind(
BK_Block);
631 }
while (Tok->isNot(tok::eof) && !LBraceStack.empty());
634 for (
const auto &Entry : LBraceStack)
644 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
647size_t UnwrappedLineParser::computePPHash()
const {
649 for (
const auto &i : PPStack) {
660bool UnwrappedLineParser::mightFitOnOneLine(
661 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
663 if (ColumnLimit == 0)
666 auto &Tokens = ParsedLine.Tokens;
667 assert(!Tokens.empty());
669 const auto *LastToken = Tokens.back().Tok;
672 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
675 for (
const auto &Token : Tokens) {
677 auto &SavedToken = SavedTokens[Index++];
678 SavedToken.Tok =
new FormatToken;
679 SavedToken.Tok->copyFrom(*Token.Tok);
680 SavedToken.Children = std::move(Token.Children);
683 AnnotatedLine Line(ParsedLine);
684 assert(Line.Last == LastToken);
686 TokenAnnotator Annotator(Style, Keywords);
687 Annotator.annotate(Line);
688 Annotator.calculateFormattingInformation(Line);
690 auto Length = LastToken->TotalLength;
692 assert(OpeningBrace != Tokens.front().Tok);
693 if (
auto Prev = OpeningBrace->Previous;
694 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
695 Length -= ColumnLimit;
697 Length -= OpeningBrace->TokenText.size() + 1;
700 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
701 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
702 Length -= FirstToken->TokenText.size() + 1;
706 for (
auto &Token : Tokens) {
707 const auto &SavedToken = SavedTokens[Index++];
708 Token.Tok->copyFrom(*SavedToken.Tok);
709 Token.Children = std::move(SavedToken.Children);
710 delete SavedToken.Tok;
714 assert(!Line.InMacroBody);
715 assert(!Line.InPPDirective);
716 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
719FormatToken *UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
720 unsigned AddLevels,
bool MunchSemi,
723 bool UnindentWhitesmithsBraces) {
724 auto HandleVerilogBlockLabel = [
this]() {
726 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
735 const bool VerilogHierarchy =
737 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
740 "'{' or macro block token expected");
741 FormatToken *Tok = FormatTok;
742 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
743 auto Index = CurrentLines->size();
744 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
749 if (!VerilogHierarchy && AddLevels > 0 &&
754 size_t PPStartHash = computePPHash();
756 const unsigned InitialLevel = Line->Level;
757 if (VerilogHierarchy) {
758 AddLevels += parseVerilogHierarchyHeader();
760 nextToken(AddLevels);
761 HandleVerilogBlockLabel();
765 if (Line->Level > 300)
768 if (MacroBlock && FormatTok->
is(tok::l_paren))
771 size_t NbPreprocessorDirectives =
772 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
774 size_t OpeningLineIndex =
775 CurrentLines->empty()
777 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
782 if (UnindentWhitesmithsBraces)
785 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
788 Line->Level += AddLevels;
790 FormatToken *IfLBrace =
nullptr;
791 const bool SimpleBlock = parseLevel(Tok, IfKind, &IfLBrace);
796 if (MacroBlock ? FormatTok->
isNot(TT_MacroBlockEnd)
797 : FormatTok->
isNot(tok::r_brace)) {
798 Line->Level = InitialLevel;
803 if (FormatTok->
is(tok::r_brace) && Tok->is(TT_NamespaceLBrace))
806 const bool IsFunctionRBrace =
807 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
809 auto RemoveBraces = [=]()
mutable {
812 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
813 assert(FormatTok->
is(tok::r_brace));
814 const bool WrappedOpeningBrace = !Tok->Previous;
815 if (WrappedOpeningBrace && FollowedByComment)
817 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
818 if (KeepBraces && !HasRequiredIfBraces)
820 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
821 const FormatToken *
Previous = Tokens->getPreviousToken();
826 assert(!CurrentLines->empty());
827 auto &LastLine = CurrentLines->back();
828 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
830 if (Tok->is(TT_ElseLBrace))
832 if (WrappedOpeningBrace) {
837 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
839 if (RemoveBraces()) {
840 Tok->MatchingParen = FormatTok;
844 size_t PPEndHash = computePPHash();
847 nextToken(-AddLevels);
853 while (FormatTok->
is(tok::semi)) {
859 HandleVerilogBlockLabel();
861 if (MacroBlock && FormatTok->
is(tok::l_paren))
864 Line->Level = InitialLevel;
866 if (FormatTok->
is(tok::kw_noexcept)) {
871 if (FormatTok->
is(tok::arrow)) {
875 parseStructuralElement();
878 if (MunchSemi && FormatTok->
is(tok::semi))
881 if (PPStartHash == PPEndHash) {
882 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
885 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
886 CurrentLines->size() - 1;
896 if (Line.Tokens.
size() < 4)
898 auto I = Line.Tokens.begin();
899 if (I->Tok->TokenText !=
"goog")
902 if (I->Tok->isNot(tok::period))
905 if (I->Tok->TokenText !=
"scope")
908 return I->Tok->is(tok::l_paren);
917 if (Line.Tokens.
size() < 3)
919 auto I = Line.Tokens.begin();
920 if (I->Tok->isNot(tok::l_paren))
926 return I->Tok->is(tok::l_paren);
932 if (InitialToken.
is(TT_NamespaceMacro))
933 Kind = tok::kw_namespace;
936 case tok::kw_namespace:
951void UnwrappedLineParser::parseChildBlock() {
952 assert(FormatTok->
is(tok::l_brace));
954 const FormatToken *OpeningBrace = FormatTok;
960 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
962 Line->Level += SkipIndent ? 0 : 1;
963 parseLevel(OpeningBrace);
964 flushComments(isOnNewLine(*FormatTok));
965 Line->Level -= SkipIndent ? 0 : 1;
970void UnwrappedLineParser::parsePPDirective() {
971 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
972 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
993 case tok::pp_elifdef:
994 case tok::pp_elifndef:
1001 case tok::pp_pragma:
1010void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1011 size_t Line = CurrentLines->size();
1012 if (CurrentLines == &PreprocessorDirectives)
1013 Line += Lines.size();
1016 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1017 PPStack.push_back({PP_Unreachable, Line});
1019 PPStack.push_back({PP_Conditional, Line});
1023void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1025 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1026 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1027 PPLevelBranchIndex.push_back(0);
1028 PPLevelBranchCount.push_back(0);
1030 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1031 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1032 conditionalCompilationCondition(Unreachable || Skip);
1035void UnwrappedLineParser::conditionalCompilationAlternative() {
1036 if (!PPStack.empty())
1038 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1039 if (!PPChainBranchIndex.empty())
1040 ++PPChainBranchIndex.top();
1041 conditionalCompilationCondition(
1042 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1043 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1046void UnwrappedLineParser::conditionalCompilationEnd() {
1047 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1048 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1049 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1050 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1053 if (PPBranchLevel > -1)
1055 if (!PPChainBranchIndex.empty())
1056 PPChainBranchIndex.pop();
1057 if (!PPStack.empty())
1061void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1062 bool IfNDef = FormatTok->
is(tok::pp_ifndef);
1064 bool Unreachable =
false;
1065 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1067 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1069 conditionalCompilationStart(Unreachable);
1070 FormatToken *IfCondition = FormatTok;
1073 bool MaybeIncludeGuard = IfNDef;
1074 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1075 for (
auto &Line : Lines) {
1076 if (Line.Tokens.front().Tok->isNot(tok::comment)) {
1077 MaybeIncludeGuard =
false;
1078 IncludeGuard = IG_Rejected;
1086 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1087 IncludeGuard = IG_IfNdefed;
1088 IncludeGuardToken = IfCondition;
1092void UnwrappedLineParser::parsePPElse() {
1094 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1095 IncludeGuard = IG_Rejected;
1097 assert(PPBranchLevel >= -1);
1098 if (PPBranchLevel == -1)
1099 conditionalCompilationStart(
true);
1100 conditionalCompilationAlternative();
1106void UnwrappedLineParser::parsePPEndIf() {
1107 conditionalCompilationEnd();
1111 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1113 IncludeGuard = IG_Found;
1117void UnwrappedLineParser::parsePPDefine() {
1121 IncludeGuard = IG_Rejected;
1122 IncludeGuardToken =
nullptr;
1127 if (IncludeGuard == IG_IfNdefed &&
1129 IncludeGuard = IG_Defined;
1130 IncludeGuardToken =
nullptr;
1131 for (
auto &Line : Lines) {
1132 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1133 IncludeGuard = IG_Rejected;
1147 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1152 Line->Level += PPBranchLevel + 1;
1156 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1157 assert((
int)Line->PPLevel >= 0);
1158 Line->InMacroBody =
true;
1168void UnwrappedLineParser::parsePPPragma() {
1169 Line->InPragmaDirective =
true;
1173void UnwrappedLineParser::parsePPUnknown() {
1178 Line->Level += PPBranchLevel + 1;
1188 assert(Tok.
isNot(TT_AttributeSquare));
1189 return !Tok.
isOneOf(tok::semi, tok::l_brace,
1192 tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
1193 tok::less, tok::greater, tok::slash, tok::percent,
1194 tok::lessless, tok::greatergreater, tok::equal,
1195 tok::plusequal, tok::minusequal, tok::starequal,
1196 tok::slashequal, tok::percentequal, tok::ampequal,
1197 tok::pipeequal, tok::caretequal, tok::greatergreaterequal,
1210 return FormatTok->
is(tok::identifier) &&
1225 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1236 tok::kw_if, tok::kw_else,
1238 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1240 tok::kw_switch, tok::kw_case,
1242 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1244 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1252 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1253 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1270 if (FuncName->
isNot(tok::identifier))
1278 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1282 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1286 if (!Tok || Tok->
isNot(tok::r_paren))
1290 if (!Tok || Tok->
isNot(tok::identifier))
1296bool UnwrappedLineParser::parseModuleImport() {
1297 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1299 if (
auto Token = Tokens->peekNextToken(
true);
1301 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1307 if (FormatTok->
is(tok::colon)) {
1311 else if (FormatTok->
is(tok::less)) {
1313 while (!FormatTok->
isOneOf(tok::semi, tok::greater, tok::eof)) {
1316 if (FormatTok->
isNot(tok::comment) &&
1317 !FormatTok->
TokenText.startswith(
"//")) {
1323 if (FormatTok->
is(tok::semi)) {
1341void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1344 FormatToken *Next = FormatTok;
1347 CommentsBeforeNextToken.empty()
1348 ? Next->NewlinesBefore == 0
1349 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1354 bool PreviousStartsTemplateExpr =
1356 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1359 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1360 return LineNode.Tok->is(tok::at);
1365 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1366 return addUnwrappedLine();
1368 bool NextEndsTemplateExpr =
1369 Next->is(TT_TemplateString) && Next->TokenText.startswith(
"}");
1370 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1371 (PreviousMustBeValue ||
1372 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1373 tok::minusminus))) {
1374 return addUnwrappedLine();
1376 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1378 return addUnwrappedLine();
1382void UnwrappedLineParser::parseStructuralElement(
1383 const FormatToken *OpeningBrace, IfStmtKind *IfKind,
1384 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1386 FormatTok->
is(tok::pp_include)) {
1388 if (FormatTok->
is(tok::string_literal))
1394 if (Style.
isCpp()) {
1395 while (FormatTok->
is(tok::l_square) && handleCppAttributes()) {
1399 parseForOrWhileLoop(
false);
1403 parseForOrWhileLoop();
1408 parseIfThenElse(IfKind,
false,
true);
1417 }
else if (FormatTok->
is(tok::l_paren) &&
1418 Tokens->peekNextToken()->is(tok::star)) {
1430 if (FormatTok->
is(tok::l_brace)) {
1433 while (FormatTok && !eof()) {
1434 if (FormatTok->
is(tok::r_brace)) {
1445 case tok::kw_namespace:
1448 case tok::kw_public:
1449 case tok::kw_protected:
1450 case tok::kw_private:
1455 parseAccessSpecifier();
1463 FormatToken *Tok = parseIfThenElse(IfKind);
1474 parseForOrWhileLoop();
1485 case tok::kw_switch:
1492 case tok::kw_default:
1501 if (FormatTok->
is(tok::colon)) {
1534 case tok::kw_extern:
1540 parseVerilogHierarchyHeader();
1543 }
else if (FormatTok->
is(tok::string_literal)) {
1545 if (FormatTok->
is(tok::l_brace)) {
1550 unsigned AddLevels =
1557 parseBlock(
true, AddLevels);
1563 case tok::kw_export:
1565 parseJavaScriptEs6ImportExport();
1568 if (Style.
isCpp()) {
1570 if (FormatTok->
is(tok::kw_namespace)) {
1574 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1578 case tok::kw_inline:
1580 if (FormatTok->
is(tok::kw_namespace)) {
1585 case tok::identifier:
1586 if (FormatTok->
is(TT_ForEachMacro)) {
1587 parseForOrWhileLoop();
1590 if (FormatTok->
is(TT_MacroBlockBegin)) {
1591 parseBlock(
false, 1u,
1597 parseJavaScriptEs6ImportExport();
1602 if (FormatTok->
is(tok::kw_public))
1604 if (FormatTok->
isNot(tok::string_literal))
1607 if (FormatTok->
is(tok::semi))
1612 if (Style.
isCpp() && parseModuleImport())
1615 if (Style.
isCpp() &&
1619 if (FormatTok->
is(tok::colon)) {
1625 if (Style.
isCpp() && FormatTok->
is(TT_StatementMacro)) {
1626 parseStatementMacro();
1629 if (Style.
isCpp() && FormatTok->
is(TT_NamespaceMacro)) {
1634 if (!Style.
isVerilog() && Tokens->peekNextToken()->is(tok::colon) &&
1635 !Line->MustBeDeclaration) {
1637 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1650 const bool InRequiresExpression =
1651 OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
1657 if (FormatTok->
is(tok::l_brace)) {
1667 case tok::objc_public:
1668 case tok::objc_protected:
1669 case tok::objc_package:
1670 case tok::objc_private:
1671 return parseAccessSpecifier();
1672 case tok::objc_interface:
1673 case tok::objc_implementation:
1674 return parseObjCInterfaceOrImplementation();
1675 case tok::objc_protocol:
1676 if (parseObjCProtocol())
1681 case tok::objc_optional:
1682 case tok::objc_required:
1686 case tok::objc_autoreleasepool:
1688 if (FormatTok->
is(tok::l_brace)) {
1697 case tok::objc_synchronized:
1699 if (FormatTok->
is(tok::l_paren)) {
1703 if (FormatTok->
is(tok::l_brace)) {
1721 case tok::kw_requires: {
1722 if (Style.
isCpp()) {
1723 bool ParsedClause = parseRequires();
1748 case tok::kw_typedef:
1764 case tok::kw_struct:
1766 if (parseStructLike())
1773 FormatTok->
is(tok::kw_class)) {
1790 case tok::l_paren: {
1797 Tokens->peekNextToken(
true),
1804 case tok::kw_operator:
1816 while (FormatTok->
is(tok::star))
1820 if (FormatTok->
is(tok::l_paren))
1823 if (FormatTok->
is(tok::l_brace))
1827 if (InRequiresExpression)
1829 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1864 case tok::identifier: {
1866 Line->MustBeDeclaration) {
1868 parseCSharpGenericTypeConstraint();
1871 if (FormatTok->
is(TT_MacroBlockEnd)) {
1880 size_t TokenCount = Line->Tokens.size();
1884 Line->Tokens.front().Tok->isNot(Keywords.
kw_async)))) {
1885 tryToParseJSFunction();
1895 unsigned StoredPosition = Tokens->getPosition();
1896 FormatToken *Next = Tokens->getNextToken();
1897 FormatTok = Tokens->setPosition(StoredPosition);
1910 parseVerilogTable();
1922 if (parseStructLike())
1927 if (Style.
isCpp() && FormatTok->
is(TT_StatementMacro)) {
1928 parseStatementMacro();
1935 FormatToken *PreviousToken = FormatTok;
1943 auto OneTokenSoFar = [&]() {
1944 auto I = Line->Tokens.begin(), E = Line->Tokens.end();
1945 while (I != E && I->Tok->is(tok::comment))
1947 while (I != E && Style.
isVerilog() && I->Tok->is(tok::hash))
1949 return I != E && (++I == E);
1951 if (OneTokenSoFar()) {
1954 bool FunctionLike = FormatTok->
is(tok::l_paren);
1958 bool FollowedByNewline =
1959 CommentsBeforeNextToken.empty()
1961 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
1963 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
1965 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
1966 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
1975 FormatTok->
is(TT_FatArrow)) {
1976 tryToParseChildBlock();
1981 if (FormatTok->
is(tok::l_brace)) {
1990 FormatTok->
is(tok::less)) {
1992 parseBracedList(
false,
false,
2021 case tok::kw_default:
2024 if (FormatTok->
is(tok::colon)) {
2034 parseVerilogCaseLabel();
2041 parseVerilogCaseLabel();
2052bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2053 assert(FormatTok->
is(tok::l_brace));
2065 unsigned int StoredPosition = Tokens->getPosition();
2066 FormatToken *Tok = Tokens->getNextToken();
2071 bool HasSpecialAccessor =
false;
2072 bool IsTrivialPropertyAccessor =
true;
2074 if (Tok->isOneOf(tok::semi, tok::kw_public, tok::kw_private,
2078 HasSpecialAccessor =
true;
2079 Tok = Tokens->getNextToken();
2082 if (Tok->isNot(tok::r_brace))
2083 IsTrivialPropertyAccessor =
false;
2087 if (!HasSpecialAccessor) {
2088 Tokens->setPosition(StoredPosition);
2094 Tokens->setPosition(StoredPosition);
2102 if (FormatTok->
is(tok::equal)) {
2103 while (!eof() && FormatTok->
isNot(tok::semi))
2116 if (FormatTok->
is(TT_FatArrow)) {
2120 }
while (!eof() && FormatTok->
isNot(tok::semi));
2131 !IsTrivialPropertyAccessor) {
2143bool UnwrappedLineParser::tryToParseLambda() {
2144 assert(FormatTok->
is(tok::l_square));
2145 if (!Style.
isCpp()) {
2149 FormatToken &LSquare = *FormatTok;
2150 if (!tryToParseLambdaIntroducer())
2153 bool SeenArrow =
false;
2154 bool InTemplateParameterList =
false;
2156 while (FormatTok->
isNot(tok::l_brace)) {
2165 parseParens(TT_PointerOrReference);
2173 InTemplateParameterList =
true;
2178 case tok::kw_template:
2179 case tok::kw_typename:
2183 case tok::kw_constexpr:
2184 case tok::kw_consteval:
2187 case tok::identifier:
2188 case tok::numeric_constant:
2189 case tok::coloncolon:
2190 case tok::kw_mutable:
2191 case tok::kw_noexcept:
2192 case tok::kw_static:
2220 case tok::equalequal:
2221 case tok::exclaimequal:
2222 case tok::greaterequal:
2223 case tok::lessequal:
2229 if (SeenArrow || InTemplateParameterList) {
2242 case tok::kw_requires: {
2243 auto *RequiresToken = FormatTok;
2245 parseRequiresClause(RequiresToken);
2253 LSquare.setFinalizedType(TT_LambdaLSquare);
2258bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2260 const FormatToken *LeftSquare = FormatTok;
2263 !
Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2264 tok::kw_co_yield, tok::kw_co_return)) ||
2266 LeftSquare->isCppStructuredBinding(Style)) {
2269 if (FormatTok->
is(tok::l_square))
2271 if (FormatTok->
is(tok::r_square)) {
2272 const FormatToken *Next = Tokens->peekNextToken(
true);
2273 if (Next->is(tok::greater))
2280void UnwrappedLineParser::tryToParseJSFunction() {
2288 if (FormatTok->
is(tok::star)) {
2294 if (FormatTok->
is(tok::identifier))
2297 if (FormatTok->
isNot(tok::l_paren))
2303 if (FormatTok->
is(tok::colon)) {
2309 if (FormatTok->
is(tok::l_brace))
2310 tryToParseBracedList();
2312 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2316 if (FormatTok->
is(tok::semi))
2322bool UnwrappedLineParser::tryToParseBracedList() {
2324 calculateBraceTypes();
2333bool UnwrappedLineParser::tryToParseChildBlock() {
2335 assert(FormatTok->
is(TT_FatArrow));
2340 if (FormatTok->
isNot(tok::l_brace))
2346bool UnwrappedLineParser::parseBracedList(
bool ContinueOnSemicolons,
2349 bool HasError =
false;
2354 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2355 tryToParseChildBlock()) {
2360 tryToParseJSFunction();
2363 if (FormatTok->
is(tok::l_brace)) {
2365 if (tryToParseBracedList())
2370 if (FormatTok->
Tok.
getKind() == ClosingBraceKind) {
2388 if (FormatTok->
is(tok::l_brace))
2402 ClosingBraceKind == tok::greater) {
2404 parseBracedList(
false,
false,
2420 if (!ContinueOnSemicolons)
2442bool UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2443 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2444 auto *LeftParen = FormatTok;
2445 bool SeenEqual =
false;
2446 const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
2451 if (parseParens(AmpAmpTokenType))
2457 if (!MightBeStmtExpr &&
2459 const auto *Prev = LeftParen->Previous;
2460 const auto *Next = Tokens->peekNextToken();
2461 const bool DoubleParens =
2462 Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
2463 const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() :
nullptr;
2464 const bool Blacklisted =
2466 (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
2468 (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
2469 PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
2470 const bool ReturnParens =
2472 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
2473 Next->is(tok::semi);
2474 if ((DoubleParens && !Blacklisted) || ReturnParens) {
2475 LeftParen->Optional =
true;
2488 if (!tryToParseBracedList())
2493 if (FormatTok->
is(tok::l_brace)) {
2500 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2501 tryToParseChildBlock();
2511 case tok::identifier:
2513 tryToParseJSFunction();
2517 case tok::kw_requires: {
2518 auto RequiresToken = FormatTok;
2520 parseRequiresExpression(RequiresToken);
2524 if (AmpAmpTokenType != TT_Unknown)
2535void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2536 if (!LambdaIntroducer) {
2537 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2538 if (tryToParseLambda())
2555 case tok::l_brace: {
2556 if (!tryToParseBracedList())
2562 if (FormatTok->
is(tok::l_brace)) {
2574void UnwrappedLineParser::keepAncestorBraces() {
2578 const int MaxNestingLevels = 2;
2579 const int Size = NestedTooDeep.size();
2580 if (Size >= MaxNestingLevels)
2581 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2582 NestedTooDeep.push_back(
false);
2586 for (
const auto &
Token : llvm::reverse(Line.Tokens))
2593void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2594 FormatToken *Tok =
nullptr;
2596 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2597 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2600 : Line->Tokens.back().Tok;
2602 if (Tok->BraceCount < 0) {
2603 assert(Tok->BraceCount == -1);
2606 Tok->BraceCount = -1;
2612 parseStructuralElement();
2615 assert(!Line->InPPDirective);
2617 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2619 Tok = L.Tokens.back().Tok;
2627 if (CheckEOF && eof())
2637 assert(LeftBrace->
is(tok::l_brace));
2645 assert(RightBrace->
is(tok::r_brace));
2653void UnwrappedLineParser::handleAttributes() {
2657 else if (FormatTok->
is(tok::l_square))
2658 handleCppAttributes();
2661bool UnwrappedLineParser::handleCppAttributes() {
2663 assert(FormatTok->
is(tok::l_square));
2664 if (!tryToParseSimpleAttribute())
2671bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2675 : Tok.is(tok::l_brace);
2678FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2680 bool IsVerilogAssert) {
2681 assert((FormatTok->
is(tok::kw_if) ||
2688 if (IsVerilogAssert) {
2692 if (FormatTok->
is(tok::numeric_constant))
2701 if (FormatTok->
is(tok::exclaim))
2704 bool KeepIfBraces =
true;
2705 if (FormatTok->
is(tok::kw_consteval)) {
2709 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2711 if (FormatTok->
is(tok::l_paren)) {
2718 if (IsVerilogAssert && FormatTok->
is(tok::semi)) {
2724 bool NeedsUnwrappedLine =
false;
2725 keepAncestorBraces();
2727 FormatToken *IfLeftBrace =
nullptr;
2728 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2730 if (isBlockBegin(*FormatTok)) {
2732 IfLeftBrace = FormatTok;
2734 parseBlock(
false, 1u,
2735 true, KeepIfBraces, &IfBlockKind);
2739 NeedsUnwrappedLine =
true;
2740 }
else if (IsVerilogAssert && FormatTok->
is(tok::kw_else)) {
2743 parseUnbracedBody();
2747 assert(!NestedTooDeep.empty());
2748 KeepIfBraces = KeepIfBraces ||
2749 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2750 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2751 IfBlockKind == IfStmtKind::IfElseIf;
2754 bool KeepElseBraces = KeepIfBraces;
2755 FormatToken *ElseLeftBrace =
nullptr;
2756 IfStmtKind
Kind = IfStmtKind::IfOnly;
2758 if (FormatTok->
is(tok::kw_else)) {
2760 NestedTooDeep.back() =
false;
2761 Kind = IfStmtKind::IfElse;
2765 if (isBlockBegin(*FormatTok)) {
2766 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2768 ElseLeftBrace = FormatTok;
2770 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2771 FormatToken *IfLBrace =
2772 parseBlock(
false, 1u,
2773 true, KeepElseBraces, &ElseBlockKind);
2774 if (FormatTok->
is(tok::kw_else)) {
2775 KeepElseBraces = KeepElseBraces ||
2776 ElseBlockKind == IfStmtKind::IfOnly ||
2777 ElseBlockKind == IfStmtKind::IfElseIf;
2778 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2779 KeepElseBraces =
true;
2780 assert(ElseLeftBrace->MatchingParen);
2784 }
else if (!IsVerilogAssert && FormatTok->
is(tok::kw_if)) {
2785 const FormatToken *
Previous = Tokens->getPreviousToken();
2787 const bool IsPrecededByComment =
Previous->is(tok::comment);
2788 if (IsPrecededByComment) {
2792 bool TooDeep =
true;
2794 Kind = IfStmtKind::IfElseIf;
2795 TooDeep = NestedTooDeep.pop_back_val();
2797 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2799 NestedTooDeep.push_back(TooDeep);
2800 if (IsPrecededByComment)
2803 parseUnbracedBody(
true);
2806 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2807 if (NeedsUnwrappedLine)
2814 assert(!NestedTooDeep.empty());
2815 KeepElseBraces = KeepElseBraces ||
2816 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2817 NestedTooDeep.back();
2819 NestedTooDeep.pop_back();
2821 if (!KeepIfBraces && !KeepElseBraces) {
2824 }
else if (IfLeftBrace) {
2825 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2827 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2828 assert(!IfLeftBrace->Optional);
2829 assert(!IfRightBrace->Optional);
2830 IfLeftBrace->MatchingParen =
nullptr;
2831 IfRightBrace->MatchingParen =
nullptr;
2841void UnwrappedLineParser::parseTryCatch() {
2842 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2844 bool NeedsUnwrappedLine =
false;
2845 if (FormatTok->
is(tok::colon)) {
2851 while (FormatTok->
is(tok::comma))
2854 while (FormatTok->
is(tok::identifier)) {
2856 if (FormatTok->
is(tok::l_paren))
2859 FormatTok->
is(tok::l_brace)) {
2862 }
while (FormatTok->
isNot(tok::r_brace));
2868 while (FormatTok->
is(tok::comma))
2876 keepAncestorBraces();
2878 if (FormatTok->
is(tok::l_brace)) {
2884 NeedsUnwrappedLine =
true;
2885 }
else if (FormatTok->
isNot(tok::kw_catch)) {
2891 parseStructuralElement();
2895 if (FormatTok->
is(tok::at))
2898 tok::kw___finally) ||
2906 while (FormatTok->
isNot(tok::l_brace)) {
2907 if (FormatTok->
is(tok::l_paren)) {
2911 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
2913 NestedTooDeep.pop_back();
2918 NeedsUnwrappedLine =
false;
2919 Line->MustBeDeclaration =
false;
2925 NeedsUnwrappedLine =
true;
2929 NestedTooDeep.pop_back();
2931 if (NeedsUnwrappedLine)
2935void UnwrappedLineParser::parseNamespace() {
2936 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
2937 "'namespace' expected");
2939 const FormatToken &InitialToken = *FormatTok;
2941 if (InitialToken.is(TT_NamespaceMacro)) {
2944 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
2945 tok::l_square, tok::period, tok::l_paren) ||
2946 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
2947 if (FormatTok->
is(tok::l_square))
2949 else if (FormatTok->
is(tok::l_paren))
2955 if (FormatTok->
is(tok::l_brace)) {
2961 unsigned AddLevels =
2964 DeclarationScopeStack.size() > 1)
2967 bool ManageWhitesmithsBraces =
2973 if (ManageWhitesmithsBraces)
2978 parseBlock(
true, AddLevels,
true,
2980 ManageWhitesmithsBraces);
2982 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
2984 if (ManageWhitesmithsBraces)
2990void UnwrappedLineParser::parseNew() {
2991 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
2997 if (FormatTok->
is(tok::l_paren))
3001 if (FormatTok->
is(tok::l_brace))
3004 if (FormatTok->
isOneOf(tok::semi, tok::comma))
3017 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
3021 if (FormatTok->
is(tok::l_paren)) {
3025 if (FormatTok->
is(tok::l_brace))
3033void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
3034 keepAncestorBraces();
3036 if (isBlockBegin(*FormatTok)) {
3039 FormatToken *LeftBrace = FormatTok;
3041 parseBlock(
false, 1u,
3044 assert(!NestedTooDeep.empty());
3045 if (!NestedTooDeep.back())
3051 parseUnbracedBody();
3055 NestedTooDeep.pop_back();
3058void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
3059 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
3066 "'for', 'while' or foreach macro expected");
3068 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
3074 if (Style.
isCpp() && FormatTok->
is(tok::kw_co_await))
3076 if (HasParens && FormatTok->
is(tok::l_paren)) {
3086 parseVerilogSensitivityList();
3089 parseLoopBody(KeepBraces,
true);
3092void UnwrappedLineParser::parseDoWhile() {
3093 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3099 if (FormatTok->
isNot(tok::kw_while)) {
3110 parseStructuralElement();
3113void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3115 unsigned OldLineLevel = Line->Level;
3116 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3122 FormatTok->
is(tok::l_brace)) {
3128 if (FormatTok->
is(tok::kw_break)) {
3137 parseStructuralElement();
3141 if (FormatTok->
is(tok::semi))
3145 Line->Level = OldLineLevel;
3146 if (FormatTok->
isNot(tok::l_brace)) {
3147 parseStructuralElement();
3152void UnwrappedLineParser::parseCaseLabel() {
3153 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3158 if (FormatTok->
is(tok::colon)) {
3166void UnwrappedLineParser::parseSwitch() {
3167 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3169 if (FormatTok->
is(tok::l_paren))
3172 keepAncestorBraces();
3174 if (FormatTok->
is(tok::l_brace)) {
3181 parseStructuralElement();
3186 NestedTooDeep.pop_back();
3196 case tok::caretequal:
3200 case tok::equalequal:
3202 case tok::exclaimequal:
3204 case tok::greaterequal:
3205 case tok::greatergreater:
3206 case tok::greatergreaterequal:
3210 case tok::lessequal:
3212 case tok::lesslessequal:
3214 case tok::minusequal:
3215 case tok::minusminus:
3217 case tok::percentequal:
3220 case tok::pipeequal:
3223 case tok::plusequal:
3231 case tok::slashequal:
3233 case tok::starequal:
3240void UnwrappedLineParser::parseAccessSpecifier() {
3241 FormatToken *AccessSpecifierCandidate = FormatTok;
3247 if (FormatTok->
is(tok::colon)) {
3250 }
else if (FormatTok->
isNot(tok::coloncolon) &&
3254 }
else if (AccessSpecifierCandidate) {
3256 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3263bool clang::format::UnwrappedLineParser::parseRequires() {
3264 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3265 auto RequiresToken = FormatTok;
3271 switch (FormatTok->Tok.getKind()) {
3274 parseRequiresExpression(RequiresToken);
3281 parseRequiresClause(RequiresToken);
3292 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3294 if (!PreviousNonComment ||
3295 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3298 parseRequiresClause(RequiresToken);
3302 switch (PreviousNonComment->Tok.getKind()) {
3305 case tok::kw_noexcept:
3308 parseRequiresClause(RequiresToken);
3318 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3319 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3320 parseRequiresClause(RequiresToken);
3326 if (PreviousNonComment->isTypeOrIdentifier()) {
3328 parseRequiresClause(RequiresToken);
3332 parseRequiresExpression(RequiresToken);
3345 auto PeekNext = [&Lookahead, &NextToken,
this] {
3350 bool FoundType =
false;
3351 bool LastWasColonColon =
false;
3354 for (; Lookahead < 50; PeekNext()) {
3355 switch (NextToken->Tok.getKind()) {
3356 case tok::kw_volatile:
3359 if (OpenAngles == 0) {
3361 parseRequiresExpression(RequiresToken);
3368 parseRequiresClause(RequiresToken);
3374 case tok::coloncolon:
3375 LastWasColonColon =
true;
3377 case tok::identifier:
3378 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3380 parseRequiresExpression(RequiresToken);
3384 LastWasColonColon =
false;
3393 if (NextToken->isSimpleTypeSpecifier()) {
3395 parseRequiresExpression(RequiresToken);
3403 parseRequiresClause(RequiresToken);
3414void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3416 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3421 bool InRequiresExpression =
3422 !RequiresToken->Previous ||
3423 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3425 RequiresToken->setFinalizedType(InRequiresExpression
3426 ? TT_RequiresClauseInARequiresExpression
3427 : TT_RequiresClause);
3431 parseConstraintExpression();
3433 if (!InRequiresExpression)
3444void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3446 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3448 RequiresToken->setFinalizedType(TT_RequiresExpression);
3450 if (FormatTok->
is(tok::l_paren)) {
3455 if (FormatTok->
is(tok::l_brace)) {
3465void UnwrappedLineParser::parseConstraintExpression() {
3472 bool LambdaNextTimeAllowed =
true;
3482 bool TopLevelParensAllowed =
true;
3485 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3488 case tok::kw_requires: {
3489 auto RequiresToken = FormatTok;
3491 parseRequiresExpression(RequiresToken);
3496 if (!TopLevelParensAllowed)
3498 parseParens(TT_BinaryOperator);
3499 TopLevelParensAllowed =
false;
3503 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3510 case tok::kw_struct:
3522 LambdaNextTimeAllowed =
true;
3523 TopLevelParensAllowed =
true;
3528 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3532 case tok::kw_sizeof:
3534 case tok::greaterequal:
3535 case tok::greatergreater:
3537 case tok::lessequal:
3539 case tok::equalequal:
3541 case tok::exclaimequal:
3546 LambdaNextTimeAllowed =
true;
3547 TopLevelParensAllowed =
true;
3552 case tok::numeric_constant:
3553 case tok::coloncolon:
3556 TopLevelParensAllowed =
false;
3561 case tok::kw_static_cast:
3562 case tok::kw_const_cast:
3563 case tok::kw_reinterpret_cast:
3564 case tok::kw_dynamic_cast:
3566 if (FormatTok->
isNot(tok::less))
3570 parseBracedList(
false,
false,
3587 case tok::coloncolon:
3591 case tok::kw_requires:
3600 if (FormatTok->
is(tok::less)) {
3602 parseBracedList(
false,
false,
3605 TopLevelParensAllowed =
false;
3611bool UnwrappedLineParser::parseEnum() {
3612 const FormatToken &InitialToken = *FormatTok;
3615 if (FormatTok->
is(tok::kw_enum))
3629 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3633 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3634 tok::greater, tok::comma, tok::question,
3635 tok::l_square, tok::r_square)) {
3640 while (FormatTok->
is(tok::l_square))
3646 if (FormatTok->
is(tok::l_paren))
3648 assert(FormatTok->
isNot(TT_AttributeSquare));
3649 if (FormatTok->
is(tok::identifier)) {
3653 if (Style.
isCpp() && FormatTok->
is(tok::identifier))
3659 if (FormatTok->
isNot(tok::l_brace))
3666 parseJavaEnumBody();
3684 bool HasError = !parseBracedList(
true,
3689 if (FormatTok->
is(tok::semi))
3700bool UnwrappedLineParser::parseStructLike() {
3707 if (FormatTok->
is(tok::semi))
3718class ScopedTokenPosition {
3719 unsigned StoredPosition;
3720 FormatTokenSource *Tokens;
3723 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3724 assert(Tokens &&
"Tokens expected to not be null");
3725 StoredPosition = Tokens->getPosition();
3728 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3734bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3735 ScopedTokenPosition AutoPosition(Tokens);
3736 FormatToken *Tok = Tokens->getNextToken();
3738 if (Tok->isNot(tok::l_square))
3742 while (Tok->isNot(tok::eof)) {
3743 if (Tok->is(tok::r_square))
3745 Tok = Tokens->getNextToken();
3747 if (Tok->is(tok::eof))
3749 Tok = Tokens->getNextToken();
3750 if (Tok->isNot(tok::r_square))
3752 Tok = Tokens->getNextToken();
3753 if (Tok->is(tok::semi))
3758void UnwrappedLineParser::parseJavaEnumBody() {
3759 assert(FormatTok->
is(tok::l_brace));
3760 const FormatToken *OpeningBrace = FormatTok;
3765 unsigned StoredPosition = Tokens->getPosition();
3766 bool IsSimple =
true;
3767 FormatToken *Tok = Tokens->getNextToken();
3768 while (Tok->isNot(tok::eof)) {
3769 if (Tok->is(tok::r_brace))
3771 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3777 Tok = Tokens->getNextToken();
3779 FormatTok = Tokens->setPosition(StoredPosition);
3796 if (FormatTok->
is(tok::l_brace)) {
3798 parseBlock(
true, 1u,
3800 }
else if (FormatTok->
is(tok::l_paren)) {
3802 }
else if (FormatTok->
is(tok::comma)) {
3805 }
else if (FormatTok->
is(tok::semi)) {
3809 }
else if (FormatTok->
is(tok::r_brace)) {
3818 parseLevel(OpeningBrace);
3824void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
3825 const FormatToken &InitialToken = *FormatTok;
3831 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3832 tok::kw_alignas, tok::l_square) ||
3835 FormatTok->
isOneOf(tok::period, tok::comma))) {
3842 if (FormatTok->
is(tok::l_brace)) {
3843 tryToParseBracedList();
3847 if (FormatTok->
is(tok::l_square) && handleCppAttributes())
3849 bool IsNonMacroIdentifier =
3850 FormatTok->
is(tok::identifier) &&
3854 if (!IsNonMacroIdentifier && FormatTok->
is(tok::l_paren))
3868 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
3870 if (FormatTok->
is(tok::l_brace)) {
3871 calculateBraceTypes(
true);
3872 if (!tryToParseBracedList())
3875 if (FormatTok->
is(tok::l_square)) {
3881 if (!tryToParseLambda())
3888 if (FormatTok->
is(tok::semi))
3893 parseCSharpGenericTypeConstraint();
3900 auto GetBraceType = [](
const FormatToken &RecordTok) {
3901 switch (RecordTok.Tok.getKind()) {
3903 return TT_ClassLBrace;
3904 case tok::kw_struct:
3905 return TT_StructLBrace;
3907 return TT_UnionLBrace;
3910 return TT_RecordLBrace;
3913 if (FormatTok->
is(tok::l_brace)) {
3922 parseBlock(
true, AddLevels,
false);
3930void UnwrappedLineParser::parseObjCMethod() {
3931 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
3932 "'(' or identifier expected.");
3934 if (FormatTok->
is(tok::semi)) {
3938 }
else if (FormatTok->
is(tok::l_brace)) {
3950void UnwrappedLineParser::parseObjCProtocolList() {
3951 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
3955 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
3959 }
while (!eof() && FormatTok->
isNot(tok::greater));
3963void UnwrappedLineParser::parseObjCUntilAtEnd() {
3970 if (FormatTok->
is(tok::l_brace)) {
3974 }
else if (FormatTok->
is(tok::r_brace)) {
3978 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
3982 parseStructuralElement();
3987void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
3995 if (FormatTok->
is(tok::less))
3996 parseObjCLightweightGenerics();
3997 if (FormatTok->
is(tok::colon)) {
4001 if (FormatTok->
is(tok::less))
4002 parseObjCLightweightGenerics();
4003 }
else if (FormatTok->
is(tok::l_paren)) {
4008 if (FormatTok->
is(tok::less))
4009 parseObjCProtocolList();
4011 if (FormatTok->
is(tok::l_brace)) {
4021 parseObjCUntilAtEnd();
4024void UnwrappedLineParser::parseObjCLightweightGenerics() {
4025 assert(FormatTok->
is(tok::less));
4033 unsigned NumOpenAngles = 1;
4037 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
4041 if (FormatTok->
is(tok::less)) {
4043 }
else if (FormatTok->
is(tok::greater)) {
4044 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
4047 }
while (!eof() && NumOpenAngles != 0);
4053bool UnwrappedLineParser::parseObjCProtocol() {
4057 if (FormatTok->
is(tok::l_paren)) {
4069 if (FormatTok->
is(tok::less))
4070 parseObjCProtocolList();
4073 if (FormatTok->
is(tok::semi)) {
4080 parseObjCUntilAtEnd();
4084void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
4085 bool IsImport = FormatTok->
is(Keywords.
kw_import);
4086 assert(IsImport || FormatTok->
is(tok::kw_export));
4090 if (FormatTok->
is(tok::kw_default))
4107 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
4110 Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
4115 if (FormatTok->
is(tok::semi))
4117 if (Line->Tokens.empty()) {
4122 if (FormatTok->
is(tok::l_brace)) {
4132void UnwrappedLineParser::parseStatementMacro() {
4134 if (FormatTok->
is(tok::l_paren))
4136 if (FormatTok->
is(tok::semi))
4141void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4144 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4145 tok::coloncolon, tok::hash) ||
4148 }
else if (FormatTok->
is(tok::l_square)) {
4156void UnwrappedLineParser::parseVerilogSensitivityList() {
4157 if (FormatTok->
isNot(tok::at))
4161 if (FormatTok->
is(tok::at))
4171 parseVerilogHierarchyIdentifier();
4176unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4177 unsigned AddLevels = 0;
4183 parseVerilogSensitivityList();
4184 if (FormatTok->
is(tok::semi))
4192 if (FormatTok->
is(tok::l_paren)) {
4205 if (FormatTok->
is(tok::l_square)) {
4220 Line->IsContinuation =
true;
4227 parseVerilogHierarchyIdentifier();
4228 if (FormatTok->
is(tok::semi))
4236 if (FormatTok->
is(tok::l_paren)) {
4241 if (FormatTok->
is(tok::l_paren)) {
4251 parseVerilogHierarchyIdentifier();
4252 if (FormatTok->
is(tok::l_paren))
4259 parseVerilogHierarchyIdentifier();
4260 }
while (FormatTok->
is(tok::comma));
4264 if (FormatTok->
is(tok::at)) {
4266 parseVerilogSensitivityList();
4269 if (FormatTok->
is(tok::semi))
4277void UnwrappedLineParser::parseVerilogTable() {
4282 auto InitialLevel = Line->Level++;
4284 FormatToken *Tok = FormatTok;
4286 if (Tok->is(tok::semi))
4288 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4289 Tok->setFinalizedType(TT_VerilogTableItem);
4291 Line->Level = InitialLevel;
4296void UnwrappedLineParser::parseVerilogCaseLabel() {
4302 auto OrigLevel = Line->Level;
4303 auto FirstLine = CurrentLines->size();
4304 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4308 parseStructuralElement();
4311 if (CurrentLines->size() > FirstLine)
4312 (*CurrentLines)[FirstLine].Level = OrigLevel;
4313 Line->Level = OrigLevel;
4316bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &Line)
const {
4317 for (
const auto &N : Line.Tokens) {
4318 if (N.Tok->MacroCtx)
4320 for (
const UnwrappedLine &Child : N.Children)
4321 if (containsExpansion(Child))
4327void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4328 if (Line->Tokens.empty())
4331 if (!parsingPPDirective()) {
4332 llvm::dbgs() <<
"Adding unwrapped line:\n";
4333 printDebugInfo(*Line);
4341 bool ClosesWhitesmithsBlock =
4348 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4350 Reconstruct.emplace(Line->Level, Unexpanded);
4351 Reconstruct->addLine(*Line);
4356 CurrentExpandedLines.push_back(std::move(*Line));
4358 if (Reconstruct->finished()) {
4359 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4360 assert(!Reconstructed.Tokens.empty() &&
4361 "Reconstructed must at least contain the macro identifier.");
4362 assert(!parsingPPDirective());
4364 llvm::dbgs() <<
"Adding unexpanded line:\n";
4365 printDebugInfo(Reconstructed);
4367 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4368 Lines.push_back(std::move(Reconstructed));
4369 CurrentExpandedLines.clear();
4370 Reconstruct.reset();
4375 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4376 CurrentLines->push_back(std::move(*Line));
4378 Line->Tokens.clear();
4380 Line->FirstStartColumn = 0;
4381 Line->IsContinuation =
false;
4383 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4385 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4386 CurrentLines->append(
4387 std::make_move_iterator(PreprocessorDirectives.begin()),
4388 std::make_move_iterator(PreprocessorDirectives.end()));
4389 PreprocessorDirectives.clear();
4395bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4397bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4398 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4399 FormatTok.NewlinesBefore > 0;
4407 const llvm::Regex &CommentPragmasRegex) {
4408 if (Line.Tokens.empty())
4411 StringRef IndentContent = FormatTok.
TokenText;
4412 if (FormatTok.
TokenText.startswith(
"//") ||
4414 IndentContent = FormatTok.
TokenText.substr(2);
4416 if (CommentPragmasRegex.match(IndentContent))
4485 const FormatToken *MinColumnToken = Line.Tokens.front().Tok;
4491 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4493 MinColumnToken = PreviousToken;
4496 PreviousToken =
Node.Tok;
4499 if (
Node.Tok->NewlinesBefore > 0)
4500 MinColumnToken =
Node.Tok;
4502 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4503 MinColumnToken = PreviousToken;
4509void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4510 bool JustComments = Line->Tokens.empty();
4511 for (FormatToken *Tok : CommentsBeforeNextToken) {
4520 Tok->ContinuesLineCommentSection =
4522 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4526 if (NewlineBeforeNext && JustComments)
4528 CommentsBeforeNextToken.clear();
4531void UnwrappedLineParser::nextToken(
int LevelDifference) {
4534 flushComments(isOnNewLine(*FormatTok));
4535 pushToken(FormatTok);
4538 readToken(LevelDifference);
4540 readTokenWithJavaScriptASI();
4550 FormatTok->Tok.setKind(tok::r_brace);
4554void UnwrappedLineParser::distributeComments(
4555 const SmallVectorImpl<FormatToken *> &Comments,
4556 const FormatToken *NextTok) {
4575 if (Comments.empty())
4577 bool ShouldPushCommentsInCurrentLine =
true;
4578 bool HasTrailAlignedWithNextToken =
false;
4579 unsigned StartOfTrailAlignedWithNextToken = 0;
4582 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4583 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4584 HasTrailAlignedWithNextToken =
true;
4585 StartOfTrailAlignedWithNextToken = i;
4589 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4590 FormatToken *FormatTok = Comments[i];
4591 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4592 FormatTok->ContinuesLineCommentSection =
false;
4594 FormatTok->ContinuesLineCommentSection =
4597 if (!FormatTok->ContinuesLineCommentSection &&
4598 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4599 ShouldPushCommentsInCurrentLine =
false;
4601 if (ShouldPushCommentsInCurrentLine)
4602 pushToken(FormatTok);
4604 CommentsBeforeNextToken.push_back(FormatTok);
4608void UnwrappedLineParser::readToken(
int LevelDifference) {
4609 SmallVector<FormatToken *, 1> Comments;
4610 bool PreviousWasComment =
false;
4611 bool FirstNonCommentOnLine =
false;
4613 FormatTok = Tokens->getNextToken();
4615 while (FormatTok->getType() == TT_ConflictStart ||
4616 FormatTok->getType() == TT_ConflictEnd ||
4617 FormatTok->getType() == TT_ConflictAlternative) {
4618 if (FormatTok->getType() == TT_ConflictStart)
4619 conditionalCompilationStart(
false);
4620 else if (FormatTok->getType() == TT_ConflictAlternative)
4621 conditionalCompilationAlternative();
4622 else if (FormatTok->getType() == TT_ConflictEnd)
4623 conditionalCompilationEnd();
4624 FormatTok = Tokens->getNextToken();
4625 FormatTok->MustBreakBefore =
true;
4628 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4629 const FormatToken &Tok,
4630 bool PreviousWasComment) {
4631 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4632 return Tok.HasUnescapedNewline || Tok.IsFirst;
4637 if (PreviousWasComment)
4638 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4639 return IsFirstOnLine(Tok);
4642 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4643 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4644 PreviousWasComment = FormatTok->is(tok::comment);
4646 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4649 FirstNonCommentOnLine) {
4650 distributeComments(Comments, FormatTok);
4654 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4656 assert((LevelDifference >= 0 ||
4657 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4658 "LevelDifference makes Line->Level negative");
4659 Line->Level += LevelDifference;
4664 PPBranchLevel > 0) {
4665 Line->Level += PPBranchLevel;
4667 flushComments(isOnNewLine(*FormatTok));
4669 PreviousWasComment = FormatTok->is(tok::comment);
4670 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4671 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4674 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4675 !Line->InPPDirective) {
4679 if (FormatTok->is(tok::identifier) &&
4680 Macros.
defined(FormatTok->TokenText) &&
4682 !Line->InPPDirective) {
4683 FormatToken *
ID = FormatTok;
4684 unsigned Position = Tokens->getPosition();
4688 auto PreCall = std::move(Line);
4689 Line.reset(
new UnwrappedLine);
4690 bool OldInExpansion = InExpansion;
4693 auto Args = parseMacroCall();
4694 InExpansion = OldInExpansion;
4695 assert(Line->Tokens.front().Tok ==
ID);
4697 auto UnexpandedLine = std::move(Line);
4699 Line = std::move(PreCall);
4702 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4704 llvm::dbgs() <<
"(";
4705 for (
const auto &Arg : Args.value())
4706 for (
const auto &T : Arg)
4707 llvm::dbgs() << T->TokenText <<
" ";
4708 llvm::dbgs() <<
")";
4710 llvm::dbgs() <<
"\n";
4713 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4719 LLVM_DEBUG(llvm::dbgs()
4720 <<
"Macro \"" <<
ID->TokenText
4721 <<
"\" not overloaded for arity " << Args->size()
4722 <<
"or not function-like, using object-like overload.");
4724 UnexpandedLine->Tokens.resize(1);
4725 Tokens->setPosition(Position);
4730 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4733 Unexpanded[
ID] = std::move(UnexpandedLine);
4734 SmallVector<FormatToken *, 8> Expansion =
4735 Macros.
expand(
ID, std::move(Args));
4736 if (!Expansion.empty())
4737 FormatTok = Tokens->insertTokens(Expansion);
4740 llvm::dbgs() <<
"Expanded: ";
4741 for (
const auto &T : Expansion)
4742 llvm::dbgs() << T->TokenText <<
" ";
4743 llvm::dbgs() <<
"\n";
4747 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4748 <<
"\", because it was used ";
4750 llvm::dbgs() <<
"with " << Args->size();
4752 llvm::dbgs() <<
"without";
4753 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4755 Tokens->setPosition(Position);
4760 if (FormatTok->isNot(tok::comment)) {
4761 distributeComments(Comments, FormatTok);
4766 Comments.push_back(FormatTok);
4769 distributeComments(Comments,
nullptr);
4774template <
typename Iterator>
4775void pushTokens(Iterator
Begin, Iterator End,
4777 for (
auto I =
Begin; I != End; ++I) {
4778 Into.push_back(I->Tok);
4779 for (
const auto &Child : I->Children)
4780 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
4785std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
4786UnwrappedLineParser::parseMacroCall() {
4787 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
4788 assert(Line->Tokens.empty());
4790 if (FormatTok->isNot(tok::l_paren))
4792 unsigned Position = Tokens->getPosition();
4793 FormatToken *Tok = FormatTok;
4796 auto ArgStart = std::prev(Line->Tokens.end());
4800 switch (FormatTok->Tok.getKind()) {
4805 case tok::r_paren: {
4811 Args->push_back({});
4812 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4821 Args->push_back({});
4822 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4824 ArgStart = std::prev(Line->Tokens.end());
4832 Line->Tokens.resize(1);
4833 Tokens->setPosition(Position);
4838void UnwrappedLineParser::pushToken(FormatToken *Tok) {
4839 Line->Tokens.push_back(UnwrappedLineNode(Tok));
4840 if (MustBreakBeforeNextToken) {
4841 Line->Tokens.back().Tok->MustBreakBefore =
true;
4842 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)
unsigned kind
All of the diagnostics that can be emitted by the frontend.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.