17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/raw_ostream.h"
23 #define DEBUG_TYPE "format-parser"
39 class ScopedDeclarationState {
41 ScopedDeclarationState(UnwrappedLine &
Line, std::vector<bool> &Stack,
42 bool MustBeDeclaration)
44 Line.MustBeDeclaration = MustBeDeclaration;
45 Stack.push_back(MustBeDeclaration);
47 ~ScopedDeclarationState() {
50 Line.MustBeDeclaration = Stack.back();
52 Line.MustBeDeclaration =
true;
57 std::vector<bool> &Stack;
60 static bool isLineComment(
const FormatToken &FormatTok) {
61 return FormatTok.is(tok::comment) && !FormatTok.TokenText.startswith(
"/*");
67 static bool continuesLineComment(
const FormatToken &FormatTok,
69 const FormatToken *MinColumnToken) {
72 unsigned MinContinueColumn =
73 MinColumnToken->OriginalColumn + (isLineComment(*MinColumnToken) ? 0 : 1);
74 return isLineComment(FormatTok) && FormatTok.NewlinesBefore == 1 &&
76 FormatTok.OriginalColumn >= MinContinueColumn;
79 class ScopedMacroState :
public FormatTokenSource {
81 ScopedMacroState(UnwrappedLine &
Line, FormatTokenSource *&TokenSource,
82 FormatToken *&ResetToken)
83 :
Line(
Line), TokenSource(TokenSource), ResetToken(ResetToken),
84 PreviousLineLevel(
Line.
Level), PreviousTokenSource(TokenSource),
85 Token(nullptr), PreviousToken(nullptr) {
86 FakeEOF.Tok.startToken();
90 Line.InPPDirective =
true;
93 ~ScopedMacroState()
override {
94 TokenSource = PreviousTokenSource;
96 Line.InPPDirective =
false;
97 Line.Level = PreviousLineLevel;
100 FormatToken *getNextToken()
override {
104 PreviousToken = Token;
105 Token = PreviousTokenSource->getNextToken();
111 unsigned getPosition()
override {
return PreviousTokenSource->getPosition(); }
113 FormatToken *setPosition(
unsigned Position)
override {
114 PreviousToken =
nullptr;
115 Token = PreviousTokenSource->setPosition(Position);
121 return Token && Token->HasUnescapedNewline &&
122 !continuesLineComment(*Token, PreviousToken,
128 FormatTokenSource *&TokenSource;
129 FormatToken *&ResetToken;
130 unsigned PreviousLineLevel;
131 FormatTokenSource *PreviousTokenSource;
134 FormatToken *PreviousToken;
142 bool SwitchToPreprocessorLines =
false)
144 if (SwitchToPreprocessorLines)
146 else if (!
Parser.Line->Tokens.empty())
147 Parser.CurrentLines = &
Parser.Line->Tokens.back().Children;
148 PreBlockLine = std::move(
Parser.Line);
149 Parser.Line = std::make_unique<UnwrappedLine>();
150 Parser.Line->Level = PreBlockLine->Level;
151 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
155 if (!
Parser.Line->Tokens.empty()) {
156 Parser.addUnwrappedLine();
158 assert(
Parser.Line->Tokens.empty());
159 Parser.Line = std::move(PreBlockLine);
160 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
161 Parser.MustBreakBeforeNextToken =
true;
162 Parser.CurrentLines = OriginalLines;
168 std::unique_ptr<UnwrappedLine> PreBlockLine;
177 Style.BraceWrapping.AfterControlStatement,
178 Style.BraceWrapping.IndentBraces) {}
180 bool WrapBrace,
bool IndentBrace)
181 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
183 Parser->addUnwrappedLine();
191 unsigned OldLineLevel;
196 class IndexedTokenSource :
public FormatTokenSource {
199 : Tokens(Tokens), Position(-1) {}
201 FormatToken *getNextToken()
override {
203 return Tokens[Position];
206 unsigned getPosition()
override {
207 assert(Position >= 0);
211 FormatToken *setPosition(
unsigned P)
override {
213 return Tokens[Position];
216 void reset() { Position = -1; }
219 ArrayRef<FormatToken *> Tokens;
227 unsigned FirstStartColumn,
231 CurrentLines(&Lines), Style(Style), Keywords(Keywords),
232 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
233 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
234 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
237 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn) {}
239 void UnwrappedLineParser::reset() {
241 IncludeGuard = Style.IndentPPDirectives == FormatStyle::PPDIS_None
244 IncludeGuardToken =
nullptr;
246 CommentsBeforeNextToken.clear();
248 MustBreakBeforeNextToken =
false;
249 PreprocessorDirectives.clear();
250 CurrentLines = &Lines;
251 DeclarationScopeStack.clear();
253 Line->FirstStartColumn = FirstStartColumn;
257 IndexedTokenSource TokenSource(AllTokens);
258 Line->FirstStartColumn = FirstStartColumn;
260 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
262 Tokens = &TokenSource;
270 if (IncludeGuard == IG_Found)
271 for (
auto &Line : Lines)
272 if (Line.InPPDirective && Line.Level > 0)
276 pushToken(FormatTok);
286 while (!PPLevelBranchIndex.empty() &&
287 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
288 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
289 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
291 if (!PPLevelBranchIndex.empty()) {
292 ++PPLevelBranchIndex.back();
293 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
294 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
296 }
while (!PPLevelBranchIndex.empty());
299 void UnwrappedLineParser::parseFile() {
302 bool MustBeDeclaration =
303 !Line->InPPDirective && Style.Language != FormatStyle::LK_JavaScript;
304 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
306 if (Style.Language == FormatStyle::LK_TextProto)
320 if (Style.Language == FormatStyle::LK_TextProto &&
321 !CommentsBeforeNextToken.empty())
327 void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
329 switch (FormatTok->Tok.getKind()) {
333 if (FormatTok->is(Keywords.
kw_where)) {
336 parseCSharpGenericTypeConstraint();
345 void UnwrappedLineParser::parseCSharpAttribute() {
346 int UnpairedSquareBrackets = 1;
348 switch (FormatTok->Tok.getKind()) {
351 --UnpairedSquareBrackets;
352 if (UnpairedSquareBrackets == 0) {
358 ++UnpairedSquareBrackets;
368 void UnwrappedLineParser::parseLevel(
bool HasOpeningBrace) {
369 bool SwitchLabelEncountered =
false;
372 if (FormatTok->getType() == TT_MacroBlockBegin) {
374 }
else if (FormatTok->getType() == TT_MacroBlockEnd) {
386 if (!FormatTok->is(TT_MacroBlockBegin) && tryToParseBracedList())
397 case tok::kw_default: {
402 }
while (Next && Next->is(tok::comment));
404 if (Next && Next->isNot(tok::colon)) {
407 parseStructuralElement();
414 if (Style.Language == FormatStyle::LK_JavaScript &&
415 Line->MustBeDeclaration) {
417 parseStructuralElement();
420 if (!SwitchLabelEncountered &&
421 (Style.IndentCaseLabels || (Line->InPPDirective && Line->Level == 1)))
423 SwitchLabelEncountered =
true;
424 parseStructuralElement();
427 if (Style.isCSharp()) {
429 parseCSharpAttribute();
434 parseStructuralElement();
440 void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
446 FormatToken *Tok = FormatTok;
447 const FormatToken *PrevTok = Tok->Previous;
451 SmallVector<FormatToken *, 8> LBraceStack;
452 assert(Tok->Tok.is(tok::l_brace));
455 FormatToken *NextTok;
456 unsigned ReadTokens = 0;
460 }
while (NextTok->is(tok::comment));
462 switch (Tok->Tok.getKind()) {
464 if (Style.Language == FormatStyle::LK_JavaScript && PrevTok) {
465 if (PrevTok->isOneOf(tok::colon, tok::less))
476 else if (PrevTok->is(tok::r_paren))
482 LBraceStack.push_back(Tok);
485 if (LBraceStack.empty())
488 bool ProbablyBracedList =
false;
489 if (Style.Language == FormatStyle::LK_Proto) {
490 ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
494 bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
495 NextTok->OriginalColumn == 0;
506 (Style.Language == FormatStyle::LK_JavaScript &&
507 NextTok->isOneOf(Keywords.
kw_of, Keywords.
kw_in,
509 (Style.isCpp() && NextTok->is(tok::l_paren)) ||
510 NextTok->isOneOf(tok::comma, tok::period, tok::colon,
511 tok::r_paren, tok::r_square, tok::l_brace,
513 (NextTok->is(tok::identifier) &&
514 !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace)) ||
515 (NextTok->is(tok::semi) &&
516 (!ExpectClassBody || LBraceStack.size() != 1)) ||
517 (NextTok->isBinaryOperator() && !NextIsObjCMethod);
518 if (!Style.isCSharp() && NextTok->is(tok::l_square)) {
523 ProbablyBracedList = NextTok->isNot(tok::l_square);
526 if (ProbablyBracedList) {
531 LBraceStack.back()->setBlockKind(
BK_Block);
534 LBraceStack.pop_back();
536 case tok::identifier:
537 if (!Tok->is(TT_StatementMacro))
548 if (!LBraceStack.empty() && LBraceStack.back()->is(
BK_Unknown))
549 LBraceStack.back()->setBlockKind(
BK_Block);
556 }
while (Tok->Tok.isNot(
tok::eof) && !LBraceStack.empty());
559 for (
unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
561 LBraceStack[i]->setBlockKind(
BK_Block);
570 seed ^= hasher(
v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
573 size_t UnwrappedLineParser::computePPHash()
const {
575 for (
const auto &i : PPStack) {
582 void UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
unsigned AddLevels,
584 assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) &&
585 "'{' or macro block token expected");
586 const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);
589 size_t PPStartHash = computePPHash();
591 unsigned InitialLevel = Line->Level;
592 nextToken(AddLevels);
594 if (MacroBlock && FormatTok->is(tok::l_paren))
597 size_t NbPreprocessorDirectives =
598 CurrentLines == &Lines ? PreprocessorDirectives.size() : 0;
600 size_t OpeningLineIndex =
601 CurrentLines->empty()
603 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
605 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
607 Line->Level += AddLevels;
613 if (MacroBlock ? !FormatTok->is(TT_MacroBlockEnd)
614 : !FormatTok->is(tok::r_brace)) {
615 Line->Level = InitialLevel;
620 size_t PPEndHash = computePPHash();
623 nextToken(-AddLevels);
625 if (MacroBlock && FormatTok->is(tok::l_paren))
628 if (FormatTok->is(tok::arrow)) {
632 parseStructuralElement();
635 if (MunchSemi && FormatTok->Tok.is(tok::semi))
638 Line->Level = InitialLevel;
640 if (PPStartHash == PPEndHash) {
641 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
644 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
645 CurrentLines->size() - 1;
653 if (
Line.Tokens.size() < 4)
655 auto I =
Line.Tokens.begin();
656 if (I->Tok->TokenText !=
"goog")
659 if (I->Tok->isNot(tok::period))
662 if (I->Tok->TokenText !=
"scope")
665 return I->Tok->is(tok::l_paren);
674 if (
Line.Tokens.size() < 3)
676 auto I =
Line.Tokens.begin();
677 if (I->Tok->isNot(tok::l_paren))
683 return I->Tok->is(tok::l_paren);
688 if (InitialToken.
isOneOf(tok::kw_namespace, TT_NamespaceMacro))
689 return Style.BraceWrapping.AfterNamespace;
690 if (InitialToken.
is(tok::kw_class))
691 return Style.BraceWrapping.AfterClass;
692 if (InitialToken.
is(tok::kw_union))
693 return Style.BraceWrapping.AfterUnion;
694 if (InitialToken.
is(tok::kw_struct))
695 return Style.BraceWrapping.AfterStruct;
699 void UnwrappedLineParser::parseChildBlock() {
703 bool SkipIndent = (Style.Language == FormatStyle::LK_JavaScript &&
706 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
708 Line->Level += SkipIndent ? 0 : 1;
710 flushComments(isOnNewLine(*FormatTok));
711 Line->Level -= SkipIndent ? 0 : 1;
716 void UnwrappedLineParser::parsePPDirective() {
717 assert(FormatTok->Tok.is(tok::hash) &&
"'#' expected");
718 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
722 if (!FormatTok->Tok.getIdentifierInfo()) {
727 switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {
753 void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
754 size_t Line = CurrentLines->size();
755 if (CurrentLines == &PreprocessorDirectives)
756 Line += Lines.size();
759 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable))
760 PPStack.push_back({PP_Unreachable, Line});
762 PPStack.push_back({PP_Conditional, Line});
765 void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
767 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
768 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
769 PPLevelBranchIndex.push_back(0);
770 PPLevelBranchCount.push_back(0);
772 PPChainBranchIndex.push(0);
773 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
774 conditionalCompilationCondition(Unreachable || Skip);
777 void UnwrappedLineParser::conditionalCompilationAlternative() {
778 if (!PPStack.empty())
780 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
781 if (!PPChainBranchIndex.empty())
782 ++PPChainBranchIndex.top();
783 conditionalCompilationCondition(
784 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
785 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
788 void UnwrappedLineParser::conditionalCompilationEnd() {
789 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
790 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
791 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel]) {
792 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
796 if (PPBranchLevel > -1)
798 if (!PPChainBranchIndex.empty())
799 PPChainBranchIndex.pop();
800 if (!PPStack.empty())
804 void UnwrappedLineParser::parsePPIf(
bool IfDef) {
807 bool Unreachable =
false;
808 if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText ==
"0"))
810 if (IfDef && !IfNDef && FormatTok->TokenText ==
"SWIG")
812 conditionalCompilationStart(Unreachable);
813 FormatToken *IfCondition = FormatTok;
816 bool MaybeIncludeGuard = IfNDef;
817 if (IncludeGuard == IG_Inited && MaybeIncludeGuard)
818 for (
auto &Line : Lines) {
819 if (!Line.Tokens.front().Tok->is(tok::comment)) {
820 MaybeIncludeGuard =
false;
821 IncludeGuard = IG_Rejected;
828 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
829 IncludeGuard = IG_IfNdefed;
830 IncludeGuardToken = IfCondition;
834 void UnwrappedLineParser::parsePPElse() {
836 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
837 IncludeGuard = IG_Rejected;
838 conditionalCompilationAlternative();
839 if (PPBranchLevel > -1)
845 void UnwrappedLineParser::parsePPElIf() { parsePPElse(); }
847 void UnwrappedLineParser::parsePPEndIf() {
848 conditionalCompilationEnd();
853 FormatToken *PeekNext = AllTokens[TokenPosition];
854 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 &&
856 Style.IndentPPDirectives != FormatStyle::PPDIS_None)
857 IncludeGuard = IG_Found;
860 void UnwrappedLineParser::parsePPDefine() {
863 if (!FormatTok->Tok.getIdentifierInfo()) {
864 IncludeGuard = IG_Rejected;
865 IncludeGuardToken =
nullptr;
870 if (IncludeGuard == IG_IfNdefed &&
871 IncludeGuardToken->
TokenText == FormatTok->TokenText) {
872 IncludeGuard = IG_Defined;
873 IncludeGuardToken =
nullptr;
874 for (
auto &Line : Lines) {
875 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
876 IncludeGuard = IG_Rejected;
883 if (FormatTok->Tok.getKind() == tok::l_paren &&
884 FormatTok->WhitespaceRange.getBegin() ==
885 FormatTok->WhitespaceRange.getEnd()) {
888 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
889 Line->Level += PPBranchLevel + 1;
901 void UnwrappedLineParser::parsePPUnknown() {
905 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
906 Line->Level += PPBranchLevel + 1;
916 return Tok.
isNot(tok::semi) && Tok.
isNot(tok::l_brace) &&
917 Tok.
isNot(TT_AttributeSquare) &&
920 Tok.
isNot(tok::period) && Tok.
isNot(tok::periodstar) &&
921 Tok.
isNot(tok::arrow) && Tok.
isNot(tok::arrowstar) &&
922 Tok.
isNot(tok::less) && Tok.
isNot(tok::greater) &&
923 Tok.
isNot(tok::slash) && Tok.
isNot(tok::percent) &&
924 Tok.
isNot(tok::lessless) && Tok.
isNot(tok::greatergreater) &&
925 Tok.
isNot(tok::equal) && Tok.
isNot(tok::plusequal) &&
926 Tok.
isNot(tok::minusequal) && Tok.
isNot(tok::starequal) &&
927 Tok.
isNot(tok::slashequal) && Tok.
isNot(tok::percentequal) &&
928 Tok.
isNot(tok::ampequal) && Tok.
isNot(tok::pipeequal) &&
929 Tok.
isNot(tok::caretequal) && Tok.
isNot(tok::greatergreaterequal) &&
930 Tok.
isNot(tok::lesslessequal) &&
934 Tok.
isNot(tok::colon) &&
936 Tok.
isNot(tok::kw_noexcept);
942 return FormatTok->
is(tok::identifier) &&
957 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
968 tok::kw_if, tok::kw_else,
970 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
972 tok::kw_switch, tok::kw_case,
974 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
976 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
989 void UnwrappedLineParser::readTokenWithJavaScriptASI() {
992 FormatToken *Next = FormatTok;
995 CommentsBeforeNextToken.empty()
996 ? Next->NewlinesBefore == 0
997 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
1002 bool PreviousStartsTemplateExpr =
1004 if (PreviousMustBeValue ||
Previous->is(tok::r_paren)) {
1007 bool HasAt = std::find_if(Line->Tokens.begin(), Line->Tokens.end(),
1008 [](UnwrappedLineNode &LineNode) {
1009 return LineNode.Tok->is(tok::at);
1010 }) != Line->Tokens.end();
1014 if (Next->is(tok::exclaim) && PreviousMustBeValue)
1015 return addUnwrappedLine();
1017 bool NextEndsTemplateExpr =
1018 Next->is(TT_TemplateString) && Next->TokenText.startswith(
"}");
1019 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
1020 (PreviousMustBeValue ||
1021 Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
1023 return addUnwrappedLine();
1024 if ((PreviousMustBeValue ||
Previous->is(tok::r_paren)) &&
1026 return addUnwrappedLine();
1029 void UnwrappedLineParser::parseStructuralElement() {
1030 assert(!FormatTok->is(tok::l_brace));
1031 if (Style.Language == FormatStyle::LK_TableGen &&
1034 if (FormatTok->is(tok::string_literal))
1039 switch (FormatTok->Tok.getKind()) {
1042 if (FormatTok->is(tok::l_brace)) {
1043 FormatTok->setType(TT_InlineASMBrace);
1045 while (FormatTok && FormatTok->isNot(
tok::eof)) {
1046 if (FormatTok->is(tok::r_brace)) {
1047 FormatTok->setType(TT_InlineASMBrace);
1052 FormatTok->Finalized =
true;
1057 case tok::kw_namespace:
1060 case tok::kw_public:
1061 case tok::kw_protected:
1062 case tok::kw_private:
1063 if (Style.Language == FormatStyle::LK_Java ||
1064 Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp())
1067 parseAccessSpecifier();
1070 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1077 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1080 parseForOrWhileLoop();
1083 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1088 case tok::kw_switch:
1089 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1094 case tok::kw_default:
1095 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1099 if (FormatTok->is(tok::colon)) {
1106 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1113 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1118 case tok::kw_extern:
1120 if (FormatTok->Tok.is(tok::string_literal)) {
1122 if (FormatTok->Tok.is(tok::l_brace)) {
1123 if (!Style.IndentExternBlock) {
1124 if (Style.BraceWrapping.AfterExternBlock) {
1127 unsigned AddLevels = Style.BraceWrapping.AfterExternBlock ? 1u : 0u;
1128 parseBlock(
true, AddLevels);
1130 unsigned AddLevels =
1131 Style.IndentExternBlock == FormatStyle::IEBS_Indent ? 1u : 0u;
1132 parseBlock(
true, AddLevels);
1139 case tok::kw_export:
1140 if (Style.Language == FormatStyle::LK_JavaScript) {
1141 parseJavaScriptEs6ImportExport();
1148 case tok::kw_inline:
1150 if (FormatTok->Tok.is(tok::kw_namespace)) {
1155 case tok::identifier:
1156 if (FormatTok->is(TT_ForEachMacro)) {
1157 parseForOrWhileLoop();
1160 if (FormatTok->is(TT_MacroBlockBegin)) {
1161 parseBlock(
false, 1u,
1165 if (FormatTok->is(Keywords.
kw_import)) {
1166 if (Style.Language == FormatStyle::LK_JavaScript) {
1167 parseJavaScriptEs6ImportExport();
1170 if (Style.Language == FormatStyle::LK_Proto) {
1172 if (FormatTok->is(tok::kw_public))
1174 if (!FormatTok->is(tok::string_literal))
1177 if (FormatTok->is(tok::semi))
1183 if (Style.isCpp() &&
1187 if (FormatTok->is(tok::colon)) {
1193 if (Style.isCpp() && FormatTok->is(TT_StatementMacro)) {
1194 parseStatementMacro();
1197 if (Style.isCpp() && FormatTok->is(TT_NamespaceMacro)) {
1207 const FormatToken *
Previous = FormatTok->Previous;
1208 switch (FormatTok->Tok.getKind()) {
1211 if (FormatTok->Tok.is(tok::l_brace)) {
1215 }
else if (Style.Language == FormatStyle::LK_Java &&
1220 switch (FormatTok->Tok.getObjCKeywordID()) {
1221 case tok::objc_public:
1222 case tok::objc_protected:
1223 case tok::objc_package:
1224 case tok::objc_private:
1225 return parseAccessSpecifier();
1226 case tok::objc_interface:
1227 case tok::objc_implementation:
1228 return parseObjCInterfaceOrImplementation();
1229 case tok::objc_protocol:
1230 if (parseObjCProtocol())
1235 case tok::objc_optional:
1236 case tok::objc_required:
1240 case tok::objc_autoreleasepool:
1242 if (FormatTok->Tok.is(tok::l_brace)) {
1243 if (Style.BraceWrapping.AfterControlStatement ==
1244 FormatStyle::BWACS_Always)
1250 case tok::objc_synchronized:
1252 if (FormatTok->Tok.is(tok::l_paren))
1255 if (FormatTok->Tok.is(tok::l_brace)) {
1256 if (Style.BraceWrapping.AfterControlStatement ==
1257 FormatStyle::BWACS_Always)
1272 case tok::kw_concept:
1275 case tok::kw_requires:
1290 if (!Style.isCpp()) {
1295 case tok::kw_typedef:
1303 case tok::kw_struct:
1310 if (Style.Language == FormatStyle::LK_Java ||
1311 Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
1312 if (FormatTok->is(tok::semi))
1321 if (Style.Language == FormatStyle::LK_Java && FormatTok &&
1322 FormatTok->is(tok::kw_class))
1324 if (Style.Language == FormatStyle::LK_JavaScript && FormatTok &&
1325 FormatTok->Tok.getIdentifierInfo())
1340 case tok::kw_operator:
1342 if (FormatTok->isBinaryOperator())
1347 if (FormatTok->Tok.isAnyIdentifier() ||
1348 FormatTok->isSimpleTypeSpecifier())
1350 if (FormatTok->is(tok::l_paren))
1352 if (FormatTok->is(tok::l_brace))
1356 if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
1361 if (Style.BraceWrapping.AfterFunction)
1363 FormatTok->setType(TT_FunctionLBrace);
1372 if (Style.Language == FormatStyle::LK_JavaScript &&
1373 Line->MustBeDeclaration) {
1379 if (Style.BraceWrapping.AfterFunction)
1383 case tok::identifier: {
1384 if (Style.isCSharp() && FormatTok->is(Keywords.
kw_where) &&
1385 Line->MustBeDeclaration) {
1387 parseCSharpGenericTypeConstraint();
1390 if (FormatTok->is(TT_MacroBlockEnd)) {
1399 size_t TokenCount = Line->Tokens.size();
1400 if (Style.Language == FormatStyle::LK_JavaScript &&
1402 (TokenCount > 1 || (TokenCount == 1 && !Line->Tokens.front().Tok->is(
1404 tryToParseJSFunction();
1407 if ((Style.Language == FormatStyle::LK_JavaScript ||
1408 Style.Language == FormatStyle::LK_Java) &&
1410 if (Style.Language == FormatStyle::LK_JavaScript) {
1428 if (Style.isCpp() && FormatTok->is(TT_StatementMacro)) {
1429 parseStatementMacro();
1434 StringRef
Text = FormatTok->TokenText;
1439 if (Style.Language == FormatStyle::LK_JavaScript)
1442 TokenCount = Line->Tokens.size();
1443 if (TokenCount == 1 ||
1444 (TokenCount == 2 && Line->Tokens.front().Tok->is(tok::comment))) {
1445 if (FormatTok->Tok.is(tok::colon) && !Line->MustBeDeclaration) {
1446 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1447 parseLabel(!Style.IndentGotoLabels);
1452 bool FunctionLike = FormatTok->is(tok::l_paren);
1456 bool FollowedByNewline =
1457 CommentsBeforeNextToken.empty()
1458 ? FormatTok->NewlinesBefore > 0
1459 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
1461 if (FollowedByNewline && (
Text.size() >= 5 || FunctionLike) &&
1473 if (FormatTok->is(TT_JsFatArrow)) {
1475 if (FormatTok->is(tok::l_brace)) {
1477 if (Style.isCSharp() && Style.BraceWrapping.AfterFunction ==
true) {
1479 FormatTok->MustBreakBefore =
true;
1487 if (FormatTok->Tok.is(tok::l_brace)) {
1491 if (Style.isCSharp())
1495 }
else if (Style.Language == FormatStyle::LK_Proto &&
1496 FormatTok->Tok.is(tok::less)) {
1498 parseBracedList(
false,
false,
1515 bool UnwrappedLineParser::tryToParsePropertyAccessor() {
1516 assert(FormatTok->is(tok::l_brace));
1517 if (!Style.isCSharp())
1520 if (FormatTok->Previous->isNot(tok::identifier))
1528 unsigned int StoredPosition = Tokens->
getPosition();
1534 bool HasGetOrSet =
false;
1535 bool IsTrivialPropertyAccessor =
true;
1537 if (Tok->isOneOf(tok::semi, tok::kw_public, tok::kw_private,
1545 if (Tok->isNot(tok::r_brace))
1546 IsTrivialPropertyAccessor =
false;
1558 if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction ==
true)
1562 switch (FormatTok->Tok.getKind()) {
1565 if (FormatTok->is(tok::equal)) {
1566 while (!eof() && FormatTok->isNot(tok::semi))
1579 if (FormatTok->is(TT_JsFatArrow)) {
1583 }
while (!eof() && FormatTok->isNot(tok::semi));
1592 if (FormatTok->isOneOf(Keywords.
kw_get, Keywords.
kw_set) &&
1593 !IsTrivialPropertyAccessor) {
1605 bool UnwrappedLineParser::tryToParseLambda() {
1606 if (!Style.isCpp()) {
1610 assert(FormatTok->is(tok::l_square));
1611 FormatToken &LSquare = *FormatTok;
1612 if (!tryToParseLambdaIntroducer())
1615 bool SeenArrow =
false;
1617 while (FormatTok->isNot(tok::l_brace)) {
1618 if (FormatTok->isSimpleTypeSpecifier()) {
1622 switch (FormatTok->Tok.getKind()) {
1634 case tok::identifier:
1635 case tok::numeric_constant:
1636 case tok::coloncolon:
1638 case tok::kw_mutable:
1639 case tok::kw_noexcept:
1640 case tok::kw_template:
1641 case tok::kw_typename:
1669 case tok::equalequal:
1670 case tok::exclaimequal:
1671 case tok::greaterequal:
1672 case tok::lessequal:
1687 FormatTok->setType(TT_LambdaArrow);
1695 FormatTok->setType(TT_LambdaLBrace);
1696 LSquare.setType(TT_LambdaLSquare);
1701 bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
1702 const FormatToken *
Previous = FormatTok->Previous;
1704 (
Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
1705 tok::kw_delete, tok::l_square) ||
1706 FormatTok->isCppStructuredBinding(Style) ||
Previous->closesScope() ||
1707 Previous->isSimpleTypeSpecifier())) {
1712 if (FormatTok->is(tok::l_square)) {
1719 void UnwrappedLineParser::tryToParseJSFunction() {
1722 if (FormatTok->is(Keywords.
kw_async))
1728 if (FormatTok->is(tok::star)) {
1729 FormatTok->setType(TT_OverloadedOperator);
1734 if (FormatTok->is(tok::identifier))
1737 if (FormatTok->isNot(tok::l_paren))
1743 if (FormatTok->is(tok::colon)) {
1749 if (FormatTok->is(tok::l_brace))
1750 tryToParseBracedList();
1752 while (!FormatTok->isOneOf(tok::l_brace, tok::semi) && !eof())
1756 if (FormatTok->is(tok::semi))
1762 bool UnwrappedLineParser::tryToParseBracedList() {
1764 calculateBraceTypes();
1773 bool UnwrappedLineParser::parseBracedList(
bool ContinueOnSemicolons,
1776 bool HasError =
false;
1781 if (Style.isCSharp()) {
1782 if (FormatTok->is(TT_JsFatArrow)) {
1786 if (FormatTok->is(tok::l_brace)) {
1792 if (Style.Language == FormatStyle::LK_JavaScript) {
1795 tryToParseJSFunction();
1798 if (FormatTok->is(TT_JsFatArrow)) {
1802 if (FormatTok->is(tok::l_brace)) {
1807 if (FormatTok->is(tok::l_brace)) {
1809 if (tryToParseBracedList())
1814 if (FormatTok->Tok.getKind() == ClosingBraceKind) {
1815 if (IsEnum && !Style.AllowShortEnumsOnASingleLine)
1820 switch (FormatTok->Tok.getKind()) {
1823 if (FormatTok->is(tok::l_brace)) {
1828 if (Style.isCSharp())
1837 if (Style.Language == FormatStyle::LK_JavaScript) {
1838 if (FormatTok->is(tok::l_brace))
1851 if (Style.Language == FormatStyle::LK_Proto) {
1853 parseBracedList(
false,
false,
1864 if (Style.Language == FormatStyle::LK_JavaScript) {
1869 if (!ContinueOnSemicolons)
1875 if (IsEnum && !Style.AllowShortEnumsOnASingleLine)
1886 void UnwrappedLineParser::parseParens() {
1887 assert(FormatTok->Tok.is(tok::l_paren) &&
"'(' expected.");
1890 switch (FormatTok->Tok.getKind()) {
1893 if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_brace))
1906 if (!tryToParseBracedList())
1911 if (FormatTok->Tok.is(tok::l_brace)) {
1917 if (Style.Language == FormatStyle::LK_JavaScript)
1922 case tok::identifier:
1923 if (Style.Language == FormatStyle::LK_JavaScript &&
1926 tryToParseJSFunction();
1937 void UnwrappedLineParser::parseSquare(
bool LambdaIntroducer) {
1938 if (!LambdaIntroducer) {
1939 assert(FormatTok->Tok.is(tok::l_square) &&
"'[' expected.");
1940 if (tryToParseLambda())
1944 switch (FormatTok->Tok.getKind()) {
1957 case tok::l_brace: {
1958 if (!tryToParseBracedList())
1964 if (FormatTok->Tok.is(tok::l_brace)) {
1976 void UnwrappedLineParser::parseIfThenElse() {
1977 assert(FormatTok->Tok.is(tok::kw_if) &&
"'if' expected");
1979 if (FormatTok->Tok.isOneOf(tok::kw_constexpr, tok::identifier))
1981 if (FormatTok->Tok.is(tok::l_paren))
1984 if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute())
1986 bool NeedsUnwrappedLine =
false;
1987 if (FormatTok->Tok.is(tok::l_brace)) {
1990 if (Style.BraceWrapping.BeforeElse)
1993 NeedsUnwrappedLine =
true;
1997 parseStructuralElement();
2000 if (FormatTok->Tok.is(tok::kw_else)) {
2003 if (FormatTok->Tok.is(tok::l_square) && tryToParseSimpleAttribute())
2005 if (FormatTok->Tok.is(tok::l_brace)) {
2009 }
else if (FormatTok->Tok.is(tok::kw_if)) {
2014 parseStructuralElement();
2019 }
else if (NeedsUnwrappedLine) {
2024 void UnwrappedLineParser::parseTryCatch() {
2025 assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
2027 bool NeedsUnwrappedLine =
false;
2028 if (FormatTok->is(tok::colon)) {
2034 while (FormatTok->is(tok::comma))
2037 while (FormatTok->is(tok::identifier)) {
2039 if (FormatTok->is(tok::l_paren))
2041 if (FormatTok->Previous && FormatTok->Previous->is(tok::identifier) &&
2042 FormatTok->is(tok::l_brace)) {
2045 }
while (!FormatTok->is(tok::r_brace));
2051 while (FormatTok->is(tok::comma))
2056 if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_paren)) {
2059 if (FormatTok->is(tok::l_brace)) {
2062 if (Style.BraceWrapping.BeforeCatch) {
2065 NeedsUnwrappedLine =
true;
2067 }
else if (!FormatTok->is(tok::kw_catch)) {
2073 parseStructuralElement();
2077 if (FormatTok->is(tok::at))
2079 if (!(FormatTok->isOneOf(tok::kw_catch, Keywords.
kw___except,
2080 tok::kw___finally) ||
2081 ((Style.Language == FormatStyle::LK_Java ||
2082 Style.Language == FormatStyle::LK_JavaScript) &&
2084 (FormatTok->Tok.isObjCAtKeyword(tok::objc_catch) ||
2085 FormatTok->Tok.isObjCAtKeyword(tok::objc_finally))))
2088 while (FormatTok->isNot(tok::l_brace)) {
2089 if (FormatTok->is(tok::l_paren)) {
2093 if (FormatTok->isOneOf(tok::semi, tok::r_brace,
tok::eof))
2097 NeedsUnwrappedLine =
false;
2100 if (Style.BraceWrapping.BeforeCatch)
2103 NeedsUnwrappedLine =
true;
2105 if (NeedsUnwrappedLine)
2109 void UnwrappedLineParser::parseNamespace() {
2110 assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
2111 "'namespace' expected");
2113 const FormatToken &InitialToken = *FormatTok;
2115 if (InitialToken.is(TT_NamespaceMacro)) {
2118 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
2120 if (FormatTok->is(tok::l_square))
2126 if (FormatTok->Tok.is(tok::l_brace)) {
2130 unsigned AddLevels =
2131 Style.NamespaceIndentation == FormatStyle::NI_All ||
2132 (Style.NamespaceIndentation == FormatStyle::NI_Inner &&
2133 DeclarationScopeStack.size() > 1)
2136 parseBlock(
true, AddLevels);
2139 if (FormatTok->Tok.is(tok::semi))
2146 void UnwrappedLineParser::parseNew() {
2147 assert(FormatTok->is(tok::kw_new) &&
"'new' expected");
2150 if (Style.isCSharp()) {
2152 if (FormatTok->is(tok::l_brace))
2155 if (FormatTok->isOneOf(tok::semi, tok::comma))
2162 if (Style.Language != FormatStyle::LK_Java)
2168 if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))
2172 if (FormatTok->is(tok::l_paren)) {
2176 if (FormatTok->is(tok::l_brace))
2184 void UnwrappedLineParser::parseForOrWhileLoop() {
2185 assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
2186 "'for', 'while' or foreach macro expected");
2189 if (Style.Language == FormatStyle::LK_JavaScript &&
2192 if (FormatTok->Tok.is(tok::l_paren))
2194 if (FormatTok->Tok.is(tok::l_brace)) {
2201 parseStructuralElement();
2206 void UnwrappedLineParser::parseDoWhile() {
2207 assert(FormatTok->Tok.is(tok::kw_do) &&
"'do' expected");
2209 if (FormatTok->Tok.is(tok::l_brace)) {
2212 if (Style.BraceWrapping.BeforeWhile)
2217 parseStructuralElement();
2222 if (!FormatTok->Tok.is(tok::kw_while)) {
2228 parseStructuralElement();
2231 void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
2233 unsigned OldLineLevel = Line->Level;
2234 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
2239 bool RemoveWhitesmithsCaseIndent =
2240 (!Style.IndentCaseBlocks &&
2241 Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths);
2243 if (RemoveWhitesmithsCaseIndent)
2246 if (!Style.IndentCaseBlocks && CommentsBeforeNextToken.empty() &&
2247 FormatTok->Tok.is(tok::l_brace)) {
2250 this, Line->Level, Style.BraceWrapping.AfterCaseLabel,
2251 Style.BraceWrapping.IndentBraces || RemoveWhitesmithsCaseIndent);
2253 if (FormatTok->Tok.is(tok::kw_break)) {
2254 if (Style.BraceWrapping.AfterControlStatement ==
2255 FormatStyle::BWACS_Always) {
2257 if (RemoveWhitesmithsCaseIndent) {
2261 parseStructuralElement();
2265 if (FormatTok->is(tok::semi))
2269 Line->Level = OldLineLevel;
2270 if (FormatTok->isNot(tok::l_brace)) {
2271 parseStructuralElement();
2276 void UnwrappedLineParser::parseCaseLabel() {
2277 assert(FormatTok->Tok.is(tok::kw_case) &&
"'case' expected");
2282 }
while (!eof() && !FormatTok->Tok.is(tok::colon));
2286 void UnwrappedLineParser::parseSwitch() {
2287 assert(FormatTok->Tok.is(tok::kw_switch) &&
"'switch' expected");
2289 if (FormatTok->Tok.is(tok::l_paren))
2291 if (FormatTok->Tok.is(tok::l_brace)) {
2298 parseStructuralElement();
2303 void UnwrappedLineParser::parseAccessSpecifier() {
2309 if (FormatTok->Tok.is(tok::colon))
2314 void UnwrappedLineParser::parseConcept() {
2315 assert(FormatTok->Tok.is(tok::kw_concept) &&
"'concept' expected");
2317 if (!FormatTok->Tok.is(tok::identifier))
2320 if (!FormatTok->Tok.is(tok::equal))
2323 if (FormatTok->Tok.is(tok::kw_requires)) {
2325 parseRequiresExpression(Line->Level);
2327 parseConstraintExpression(Line->Level);
2331 void UnwrappedLineParser::parseRequiresExpression(
unsigned int OriginalLevel) {
2333 if (FormatTok->Tok.is(tok::l_paren)) {
2335 if (Style.IndentRequires && OriginalLevel != Line->Level) {
2341 if (FormatTok->Tok.is(tok::l_brace)) {
2342 if (Style.BraceWrapping.AfterFunction)
2344 FormatTok->setType(TT_FunctionLBrace);
2348 parseConstraintExpression(OriginalLevel);
2352 void UnwrappedLineParser::parseConstraintExpression(
2353 unsigned int OriginalLevel) {
2356 FormatTok->isOneOf(tok::identifier, tok::kw_requires, tok::coloncolon)) {
2358 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::less,
2359 tok::greater, tok::comma, tok::ellipsis)) {
2360 if (FormatTok->Tok.is(tok::less)) {
2361 parseBracedList(
false,
false,
2367 if (FormatTok->Tok.is(tok::kw_requires)) {
2368 parseRequiresExpression(OriginalLevel);
2370 if (FormatTok->Tok.is(tok::less)) {
2371 parseBracedList(
false,
false,
2375 if (FormatTok->Tok.is(tok::l_paren)) {
2378 if (FormatTok->Tok.is(tok::l_brace)) {
2379 if (Style.BraceWrapping.AfterFunction)
2381 FormatTok->setType(TT_FunctionLBrace);
2384 if (FormatTok->Tok.is(tok::semi)) {
2389 if (FormatTok->Tok.is(tok::colon)) {
2392 if (!FormatTok->Tok.isOneOf(tok::ampamp, tok::pipepipe)) {
2393 if (FormatTok->Previous &&
2394 !FormatTok->Previous->isOneOf(tok::identifier, tok::kw_requires,
2398 if (Style.IndentRequires && OriginalLevel != Line->Level) {
2403 FormatTok->setType(TT_ConstraintJunctions);
2410 void UnwrappedLineParser::parseRequires() {
2411 assert(FormatTok->Tok.is(tok::kw_requires) &&
"'requires' expected");
2413 unsigned OriginalLevel = Line->Level;
2414 if (FormatTok->Previous && FormatTok->Previous->is(tok::greater)) {
2416 if (Style.IndentRequires) {
2422 parseRequiresExpression(OriginalLevel);
2425 bool UnwrappedLineParser::parseEnum() {
2427 if (FormatTok->Tok.is(tok::kw_enum))
2433 if (Style.Language == FormatStyle::LK_JavaScript &&
2434 FormatTok->isOneOf(tok::colon, tok::question))
2438 if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))
2442 if (FormatTok->Tok.is(tok::kw_class) || FormatTok->Tok.is(tok::kw_struct))
2445 while (FormatTok->Tok.getIdentifierInfo() ||
2446 FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
2447 tok::greater, tok::comma, tok::question)) {
2450 if (FormatTok->is(tok::l_paren))
2452 if (FormatTok->is(tok::identifier)) {
2456 if (Style.isCpp() && FormatTok->is(tok::identifier))
2462 if (FormatTok->isNot(tok::l_brace))
2466 if (Style.Language == FormatStyle::LK_Java) {
2468 parseJavaEnumBody();
2471 if (Style.Language == FormatStyle::LK_Proto) {
2476 if (!Style.AllowShortEnumsOnASingleLine)
2480 if (!Style.AllowShortEnumsOnASingleLine) {
2484 bool HasError = !parseBracedList(
true,
2486 if (!Style.AllowShortEnumsOnASingleLine)
2489 if (FormatTok->is(tok::semi))
2503 class ScopedTokenPosition {
2504 unsigned StoredPosition;
2505 FormatTokenSource *Tokens;
2508 ScopedTokenPosition(FormatTokenSource *Tokens) : Tokens(Tokens) {
2509 assert(Tokens &&
"Tokens expected to not be null");
2510 StoredPosition = Tokens->getPosition();
2513 ~ScopedTokenPosition() { Tokens->setPosition(StoredPosition); }
2519 bool UnwrappedLineParser::tryToParseSimpleAttribute() {
2520 ScopedTokenPosition AutoPosition(Tokens);
2521 FormatToken *Tok = Tokens->getNextToken();
2523 if (Tok && !Tok->is(tok::l_square)) {
2529 if (Tok->is(tok::r_square)) {
2532 Tok = Tokens->getNextToken();
2534 Tok = Tokens->getNextToken();
2535 if (Tok && !Tok->is(tok::r_square)) {
2538 Tok = Tokens->getNextToken();
2539 if (Tok && Tok->is(tok::semi)) {
2545 void UnwrappedLineParser::parseJavaEnumBody() {
2549 unsigned StoredPosition = Tokens->getPosition();
2550 bool IsSimple =
true;
2551 FormatToken *Tok = Tokens->getNextToken();
2553 if (Tok->is(tok::r_brace))
2555 if (Tok->isOneOf(tok::l_brace, tok::semi)) {
2561 Tok = Tokens->getNextToken();
2563 FormatTok = Tokens->setPosition(StoredPosition);
2580 if (FormatTok->is(tok::l_brace)) {
2582 parseBlock(
true, 1u,
2584 }
else if (FormatTok->is(tok::l_paren)) {
2586 }
else if (FormatTok->is(tok::comma)) {
2589 }
else if (FormatTok->is(tok::semi)) {
2593 }
else if (FormatTok->is(tok::r_brace)) {
2608 void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
2609 const FormatToken &InitialToken = *FormatTok;
2615 while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
2616 tok::kw___attribute, tok::kw___declspec,
2617 tok::kw_alignas, tok::l_square, tok::r_square) ||
2618 ((Style.Language == FormatStyle::LK_Java ||
2619 Style.Language == FormatStyle::LK_JavaScript) &&
2620 FormatTok->isOneOf(tok::period, tok::comma))) {
2621 if (Style.Language == FormatStyle::LK_JavaScript &&
2627 if (FormatTok->is(tok::l_brace)) {
2628 tryToParseBracedList();
2632 bool IsNonMacroIdentifier =
2633 FormatTok->is(tok::identifier) &&
2634 FormatTok->TokenText != FormatTok->TokenText.upper();
2637 if (!IsNonMacroIdentifier) {
2638 if (FormatTok->Tok.is(tok::l_paren)) {
2640 }
else if (FormatTok->is(TT_AttributeSquare)) {
2643 if (FormatTok->Next && FormatTok->is(TT_AttributeSquare))
2659 if (FormatTok->isOneOf(tok::colon, tok::less)) {
2661 if (FormatTok->is(tok::l_brace)) {
2662 calculateBraceTypes(
true);
2663 if (!tryToParseBracedList())
2666 if (FormatTok->Tok.is(tok::semi))
2668 if (Style.isCSharp() && FormatTok->is(Keywords.
kw_where)) {
2671 parseCSharpGenericTypeConstraint();
2677 if (FormatTok->Tok.is(tok::l_brace)) {
2684 unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;
2685 parseBlock(
true, AddLevels,
false);
2693 void UnwrappedLineParser::parseObjCMethod() {
2694 assert(FormatTok->Tok.isOneOf(tok::l_paren, tok::identifier) &&
2695 "'(' or identifier expected.");
2697 if (FormatTok->Tok.is(tok::semi)) {
2701 }
else if (FormatTok->Tok.is(tok::l_brace)) {
2702 if (Style.BraceWrapping.AfterFunction)
2713 void UnwrappedLineParser::parseObjCProtocolList() {
2714 assert(FormatTok->Tok.is(tok::less) &&
"'<' expected.");
2718 if (FormatTok->isOneOf(tok::semi, tok::l_brace) ||
2719 FormatTok->Tok.isObjCAtKeyword(tok::objc_end))
2721 }
while (!eof() && FormatTok->Tok.isNot(tok::greater));
2725 void UnwrappedLineParser::parseObjCUntilAtEnd() {
2727 if (FormatTok->Tok.isObjCAtKeyword(tok::objc_end)) {
2732 if (FormatTok->is(tok::l_brace)) {
2736 }
else if (FormatTok->is(tok::r_brace)) {
2740 }
else if (FormatTok->isOneOf(tok::minus, tok::plus)) {
2744 parseStructuralElement();
2749 void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
2750 assert(FormatTok->Tok.getObjCKeywordID() == tok::objc_interface ||
2751 FormatTok->Tok.getObjCKeywordID() == tok::objc_implementation);
2757 if (FormatTok->Tok.is(tok::less)) {
2758 parseObjCLightweightGenerics();
2760 if (FormatTok->Tok.is(tok::colon)) {
2764 if (FormatTok->Tok.is(tok::less)) {
2765 parseObjCLightweightGenerics();
2767 }
else if (FormatTok->Tok.is(tok::l_paren))
2771 if (FormatTok->Tok.is(tok::less))
2772 parseObjCProtocolList();
2774 if (FormatTok->Tok.is(tok::l_brace)) {
2775 if (Style.BraceWrapping.AfterObjCDeclaration)
2784 parseObjCUntilAtEnd();
2787 void UnwrappedLineParser::parseObjCLightweightGenerics() {
2788 assert(FormatTok->Tok.is(tok::less));
2796 unsigned NumOpenAngles = 1;
2800 if (FormatTok->isOneOf(tok::semi, tok::l_brace) ||
2801 FormatTok->Tok.isObjCAtKeyword(tok::objc_end))
2803 if (FormatTok->Tok.is(tok::less))
2805 else if (FormatTok->Tok.is(tok::greater)) {
2806 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
2809 }
while (!eof() && NumOpenAngles != 0);
2815 bool UnwrappedLineParser::parseObjCProtocol() {
2816 assert(FormatTok->Tok.getObjCKeywordID() == tok::objc_protocol);
2819 if (FormatTok->is(tok::l_paren))
2830 if (FormatTok->Tok.is(tok::less))
2831 parseObjCProtocolList();
2834 if (FormatTok->Tok.is(tok::semi)) {
2841 parseObjCUntilAtEnd();
2845 void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
2846 bool IsImport = FormatTok->is(Keywords.
kw_import);
2847 assert(IsImport || FormatTok->is(tok::kw_export));
2851 if (FormatTok->is(tok::kw_default))
2857 if (FormatTok->is(Keywords.
kw_async))
2868 if (!IsImport && !FormatTok->isOneOf(tok::l_brace, tok::star) &&
2869 !FormatTok->isStringLiteral())
2873 if (FormatTok->is(tok::semi))
2875 if (Line->Tokens.empty()) {
2880 if (FormatTok->is(tok::l_brace)) {
2890 void UnwrappedLineParser::parseStatementMacro() {
2892 if (FormatTok->is(tok::l_paren))
2894 if (FormatTok->is(tok::semi))
2900 StringRef Prefix =
"") {
2901 llvm::dbgs() << Prefix <<
"Line(" <<
Line.
Level
2904 for (std::list<UnwrappedLineNode>::const_iterator I =
Line.Tokens.begin(),
2905 E =
Line.Tokens.end();
2907 llvm::dbgs() << I->Tok->Tok.getName() <<
"["
2908 <<
"T=" << (
unsigned)I->Tok->getType()
2909 <<
", OC=" << I->Tok->OriginalColumn <<
"] ";
2911 for (std::list<UnwrappedLineNode>::const_iterator I =
Line.Tokens.begin(),
2912 E =
Line.Tokens.end();
2916 I =
Node.Children.begin(),
2917 E =
Node.Children.end();
2922 llvm::dbgs() <<
"\n";
2925 void UnwrappedLineParser::addUnwrappedLine() {
2926 if (Line->Tokens.empty())
2929 if (CurrentLines == &Lines)
2932 CurrentLines->push_back(std::move(*Line));
2933 Line->Tokens.clear();
2935 Line->FirstStartColumn = 0;
2936 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
2937 CurrentLines->append(
2938 std::make_move_iterator(PreprocessorDirectives.begin()),
2939 std::make_move_iterator(PreprocessorDirectives.end()));
2940 PreprocessorDirectives.clear();
2943 FormatTok->Previous =
nullptr;
2946 bool UnwrappedLineParser::eof()
const {
return FormatTok->Tok.is(
tok::eof); }
2948 bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
2949 return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
2950 FormatTok.NewlinesBefore > 0;
2958 const llvm::Regex &CommentPragmasRegex) {
2959 if (
Line.Tokens.empty())
2962 StringRef IndentContent = FormatTok.
TokenText;
2963 if (FormatTok.
TokenText.startswith(
"//") ||
2965 IndentContent = FormatTok.
TokenText.substr(2);
2966 if (CommentPragmasRegex.match(IndentContent))
3041 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
3042 isLineComment(*
Node.Tok)) {
3043 MinColumnToken = PreviousToken;
3046 PreviousToken =
Node.Tok;
3049 if (
Node.Tok->NewlinesBefore > 0) {
3050 MinColumnToken =
Node.Tok;
3053 if (PreviousToken && PreviousToken->
is(tok::l_brace)) {
3054 MinColumnToken = PreviousToken;
3057 return continuesLineComment(FormatTok,
Line.Tokens.back().Tok,
3061 void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
3062 bool JustComments = Line->Tokens.empty();
3064 I = CommentsBeforeNextToken.begin(),
3065 E = CommentsBeforeNextToken.end();
3075 (*I)->ContinuesLineCommentSection =
3077 if (isOnNewLine(**I) && JustComments && !(*I)->ContinuesLineCommentSection)
3081 if (NewlineBeforeNext && JustComments)
3083 CommentsBeforeNextToken.clear();
3086 void UnwrappedLineParser::nextToken(
int LevelDifference) {
3089 flushComments(isOnNewLine(*FormatTok));
3090 pushToken(FormatTok);
3092 if (Style.Language != FormatStyle::LK_JavaScript)
3093 readToken(LevelDifference);
3095 readTokenWithJavaScriptASI();
3099 void UnwrappedLineParser::distributeComments(
3100 const SmallVectorImpl<FormatToken *> &Comments,
3101 const FormatToken *NextTok) {
3120 if (Comments.empty())
3122 bool ShouldPushCommentsInCurrentLine =
true;
3123 bool HasTrailAlignedWithNextToken =
false;
3124 unsigned StartOfTrailAlignedWithNextToken = 0;
3127 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
3128 if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
3129 HasTrailAlignedWithNextToken =
true;
3130 StartOfTrailAlignedWithNextToken = i;
3134 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
3135 FormatToken *FormatTok = Comments[i];
3136 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
3137 FormatTok->ContinuesLineCommentSection =
false;
3139 FormatTok->ContinuesLineCommentSection =
3142 if (!FormatTok->ContinuesLineCommentSection &&
3143 (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
3144 ShouldPushCommentsInCurrentLine =
false;
3146 if (ShouldPushCommentsInCurrentLine) {
3147 pushToken(FormatTok);
3149 CommentsBeforeNextToken.push_back(FormatTok);
3154 void UnwrappedLineParser::readToken(
int LevelDifference) {
3155 SmallVector<FormatToken *, 1> Comments;
3157 FormatTok = Tokens->getNextToken();
3159 while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) &&
3160 (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) {
3161 distributeComments(Comments, FormatTok);
3165 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
3167 assert((LevelDifference >= 0 ||
3168 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
3169 "LevelDifference makes Line->Level negative");
3170 Line->Level += LevelDifference;
3174 if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
3176 Line->Level += PPBranchLevel;
3177 flushComments(isOnNewLine(*FormatTok));
3180 while (FormatTok->getType() == TT_ConflictStart ||
3181 FormatTok->getType() == TT_ConflictEnd ||
3182 FormatTok->getType() == TT_ConflictAlternative) {
3183 if (FormatTok->getType() == TT_ConflictStart) {
3184 conditionalCompilationStart(
false);
3185 }
else if (FormatTok->getType() == TT_ConflictAlternative) {
3186 conditionalCompilationAlternative();
3187 }
else if (FormatTok->getType() == TT_ConflictEnd) {
3188 conditionalCompilationEnd();
3190 FormatTok = Tokens->getNextToken();
3191 FormatTok->MustBreakBefore =
true;
3194 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
3195 !Line->InPPDirective) {
3199 if (!FormatTok->Tok.is(tok::comment)) {
3200 distributeComments(Comments, FormatTok);
3205 Comments.push_back(FormatTok);
3208 distributeComments(Comments,
nullptr);
3212 void UnwrappedLineParser::pushToken(FormatToken *Tok) {
3213 Line->Tokens.push_back(UnwrappedLineNode(Tok));
3214 if (MustBreakBeforeNextToken) {
3215 Line->Tokens.back().Tok->MustBreakBefore =
true;
3216 MustBreakBeforeNextToken =
false;