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)
346bool UnwrappedLineParser::parseLevel(
const FormatToken *OpeningBrace,
347 bool CanContainBracedList,
350 FormatToken **IfLeftBrace) {
351 auto NextLevelLBracesType = NextLBracesType == TT_CompoundRequirementLBrace
352 ? TT_BracedListLBrace
354 const bool IsPrecededByCommentOrPPDirective =
356 FormatToken *IfLBrace =
nullptr;
357 bool HasDoWhile =
false;
358 bool HasLabel =
false;
359 unsigned StatementCount = 0;
360 bool SwitchLabelEncountered =
false;
363 if (FormatTok->
getType() == TT_AttributeMacro) {
368 if (FormatTok->
getType() == TT_MacroBlockBegin)
370 else if (FormatTok->
getType() == TT_MacroBlockEnd)
373 auto ParseDefault = [
this, OpeningBrace, NextLevelLBracesType, IfKind,
374 &IfLBrace, &HasDoWhile, &HasLabel, &StatementCount] {
375 parseStructuralElement(!OpeningBrace, NextLevelLBracesType, IfKind,
376 &IfLBrace, HasDoWhile ?
nullptr : &HasDoWhile,
377 HasLabel ?
nullptr : &HasLabel);
379 assert(StatementCount > 0 &&
"StatementCount overflow!");
388 if (NextLBracesType != TT_Unknown) {
397 if (CanContainBracedList && !FormatTok->
is(TT_MacroBlockBegin) &&
398 tryToParseBracedList()) {
401 parseBlock(
false, 1u,
403 false, CanContainBracedList,
406 assert(StatementCount > 0 &&
"StatementCount overflow!");
412 !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
415 if (FormatTok->
isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
416 HasDoWhile || IsPrecededByCommentOrPPDirective ||
417 precededByCommentOrPPDirective()) {
421 if (Next->is(tok::comment) && Next->NewlinesBefore == 0)
424 *IfLeftBrace = IfLBrace;
430 case tok::kw_default: {
436 }
while (Next->is(tok::comment));
438 if (Next->isNot(tok::colon)) {
441 parseStructuralElement();
457 if (!SwitchLabelEncountered &&
459 (Line->InPPDirective && Line->Level == 1))) {
462 SwitchLabelEncountered =
true;
463 parseStructuralElement();
468 parseCSharpAttribute();
471 if (handleCppAttributes())
483void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
489 FormatToken *Tok = FormatTok;
490 const FormatToken *PrevTok = Tok->
Previous;
494 SmallVector<FormatToken *, 8> LBraceStack;
495 assert(Tok->is(tok::l_brace));
498 FormatToken *NextTok;
501 }
while (NextTok->is(tok::comment));
503 switch (Tok->Tok.getKind()) {
506 if (PrevTok->isOneOf(tok::colon, tok::less)) {
517 }
else if (PrevTok->is(tok::r_paren)) {
524 LBraceStack.push_back(Tok);
527 if (LBraceStack.empty())
530 bool ProbablyBracedList =
false;
532 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
537 while (NextTok->is(tok::hash)) {
538 ScopedMacroState MacroState(*Line, Tokens, NextTok);
541 }
while (NextTok->isNot(tok::eof));
546 bool NextIsObjCMethod = NextTok->
isOneOf(tok::plus, tok::minus) &&
547 NextTok->OriginalColumn == 0;
557 ProbablyBracedList = LBraceStack.back()->is(TT_BracedListLBrace);
559 ProbablyBracedList = ProbablyBracedList ||
561 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
563 ProbablyBracedList = ProbablyBracedList ||
564 (Style.
isCpp() && NextTok->is(tok::l_paren));
571 ProbablyBracedList ||
572 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
573 tok::r_paren, tok::r_square, tok::l_brace,
577 ProbablyBracedList ||
578 (NextTok->is(tok::identifier) &&
579 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
581 ProbablyBracedList = ProbablyBracedList ||
582 (NextTok->is(tok::semi) &&
583 (!ExpectClassBody || LBraceStack.size() != 1));
586 ProbablyBracedList ||
587 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
589 if (!Style.
isCSharp() && NextTok->is(tok::l_square)) {
593 ProbablyBracedList = NextTok->
isNot(tok::l_square);
596 if (ProbablyBracedList) {
601 LBraceStack.back()->setBlockKind(
BK_Block);
604 LBraceStack.pop_back();
606 case tok::identifier:
607 if (!Tok->is(TT_StatementMacro))
618 if (!LBraceStack.empty() && LBraceStack.back()->is(
BK_Unknown))
619 LBraceStack.back()->setBlockKind(
BK_Block);
626 }
while (Tok->isNot(tok::eof) && !LBraceStack.empty());
629 for (FormatToken *LBrace : LBraceStack)
639 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
642size_t UnwrappedLineParser::computePPHash()
const {
644 for (
const auto &i : PPStack) {
655bool UnwrappedLineParser::mightFitOnOneLine(
656 UnwrappedLine &ParsedLine,
const FormatToken *OpeningBrace)
const {
658 if (ColumnLimit == 0)
661 auto &Tokens = ParsedLine.Tokens;
662 assert(!Tokens.empty());
664 const auto *LastToken = Tokens.back().Tok;
667 SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size());
670 for (
const auto &Token : Tokens) {
672 auto &SavedToken = SavedTokens[Index++];
673 SavedToken.Tok =
new FormatToken;
674 SavedToken.Tok->copyFrom(*Token.Tok);
675 SavedToken.Children = std::move(Token.Children);
678 AnnotatedLine Line(ParsedLine);
679 assert(Line.Last == LastToken);
681 TokenAnnotator Annotator(Style, Keywords);
682 Annotator.annotate(Line);
683 Annotator.calculateFormattingInformation(Line);
685 auto Length = LastToken->TotalLength;
687 assert(OpeningBrace != Tokens.front().Tok);
688 if (
auto Prev = OpeningBrace->Previous;
689 Prev && Prev->TotalLength + ColumnLimit == OpeningBrace->TotalLength) {
690 Length -= ColumnLimit;
692 Length -= OpeningBrace->TokenText.size() + 1;
695 if (
const auto *FirstToken = Line.First; FirstToken->is(tok::r_brace)) {
696 assert(!OpeningBrace || OpeningBrace->is(TT_ControlStatementLBrace));
697 Length -= FirstToken->TokenText.size() + 1;
701 for (
auto &Token : Tokens) {
702 const auto &SavedToken = SavedTokens[Index++];
703 Token.Tok->copyFrom(*SavedToken.Tok);
704 Token.Children = std::move(SavedToken.Children);
705 delete SavedToken.Tok;
709 assert(!Line.InMacroBody);
710 assert(!Line.InPPDirective);
711 return Line.Level * Style.
IndentWidth + Length <= ColumnLimit;
714FormatToken *UnwrappedLineParser::parseBlock(
715 bool MustBeDeclaration,
unsigned AddLevels,
bool MunchSemi,
bool KeepBraces,
716 IfStmtKind *IfKind,
bool UnindentWhitesmithsBraces,
717 bool CanContainBracedList,
TokenType NextLBracesType) {
718 auto HandleVerilogBlockLabel = [
this]() {
720 if (Style.
isVerilog() && FormatTok->
is(tok::colon)) {
729 const bool VerilogHierarchy =
731 assert((FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) ||
734 "'{' or macro block token expected");
735 FormatToken *Tok = FormatTok;
736 const bool FollowedByComment = Tokens->peekNextToken()->is(tok::comment);
737 auto Index = CurrentLines->size();
738 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
743 if (!VerilogHierarchy && AddLevels > 0 &&
748 size_t PPStartHash = computePPHash();
750 const unsigned InitialLevel = Line->Level;
751 if (VerilogHierarchy) {
752 AddLevels += parseVerilogHierarchyHeader();
754 nextToken(AddLevels);
755 HandleVerilogBlockLabel();
759 if (Line->Level > 300)
762 if (MacroBlock && FormatTok->
is(tok::l_paren))
765 size_t NbPreprocessorDirectives =
766 !parsingPPDirective() ? PreprocessorDirectives.size() : 0;
768 size_t OpeningLineIndex =
769 CurrentLines->empty()
771 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
776 if (UnindentWhitesmithsBraces)
779 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
782 Line->Level += AddLevels;
784 FormatToken *IfLBrace =
nullptr;
785 const bool SimpleBlock =
786 parseLevel(Tok, CanContainBracedList, NextLBracesType, IfKind, &IfLBrace);
791 if (MacroBlock ? !FormatTok->
is(TT_MacroBlockEnd)
792 : !FormatTok->
is(tok::r_brace)) {
793 Line->Level = InitialLevel;
798 const bool IsFunctionRBrace =
799 FormatTok->
is(tok::r_brace) && Tok->is(TT_FunctionLBrace);
801 auto RemoveBraces = [=]()
mutable {
804 assert(Tok->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace));
805 assert(FormatTok->
is(tok::r_brace));
806 const bool WrappedOpeningBrace = !Tok->Previous;
807 if (WrappedOpeningBrace && FollowedByComment)
809 const bool HasRequiredIfBraces = IfLBrace && !IfLBrace->Optional;
810 if (KeepBraces && !HasRequiredIfBraces)
812 if (Tok->isNot(TT_ElseLBrace) || !HasRequiredIfBraces) {
813 const FormatToken *
Previous = Tokens->getPreviousToken();
818 assert(!CurrentLines->empty());
819 auto &LastLine = CurrentLines->back();
820 if (LastLine.Level == InitialLevel + 1 && !mightFitOnOneLine(LastLine))
822 if (Tok->is(TT_ElseLBrace))
824 if (WrappedOpeningBrace) {
829 return mightFitOnOneLine((*CurrentLines)[Index], Tok);
831 if (RemoveBraces()) {
832 Tok->MatchingParen = FormatTok;
836 size_t PPEndHash = computePPHash();
839 nextToken(-AddLevels);
845 while (FormatTok->
is(tok::semi)) {
851 HandleVerilogBlockLabel();
853 if (MacroBlock && FormatTok->
is(tok::l_paren))
856 Line->Level = InitialLevel;
858 if (FormatTok->
is(tok::kw_noexcept)) {
863 if (FormatTok->
is(tok::arrow)) {
867 parseStructuralElement();
870 if (MunchSemi && FormatTok->
is(tok::semi))
873 if (PPStartHash == PPEndHash) {
874 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
877 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
878 CurrentLines->size() - 1;
888 if (Line.Tokens.size() < 4)
890 auto I = Line.Tokens.begin();
891 if (I->Tok->TokenText !=
"goog")
894 if (I->Tok->isNot(tok::period))
897 if (I->Tok->TokenText !=
"scope")
900 return I->Tok->is(tok::l_paren);
909 if (Line.Tokens.size() < 3)
911 auto I = Line.Tokens.begin();
912 if (I->Tok->isNot(tok::l_paren))
918 return I->Tok->is(tok::l_paren);
924 if (InitialToken.
is(TT_NamespaceMacro))
925 Kind = tok::kw_namespace;
928 case tok::kw_namespace:
943void UnwrappedLineParser::parseChildBlock(
945 assert(FormatTok->
is(tok::l_brace));
947 const FormatToken *OpeningBrace = FormatTok;
953 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
955 Line->Level += SkipIndent ? 0 : 1;
956 parseLevel(OpeningBrace, CanContainBracedList, NextLBracesType);
957 flushComments(isOnNewLine(*FormatTok));
958 Line->Level -= SkipIndent ? 0 : 1;
963void UnwrappedLineParser::parsePPDirective() {
964 assert(FormatTok->
is(tok::hash) &&
"'#' expected");
965 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
986 case tok::pp_elifdef:
987 case tok::pp_elifndef:
1003void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
1004 size_t Line = CurrentLines->size();
1005 if (CurrentLines == &PreprocessorDirectives)
1006 Line += Lines.size();
1009 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) {
1010 PPStack.push_back({PP_Unreachable, Line});
1012 PPStack.push_back({PP_Conditional, Line});
1016void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
1018 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
1019 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
1020 PPLevelBranchIndex.push_back(0);
1021 PPLevelBranchCount.push_back(0);
1023 PPChainBranchIndex.push(Unreachable ? -1 : 0);
1024 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
1025 conditionalCompilationCondition(Unreachable || Skip);
1028void UnwrappedLineParser::conditionalCompilationAlternative() {
1029 if (!PPStack.empty())
1031 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1032 if (!PPChainBranchIndex.empty())
1033 ++PPChainBranchIndex.top();
1034 conditionalCompilationCondition(
1035 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
1036 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
1039void UnwrappedLineParser::conditionalCompilationEnd() {
1040 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
1041 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
1042 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel])
1043 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
1046 if (PPBranchLevel > -1)
1048 if (!PPChainBranchIndex.empty())
1049 PPChainBranchIndex.pop();
1050 if (!PPStack.empty())
1054void UnwrappedLineParser::parsePPIf(
bool IfDef) {
1055 bool IfNDef = FormatTok->
is(tok::pp_ifndef);
1057 bool Unreachable =
false;
1058 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
1060 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
1062 conditionalCompilationStart(Unreachable);
1063 FormatToken *IfCondition = FormatTok;
1066 bool MaybeIncludeGuard = IfNDef;
1067 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1068 for (
auto &Line : Lines) {
1069 if (!Line.Tokens.front().Tok->is(tok::comment)) {
1070 MaybeIncludeGuard =
false;
1071 IncludeGuard = IG_Rejected;
1079 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
1080 IncludeGuard = IG_IfNdefed;
1081 IncludeGuardToken = IfCondition;
1085void UnwrappedLineParser::parsePPElse() {
1087 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
1088 IncludeGuard = IG_Rejected;
1090 assert(PPBranchLevel >= -1);
1091 if (PPBranchLevel == -1)
1092 conditionalCompilationStart(
true);
1093 conditionalCompilationAlternative();
1099void UnwrappedLineParser::parsePPEndIf() {
1100 conditionalCompilationEnd();
1104 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
1106 IncludeGuard = IG_Found;
1110void UnwrappedLineParser::parsePPDefine() {
1114 IncludeGuard = IG_Rejected;
1115 IncludeGuardToken =
nullptr;
1120 if (IncludeGuard == IG_IfNdefed &&
1122 IncludeGuard = IG_Defined;
1123 IncludeGuardToken =
nullptr;
1124 for (
auto &Line : Lines) {
1125 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
1126 IncludeGuard = IG_Rejected;
1140 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
1145 Line->Level += PPBranchLevel + 1;
1149 Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
1150 assert((
int)Line->PPLevel >= 0);
1151 Line->InMacroBody =
true;
1161void UnwrappedLineParser::parsePPPragma() {
1162 Line->InPragmaDirective =
true;
1166void UnwrappedLineParser::parsePPUnknown() {
1171 Line->Level += PPBranchLevel + 1;
1181 return Tok.
isNot(tok::semi) && Tok.
isNot(tok::l_brace) &&
1182 Tok.
isNot(TT_AttributeSquare) &&
1185 Tok.
isNot(tok::period) && Tok.
isNot(tok::periodstar) &&
1186 Tok.
isNot(tok::arrow) && Tok.
isNot(tok::arrowstar) &&
1187 Tok.
isNot(tok::less) && Tok.
isNot(tok::greater) &&
1188 Tok.
isNot(tok::slash) && Tok.
isNot(tok::percent) &&
1189 Tok.
isNot(tok::lessless) && Tok.
isNot(tok::greatergreater) &&
1190 Tok.
isNot(tok::equal) && Tok.
isNot(tok::plusequal) &&
1191 Tok.
isNot(tok::minusequal) && Tok.
isNot(tok::starequal) &&
1192 Tok.
isNot(tok::slashequal) && Tok.
isNot(tok::percentequal) &&
1193 Tok.
isNot(tok::ampequal) && Tok.
isNot(tok::pipeequal) &&
1194 Tok.
isNot(tok::caretequal) && Tok.
isNot(tok::greatergreaterequal) &&
1195 Tok.
isNot(tok::lesslessequal) &&
1199 Tok.
isNot(tok::colon) &&
1201 Tok.
isNot(tok::kw_noexcept);
1207 return FormatTok->
is(tok::identifier) &&
1222 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
1233 tok::kw_if, tok::kw_else,
1235 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
1237 tok::kw_switch, tok::kw_case,
1239 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
1241 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
1249 return Tok.
isOneOf(tok::kw_char, tok::kw_short, tok::kw_int, tok::kw_long,
1250 tok::kw_unsigned, tok::kw_float, tok::kw_double,
1267 if (FuncName->
isNot(tok::identifier))
1275 !Tok->
isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
1279 if (Next->isNot(tok::star) && !Next->Tok.getIdentifierInfo())
1283 if (!Tok || Tok->
isNot(tok::r_paren))
1287 if (!Tok || Tok->
isNot(tok::identifier))
1293bool UnwrappedLineParser::parseModuleImport() {
1294 assert(FormatTok->
is(Keywords.
kw_import) &&
"'import' expected");
1296 if (
auto Token = Tokens->peekNextToken(
true);
1298 !
Token->
isOneOf(tok::colon, tok::less, tok::string_literal)) {
1304 if (FormatTok->
is(tok::colon)) {
1308 else if (FormatTok->
is(tok::less)) {
1310 while (!FormatTok->
isOneOf(tok::semi, tok::greater, tok::eof)) {
1313 if (FormatTok->
isNot(tok::comment) &&
1314 !FormatTok->
TokenText.startswith(
"//")) {
1320 if (FormatTok->
is(tok::semi)) {
1338void UnwrappedLineParser::readTokenWithJavaScriptASI() {
1341 FormatToken *Next = FormatTok;
1344 CommentsBeforeNextToken.empty()
1345 ? Next->NewlinesBefore == 0
1346 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1351 bool PreviousStartsTemplateExpr =
1353 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1356 bool HasAt = llvm::any_of(Line->Tokens, [](UnwrappedLineNode &LineNode) {
1357 return LineNode.Tok->is(tok::at);
1362 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1363 return addUnwrappedLine();
1365 bool NextEndsTemplateExpr =
1366 Next->is(TT_TemplateString) && Next->TokenText.startswith(
"}");
1367 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1368 (PreviousMustBeValue ||
1369 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1370 tok::minusminus))) {
1371 return addUnwrappedLine();
1373 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1375 return addUnwrappedLine();
1379void UnwrappedLineParser::parseStructuralElement(
1380 bool IsTopLevel,
TokenType NextLBracesType, IfStmtKind *IfKind,
1381 FormatToken **IfLeftBrace,
bool *HasDoWhile,
bool *HasLabel) {
1383 FormatTok->
is(tok::pp_include)) {
1385 if (FormatTok->
is(tok::string_literal))
1393 parseForOrWhileLoop(
false);
1402 }
else if (FormatTok->
is(tok::l_paren) &&
1403 Tokens->peekNextToken()->is(tok::star)) {
1415 if (FormatTok->
is(tok::l_brace)) {
1418 while (FormatTok && !eof()) {
1419 if (FormatTok->
is(tok::r_brace)) {
1430 case tok::kw_namespace:
1433 case tok::kw_public:
1434 case tok::kw_protected:
1435 case tok::kw_private:
1440 parseAccessSpecifier();
1448 FormatToken *Tok = parseIfThenElse(IfKind);
1459 parseForOrWhileLoop();
1470 case tok::kw_switch:
1477 case tok::kw_default:
1486 if (FormatTok->
is(tok::colon)) {
1518 case tok::kw_extern:
1524 parseVerilogHierarchyHeader();
1527 }
else if (FormatTok->
is(tok::string_literal)) {
1529 if (FormatTok->
is(tok::l_brace)) {
1534 unsigned AddLevels =
1541 parseBlock(
true, AddLevels);
1547 case tok::kw_export:
1549 parseJavaScriptEs6ImportExport();
1552 if (Style.
isCpp()) {
1554 if (FormatTok->
is(tok::kw_namespace)) {
1558 if (FormatTok->
is(Keywords.
kw_import) && parseModuleImport())
1562 case tok::kw_inline:
1564 if (FormatTok->
is(tok::kw_namespace)) {
1569 case tok::identifier:
1570 if (FormatTok->
is(TT_ForEachMacro)) {
1571 parseForOrWhileLoop();
1574 if (FormatTok->
is(TT_MacroBlockBegin)) {
1575 parseBlock(
false, 1u,
1581 parseJavaScriptEs6ImportExport();
1586 if (FormatTok->
is(tok::kw_public))
1588 if (!FormatTok->
is(tok::string_literal))
1591 if (FormatTok->
is(tok::semi))
1596 if (Style.
isCpp() && parseModuleImport())
1599 if (Style.
isCpp() &&
1603 if (FormatTok->
is(tok::colon)) {
1609 if (Style.
isCpp() && FormatTok->
is(TT_StatementMacro)) {
1610 parseStatementMacro();
1613 if (Style.
isCpp() && FormatTok->
is(TT_NamespaceMacro)) {
1627 if (FormatTok->
is(tok::l_brace)) {
1637 case tok::objc_public:
1638 case tok::objc_protected:
1639 case tok::objc_package:
1640 case tok::objc_private:
1641 return parseAccessSpecifier();
1642 case tok::objc_interface:
1643 case tok::objc_implementation:
1644 return parseObjCInterfaceOrImplementation();
1645 case tok::objc_protocol:
1646 if (parseObjCProtocol())
1651 case tok::objc_optional:
1652 case tok::objc_required:
1656 case tok::objc_autoreleasepool:
1658 if (FormatTok->
is(tok::l_brace)) {
1667 case tok::objc_synchronized:
1669 if (FormatTok->
is(tok::l_paren)) {
1673 if (FormatTok->
is(tok::l_brace)) {
1691 case tok::kw_requires: {
1692 if (Style.
isCpp()) {
1693 bool ParsedClause = parseRequires();
1713 if (!Style.
isCpp()) {
1718 case tok::kw_typedef:
1734 case tok::kw_struct:
1736 if (parseStructLike())
1743 FormatTok->
is(tok::kw_class)) {
1760 case tok::l_paren: {
1767 Tokens->peekNextToken(
true),
1774 case tok::kw_operator:
1785 if (FormatTok->
is(tok::l_paren))
1787 if (FormatTok->
is(tok::l_brace))
1791 if (NextLBracesType != TT_Unknown)
1793 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1828 case tok::identifier: {
1830 Line->MustBeDeclaration) {
1832 parseCSharpGenericTypeConstraint();
1835 if (FormatTok->
is(TT_MacroBlockEnd)) {
1844 size_t TokenCount = Line->Tokens.size();
1846 (TokenCount > 1 || (TokenCount == 1 && !Line->Tokens.front().Tok->is(
1848 tryToParseJSFunction();
1858 unsigned StoredPosition = Tokens->getPosition();
1859 FormatToken *Next = Tokens->getNextToken();
1860 FormatTok = Tokens->setPosition(StoredPosition);
1873 parseVerilogTable();
1885 if (parseStructLike())
1890 if (Style.
isCpp() && FormatTok->
is(TT_StatementMacro)) {
1891 parseStatementMacro();
1898 FormatToken *PreviousToken = FormatTok;
1906 auto OneTokenSoFar = [&]() {
1907 auto I = Line->Tokens.begin(), E = Line->Tokens.end();
1908 while (I != E && I->Tok->is(tok::comment))
1910 while (I != E && Style.
isVerilog() && I->Tok->is(tok::hash))
1912 return I != E && (++I == E);
1914 if (OneTokenSoFar()) {
1916 if (!Style.
isVerilog() && FormatTok->
is(tok::colon) &&
1917 !Line->MustBeDeclaration) {
1918 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1926 bool FunctionLike = FormatTok->
is(tok::l_paren);
1930 bool FollowedByNewline =
1931 CommentsBeforeNextToken.empty()
1933 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
1935 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
1937 if (PreviousToken->isNot(TT_UntouchableMacroFunc))
1938 PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
1947 FormatTok->
is(TT_FatArrow)) {
1948 tryToParseChildBlock();
1953 if (FormatTok->
is(tok::l_brace)) {
1962 FormatTok->
is(tok::less)) {
1964 parseBracedList(
false,
false,
1993 case tok::kw_default:
1996 if (FormatTok->
is(tok::colon)) {
2006 parseVerilogCaseLabel();
2013 parseVerilogCaseLabel();
2024bool UnwrappedLineParser::tryToParsePropertyAccessor() {
2025 assert(FormatTok->
is(tok::l_brace));
2037 unsigned int StoredPosition = Tokens->getPosition();
2038 FormatToken *Tok = Tokens->getNextToken();
2043 bool HasSpecialAccessor =
false;
2044 bool IsTrivialPropertyAccessor =
true;
2046 if (Tok->isOneOf(tok::semi, tok::kw_public, tok::kw_private,
2050 HasSpecialAccessor =
true;
2051 Tok = Tokens->getNextToken();
2054 if (Tok->isNot(tok::r_brace))
2055 IsTrivialPropertyAccessor =
false;
2059 if (!HasSpecialAccessor) {
2060 Tokens->setPosition(StoredPosition);
2066 Tokens->setPosition(StoredPosition);
2074 if (FormatTok->
is(tok::equal)) {
2075 while (!eof() && FormatTok->
isNot(tok::semi))
2088 if (FormatTok->
is(TT_FatArrow)) {
2092 }
while (!eof() && FormatTok->
isNot(tok::semi));
2103 !IsTrivialPropertyAccessor) {
2115bool UnwrappedLineParser::tryToParseLambda() {
2116 assert(FormatTok->
is(tok::l_square));
2117 if (!Style.
isCpp()) {
2121 FormatToken &LSquare = *FormatTok;
2122 if (!tryToParseLambdaIntroducer())
2125 bool SeenArrow =
false;
2126 bool InTemplateParameterList =
false;
2128 while (FormatTok->
isNot(tok::l_brace)) {
2145 InTemplateParameterList =
true;
2150 case tok::kw_template:
2151 case tok::kw_typename:
2155 case tok::kw_constexpr:
2156 case tok::kw_consteval:
2159 case tok::identifier:
2160 case tok::numeric_constant:
2161 case tok::coloncolon:
2162 case tok::kw_mutable:
2163 case tok::kw_noexcept:
2164 case tok::kw_static:
2192 case tok::equalequal:
2193 case tok::exclaimequal:
2194 case tok::greaterequal:
2195 case tok::lessequal:
2201 if (SeenArrow || InTemplateParameterList) {
2219 LSquare.setFinalizedType(TT_LambdaLSquare);
2224bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
2226 const FormatToken *LeftSquare = FormatTok;
2229 (
Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
2230 tok::kw_delete, tok::l_square) ||
2231 LeftSquare->isCppStructuredBinding(Style) ||
Previous->closesScope() ||
2232 Previous->isSimpleTypeSpecifier())) {
2235 if (FormatTok->
is(tok::l_square))
2237 if (FormatTok->
is(tok::r_square)) {
2238 const FormatToken *Next = Tokens->peekNextToken(
true);
2239 if (Next->is(tok::greater))
2246void UnwrappedLineParser::tryToParseJSFunction() {
2255 if (FormatTok->
is(tok::star)) {
2261 if (FormatTok->
is(tok::identifier))
2264 if (FormatTok->
isNot(tok::l_paren))
2270 if (FormatTok->
is(tok::colon)) {
2276 if (FormatTok->
is(tok::l_brace))
2277 tryToParseBracedList();
2279 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
2283 if (FormatTok->
is(tok::semi))
2289bool UnwrappedLineParser::tryToParseBracedList() {
2291 calculateBraceTypes();
2300bool UnwrappedLineParser::tryToParseChildBlock() {
2302 assert(FormatTok->
is(TT_FatArrow));
2307 if (FormatTok->
isNot(tok::l_brace))
2313bool UnwrappedLineParser::parseBracedList(
bool ContinueOnSemicolons,
2316 bool HasError =
false;
2321 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow) &&
2322 tryToParseChildBlock()) {
2328 tryToParseJSFunction();
2331 if (FormatTok->
is(tok::l_brace)) {
2333 if (tryToParseBracedList())
2338 if (FormatTok->
Tok.
getKind() == ClosingBraceKind) {
2356 if (FormatTok->
is(tok::l_brace))
2370 ClosingBraceKind == tok::greater) {
2372 parseBracedList(
false,
false,
2388 if (!ContinueOnSemicolons)
2408void UnwrappedLineParser::parseParens(
TokenType AmpAmpTokenType) {
2409 assert(FormatTok->
is(tok::l_paren) &&
"'(' expected.");
2428 if (!tryToParseBracedList())
2433 if (FormatTok->
is(tok::l_brace)) {
2439 if (Style.
isCSharp() && FormatTok->
is(TT_FatArrow))
2440 tryToParseChildBlock();
2450 case tok::identifier:
2455 tryToParseJSFunction();
2460 case tok::kw_requires: {
2461 auto RequiresToken = FormatTok;
2463 parseRequiresExpression(RequiresToken);
2467 if (AmpAmpTokenType != TT_Unknown)
2477void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
2478 if (!LambdaIntroducer) {
2479 assert(FormatTok->
is(tok::l_square) &&
"'[' expected.");
2480 if (tryToParseLambda())
2497 case tok::l_brace: {
2498 if (!tryToParseBracedList())
2504 if (FormatTok->
is(tok::l_brace)) {
2516void UnwrappedLineParser::keepAncestorBraces() {
2520 const int MaxNestingLevels = 2;
2521 const int Size = NestedTooDeep.size();
2522 if (Size >= MaxNestingLevels)
2523 NestedTooDeep[
Size - MaxNestingLevels] =
true;
2524 NestedTooDeep.push_back(
false);
2528 for (
const auto &
Token : llvm::reverse(Line.Tokens))
2535void UnwrappedLineParser::parseUnbracedBody(
bool CheckEOF) {
2536 FormatToken *Tok =
nullptr;
2538 if (Style.
InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2539 PreprocessorDirectives.empty() && FormatTok->
isNot(tok::semi)) {
2542 : Line->Tokens.back().Tok;
2544 if (Tok->BraceCount < 0) {
2545 assert(Tok->BraceCount == -1);
2548 Tok->BraceCount = -1;
2554 parseStructuralElement();
2557 assert(!Line->InPPDirective);
2559 for (
const auto &L : llvm::reverse(*CurrentLines)) {
2561 Tok = L.Tokens.back().Tok;
2569 if (CheckEOF && eof())
2579 assert(LeftBrace->
is(tok::l_brace));
2587 assert(RightBrace->
is(tok::r_brace));
2595void UnwrappedLineParser::handleAttributes() {
2597 if (FormatTok->
is(TT_AttributeMacro))
2599 handleCppAttributes();
2602bool UnwrappedLineParser::handleCppAttributes() {
2604 if (FormatTok->
is(tok::l_square) && tryToParseSimpleAttribute()) {
2612bool UnwrappedLineParser::isBlockBegin(
const FormatToken &Tok)
const {
2616 : Tok.is(tok::l_brace);
2619FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
2621 assert(FormatTok->
is(tok::kw_if) &&
"'if' expected");
2623 if (FormatTok->
is(tok::exclaim))
2626 bool KeepIfBraces =
true;
2627 if (FormatTok->
is(tok::kw_consteval)) {
2631 if (FormatTok->
isOneOf(tok::kw_constexpr, tok::identifier))
2633 if (FormatTok->
is(tok::l_paren))
2638 bool NeedsUnwrappedLine =
false;
2639 keepAncestorBraces();
2641 FormatToken *IfLeftBrace =
nullptr;
2642 IfStmtKind IfBlockKind = IfStmtKind::NotIf;
2644 if (isBlockBegin(*FormatTok)) {
2646 IfLeftBrace = FormatTok;
2648 parseBlock(
false, 1u,
2649 true, KeepIfBraces, &IfBlockKind);
2653 NeedsUnwrappedLine =
true;
2655 parseUnbracedBody();
2659 assert(!NestedTooDeep.empty());
2660 KeepIfBraces = KeepIfBraces ||
2661 (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
2662 NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
2663 IfBlockKind == IfStmtKind::IfElseIf;
2666 bool KeepElseBraces = KeepIfBraces;
2667 FormatToken *ElseLeftBrace =
nullptr;
2668 IfStmtKind
Kind = IfStmtKind::IfOnly;
2670 if (FormatTok->
is(tok::kw_else)) {
2672 NestedTooDeep.back() =
false;
2673 Kind = IfStmtKind::IfElse;
2677 if (isBlockBegin(*FormatTok)) {
2678 const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
2680 ElseLeftBrace = FormatTok;
2682 IfStmtKind ElseBlockKind = IfStmtKind::NotIf;
2683 FormatToken *IfLBrace =
2684 parseBlock(
false, 1u,
2685 true, KeepElseBraces, &ElseBlockKind);
2686 if (FormatTok->
is(tok::kw_else)) {
2687 KeepElseBraces = KeepElseBraces ||
2688 ElseBlockKind == IfStmtKind::IfOnly ||
2689 ElseBlockKind == IfStmtKind::IfElseIf;
2690 }
else if (FollowedByIf && IfLBrace && !IfLBrace->Optional) {
2691 KeepElseBraces =
true;
2692 assert(ElseLeftBrace->MatchingParen);
2696 }
else if (FormatTok->
is(tok::kw_if)) {
2697 const FormatToken *
Previous = Tokens->getPreviousToken();
2699 const bool IsPrecededByComment =
Previous->is(tok::comment);
2700 if (IsPrecededByComment) {
2704 bool TooDeep =
true;
2706 Kind = IfStmtKind::IfElseIf;
2707 TooDeep = NestedTooDeep.pop_back_val();
2709 ElseLeftBrace = parseIfThenElse(
nullptr, KeepIfBraces);
2711 NestedTooDeep.push_back(TooDeep);
2712 if (IsPrecededByComment)
2715 parseUnbracedBody(
true);
2718 KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse;
2719 if (NeedsUnwrappedLine)
2726 assert(!NestedTooDeep.empty());
2727 KeepElseBraces = KeepElseBraces ||
2728 (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
2729 NestedTooDeep.back();
2731 NestedTooDeep.pop_back();
2733 if (!KeepIfBraces && !KeepElseBraces) {
2736 }
else if (IfLeftBrace) {
2737 FormatToken *IfRightBrace = IfLeftBrace->MatchingParen;
2739 assert(IfRightBrace->MatchingParen == IfLeftBrace);
2740 assert(!IfLeftBrace->Optional);
2741 assert(!IfRightBrace->Optional);
2742 IfLeftBrace->MatchingParen =
nullptr;
2743 IfRightBrace->MatchingParen =
nullptr;
2753void UnwrappedLineParser::parseTryCatch() {
2754 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2756 bool NeedsUnwrappedLine =
false;
2757 if (FormatTok->
is(tok::colon)) {
2763 while (FormatTok->
is(tok::comma))
2766 while (FormatTok->
is(tok::identifier)) {
2768 if (FormatTok->
is(tok::l_paren))
2771 FormatTok->
is(tok::l_brace)) {
2774 }
while (!FormatTok->
is(tok::r_brace));
2780 while (FormatTok->
is(tok::comma))
2788 keepAncestorBraces();
2790 if (FormatTok->
is(tok::l_brace)) {
2796 NeedsUnwrappedLine =
true;
2797 }
else if (!FormatTok->
is(tok::kw_catch)) {
2803 parseStructuralElement();
2807 if (FormatTok->
is(tok::at))
2810 tok::kw___finally) ||
2818 while (FormatTok->
isNot(tok::l_brace)) {
2819 if (FormatTok->
is(tok::l_paren)) {
2823 if (FormatTok->
isOneOf(tok::semi, tok::r_brace, tok::eof)) {
2825 NestedTooDeep.pop_back();
2830 NeedsUnwrappedLine =
false;
2831 Line->MustBeDeclaration =
false;
2837 NeedsUnwrappedLine =
true;
2841 NestedTooDeep.pop_back();
2843 if (NeedsUnwrappedLine)
2847void UnwrappedLineParser::parseNamespace() {
2848 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
2849 "'namespace' expected");
2851 const FormatToken &InitialToken = *FormatTok;
2853 if (InitialToken.is(TT_NamespaceMacro)) {
2856 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
2857 tok::l_square, tok::period, tok::l_paren) ||
2858 (Style.
isCSharp() && FormatTok->
is(tok::kw_union))) {
2859 if (FormatTok->
is(tok::l_square))
2861 else if (FormatTok->
is(tok::l_paren))
2867 if (FormatTok->
is(tok::l_brace)) {
2871 unsigned AddLevels =
2874 DeclarationScopeStack.size() > 1)
2877 bool ManageWhitesmithsBraces =
2883 if (ManageWhitesmithsBraces)
2886 parseBlock(
true, AddLevels,
true,
2888 ManageWhitesmithsBraces);
2892 if (FormatTok->
is(tok::semi))
2895 addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
2897 if (ManageWhitesmithsBraces)
2903void UnwrappedLineParser::parseNew() {
2904 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
2910 if (FormatTok->
is(tok::l_paren))
2914 if (FormatTok->
is(tok::l_brace))
2917 if (FormatTok->
isOneOf(tok::semi, tok::comma))
2930 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
2934 if (FormatTok->
is(tok::l_paren)) {
2938 if (FormatTok->
is(tok::l_brace))
2946void UnwrappedLineParser::parseLoopBody(
bool KeepBraces,
bool WrapRightBrace) {
2947 keepAncestorBraces();
2949 if (isBlockBegin(*FormatTok)) {
2952 FormatToken *LeftBrace = FormatTok;
2954 parseBlock(
false, 1u,
2957 assert(!NestedTooDeep.empty());
2958 if (!NestedTooDeep.back())
2964 parseUnbracedBody();
2968 NestedTooDeep.pop_back();
2971void UnwrappedLineParser::parseForOrWhileLoop(
bool HasParens) {
2972 assert((FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
2979 "'for', 'while' or foreach macro expected");
2981 !FormatTok->
isOneOf(tok::kw_for, tok::kw_while);
2987 if (Style.
isCpp() && FormatTok->
is(tok::kw_co_await))
2989 if (HasParens && FormatTok->
is(tok::l_paren))
2993 parseVerilogSensitivityList();
2996 parseLoopBody(KeepBraces,
true);
2999void UnwrappedLineParser::parseDoWhile() {
3000 assert(FormatTok->
is(tok::kw_do) &&
"'do' expected");
3006 if (!FormatTok->
is(tok::kw_while)) {
3017 parseStructuralElement();
3020void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
3022 unsigned OldLineLevel = Line->Level;
3023 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
3029 FormatTok->
is(tok::l_brace)) {
3035 if (FormatTok->
is(tok::kw_break)) {
3044 parseStructuralElement();
3048 if (FormatTok->
is(tok::semi))
3052 Line->Level = OldLineLevel;
3053 if (FormatTok->
isNot(tok::l_brace)) {
3054 parseStructuralElement();
3059void UnwrappedLineParser::parseCaseLabel() {
3060 assert(FormatTok->
is(tok::kw_case) &&
"'case' expected");
3065 }
while (!eof() && !FormatTok->
is(tok::colon));
3069void UnwrappedLineParser::parseSwitch() {
3070 assert(FormatTok->
is(tok::kw_switch) &&
"'switch' expected");
3072 if (FormatTok->
is(tok::l_paren))
3075 keepAncestorBraces();
3077 if (FormatTok->
is(tok::l_brace)) {
3084 parseStructuralElement();
3089 NestedTooDeep.pop_back();
3099 case tok::caretequal:
3103 case tok::equalequal:
3105 case tok::exclaimequal:
3107 case tok::greaterequal:
3108 case tok::greatergreater:
3109 case tok::greatergreaterequal:
3113 case tok::lessequal:
3115 case tok::lesslessequal:
3117 case tok::minusequal:
3118 case tok::minusminus:
3120 case tok::percentequal:
3123 case tok::pipeequal:
3126 case tok::plusequal:
3134 case tok::slashequal:
3136 case tok::starequal:
3143void UnwrappedLineParser::parseAccessSpecifier() {
3144 FormatToken *AccessSpecifierCandidate = FormatTok;
3150 if (FormatTok->
is(tok::colon)) {
3153 }
else if (!FormatTok->
is(tok::coloncolon) &&
3157 }
else if (AccessSpecifierCandidate) {
3159 AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3166bool clang::format::UnwrappedLineParser::parseRequires() {
3167 assert(FormatTok->is(tok::kw_requires) &&
"'requires' expected");
3168 auto RequiresToken = FormatTok;
3174 switch (FormatTok->Tok.getKind()) {
3177 parseRequiresExpression(RequiresToken);
3184 parseRequiresClause(RequiresToken);
3195 auto *PreviousNonComment = RequiresToken->getPreviousNonComment();
3197 if (!PreviousNonComment ||
3198 PreviousNonComment->is(TT_RequiresExpressionLBrace)) {
3201 parseRequiresClause(RequiresToken);
3205 switch (PreviousNonComment->Tok.getKind()) {
3208 case tok::kw_noexcept:
3211 parseRequiresClause(RequiresToken);
3221 auto PrevPrev = PreviousNonComment->getPreviousNonComment();
3222 if (PrevPrev && PrevPrev->is(tok::kw_const)) {
3223 parseRequiresClause(RequiresToken);
3229 if (PreviousNonComment->isTypeOrIdentifier()) {
3231 parseRequiresClause(RequiresToken);
3235 parseRequiresExpression(RequiresToken);
3248 auto PeekNext = [&Lookahead, &NextToken,
this] {
3253 bool FoundType =
false;
3254 bool LastWasColonColon =
false;
3257 for (; Lookahead < 50; PeekNext()) {
3258 switch (NextToken->Tok.getKind()) {
3259 case tok::kw_volatile:
3263 parseRequiresExpression(RequiresToken);
3268 parseRequiresClause(RequiresToken);
3274 case tok::coloncolon:
3275 LastWasColonColon =
true;
3277 case tok::identifier:
3278 if (FoundType && !LastWasColonColon && OpenAngles == 0) {
3280 parseRequiresExpression(RequiresToken);
3284 LastWasColonColon =
false;
3293 if (NextToken->isSimpleTypeSpecifier()) {
3295 parseRequiresExpression(RequiresToken);
3303 parseRequiresClause(RequiresToken);
3314void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
3316 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3321 bool InRequiresExpression =
3322 !RequiresToken->Previous ||
3323 RequiresToken->Previous->is(TT_RequiresExpressionLBrace);
3325 RequiresToken->setFinalizedType(InRequiresExpression
3326 ? TT_RequiresClauseInARequiresExpression
3327 : TT_RequiresClause);
3331 parseConstraintExpression();
3333 if (!InRequiresExpression)
3344void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
3346 assert(RequiresToken->is(tok::kw_requires) &&
"'requires' expected");
3348 RequiresToken->setFinalizedType(TT_RequiresExpression);
3350 if (FormatTok->
is(tok::l_paren)) {
3355 if (FormatTok->
is(tok::l_brace)) {
3357 parseChildBlock(
false,
3358 TT_CompoundRequirementLBrace);
3366void UnwrappedLineParser::parseConstraintExpression() {
3373 bool LambdaNextTimeAllowed =
true;
3375 bool LambdaThisTimeAllowed = std::exchange(LambdaNextTimeAllowed,
false);
3378 case tok::kw_requires: {
3379 auto RequiresToken = FormatTok;
3381 parseRequiresExpression(RequiresToken);
3386 parseParens(TT_BinaryOperator);
3390 if (!LambdaThisTimeAllowed || !tryToParseLambda())
3397 case tok::kw_struct:
3409 LambdaNextTimeAllowed =
true;
3414 LambdaNextTimeAllowed = LambdaThisTimeAllowed;
3418 case tok::kw_sizeof:
3420 case tok::greaterequal:
3421 case tok::greatergreater:
3423 case tok::lessequal:
3425 case tok::equalequal:
3427 case tok::exclaimequal:
3432 LambdaNextTimeAllowed =
true;
3437 case tok::numeric_constant:
3438 case tok::coloncolon:
3445 case tok::kw_static_cast:
3446 case tok::kw_const_cast:
3447 case tok::kw_reinterpret_cast:
3448 case tok::kw_dynamic_cast:
3450 if (!FormatTok->
is(tok::less))
3454 parseBracedList(
false,
false,
3471 case tok::coloncolon:
3475 case tok::kw_requires:
3484 if (FormatTok->
is(tok::less)) {
3486 parseBracedList(
false,
false,
3494bool UnwrappedLineParser::parseEnum() {
3495 const FormatToken &InitialToken = *FormatTok;
3498 if (FormatTok->
is(tok::kw_enum))
3512 if (FormatTok->
isOneOf(tok::kw_class, tok::kw_struct))
3516 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
3517 tok::greater, tok::comma, tok::question,
3518 tok::l_square, tok::r_square)) {
3521 if (FormatTok->
is(tok::l_paren))
3523 if (FormatTok->
is(TT_AttributeSquare)) {
3526 if (FormatTok->
Next && FormatTok->
is(TT_AttributeSquare))
3529 if (FormatTok->
is(tok::identifier)) {
3533 if (Style.
isCpp() && FormatTok->
is(tok::identifier))
3539 if (FormatTok->
isNot(tok::l_brace))
3546 parseJavaEnumBody();
3564 bool HasError = !parseBracedList(
true,
3569 if (FormatTok->
is(tok::semi))
3580bool UnwrappedLineParser::parseStructLike() {
3587 if (FormatTok->
is(tok::semi))
3598class ScopedTokenPosition {
3599 unsigned StoredPosition;
3600 FormatTokenSource *Tokens;
3603 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
3604 assert(Tokens &&
"Tokens expected to not be null");
3605 StoredPosition = Tokens->getPosition();
3608 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
3614bool UnwrappedLineParser::tryToParseSimpleAttribute() {
3615 ScopedTokenPosition AutoPosition(Tokens);
3616 FormatToken *Tok = Tokens->getNextToken();
3618 if (!Tok->is(tok::l_square))
3622 while (Tok->isNot(tok::eof)) {
3623 if (Tok->is(tok::r_square))
3625 Tok = Tokens->getNextToken();
3627 if (Tok->is(tok::eof))
3629 Tok = Tokens->getNextToken();
3630 if (!Tok->is(tok::r_square))
3632 Tok = Tokens->getNextToken();
3633 if (Tok->is(tok::semi))
3638void UnwrappedLineParser::parseJavaEnumBody() {
3639 assert(FormatTok->
is(tok::l_brace));
3640 const FormatToken *OpeningBrace = FormatTok;
3645 unsigned StoredPosition = Tokens->getPosition();
3646 bool IsSimple =
true;
3647 FormatToken *Tok = Tokens->getNextToken();
3648 while (!Tok->is(tok::eof)) {
3649 if (Tok->is(tok::r_brace))
3651 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
3657 Tok = Tokens->getNextToken();
3659 FormatTok = Tokens->setPosition(StoredPosition);
3676 if (FormatTok->
is(tok::l_brace)) {
3678 parseBlock(
true, 1u,
3680 }
else if (FormatTok->
is(tok::l_paren)) {
3682 }
else if (FormatTok->
is(tok::comma)) {
3685 }
else if (FormatTok->
is(tok::semi)) {
3689 }
else if (FormatTok->
is(tok::r_brace)) {
3698 parseLevel(OpeningBrace);
3704void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
3705 const FormatToken &InitialToken = *FormatTok;
3711 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3712 tok::kw___attribute, tok::kw___declspec,
3715 FormatTok->
isOneOf(tok::period, tok::comma))) {
3722 if (FormatTok->
is(tok::l_brace)) {
3723 tryToParseBracedList();
3727 bool IsNonMacroIdentifier =
3728 FormatTok->
is(tok::identifier) &&
3732 if (!IsNonMacroIdentifier) {
3733 if (FormatTok->
is(tok::l_paren)) {
3749 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
3751 if (FormatTok->
is(tok::l_brace)) {
3752 calculateBraceTypes(
true);
3753 if (!tryToParseBracedList())
3756 if (FormatTok->
is(tok::l_square)) {
3762 if (!tryToParseLambda())
3769 if (FormatTok->
is(tok::semi))
3774 parseCSharpGenericTypeConstraint();
3781 auto GetBraceType = [](
const FormatToken &RecordTok) {
3782 switch (RecordTok.Tok.getKind()) {
3784 return TT_ClassLBrace;
3785 case tok::kw_struct:
3786 return TT_StructLBrace;
3788 return TT_UnionLBrace;
3791 return TT_RecordLBrace;
3794 if (FormatTok->
is(tok::l_brace)) {
3803 parseBlock(
true, AddLevels,
false);
3811void UnwrappedLineParser::parseObjCMethod() {
3812 assert(FormatTok->
isOneOf(tok::l_paren, tok::identifier) &&
3813 "'(' or identifier expected.");
3815 if (FormatTok->
is(tok::semi)) {
3819 }
else if (FormatTok->
is(tok::l_brace)) {
3831void UnwrappedLineParser::parseObjCProtocolList() {
3832 assert(FormatTok->
is(tok::less) &&
"'<' expected.");
3836 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
3840 }
while (!eof() && FormatTok->
isNot(tok::greater));
3844void UnwrappedLineParser::parseObjCUntilAtEnd() {
3851 if (FormatTok->
is(tok::l_brace)) {
3855 }
else if (FormatTok->
is(tok::r_brace)) {
3859 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
3863 parseStructuralElement();
3868void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
3876 if (FormatTok->
is(tok::less))
3877 parseObjCLightweightGenerics();
3878 if (FormatTok->
is(tok::colon)) {
3882 if (FormatTok->
is(tok::less))
3883 parseObjCLightweightGenerics();
3884 }
else if (FormatTok->
is(tok::l_paren)) {
3889 if (FormatTok->
is(tok::less))
3890 parseObjCProtocolList();
3892 if (FormatTok->
is(tok::l_brace)) {
3902 parseObjCUntilAtEnd();
3905void UnwrappedLineParser::parseObjCLightweightGenerics() {
3906 assert(FormatTok->
is(tok::less));
3914 unsigned NumOpenAngles = 1;
3918 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
3922 if (FormatTok->
is(tok::less)) {
3924 }
else if (FormatTok->
is(tok::greater)) {
3925 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
3928 }
while (!eof() && NumOpenAngles != 0);
3934bool UnwrappedLineParser::parseObjCProtocol() {
3938 if (FormatTok->
is(tok::l_paren)) {
3950 if (FormatTok->
is(tok::less))
3951 parseObjCProtocolList();
3954 if (FormatTok->
is(tok::semi)) {
3961 parseObjCUntilAtEnd();
3965void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
3966 bool IsImport = FormatTok->
is(Keywords.
kw_import);
3967 assert(IsImport || FormatTok->
is(tok::kw_export));
3971 if (FormatTok->
is(tok::kw_default))
3988 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
3994 if (FormatTok->
is(tok::semi))
3996 if (Line->Tokens.empty()) {
4001 if (FormatTok->
is(tok::l_brace)) {
4011void UnwrappedLineParser::parseStatementMacro() {
4013 if (FormatTok->
is(tok::l_paren))
4015 if (FormatTok->
is(tok::semi))
4020void UnwrappedLineParser::parseVerilogHierarchyIdentifier() {
4023 if (FormatTok->
isOneOf(tok::star, tok::period, tok::periodstar,
4024 tok::coloncolon, tok::hash) ||
4027 }
else if (FormatTok->
is(tok::l_square)) {
4035void UnwrappedLineParser::parseVerilogSensitivityList() {
4036 if (!FormatTok->
is(tok::at))
4040 if (FormatTok->
is(tok::at))
4050 parseVerilogHierarchyIdentifier();
4055unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
4056 unsigned AddLevels = 0;
4062 parseVerilogSensitivityList();
4063 if (FormatTok->
is(tok::semi))
4071 if (FormatTok->
is(tok::l_paren)) {
4084 if (FormatTok->
is(tok::l_square)) {
4099 Line->IsContinuation =
true;
4106 parseVerilogHierarchyIdentifier();
4107 if (FormatTok->
is(tok::semi))
4115 if (FormatTok->
is(tok::l_paren))
4118 if (FormatTok->
is(tok::l_paren)) {
4127 parseVerilogHierarchyIdentifier();
4128 if (FormatTok->
is(tok::l_paren))
4135 parseVerilogHierarchyIdentifier();
4136 }
while (FormatTok->
is(tok::comma));
4140 if (FormatTok->
is(tok::at)) {
4142 parseVerilogSensitivityList();
4145 if (FormatTok->
is(tok::semi))
4153void UnwrappedLineParser::parseVerilogTable() {
4158 auto InitialLevel = Line->Level++;
4160 FormatToken *Tok = FormatTok;
4162 if (Tok->is(tok::semi))
4164 else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
4165 Tok->setFinalizedType(TT_VerilogTableItem);
4167 Line->Level = InitialLevel;
4172void UnwrappedLineParser::parseVerilogCaseLabel() {
4178 auto OrigLevel = Line->Level;
4179 auto FirstLine = CurrentLines->size();
4180 if (Line->Level == 0 || (Line->InPPDirective && Line->Level <= 1))
4184 parseStructuralElement();
4187 if (CurrentLines->size() > FirstLine)
4188 (*CurrentLines)[FirstLine].Level = OrigLevel;
4189 Line->Level = OrigLevel;
4192bool UnwrappedLineParser::containsExpansion(
const UnwrappedLine &Line)
const {
4193 for (
const auto &N : Line.Tokens) {
4194 if (N.Tok->MacroCtx)
4196 for (
const UnwrappedLine &Child : N.Children)
4197 if (containsExpansion(Child))
4203void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
4204 if (Line->Tokens.empty())
4207 if (!parsingPPDirective()) {
4208 llvm::dbgs() <<
"Adding unwrapped line:\n";
4209 printDebugInfo(*Line);
4217 bool ClosesWhitesmithsBlock =
4224 if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
4226 Reconstruct.emplace(Line->Level, Unexpanded);
4227 Reconstruct->addLine(*Line);
4232 CurrentExpandedLines.push_back(std::move(*Line));
4234 if (Reconstruct->finished()) {
4235 UnwrappedLine Reconstructed = std::move(*Reconstruct).takeResult();
4236 assert(!Reconstructed.Tokens.empty() &&
4237 "Reconstructed must at least contain the macro identifier.");
4238 assert(!parsingPPDirective());
4240 llvm::dbgs() <<
"Adding unexpanded line:\n";
4241 printDebugInfo(Reconstructed);
4243 ExpandedLines[Reconstructed.Tokens.begin()->Tok] = CurrentExpandedLines;
4244 Lines.push_back(std::move(Reconstructed));
4245 CurrentExpandedLines.clear();
4246 Reconstruct.reset();
4251 assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
4252 CurrentLines->push_back(std::move(*Line));
4254 Line->Tokens.clear();
4256 Line->FirstStartColumn = 0;
4257 Line->IsContinuation =
false;
4259 if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
4261 if (!parsingPPDirective() && !PreprocessorDirectives.empty()) {
4262 CurrentLines->append(
4263 std::make_move_iterator(PreprocessorDirectives.begin()),
4264 std::make_move_iterator(PreprocessorDirectives.end()));
4265 PreprocessorDirectives.clear();
4271bool UnwrappedLineParser::eof()
const {
return FormatTok->
is(tok::eof); }
4273bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
4274 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
4275 FormatTok.NewlinesBefore > 0;
4283 const llvm::Regex &CommentPragmasRegex) {
4284 if (Line.Tokens.empty())
4287 StringRef IndentContent = FormatTok.
TokenText;
4288 if (FormatTok.
TokenText.startswith(
"//") ||
4290 IndentContent = FormatTok.
TokenText.substr(2);
4292 if (CommentPragmasRegex.match(IndentContent))
4361 const FormatToken *MinColumnToken = Line.Tokens.front().Tok;
4367 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
4369 MinColumnToken = PreviousToken;
4372 PreviousToken =
Node.Tok;
4375 if (
Node.Tok->NewlinesBefore > 0)
4376 MinColumnToken =
Node.Tok;
4378 if (PreviousToken && PreviousToken->
is(tok::l_brace))
4379 MinColumnToken = PreviousToken;
4385void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
4386 bool JustComments = Line->Tokens.empty();
4387 for (FormatToken *Tok : CommentsBeforeNextToken) {
4396 Tok->ContinuesLineCommentSection =
4398 if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
4402 if (NewlineBeforeNext && JustComments)
4404 CommentsBeforeNextToken.clear();
4407void UnwrappedLineParser::nextToken(
int LevelDifference) {
4410 flushComments(isOnNewLine(*FormatTok));
4411 pushToken(FormatTok);
4414 readToken(LevelDifference);
4416 readTokenWithJavaScriptASI();
4426 FormatTok->Tok.setKind(tok::r_brace);
4430void UnwrappedLineParser::distributeComments(
4431 const SmallVectorImpl<FormatToken *> &Comments,
4432 const FormatToken *NextTok) {
4451 if (Comments.empty())
4453 bool ShouldPushCommentsInCurrentLine =
true;
4454 bool HasTrailAlignedWithNextToken =
false;
4455 unsigned StartOfTrailAlignedWithNextToken = 0;
4458 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
4459 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
4460 HasTrailAlignedWithNextToken =
true;
4461 StartOfTrailAlignedWithNextToken = i;
4465 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
4466 FormatToken *FormatTok = Comments[i];
4467 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
4468 FormatTok->ContinuesLineCommentSection =
false;
4470 FormatTok->ContinuesLineCommentSection =
4473 if (!FormatTok->ContinuesLineCommentSection &&
4474 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
4475 ShouldPushCommentsInCurrentLine =
false;
4477 if (ShouldPushCommentsInCurrentLine)
4478 pushToken(FormatTok);
4480 CommentsBeforeNextToken.push_back(FormatTok);
4484void UnwrappedLineParser::readToken(
int LevelDifference) {
4485 SmallVector<FormatToken *, 1> Comments;
4486 bool PreviousWasComment =
false;
4487 bool FirstNonCommentOnLine =
false;
4489 FormatTok = Tokens->getNextToken();
4491 while (FormatTok->getType() == TT_ConflictStart ||
4492 FormatTok->getType() == TT_ConflictEnd ||
4493 FormatTok->getType() == TT_ConflictAlternative) {
4494 if (FormatTok->getType() == TT_ConflictStart)
4495 conditionalCompilationStart(
false);
4496 else if (FormatTok->getType() == TT_ConflictAlternative)
4497 conditionalCompilationAlternative();
4498 else if (FormatTok->getType() == TT_ConflictEnd)
4499 conditionalCompilationEnd();
4500 FormatTok = Tokens->getNextToken();
4501 FormatTok->MustBreakBefore =
true;
4504 auto IsFirstNonCommentOnLine = [](
bool FirstNonCommentOnLine,
4505 const FormatToken &Tok,
4506 bool PreviousWasComment) {
4507 auto IsFirstOnLine = [](
const FormatToken &Tok) {
4508 return Tok.HasUnescapedNewline || Tok.IsFirst;
4513 if (PreviousWasComment)
4514 return FirstNonCommentOnLine || IsFirstOnLine(Tok);
4515 return IsFirstOnLine(Tok);
4518 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4519 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4520 PreviousWasComment = FormatTok->is(tok::comment);
4522 while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
4525 FirstNonCommentOnLine) {
4526 distributeComments(Comments, FormatTok);
4530 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
4532 assert((LevelDifference >= 0 ||
4533 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
4534 "LevelDifference makes Line->Level negative");
4535 Line->Level += LevelDifference;
4540 PPBranchLevel > 0) {
4541 Line->Level += PPBranchLevel;
4543 flushComments(isOnNewLine(*FormatTok));
4545 PreviousWasComment = FormatTok->is(tok::comment);
4546 FirstNonCommentOnLine = IsFirstNonCommentOnLine(
4547 FirstNonCommentOnLine, *FormatTok, PreviousWasComment);
4550 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
4551 !Line->InPPDirective) {
4555 if (FormatTok->is(tok::identifier) &&
4556 Macros.
defined(FormatTok->TokenText) &&
4558 !Line->InPPDirective) {
4559 FormatToken *
ID = FormatTok;
4560 unsigned Position = Tokens->getPosition();
4564 auto PreCall = std::move(Line);
4565 Line.reset(
new UnwrappedLine);
4566 bool OldInExpansion = InExpansion;
4569 auto Args = parseMacroCall();
4570 InExpansion = OldInExpansion;
4571 assert(Line->Tokens.front().Tok == ID);
4573 auto UnexpandedLine = std::move(Line);
4575 Line = std::move(PreCall);
4578 llvm::dbgs() <<
"Macro call: " <<
ID->TokenText <<
"(";
4580 llvm::dbgs() <<
"(";
4581 for (
const auto &Arg : Args.value())
4582 for (
const auto &T : Arg)
4583 llvm::dbgs() << T->TokenText <<
" ";
4584 llvm::dbgs() <<
")";
4586 llvm::dbgs() <<
"\n";
4589 !Macros.
hasArity(
ID->TokenText, Args->size())) {
4595 LLVM_DEBUG(llvm::dbgs()
4596 <<
"Macro \"" <<
ID->TokenText
4597 <<
"\" not overloaded for arity " << Args->size()
4598 <<
"or not function-like, using object-like overload.");
4600 UnexpandedLine->Tokens.resize(1);
4601 Tokens->setPosition(Position);
4606 (Args && Macros.
hasArity(
ID->TokenText, Args->size()))) {
4609 Unexpanded[
ID] = std::move(UnexpandedLine);
4610 SmallVector<FormatToken *, 8> Expansion =
4611 Macros.
expand(ID, std::move(Args));
4612 if (!Expansion.empty())
4613 FormatTok = Tokens->insertTokens(Expansion);
4616 llvm::dbgs() <<
"Expanded: ";
4617 for (
const auto &T : Expansion)
4618 llvm::dbgs() << T->TokenText <<
" ";
4619 llvm::dbgs() <<
"\n";
4623 llvm::dbgs() <<
"Did not expand macro \"" <<
ID->TokenText
4624 <<
"\", because it was used ";
4626 llvm::dbgs() <<
"with " << Args->size();
4628 llvm::dbgs() <<
"without";
4629 llvm::dbgs() <<
" arguments, which doesn't match any definition.\n";
4631 Tokens->setPosition(Position);
4636 if (!FormatTok->is(tok::comment)) {
4637 distributeComments(Comments, FormatTok);
4642 Comments.push_back(FormatTok);
4645 distributeComments(Comments,
nullptr);
4650template <
typename Iterator>
4651void pushTokens(Iterator
Begin, Iterator End,
4653 for (
auto I =
Begin; I != End; ++I) {
4654 Into.push_back(I->Tok);
4655 for (
const auto &Child : I->Children)
4656 pushTokens(Child.Tokens.begin(), Child.Tokens.end(), Into);
4661std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
4662UnwrappedLineParser::parseMacroCall() {
4663 std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>> Args;
4664 assert(Line->Tokens.empty());
4666 if (!FormatTok->is(tok::l_paren))
4668 unsigned Position = Tokens->getPosition();
4669 FormatToken *Tok = FormatTok;
4672 auto ArgStart = std::prev(Line->Tokens.end());
4676 switch (FormatTok->Tok.getKind()) {
4681 case tok::r_paren: {
4687 Args->push_back({});
4688 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4697 Args->push_back({});
4698 pushTokens(std::next(ArgStart), Line->Tokens.end(), Args->back());
4700 ArgStart = std::prev(Line->Tokens.end());
4708 Line->Tokens.resize(1);
4709 Tokens->setPosition(Position);
4714void UnwrappedLineParser::pushToken(FormatToken *Tok) {
4715 Line->Tokens.push_back(UnwrappedLineNode(Tok));
4716 if (MustBreakBeforeNextToken) {
4717 Line->Tokens.back().Tok->MustBreakBefore =
true;
4718 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.