16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/Support/Debug.h" 18 #include "llvm/Support/raw_ostream.h" 22 #define DEBUG_TYPE "format-parser" 38 class ScopedDeclarationState {
41 bool MustBeDeclaration)
42 :
Line(Line), Stack(Stack) {
44 Stack.push_back(MustBeDeclaration);
46 ~ScopedDeclarationState() {
56 std::vector<bool> &Stack;
59 static bool isLineComment(
const FormatToken &FormatTok) {
60 return FormatTok.
is(tok::comment) && !FormatTok.
TokenText.startswith(
"/*");
66 static bool continuesLineComment(
const FormatToken &FormatTok,
69 if (!Previous || !MinColumnToken)
71 unsigned MinContinueColumn =
72 MinColumnToken->
OriginalColumn + (isLineComment(*MinColumnToken) ? 0 : 1);
73 return isLineComment(FormatTok) && FormatTok.
NewlinesBefore == 1 &&
74 isLineComment(*Previous) &&
82 :
Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
83 PreviousLineLevel(Line.
Level), PreviousTokenSource(TokenSource),
84 Token(
nullptr), PreviousToken(
nullptr) {
85 FakeEOF.Tok.startToken();
92 ~ScopedMacroState()
override {
93 TokenSource = PreviousTokenSource;
96 Line.
Level = PreviousLineLevel;
103 PreviousToken =
Token;
104 Token = PreviousTokenSource->getNextToken();
110 unsigned getPosition()
override {
return PreviousTokenSource->getPosition(); }
113 PreviousToken =
nullptr;
114 Token = PreviousTokenSource->setPosition(Position);
121 !continuesLineComment(*
Token, PreviousToken,
129 unsigned PreviousLineLevel;
141 bool SwitchToPreprocessorLines =
false)
142 : Parser(Parser), OriginalLines(Parser.CurrentLines) {
143 if (SwitchToPreprocessorLines)
144 Parser.CurrentLines = &Parser.PreprocessorDirectives;
145 else if (!Parser.Line->Tokens.empty())
146 Parser.CurrentLines = &Parser.Line->Tokens.back().Children;
147 PreBlockLine = std::move(Parser.Line);
148 Parser.Line = std::make_unique<UnwrappedLine>();
149 Parser.Line->Level = PreBlockLine->Level;
150 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
154 if (!
Parser.Line->Tokens.empty()) {
155 Parser.addUnwrappedLine();
157 assert(
Parser.Line->Tokens.empty());
158 Parser.Line = std::move(PreBlockLine);
159 if (
Parser.CurrentLines == &
Parser.PreprocessorDirectives)
160 Parser.MustBreakBeforeNextToken =
true;
161 Parser.CurrentLines = OriginalLines;
167 std::unique_ptr<UnwrappedLine> PreBlockLine;
176 Style.BraceWrapping.AfterControlStatement,
177 Style.BraceWrapping.IndentBraces) {}
179 bool WrapBrace,
bool IndentBrace)
180 : LineLevel(LineLevel), OldLineLevel(LineLevel) {
182 Parser->addUnwrappedLine();
190 unsigned OldLineLevel;
198 : Tokens(Tokens), Position(-1) {}
202 return Tokens[Position];
206 assert(Position >= 0);
212 return Tokens[Position];
215 void reset() { Position = -1; }
226 unsigned FirstStartColumn,
230 CurrentLines(&Lines), Style(Style), Keywords(Keywords),
231 CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
232 Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
233 IncludeGuard(Style.IndentPPDirectives ==
FormatStyle::PPDIS_None
236 IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn) {}
238 void UnwrappedLineParser::reset() {
240 IncludeGuard = Style.IndentPPDirectives == FormatStyle::PPDIS_None
243 IncludeGuardToken =
nullptr;
245 CommentsBeforeNextToken.clear();
247 MustBreakBeforeNextToken =
false;
248 PreprocessorDirectives.clear();
249 CurrentLines = &Lines;
250 DeclarationScopeStack.clear();
252 Line->FirstStartColumn = FirstStartColumn;
256 IndexedTokenSource TokenSource(AllTokens);
257 Line->FirstStartColumn = FirstStartColumn;
259 LLVM_DEBUG(llvm::dbgs() <<
"----\n");
261 Tokens = &TokenSource;
269 if (IncludeGuard == IG_Found)
270 for (
auto &Line : Lines)
271 if (Line.InPPDirective && Line.Level > 0)
275 pushToken(FormatTok);
285 while (!PPLevelBranchIndex.empty() &&
286 PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
287 PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
288 PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
290 if (!PPLevelBranchIndex.empty()) {
291 ++PPLevelBranchIndex.back();
292 assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
293 assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
295 }
while (!PPLevelBranchIndex.empty());
298 void UnwrappedLineParser::parseFile() {
301 bool MustBeDeclaration =
302 !Line->InPPDirective && Style.Language != FormatStyle::LK_JavaScript;
303 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
305 if (Style.Language == FormatStyle::LK_TextProto)
319 if (Style.Language == FormatStyle::LK_TextProto &&
320 !CommentsBeforeNextToken.empty())
326 void UnwrappedLineParser::parseLevel(
bool HasOpeningBrace) {
327 bool SwitchLabelEncountered =
false;
330 if (FormatTok->
Type == TT_MacroBlockBegin) {
332 }
else if (FormatTok->
Type == TT_MacroBlockEnd) {
344 if (!FormatTok->
is(TT_MacroBlockBegin) && tryToParseBracedList())
355 case tok::kw_default: {
360 }
while (Next && Next->
is(tok::comment));
362 if (Next && Next->
isNot(tok::colon)) {
365 parseStructuralElement();
372 if (Style.Language == FormatStyle::LK_JavaScript &&
373 Line->MustBeDeclaration) {
375 parseStructuralElement();
378 if (!SwitchLabelEncountered &&
379 (Style.IndentCaseLabels || (Line->InPPDirective && Line->Level == 1)))
381 SwitchLabelEncountered =
true;
382 parseStructuralElement();
385 parseStructuralElement();
391 void UnwrappedLineParser::calculateBraceTypes(
bool ExpectClassBody) {
403 assert(Tok->
Tok.
is(tok::l_brace));
407 unsigned ReadTokens = 0;
411 }
while (NextTok->
is(tok::comment));
415 if (Style.Language == FormatStyle::LK_JavaScript && PrevTok) {
416 if (PrevTok->
isOneOf(tok::colon, tok::less))
427 else if (PrevTok->
is(tok::r_paren))
433 LBraceStack.push_back(Tok);
436 if (LBraceStack.empty())
438 if (LBraceStack.back()->BlockKind ==
BK_Unknown) {
439 bool ProbablyBracedList =
false;
440 if (Style.Language == FormatStyle::LK_Proto) {
441 ProbablyBracedList = NextTok->
isOneOf(tok::comma, tok::r_square);
445 bool NextIsObjCMethod = NextTok->
isOneOf(tok::plus, tok::minus) &&
457 (Style.Language == FormatStyle::LK_JavaScript &&
460 (Style.isCpp() && NextTok->
is(tok::l_paren)) ||
461 NextTok->
isOneOf(tok::comma, tok::period, tok::colon,
462 tok::r_paren, tok::r_square, tok::l_brace,
464 (NextTok->
is(tok::identifier) &&
465 !PrevTok->
isOneOf(tok::semi, tok::r_brace, tok::l_brace)) ||
466 (NextTok->
is(tok::semi) &&
467 (!ExpectClassBody || LBraceStack.size() != 1)) ||
469 if (!Style.isCSharp() && NextTok->
is(tok::l_square)) {
474 ProbablyBracedList = NextTok->
isNot(tok::l_square);
477 if (ProbablyBracedList) {
482 LBraceStack.back()->BlockKind =
BK_Block;
485 LBraceStack.pop_back();
487 case tok::identifier:
488 if (!Tok->
is(TT_StatementMacro))
499 if (!LBraceStack.empty() && LBraceStack.back()->BlockKind ==
BK_Unknown)
500 LBraceStack.back()->BlockKind =
BK_Block;
510 for (
unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
512 LBraceStack[i]->BlockKind =
BK_Block;
521 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
524 size_t UnwrappedLineParser::computePPHash()
const {
526 for (
const auto &i : PPStack) {
533 void UnwrappedLineParser::parseBlock(
bool MustBeDeclaration,
bool AddLevel,
535 assert(FormatTok->
isOneOf(tok::l_brace, TT_MacroBlockBegin) &&
536 "'{' or macro block token expected");
537 const bool MacroBlock = FormatTok->
is(TT_MacroBlockBegin);
540 size_t PPStartHash = computePPHash();
542 unsigned InitialLevel = Line->Level;
543 nextToken(AddLevel ? 1 : 0);
545 if (MacroBlock && FormatTok->
is(tok::l_paren))
548 size_t NbPreprocessorDirectives =
549 CurrentLines == &Lines ? PreprocessorDirectives.size() : 0;
551 size_t OpeningLineIndex =
552 CurrentLines->empty()
554 : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
556 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
565 if (MacroBlock ? !FormatTok->
is(TT_MacroBlockEnd)
566 : !FormatTok->
is(tok::r_brace)) {
567 Line->Level = InitialLevel;
572 size_t PPEndHash = computePPHash();
575 nextToken(AddLevel ? -1 : 0);
577 if (MacroBlock && FormatTok->
is(tok::l_paren))
580 if (MunchSemi && FormatTok->
Tok.
is(tok::semi))
582 Line->Level = InitialLevel;
584 if (PPStartHash == PPEndHash) {
585 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
588 (*CurrentLines)[OpeningLineIndex].MatchingClosingBlockLineIndex =
589 CurrentLines->size() - 1;
597 if (Line.
Tokens.size() < 4)
599 auto I = Line.
Tokens.begin();
600 if (I->Tok->TokenText !=
"goog")
603 if (I->Tok->isNot(tok::period))
606 if (I->Tok->TokenText !=
"scope")
609 return I->Tok->is(tok::l_paren);
618 if (Line.
Tokens.size() < 3)
620 auto I = Line.
Tokens.begin();
621 if (I->Tok->isNot(tok::l_paren))
627 return I->Tok->is(tok::l_paren);
632 if (InitialToken.
isOneOf(tok::kw_namespace, TT_NamespaceMacro))
633 return Style.BraceWrapping.AfterNamespace;
634 if (InitialToken.
is(tok::kw_class))
635 return Style.BraceWrapping.AfterClass;
636 if (InitialToken.
is(tok::kw_union))
637 return Style.BraceWrapping.AfterUnion;
638 if (InitialToken.
is(tok::kw_struct))
639 return Style.BraceWrapping.AfterStruct;
643 void UnwrappedLineParser::parseChildBlock() {
647 bool SkipIndent = (Style.Language == FormatStyle::LK_JavaScript &&
650 ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
652 Line->Level += SkipIndent ? 0 : 1;
654 flushComments(isOnNewLine(*FormatTok));
655 Line->Level -= SkipIndent ? 0 : 1;
660 void UnwrappedLineParser::parsePPDirective() {
661 assert(FormatTok->
Tok.
is(tok::hash) &&
"'#' expected");
662 ScopedMacroState MacroState(*Line, Tokens, FormatTok);
697 void UnwrappedLineParser::conditionalCompilationCondition(
bool Unreachable) {
698 size_t Line = CurrentLines->size();
699 if (CurrentLines == &PreprocessorDirectives)
700 Line += Lines.size();
703 (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable))
704 PPStack.push_back({PP_Unreachable, Line});
706 PPStack.push_back({PP_Conditional, Line});
709 void UnwrappedLineParser::conditionalCompilationStart(
bool Unreachable) {
711 assert(PPBranchLevel >= 0 && PPBranchLevel <= (
int)PPLevelBranchIndex.size());
712 if (PPBranchLevel == (
int)PPLevelBranchIndex.size()) {
713 PPLevelBranchIndex.push_back(0);
714 PPLevelBranchCount.push_back(0);
716 PPChainBranchIndex.push(0);
717 bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
718 conditionalCompilationCondition(Unreachable || Skip);
721 void UnwrappedLineParser::conditionalCompilationAlternative() {
722 if (!PPStack.empty())
724 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
725 if (!PPChainBranchIndex.empty())
726 ++PPChainBranchIndex.top();
727 conditionalCompilationCondition(
728 PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
729 PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
732 void UnwrappedLineParser::conditionalCompilationEnd() {
733 assert(PPBranchLevel < (
int)PPLevelBranchIndex.size());
734 if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
735 if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel]) {
736 PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
740 if (PPBranchLevel > -1)
742 if (!PPChainBranchIndex.empty())
743 PPChainBranchIndex.pop();
744 if (!PPStack.empty())
748 void UnwrappedLineParser::parsePPIf(
bool IfDef) {
751 bool Unreachable =
false;
752 if (!IfDef && (FormatTok->
is(tok::kw_false) || FormatTok->
TokenText ==
"0"))
754 if (IfDef && !IfNDef && FormatTok->
TokenText ==
"SWIG")
756 conditionalCompilationStart(Unreachable);
757 FormatToken *IfCondition = FormatTok;
760 bool MaybeIncludeGuard = IfNDef;
761 if (IncludeGuard == IG_Inited && MaybeIncludeGuard)
762 for (
auto &Line : Lines) {
763 if (!Line.Tokens.front().Tok->is(tok::comment)) {
764 MaybeIncludeGuard =
false;
765 IncludeGuard = IG_Rejected;
772 if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
773 IncludeGuard = IG_IfNdefed;
774 IncludeGuardToken = IfCondition;
778 void UnwrappedLineParser::parsePPElse() {
780 if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
781 IncludeGuard = IG_Rejected;
782 conditionalCompilationAlternative();
783 if (PPBranchLevel > -1)
789 void UnwrappedLineParser::parsePPElIf() { parsePPElse(); }
791 void UnwrappedLineParser::parsePPEndIf() {
792 conditionalCompilationEnd();
797 FormatToken *PeekNext = AllTokens[TokenPosition];
798 if (IncludeGuard == IG_Defined && PPBranchLevel == -1 &&
800 Style.IndentPPDirectives != FormatStyle::PPDIS_None)
801 IncludeGuard = IG_Found;
804 void UnwrappedLineParser::parsePPDefine() {
808 IncludeGuard = IG_Rejected;
809 IncludeGuardToken =
nullptr;
814 if (IncludeGuard == IG_IfNdefed &&
816 IncludeGuard = IG_Defined;
817 IncludeGuardToken =
nullptr;
818 for (
auto &Line : Lines) {
819 if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
820 IncludeGuard = IG_Rejected;
827 if (FormatTok->
Tok.
getKind() == tok::l_paren &&
832 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
833 Line->Level += PPBranchLevel + 1;
845 void UnwrappedLineParser::parsePPUnknown() {
849 if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
850 Line->Level += PPBranchLevel + 1;
860 return Tok.
isNot(tok::semi) && Tok.
isNot(tok::l_brace) &&
861 Tok.
isNot(tok::l_square) &&
864 Tok.
isNot(tok::period) && Tok.
isNot(tok::periodstar) &&
865 Tok.
isNot(tok::arrow) && Tok.
isNot(tok::arrowstar) &&
866 Tok.
isNot(tok::less) && Tok.
isNot(tok::greater) &&
867 Tok.
isNot(tok::slash) && Tok.
isNot(tok::percent) &&
868 Tok.
isNot(tok::lessless) && Tok.
isNot(tok::greatergreater) &&
869 Tok.
isNot(tok::equal) && Tok.
isNot(tok::plusequal) &&
870 Tok.
isNot(tok::minusequal) && Tok.
isNot(tok::starequal) &&
871 Tok.
isNot(tok::slashequal) && Tok.
isNot(tok::percentequal) &&
872 Tok.
isNot(tok::ampequal) && Tok.
isNot(tok::pipeequal) &&
873 Tok.
isNot(tok::caretequal) && Tok.
isNot(tok::greatergreaterequal) &&
874 Tok.
isNot(tok::lesslessequal) &&
878 Tok.
isNot(tok::colon) &&
880 Tok.
isNot(tok::kw_noexcept);
886 return FormatTok->
is(tok::identifier) &&
901 FormatTok->
isOneOf(tok::kw_true, tok::kw_false) ||
912 tok::kw_if, tok::kw_else,
914 tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
916 tok::kw_switch, tok::kw_case,
918 tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.
kw_finally,
920 tok::kw_const, tok::kw_class, Keywords.
kw_var, Keywords.
kw_let,
933 void UnwrappedLineParser::readTokenWithJavaScriptASI() {
939 CommentsBeforeNextToken.empty()
941 : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
946 bool PreviousStartsTemplateExpr =
947 Previous->
is(TT_TemplateString) && Previous->
TokenText.endswith(
"${");
948 if (PreviousMustBeValue || Previous->
is(tok::r_paren)) {
951 bool HasAt = std::find_if(Line->Tokens.begin(), Line->Tokens.end(),
953 return LineNode.Tok->is(tok::at);
954 }) != Line->Tokens.end();
958 if (Next->
is(tok::exclaim) && PreviousMustBeValue)
959 return addUnwrappedLine();
961 bool NextEndsTemplateExpr =
962 Next->
is(TT_TemplateString) && Next->
TokenText.startswith(
"}");
963 if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr &&
964 (PreviousMustBeValue ||
965 Previous->
isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
967 return addUnwrappedLine();
968 if ((PreviousMustBeValue || Previous->
is(tok::r_paren)) &&
970 return addUnwrappedLine();
973 void UnwrappedLineParser::parseStructuralElement() {
974 assert(!FormatTok->
is(tok::l_brace));
975 if (Style.Language == FormatStyle::LK_TableGen &&
978 if (FormatTok->
is(tok::string_literal))
986 if (FormatTok->
is(tok::l_brace)) {
987 FormatTok->
Type = TT_InlineASMBrace;
990 if (FormatTok->
is(tok::r_brace)) {
991 FormatTok->
Type = TT_InlineASMBrace;
1001 case tok::kw_namespace:
1004 case tok::kw_public:
1005 case tok::kw_protected:
1006 case tok::kw_private:
1007 if (Style.Language == FormatStyle::LK_Java ||
1008 Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp())
1011 parseAccessSpecifier();
1018 parseForOrWhileLoop();
1023 case tok::kw_switch:
1024 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1029 case tok::kw_default:
1030 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1034 if (FormatTok->
is(tok::colon)) {
1041 if (Style.Language == FormatStyle::LK_JavaScript && Line->MustBeDeclaration)
1050 case tok::kw_extern:
1052 if (FormatTok->
Tok.
is(tok::string_literal)) {
1054 if (FormatTok->
Tok.
is(tok::l_brace)) {
1055 if (Style.BraceWrapping.AfterExternBlock) {
1059 parseBlock(
true,
false);
1066 case tok::kw_export:
1067 if (Style.Language == FormatStyle::LK_JavaScript) {
1068 parseJavaScriptEs6ImportExport();
1075 case tok::kw_inline:
1077 if (FormatTok->
Tok.
is(tok::kw_namespace)) {
1082 case tok::identifier:
1083 if (FormatTok->
is(TT_ForEachMacro)) {
1084 parseForOrWhileLoop();
1087 if (FormatTok->
is(TT_MacroBlockBegin)) {
1088 parseBlock(
false,
true,
1093 if (Style.Language == FormatStyle::LK_JavaScript) {
1094 parseJavaScriptEs6ImportExport();
1097 if (Style.Language == FormatStyle::LK_Proto) {
1099 if (FormatTok->
is(tok::kw_public))
1101 if (!FormatTok->
is(tok::string_literal))
1104 if (FormatTok->
is(tok::semi))
1110 if (Style.isCpp() &&
1114 if (FormatTok->
is(tok::colon)) {
1120 if (Style.isCpp() && FormatTok->
is(TT_StatementMacro)) {
1121 parseStatementMacro();
1124 if (Style.isCpp() && FormatTok->
is(TT_NamespaceMacro)) {
1138 if (FormatTok->
Tok.
is(tok::l_brace)) {
1142 }
else if (Style.Language == FormatStyle::LK_Java &&
1148 case tok::objc_public:
1149 case tok::objc_protected:
1150 case tok::objc_package:
1151 case tok::objc_private:
1152 return parseAccessSpecifier();
1153 case tok::objc_interface:
1154 case tok::objc_implementation:
1155 return parseObjCInterfaceOrImplementation();
1156 case tok::objc_protocol:
1157 if (parseObjCProtocol())
1162 case tok::objc_optional:
1163 case tok::objc_required:
1167 case tok::objc_autoreleasepool:
1169 if (FormatTok->
Tok.
is(tok::l_brace)) {
1170 if (Style.BraceWrapping.AfterControlStatement ==
1171 FormatStyle::BWACS_Always)
1177 case tok::objc_synchronized:
1179 if (FormatTok->
Tok.
is(tok::l_paren))
1182 if (FormatTok->
Tok.
is(tok::l_brace)) {
1183 if (Style.BraceWrapping.AfterControlStatement ==
1184 FormatStyle::BWACS_Always)
1201 if (Previous && Previous->
is(tok::less)) {
1211 if (!Style.isCpp()) {
1216 case tok::kw_typedef:
1224 case tok::kw_struct:
1231 if (Style.Language == FormatStyle::LK_Java ||
1232 Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
1233 if (FormatTok->
is(tok::semi))
1242 if (Style.Language == FormatStyle::LK_Java && FormatTok &&
1243 FormatTok->
is(tok::kw_class))
1245 if (Style.Language == FormatStyle::LK_JavaScript && FormatTok &&
1261 case tok::kw_operator:
1271 if (FormatTok->
is(tok::l_paren))
1273 if (FormatTok->
is(tok::l_brace))
1277 if (!tryToParseBracedList()) {
1282 if (Style.BraceWrapping.AfterFunction)
1284 FormatTok->
Type = TT_FunctionLBrace;
1294 if (Style.BraceWrapping.AfterFunction)
1298 case tok::identifier: {
1299 if (FormatTok->
is(TT_MacroBlockEnd)) {
1308 size_t TokenCount = Line->Tokens.size();
1309 if (Style.Language == FormatStyle::LK_JavaScript &&
1311 (TokenCount > 1 || (TokenCount == 1 && !Line->Tokens.front().Tok->is(
1313 tryToParseJSFunction();
1316 if ((Style.Language == FormatStyle::LK_JavaScript ||
1317 Style.Language == FormatStyle::LK_Java) &&
1319 if (Style.Language == FormatStyle::LK_JavaScript) {
1337 if (Style.isCpp() && FormatTok->
is(TT_StatementMacro)) {
1338 parseStatementMacro();
1348 if (Style.Language == FormatStyle::LK_JavaScript)
1351 TokenCount = Line->Tokens.size();
1352 if (TokenCount == 1 ||
1353 (TokenCount == 2 && Line->Tokens.front().Tok->is(tok::comment))) {
1354 if (FormatTok->
Tok.
is(tok::colon) && !Line->MustBeDeclaration) {
1355 Line->Tokens.begin()->Tok->MustBreakBefore =
true;
1356 parseLabel(!Style.IndentGotoLabels);
1361 bool FunctionLike = FormatTok->
is(tok::l_paren);
1365 bool FollowedByNewline =
1366 CommentsBeforeNextToken.empty()
1368 : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
1370 if (FollowedByNewline && (Text.size() >= 5 || FunctionLike) &&
1382 if (FormatTok->
is(TT_JsFatArrow)) {
1384 if (FormatTok->
is(tok::l_brace))
1390 if (FormatTok->
Tok.
is(tok::l_brace)) {
1393 }
else if (Style.Language == FormatStyle::LK_Proto &&
1394 FormatTok->
Tok.
is(tok::less)) {
1396 parseBracedList(
false,
1413 bool UnwrappedLineParser::tryToParseLambda() {
1414 if (!Style.isCpp()) {
1418 assert(FormatTok->
is(tok::l_square));
1420 if (!tryToParseLambdaIntroducer())
1423 bool SeenArrow =
false;
1425 while (FormatTok->
isNot(tok::l_brace)) {
1442 case tok::identifier:
1443 case tok::numeric_constant:
1444 case tok::coloncolon:
1446 case tok::kw_mutable:
1447 case tok::kw_noexcept:
1448 case tok::kw_template:
1449 case tok::kw_typename:
1477 case tok::equalequal:
1478 case tok::exclaimequal:
1479 case tok::greaterequal:
1480 case tok::lessequal:
1494 FormatTok->
Type = TT_LambdaArrow;
1502 FormatTok->
Type = TT_LambdaLBrace;
1503 LSquare.Type = TT_LambdaLSquare;
1508 bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
1511 (Previous->
isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
1512 tok::kw_delete, tok::l_square) ||
1519 if (FormatTok->
is(tok::l_square)) {
1526 void UnwrappedLineParser::tryToParseJSFunction() {
1535 if (FormatTok->
is(tok::star)) {
1536 FormatTok->
Type = TT_OverloadedOperator;
1541 if (FormatTok->
is(tok::identifier))
1544 if (FormatTok->
isNot(tok::l_paren))
1550 if (FormatTok->
is(tok::colon)) {
1556 if (FormatTok->
is(tok::l_brace))
1557 tryToParseBracedList();
1559 while (!FormatTok->
isOneOf(tok::l_brace, tok::semi) && !eof())
1563 if (FormatTok->
is(tok::semi))
1569 bool UnwrappedLineParser::tryToParseBracedList() {
1571 calculateBraceTypes();
1580 bool UnwrappedLineParser::parseBracedList(
bool ContinueOnSemicolons,
1582 bool HasError =
false;
1587 if (Style.Language == FormatStyle::LK_JavaScript) {
1590 tryToParseJSFunction();
1593 if (FormatTok->
is(TT_JsFatArrow)) {
1597 if (FormatTok->
is(tok::l_brace)) {
1602 if (FormatTok->
is(tok::l_brace)) {
1604 if (tryToParseBracedList())
1609 if (FormatTok->
Tok.
getKind() == ClosingBraceKind) {
1616 if (FormatTok->
is(tok::l_brace)) {
1627 if (Style.Language == FormatStyle::LK_JavaScript) {
1628 if (FormatTok->
is(tok::l_brace))
1641 if (Style.Language == FormatStyle::LK_Proto) {
1643 parseBracedList(
false,
1654 if (Style.Language == FormatStyle::LK_JavaScript) {
1659 if (!ContinueOnSemicolons)
1674 void UnwrappedLineParser::parseParens() {
1675 assert(FormatTok->
Tok.
is(tok::l_paren) &&
"'(' expected.");
1681 if (Style.Language == FormatStyle::LK_Java && FormatTok->
is(tok::l_brace))
1694 if (!tryToParseBracedList())
1699 if (FormatTok->
Tok.
is(tok::l_brace)) {
1705 if (Style.Language == FormatStyle::LK_JavaScript)
1710 case tok::identifier:
1711 if (Style.Language == FormatStyle::LK_JavaScript &&
1714 tryToParseJSFunction();
1726 if (!LambdaIntroducer) {
1727 assert(FormatTok->
Tok.
is(tok::l_square) &&
"'[' expected.");
1728 if (tryToParseLambda())
1745 case tok::l_brace: {
1746 if (!tryToParseBracedList())
1752 if (FormatTok->
Tok.
is(tok::l_brace)) {
1764 void UnwrappedLineParser::parseIfThenElse() {
1765 assert(FormatTok->
Tok.
is(tok::kw_if) &&
"'if' expected");
1767 if (FormatTok->
Tok.
isOneOf(tok::kw_constexpr, tok::identifier))
1769 if (FormatTok->
Tok.
is(tok::l_paren))
1771 bool NeedsUnwrappedLine =
false;
1772 if (FormatTok->
Tok.
is(tok::l_brace)) {
1775 if (Style.BraceWrapping.BeforeElse)
1778 NeedsUnwrappedLine =
true;
1782 parseStructuralElement();
1785 if (FormatTok->
Tok.
is(tok::kw_else)) {
1787 if (FormatTok->
Tok.
is(tok::l_brace)) {
1791 }
else if (FormatTok->
Tok.
is(tok::kw_if)) {
1796 parseStructuralElement();
1801 }
else if (NeedsUnwrappedLine) {
1806 void UnwrappedLineParser::parseTryCatch() {
1807 assert(FormatTok->
isOneOf(tok::kw_try, tok::kw___try) &&
"'try' expected");
1809 bool NeedsUnwrappedLine =
false;
1810 if (FormatTok->
is(tok::colon)) {
1813 while (FormatTok->
is(tok::identifier)) {
1815 if (FormatTok->
is(tok::l_paren))
1817 if (FormatTok->
is(tok::comma))
1822 if (Style.Language == FormatStyle::LK_Java && FormatTok->
is(tok::l_paren)) {
1825 if (FormatTok->
is(tok::l_brace)) {
1828 if (Style.BraceWrapping.BeforeCatch) {
1831 NeedsUnwrappedLine =
true;
1833 }
else if (!FormatTok->
is(tok::kw_catch)) {
1839 parseStructuralElement();
1843 if (FormatTok->
is(tok::at))
1846 tok::kw___finally) ||
1847 ((Style.Language == FormatStyle::LK_Java ||
1848 Style.Language == FormatStyle::LK_JavaScript) &&
1854 while (FormatTok->
isNot(tok::l_brace)) {
1855 if (FormatTok->
is(tok::l_paren)) {
1863 NeedsUnwrappedLine =
false;
1866 if (Style.BraceWrapping.BeforeCatch)
1869 NeedsUnwrappedLine =
true;
1871 if (NeedsUnwrappedLine)
1875 void UnwrappedLineParser::parseNamespace() {
1876 assert(FormatTok->
isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
1877 "'namespace' expected");
1881 if (InitialToken.is(TT_NamespaceMacro)) {
1884 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
1886 if (FormatTok->
is(tok::l_square))
1892 if (FormatTok->
Tok.
is(tok::l_brace)) {
1896 bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All ||
1897 (Style.NamespaceIndentation == FormatStyle::NI_Inner &&
1898 DeclarationScopeStack.size() > 1);
1899 parseBlock(
true, AddLevel);
1902 if (FormatTok->
Tok.
is(tok::semi))
1909 void UnwrappedLineParser::parseNew() {
1910 assert(FormatTok->
is(tok::kw_new) &&
"'new' expected");
1912 if (Style.Language != FormatStyle::LK_Java)
1918 if (FormatTok->
isOneOf(tok::semi, tok::l_brace, tok::r_brace))
1922 if (FormatTok->
is(tok::l_paren)) {
1926 if (FormatTok->
is(tok::l_brace))
1934 void UnwrappedLineParser::parseForOrWhileLoop() {
1935 assert(FormatTok->
isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
1936 "'for', 'while' or foreach macro expected");
1939 if (Style.Language == FormatStyle::LK_JavaScript &&
1942 if (FormatTok->
Tok.
is(tok::l_paren))
1944 if (FormatTok->
Tok.
is(tok::l_brace)) {
1951 parseStructuralElement();
1956 void UnwrappedLineParser::parseDoWhile() {
1957 assert(FormatTok->
Tok.
is(tok::kw_do) &&
"'do' expected");
1959 if (FormatTok->
Tok.
is(tok::l_brace)) {
1962 if (Style.BraceWrapping.IndentBraces)
1967 parseStructuralElement();
1972 if (!FormatTok->
Tok.
is(tok::kw_while)) {
1978 parseStructuralElement();
1981 void UnwrappedLineParser::parseLabel(
bool LeftAlignLabel) {
1983 unsigned OldLineLevel = Line->Level;
1984 if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
1988 if (CommentsBeforeNextToken.empty() && FormatTok->
Tok.
is(tok::l_brace)) {
1990 Style.BraceWrapping.AfterCaseLabel,
1991 Style.BraceWrapping.IndentBraces);
1993 if (FormatTok->
Tok.
is(tok::kw_break)) {
1994 if (Style.BraceWrapping.AfterControlStatement ==
1995 FormatStyle::BWACS_Always)
1997 parseStructuralElement();
2001 if (FormatTok->
is(tok::semi))
2005 Line->Level = OldLineLevel;
2006 if (FormatTok->
isNot(tok::l_brace)) {
2007 parseStructuralElement();
2012 void UnwrappedLineParser::parseCaseLabel() {
2013 assert(FormatTok->
Tok.
is(tok::kw_case) &&
"'case' expected");
2017 }
while (!eof() && !FormatTok->
Tok.
is(tok::colon));
2021 void UnwrappedLineParser::parseSwitch() {
2022 assert(FormatTok->
Tok.
is(tok::kw_switch) &&
"'switch' expected");
2024 if (FormatTok->
Tok.
is(tok::l_paren))
2026 if (FormatTok->
Tok.
is(tok::l_brace)) {
2033 parseStructuralElement();
2038 void UnwrappedLineParser::parseAccessSpecifier() {
2044 if (FormatTok->
Tok.
is(tok::colon))
2049 bool UnwrappedLineParser::parseEnum() {
2051 if (FormatTok->
Tok.
is(tok::kw_enum))
2057 if (Style.Language == FormatStyle::LK_JavaScript &&
2058 FormatTok->
isOneOf(tok::colon, tok::question))
2062 if (Style.Language == FormatStyle::LK_Proto && FormatTok->
is(tok::equal))
2066 if (FormatTok->
Tok.
is(tok::kw_class) || FormatTok->
Tok.
is(tok::kw_struct))
2070 FormatTok->
isOneOf(tok::colon, tok::coloncolon, tok::less,
2071 tok::greater, tok::comma, tok::question)) {
2074 if (FormatTok->
is(tok::l_paren))
2076 if (FormatTok->
is(tok::identifier)) {
2080 if (Style.isCpp() && FormatTok->
is(tok::identifier))
2086 if (FormatTok->
isNot(tok::l_brace))
2090 if (Style.Language == FormatStyle::LK_Java) {
2092 parseJavaEnumBody();
2095 if (Style.Language == FormatStyle::LK_Proto) {
2102 bool HasError = !parseBracedList(
true);
2104 if (FormatTok->
is(tok::semi))
2115 void UnwrappedLineParser::parseJavaEnumBody() {
2120 bool IsSimple =
true;
2123 if (Tok->
is(tok::r_brace))
2125 if (Tok->
isOneOf(tok::l_brace, tok::semi)) {
2150 if (FormatTok->
is(tok::l_brace)) {
2152 parseBlock(
true,
true,
2154 }
else if (FormatTok->
is(tok::l_paren)) {
2156 }
else if (FormatTok->
is(tok::comma)) {
2159 }
else if (FormatTok->
is(tok::semi)) {
2163 }
else if (FormatTok->
is(tok::r_brace)) {
2178 void UnwrappedLineParser::parseRecord(
bool ParseAsExpr) {
2184 while (FormatTok->
isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
2185 tok::kw___attribute, tok::kw___declspec,
2187 ((Style.Language == FormatStyle::LK_Java ||
2188 Style.Language == FormatStyle::LK_JavaScript) &&
2189 FormatTok->
isOneOf(tok::period, tok::comma))) {
2190 if (Style.Language == FormatStyle::LK_JavaScript &&
2196 if (FormatTok->
is(tok::l_brace)) {
2197 tryToParseBracedList();
2201 bool IsNonMacroIdentifier =
2202 FormatTok->
is(tok::identifier) &&
2206 if (!IsNonMacroIdentifier && FormatTok->
Tok.
is(tok::l_paren))
2220 if (FormatTok->
isOneOf(tok::colon, tok::less)) {
2222 if (FormatTok->
is(tok::l_brace)) {
2223 calculateBraceTypes(
true);
2224 if (!tryToParseBracedList())
2227 if (FormatTok->
Tok.
is(tok::semi))
2232 if (FormatTok->
Tok.
is(tok::l_brace)) {
2239 parseBlock(
true,
true,
2248 void UnwrappedLineParser::parseObjCMethod() {
2249 assert(FormatTok->
Tok.
isOneOf(tok::l_paren, tok::identifier) &&
2250 "'(' or identifier expected.");
2252 if (FormatTok->
Tok.
is(tok::semi)) {
2256 }
else if (FormatTok->
Tok.
is(tok::l_brace)) {
2257 if (Style.BraceWrapping.AfterFunction)
2268 void UnwrappedLineParser::parseObjCProtocolList() {
2269 assert(FormatTok->
Tok.
is(tok::less) &&
"'<' expected.");
2273 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
2276 }
while (!eof() && FormatTok->
Tok.
isNot(tok::greater));
2280 void UnwrappedLineParser::parseObjCUntilAtEnd() {
2287 if (FormatTok->
is(tok::l_brace)) {
2291 }
else if (FormatTok->
is(tok::r_brace)) {
2295 }
else if (FormatTok->
isOneOf(tok::minus, tok::plus)) {
2299 parseStructuralElement();
2304 void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
2312 if (FormatTok->
Tok.
is(tok::less)) {
2320 unsigned NumOpenAngles = 1;
2324 if (FormatTok->
isOneOf(tok::semi, tok::l_brace) ||
2327 if (FormatTok->
Tok.
is(tok::less))
2329 else if (FormatTok->
Tok.
is(tok::greater)) {
2330 assert(NumOpenAngles > 0 &&
"'>' makes NumOpenAngles negative");
2333 }
while (!eof() && NumOpenAngles != 0);
2336 if (FormatTok->
Tok.
is(tok::colon)) {
2339 }
else if (FormatTok->
Tok.
is(tok::l_paren))
2343 if (FormatTok->
Tok.
is(tok::less))
2344 parseObjCProtocolList();
2346 if (FormatTok->
Tok.
is(tok::l_brace)) {
2347 if (Style.BraceWrapping.AfterObjCDeclaration)
2356 parseObjCUntilAtEnd();
2361 bool UnwrappedLineParser::parseObjCProtocol() {
2365 if (FormatTok->
is(tok::l_paren))
2376 if (FormatTok->
Tok.
is(tok::less))
2377 parseObjCProtocolList();
2380 if (FormatTok->
Tok.
is(tok::semi)) {
2387 parseObjCUntilAtEnd();
2391 void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
2392 bool IsImport = FormatTok->
is(Keywords.
kw_import);
2393 assert(IsImport || FormatTok->
is(tok::kw_export));
2397 if (FormatTok->
is(tok::kw_default))
2414 if (!IsImport && !FormatTok->
isOneOf(tok::l_brace, tok::star) &&
2419 if (FormatTok->
is(tok::semi))
2421 if (Line->Tokens.empty()) {
2426 if (FormatTok->
is(tok::l_brace)) {
2436 void UnwrappedLineParser::parseStatementMacro() {
2438 if (FormatTok->
is(tok::l_paren))
2440 if (FormatTok->
is(tok::semi))
2446 StringRef Prefix =
"") {
2447 llvm::dbgs() << Prefix <<
"Line(" << Line.
Level 2450 for (std::list<UnwrappedLineNode>::const_iterator I = Line.
Tokens.begin(),
2453 llvm::dbgs() << I->Tok->Tok.getName() <<
"[" 2454 <<
"T=" << I->Tok->Type <<
", OC=" << I->Tok->OriginalColumn
2457 for (std::list<UnwrappedLineNode>::const_iterator I = Line.
Tokens.begin(),
2468 llvm::dbgs() <<
"\n";
2471 void UnwrappedLineParser::addUnwrappedLine() {
2472 if (Line->Tokens.empty())
2475 if (CurrentLines == &Lines)
2478 CurrentLines->push_back(std::move(*Line));
2479 Line->Tokens.clear();
2481 Line->FirstStartColumn = 0;
2482 if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
2483 CurrentLines->append(
2484 std::make_move_iterator(PreprocessorDirectives.begin()),
2485 std::make_move_iterator(PreprocessorDirectives.end()));
2486 PreprocessorDirectives.clear();
2492 bool UnwrappedLineParser::eof()
const {
return FormatTok->
Tok.
is(
tok::eof); }
2494 bool UnwrappedLineParser::isOnNewLine(
const FormatToken &FormatTok) {
2504 const llvm::Regex &CommentPragmasRegex) {
2508 StringRef IndentContent = FormatTok.
TokenText;
2509 if (FormatTok.
TokenText.startswith(
"//") ||
2511 IndentContent = FormatTok.
TokenText.substr(2);
2512 if (CommentPragmasRegex.match(IndentContent))
2587 if (PreviousToken && PreviousToken->
is(tok::l_brace) &&
2588 isLineComment(*Node.
Tok)) {
2589 MinColumnToken = PreviousToken;
2592 PreviousToken = Node.
Tok;
2596 MinColumnToken = Node.
Tok;
2599 if (PreviousToken && PreviousToken->
is(tok::l_brace)) {
2600 MinColumnToken = PreviousToken;
2603 return continuesLineComment(FormatTok, Line.
Tokens.back().Tok,
2607 void UnwrappedLineParser::flushComments(
bool NewlineBeforeNext) {
2608 bool JustComments = Line->Tokens.empty();
2610 I = CommentsBeforeNextToken.begin(),
2611 E = CommentsBeforeNextToken.end();
2623 if (isOnNewLine(**I) && JustComments && !(*I)->ContinuesLineCommentSection)
2627 if (NewlineBeforeNext && JustComments)
2629 CommentsBeforeNextToken.clear();
2632 void UnwrappedLineParser::nextToken(
int LevelDifference) {
2635 flushComments(isOnNewLine(*FormatTok));
2636 pushToken(FormatTok);
2638 if (Style.Language != FormatStyle::LK_JavaScript)
2639 readToken(LevelDifference);
2641 readTokenWithJavaScriptASI();
2645 void UnwrappedLineParser::distributeComments(
2666 if (Comments.empty())
2668 bool ShouldPushCommentsInCurrentLine =
true;
2669 bool HasTrailAlignedWithNextToken =
false;
2670 unsigned StartOfTrailAlignedWithNextToken = 0;
2673 for (
unsigned i = Comments.size() - 1; i > 0; --i) {
2675 HasTrailAlignedWithNextToken =
true;
2676 StartOfTrailAlignedWithNextToken = i;
2680 for (
unsigned i = 0, e = Comments.size(); i < e; ++i) {
2682 if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
2689 (isOnNewLine(*FormatTok) || FormatTok->
IsFirst)) {
2690 ShouldPushCommentsInCurrentLine =
false;
2692 if (ShouldPushCommentsInCurrentLine) {
2693 pushToken(FormatTok);
2695 CommentsBeforeNextToken.push_back(FormatTok);
2700 void UnwrappedLineParser::readToken(
int LevelDifference) {
2705 while (!Line->InPPDirective && FormatTok->
Tok.
is(tok::hash) &&
2707 distributeComments(Comments, FormatTok);
2711 bool SwitchToPreprocessorLines = !Line->Tokens.empty();
2713 assert((LevelDifference >= 0 ||
2714 static_cast<unsigned>(-LevelDifference) <= Line->Level) &&
2715 "LevelDifference makes Line->Level negative");
2716 Line->Level += LevelDifference;
2720 if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
2722 Line->Level += PPBranchLevel;
2723 flushComments(isOnNewLine(*FormatTok));
2726 while (FormatTok->
Type == TT_ConflictStart ||
2727 FormatTok->
Type == TT_ConflictEnd ||
2728 FormatTok->
Type == TT_ConflictAlternative) {
2729 if (FormatTok->
Type == TT_ConflictStart) {
2730 conditionalCompilationStart(
false);
2731 }
else if (FormatTok->
Type == TT_ConflictAlternative) {
2732 conditionalCompilationAlternative();
2733 }
else if (FormatTok->
Type == TT_ConflictEnd) {
2734 conditionalCompilationEnd();
2740 if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
2741 !Line->InPPDirective) {
2745 if (!FormatTok->
Tok.
is(tok::comment)) {
2746 distributeComments(Comments, FormatTok);
2751 Comments.push_back(FormatTok);
2754 distributeComments(Comments,
nullptr);
2760 if (MustBreakBeforeNextToken) {
2761 Line->Tokens.back().Tok->MustBreakBefore =
true;
2762 MustBreakBeforeNextToken =
false;
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
Parser - This implements a parser for the C family of languages.
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
tok::TokenKind getKind() const
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
Token - This structure provides full information about a lexed token.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
const AnnotatedLine * Line
SourceLocation getEnd() const
IdentifierInfo * getIdentifierInfo() const
This file contains the declaration of the UnwrappedLineParser, which turns a stream of tokens into Un...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
ast_type_traits::DynTypedNode Node
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Represents a complete lambda introducer.
SourceLocation getBegin() const