19#include "llvm/ADT/SmallPtrSet.h"
20#include "llvm/Support/Debug.h"
22#define DEBUG_TYPE "format-token-annotator"
31static bool startsWithInitStatement(
const AnnotatedLine &Line) {
47static bool canBeObjCSelectorComponent(
const FormatToken &Tok) {
48 return Tok.Tok.getIdentifierInfo();
53static bool isLambdaParameterList(
const FormatToken *Left) {
55 if (Left->Previous && Left->Previous->is(tok::greater) &&
56 Left->Previous->MatchingParen &&
57 Left->Previous->MatchingParen->is(TT_TemplateOpener)) {
58 Left = Left->Previous->MatchingParen;
62 return Left->Previous && Left->Previous->is(tok::r_square) &&
63 Left->Previous->MatchingParen &&
64 Left->Previous->MatchingParen->is(TT_LambdaLSquare);
69static bool isKeywordWithCondition(
const FormatToken &Tok) {
70 return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
71 tok::kw_constexpr, tok::kw_catch);
75static bool isCppAttribute(
bool IsCpp,
const FormatToken &Tok) {
76 if (!IsCpp || !Tok.startsSequence(tok::l_square, tok::l_square))
79 if (Tok.Previous && Tok.Previous->is(tok::at))
81 const FormatToken *AttrTok = Tok.Next->Next;
86 if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))
88 if (AttrTok->isNot(tok::identifier))
90 while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {
94 if (AttrTok->is(tok::colon) ||
95 AttrTok->startsSequence(tok::identifier, tok::identifier) ||
96 AttrTok->startsSequence(tok::r_paren, tok::identifier)) {
99 if (AttrTok->is(tok::ellipsis))
101 AttrTok = AttrTok->Next;
103 return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
111class AnnotatingParser {
113 AnnotatingParser(
const FormatStyle &Style, AnnotatedLine &Line,
114 const AdditionalKeywords &Keywords,
115 SmallVector<ScopeType> &Scopes)
116 : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(
false),
117 Keywords(Keywords), Scopes(Scopes) {
118 Contexts.push_back(Context(tok::unknown, 1,
false));
119 resetTokenMetadata();
123 ScopeType getScopeType(
const FormatToken &Token)
const {
124 switch (Token.getType()) {
125 case TT_FunctionLBrace:
126 case TT_LambdaLBrace:
129 case TT_StructLBrace:
138 if (!CurrentToken || !CurrentToken->Previous)
140 if (NonTemplateLess.count(CurrentToken->Previous) > 0)
143 const FormatToken &
Previous = *CurrentToken->Previous;
145 if (
Previous.Previous->Tok.isLiteral())
147 if (
Previous.Previous->is(tok::r_brace))
149 if (
Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 &&
150 (!
Previous.Previous->MatchingParen ||
151 Previous.Previous->MatchingParen->isNot(
152 TT_OverloadedOperatorLParen))) {
157 FormatToken *Left = CurrentToken->Previous;
158 Left->ParentBracket = Contexts.back().ContextKind;
159 ScopedContextCreator ContextCreator(*
this, tok::less, 12);
163 bool InExprContext = Contexts.back().IsExpression;
165 Contexts.back().IsExpression =
false;
168 if (Left->Previous && Left->Previous->isNot(tok::kw_template))
169 Contexts.back().ContextType = Context::TemplateArgument;
172 CurrentToken->is(tok::question)) {
176 while (CurrentToken) {
177 if (CurrentToken->is(tok::greater)) {
184 if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
185 Left->ParentBracket != tok::less &&
186 CurrentToken->getStartOfNonWhitespace() ==
187 CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset(
191 Left->MatchingParen = CurrentToken;
192 CurrentToken->MatchingParen = Left;
200 Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
201 CurrentToken->setType(TT_DictLiteral);
203 CurrentToken->setType(TT_TemplateCloser);
204 CurrentToken->Tok.setLength(1);
206 if (CurrentToken->Next && CurrentToken->Next->Tok.isLiteral())
211 if (CurrentToken->is(tok::question) &&
216 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
217 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
228 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
229 CurrentToken->Previous->is(TT_BinaryOperator) &&
230 Contexts[Contexts.size() - 2].IsExpression &&
231 !Line.startsWith(tok::kw_template)) {
234 updateParameterCount(Left, CurrentToken);
236 if (FormatToken *
Previous = CurrentToken->getPreviousNonComment()) {
237 if (CurrentToken->is(tok::colon) ||
238 (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
250 bool parseUntouchableParens() {
251 while (CurrentToken) {
252 CurrentToken->Finalized =
true;
253 switch (CurrentToken->Tok.getKind()) {
256 if (!parseUntouchableParens())
271 bool parseParens(
bool LookForDecls =
false) {
274 assert(CurrentToken->Previous &&
"Unknown previous token");
275 FormatToken &OpeningParen = *CurrentToken->Previous;
276 assert(OpeningParen.is(tok::l_paren));
277 FormatToken *PrevNonComment = OpeningParen.getPreviousNonComment();
278 OpeningParen.ParentBracket = Contexts.back().ContextKind;
279 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 1);
282 Contexts.back().ColonIsForRangeExpr =
283 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
285 if (OpeningParen.Previous &&
286 OpeningParen.Previous->is(TT_UntouchableMacroFunc)) {
287 OpeningParen.Finalized =
true;
288 return parseUntouchableParens();
291 bool StartsObjCMethodExpr =
false;
292 if (!Style.isVerilog()) {
293 if (FormatToken *MaybeSel = OpeningParen.Previous) {
295 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) &&
296 MaybeSel->Previous && MaybeSel->Previous->is(tok::at)) {
297 StartsObjCMethodExpr =
true;
302 if (OpeningParen.is(TT_OverloadedOperatorLParen)) {
304 FormatToken *Prev = &OpeningParen;
305 while (Prev->isNot(tok::kw_operator)) {
306 Prev = Prev->Previous;
307 assert(Prev &&
"Expect a kw_operator prior to the OperatorLParen!");
313 bool OperatorCalledAsMemberFunction =
314 Prev->Previous && Prev->Previous->isOneOf(tok::period, tok::arrow);
315 Contexts.back().IsExpression = OperatorCalledAsMemberFunction;
316 }
else if (OpeningParen.is(TT_VerilogInstancePortLParen)) {
317 Contexts.back().IsExpression =
true;
318 Contexts.back().ContextType = Context::VerilogInstancePortList;
319 }
else if (Style.isJavaScript() &&
320 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
321 Line.startsWith(tok::kw_export, Keywords.kw_type,
325 Contexts.back().IsExpression =
false;
326 }
else if (OpeningParen.Previous &&
327 (OpeningParen.Previous->isOneOf(
328 tok::kw_static_assert, tok::kw_noexcept, tok::kw_explicit,
329 tok::kw_while, tok::l_paren, tok::comma,
330 TT_BinaryOperator) ||
331 OpeningParen.Previous->isIf())) {
333 Contexts.back().IsExpression =
true;
334 }
else if (Style.isJavaScript() && OpeningParen.Previous &&
335 (OpeningParen.Previous->is(Keywords.kw_function) ||
336 (OpeningParen.Previous->endsSequence(tok::identifier,
337 Keywords.kw_function)))) {
339 Contexts.back().IsExpression =
false;
340 }
else if (Style.isJavaScript() && OpeningParen.Previous &&
341 OpeningParen.Previous->is(TT_JsTypeColon)) {
343 Contexts.back().IsExpression =
false;
344 }
else if (isLambdaParameterList(&OpeningParen)) {
346 Contexts.back().IsExpression =
false;
347 }
else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
348 Contexts.back().IsExpression =
false;
349 }
else if (OpeningParen.Previous &&
350 OpeningParen.Previous->is(tok::kw__Generic)) {
351 Contexts.back().ContextType = Context::C11GenericSelection;
352 Contexts.back().IsExpression =
true;
353 }
else if (Line.InPPDirective &&
354 (!OpeningParen.Previous ||
355 OpeningParen.Previous->isNot(tok::identifier))) {
356 Contexts.back().IsExpression =
true;
357 }
else if (Contexts[Contexts.size() - 2].CaretFound) {
359 Contexts.back().IsExpression =
false;
360 }
else if (OpeningParen.Previous &&
361 OpeningParen.Previous->is(TT_ForEachMacro)) {
363 Contexts.back().ContextType = Context::ForEachMacro;
364 Contexts.back().IsExpression =
false;
365 }
else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
366 OpeningParen.Previous->MatchingParen->isOneOf(
367 TT_ObjCBlockLParen, TT_FunctionTypeLParen)) {
368 Contexts.back().IsExpression =
false;
369 }
else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
371 OpeningParen.Previous &&
372 OpeningParen.Previous->isOneOf(tok::kw_for, tok::kw_catch);
373 Contexts.back().IsExpression = !IsForOrCatch;
378 if (PrevNonComment && OpeningParen.is(TT_Unknown)) {
379 if (PrevNonComment->isAttribute()) {
380 OpeningParen.setType(TT_AttributeLParen);
381 }
else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
384#include
"clang/Basic/TransformTypeTraits.def"
386 OpeningParen.setType(TT_TypeDeclarationParen);
388 if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))
389 Contexts.back().IsExpression =
true;
393 if (StartsObjCMethodExpr) {
394 Contexts.back().ColonIsObjCMethodExpr =
true;
395 OpeningParen.setType(TT_ObjCMethodExpr);
406 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
407 bool ProbablyFunctionType =
408 CurrentToken->isOneOf(tok::star, tok::amp, tok::ampamp, tok::caret);
409 bool HasMultipleLines =
false;
410 bool HasMultipleParametersOnALine =
false;
411 bool MightBeObjCForRangeLoop =
412 OpeningParen.Previous && OpeningParen.Previous->is(tok::kw_for);
413 FormatToken *PossibleObjCForInToken =
nullptr;
414 while (CurrentToken) {
419 if (LookForDecls && CurrentToken->Next) {
420 FormatToken *Prev = CurrentToken->getPreviousNonComment();
422 FormatToken *PrevPrev = Prev->getPreviousNonComment();
423 FormatToken *Next = CurrentToken->Next;
424 if (PrevPrev && PrevPrev->is(tok::identifier) &&
425 PrevPrev->isNot(TT_TypeName) &&
426 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
427 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
428 Prev->setType(TT_BinaryOperator);
429 LookForDecls =
false;
434 if (CurrentToken->Previous->is(TT_PointerOrReference) &&
435 CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
437 ProbablyFunctionType =
true;
439 if (CurrentToken->is(tok::comma))
440 MightBeFunctionType =
false;
441 if (CurrentToken->Previous->is(TT_BinaryOperator))
442 Contexts.back().IsExpression =
true;
443 if (CurrentToken->is(tok::r_paren)) {
444 if (OpeningParen.isNot(TT_CppCastLParen) && MightBeFunctionType &&
445 ProbablyFunctionType && CurrentToken->Next &&
446 (CurrentToken->Next->is(tok::l_paren) ||
447 (CurrentToken->Next->is(tok::l_square) &&
448 Line.MustBeDeclaration))) {
449 OpeningParen.setType(OpeningParen.Next->is(tok::caret)
451 : TT_FunctionTypeLParen);
453 OpeningParen.MatchingParen = CurrentToken;
454 CurrentToken->MatchingParen = &OpeningParen;
456 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
457 OpeningParen.Previous && OpeningParen.Previous->is(tok::l_paren)) {
461 for (FormatToken *Tok = &OpeningParen; Tok != CurrentToken;
463 if (Tok->is(TT_BinaryOperator) &&
464 Tok->isOneOf(tok::star, tok::amp, tok::ampamp)) {
465 Tok->setType(TT_PointerOrReference);
470 if (StartsObjCMethodExpr) {
471 CurrentToken->setType(TT_ObjCMethodExpr);
472 if (Contexts.back().FirstObjCSelectorName) {
473 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
474 Contexts.back().LongestObjCSelectorName;
478 if (OpeningParen.is(TT_AttributeLParen))
479 CurrentToken->setType(TT_AttributeRParen);
480 if (OpeningParen.is(TT_TypeDeclarationParen))
481 CurrentToken->setType(TT_TypeDeclarationParen);
482 if (OpeningParen.Previous &&
483 OpeningParen.Previous->is(TT_JavaAnnotation)) {
484 CurrentToken->setType(TT_JavaAnnotation);
486 if (OpeningParen.Previous &&
487 OpeningParen.Previous->is(TT_LeadingJavaAnnotation)) {
488 CurrentToken->setType(TT_LeadingJavaAnnotation);
490 if (OpeningParen.Previous &&
491 OpeningParen.Previous->is(TT_AttributeSquare)) {
492 CurrentToken->setType(TT_AttributeSquare);
495 if (!HasMultipleLines)
497 else if (HasMultipleParametersOnALine)
505 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
508 if (CurrentToken->is(tok::l_brace) && OpeningParen.is(TT_ObjCBlockLParen))
509 OpeningParen.setType(TT_Unknown);
510 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
511 !CurrentToken->Next->HasUnescapedNewline &&
512 !CurrentToken->Next->isTrailingComment()) {
513 HasMultipleParametersOnALine =
true;
515 bool ProbablyFunctionTypeLParen =
516 (CurrentToken->is(tok::l_paren) && CurrentToken->Next &&
517 CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret));
518 if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
519 CurrentToken->Previous->isSimpleTypeSpecifier()) &&
520 !(CurrentToken->is(tok::l_brace) ||
521 (CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) {
522 Contexts.back().IsExpression =
false;
524 if (CurrentToken->isOneOf(tok::semi, tok::colon)) {
525 MightBeObjCForRangeLoop =
false;
526 if (PossibleObjCForInToken) {
527 PossibleObjCForInToken->setType(TT_Unknown);
528 PossibleObjCForInToken =
nullptr;
531 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
532 PossibleObjCForInToken = CurrentToken;
533 PossibleObjCForInToken->setType(TT_ObjCForIn);
537 if (CurrentToken->is(tok::comma))
538 Contexts.back().CanBeExpression =
true;
540 FormatToken *Tok = CurrentToken;
543 updateParameterCount(&OpeningParen, Tok);
544 if (CurrentToken && CurrentToken->HasUnescapedNewline)
545 HasMultipleLines =
true;
550 bool isCSharpAttributeSpecifier(
const FormatToken &Tok) {
551 if (!Style.isCSharp())
555 if (Tok.Previous && Tok.Previous->is(tok::identifier))
559 if (Tok.Previous && Tok.Previous->is(tok::r_square)) {
560 auto *MatchingParen = Tok.Previous->MatchingParen;
561 if (!MatchingParen || MatchingParen->is(TT_ArraySubscriptLSquare))
565 const FormatToken *AttrTok = Tok.Next;
570 if (AttrTok->is(tok::r_square))
574 while (AttrTok && AttrTok->isNot(tok::r_square))
575 AttrTok = AttrTok->Next;
581 AttrTok = AttrTok->Next;
586 if (AttrTok->isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
587 tok::comment, tok::kw_class, tok::kw_static,
588 tok::l_square, Keywords.kw_internal)) {
594 AttrTok->Next->startsSequence(tok::identifier, tok::l_paren)) {
609 FormatToken *Left = CurrentToken->Previous;
610 Left->ParentBracket = Contexts.back().ContextKind;
611 FormatToken *
Parent = Left->getPreviousNonComment();
616 bool CppArrayTemplates =
617 Style.isCpp() &&
Parent &&
Parent->is(TT_TemplateCloser) &&
618 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
619 Contexts.back().ContextType == Context::TemplateArgument);
621 const bool IsInnerSquare = Contexts.back().InCpp11AttributeSpecifier;
622 const bool IsCpp11AttributeSpecifier =
623 isCppAttribute(Style.isCpp(), *Left) || IsInnerSquare;
626 bool IsCSharpAttributeSpecifier =
627 isCSharpAttributeSpecifier(*Left) ||
628 Contexts.back().InCSharpAttributeSpecifier;
630 bool InsideInlineASM = Line.startsWith(tok::kw_asm);
631 bool IsCppStructuredBinding = Left->isCppStructuredBinding(Style);
632 bool StartsObjCMethodExpr =
633 !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
634 Style.isCpp() && !IsCpp11AttributeSpecifier &&
635 !IsCSharpAttributeSpecifier && Contexts.back().CanBeExpression &&
636 Left->isNot(TT_LambdaLSquare) &&
637 !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
639 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
640 tok::kw_return, tok::kw_throw) ||
641 Parent->isUnaryOperator() ||
643 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
646 bool ColonFound =
false;
648 unsigned BindingIncrease = 1;
649 if (IsCppStructuredBinding) {
650 Left->setType(TT_StructuredBindingLSquare);
651 }
else if (Left->is(TT_Unknown)) {
652 if (StartsObjCMethodExpr) {
653 Left->setType(TT_ObjCMethodExpr);
654 }
else if (InsideInlineASM) {
655 Left->setType(TT_InlineASMSymbolicNameLSquare);
656 }
else if (IsCpp11AttributeSpecifier) {
657 Left->setType(TT_AttributeSquare);
658 if (!IsInnerSquare && Left->Previous)
659 Left->Previous->EndsCppAttributeGroup =
false;
660 }
else if (Style.isJavaScript() &&
Parent &&
661 Contexts.back().ContextKind == tok::l_brace &&
662 Parent->isOneOf(tok::l_brace, tok::comma)) {
663 Left->setType(TT_JsComputedPropertyName);
664 }
else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace &&
666 Left->setType(TT_DesignatedInitializerLSquare);
667 }
else if (IsCSharpAttributeSpecifier) {
668 Left->setType(TT_AttributeSquare);
669 }
else if (CurrentToken->is(tok::r_square) &&
Parent &&
670 Parent->is(TT_TemplateCloser)) {
671 Left->setType(TT_ArraySubscriptLSquare);
700 Left->setType(TT_ArrayInitializerLSquare);
701 if (!Left->endsSequence(tok::l_square, tok::numeric_constant,
703 !Left->endsSequence(tok::l_square, tok::numeric_constant,
705 !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
706 Left->setType(TT_ProtoExtensionLSquare);
707 BindingIncrease = 10;
709 }
else if (!CppArrayTemplates &&
Parent &&
710 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
711 tok::comma, tok::l_paren, tok::l_square,
712 tok::question, tok::colon, tok::kw_return,
715 Left->setType(TT_ArrayInitializerLSquare);
717 BindingIncrease = 10;
718 Left->setType(TT_ArraySubscriptLSquare);
722 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
723 Contexts.back().IsExpression =
true;
724 if (Style.isJavaScript() &&
Parent &&
Parent->is(TT_JsTypeColon))
725 Contexts.back().IsExpression =
false;
727 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
728 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
729 Contexts.back().InCSharpAttributeSpecifier = IsCSharpAttributeSpecifier;
731 while (CurrentToken) {
732 if (CurrentToken->is(tok::r_square)) {
733 if (IsCpp11AttributeSpecifier) {
734 CurrentToken->setType(TT_AttributeSquare);
736 CurrentToken->EndsCppAttributeGroup =
true;
738 if (IsCSharpAttributeSpecifier) {
739 CurrentToken->setType(TT_AttributeSquare);
740 }
else if (((CurrentToken->Next &&
741 CurrentToken->Next->is(tok::l_paren)) ||
742 (CurrentToken->Previous &&
743 CurrentToken->Previous->Previous == Left)) &&
744 Left->is(TT_ObjCMethodExpr)) {
749 StartsObjCMethodExpr =
false;
750 Left->setType(TT_Unknown);
752 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
753 CurrentToken->setType(TT_ObjCMethodExpr);
756 if (!ColonFound && CurrentToken->Previous &&
757 CurrentToken->Previous->is(TT_Unknown) &&
758 canBeObjCSelectorComponent(*CurrentToken->Previous)) {
759 CurrentToken->Previous->setType(TT_SelectorName);
765 Parent->overwriteFixedType(TT_BinaryOperator);
768 if (CurrentToken->getType() == TT_ObjCMethodExpr &&
769 CurrentToken->Next && CurrentToken->Next->is(TT_LambdaArrow)) {
770 CurrentToken->Next->overwriteFixedType(TT_Unknown);
772 Left->MatchingParen = CurrentToken;
773 CurrentToken->MatchingParen = Left;
778 if (!Contexts.back().FirstObjCSelectorName) {
779 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
781 Previous->ObjCSelectorNameParts = 1;
782 Contexts.back().FirstObjCSelectorName =
Previous;
785 Left->ParameterCount =
786 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
788 if (Contexts.back().FirstObjCSelectorName) {
789 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
790 Contexts.back().LongestObjCSelectorName;
791 if (Left->BlockParameterCount > 1)
792 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
797 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
799 if (CurrentToken->is(tok::colon)) {
800 if (IsCpp11AttributeSpecifier &&
801 CurrentToken->endsSequence(tok::colon, tok::identifier,
805 CurrentToken->setType(TT_AttributeColon);
806 }
else if (!Style.isVerilog() && !Line.InPragmaDirective &&
807 Left->isOneOf(TT_ArraySubscriptLSquare,
808 TT_DesignatedInitializerLSquare)) {
809 Left->setType(TT_ObjCMethodExpr);
810 StartsObjCMethodExpr =
true;
811 Contexts.back().ColonIsObjCMethodExpr =
true;
814 Parent->setType(TT_CastRParen);
819 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
821 Left->setType(TT_ArrayInitializerLSquare);
823 FormatToken *Tok = CurrentToken;
826 updateParameterCount(Left, Tok);
831 bool couldBeInStructArrayInitializer()
const {
832 if (Contexts.size() < 2)
836 const auto End = std::next(Contexts.rbegin(), 2);
837 auto Last = Contexts.rbegin();
840 if (
Last->ContextKind == tok::l_brace)
842 return Depth == 2 &&
Last->ContextKind != tok::l_brace;
849 assert(CurrentToken->Previous);
850 FormatToken &OpeningBrace = *CurrentToken->Previous;
851 assert(OpeningBrace.is(tok::l_brace));
852 OpeningBrace.ParentBracket = Contexts.back().ContextKind;
854 if (Contexts.back().CaretFound)
855 OpeningBrace.overwriteFixedType(TT_ObjCBlockLBrace);
856 Contexts.back().CaretFound =
false;
858 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
859 Contexts.back().ColonIsDictLiteral =
true;
861 Contexts.back().IsExpression =
true;
862 if (Style.isJavaScript() && OpeningBrace.Previous &&
863 OpeningBrace.Previous->is(TT_JsTypeColon)) {
864 Contexts.back().IsExpression =
false;
866 if (Style.isVerilog() &&
867 (!OpeningBrace.getPreviousNonComment() ||
868 OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
869 Contexts.back().VerilogMayBeConcatenation =
true;
872 unsigned CommaCount = 0;
873 while (CurrentToken) {
874 if (CurrentToken->is(tok::r_brace)) {
875 assert(!Scopes.empty());
876 assert(Scopes.back() == getScopeType(OpeningBrace));
878 assert(OpeningBrace.Optional == CurrentToken->Optional);
879 OpeningBrace.MatchingParen = CurrentToken;
880 CurrentToken->MatchingParen = &OpeningBrace;
882 if (OpeningBrace.ParentBracket == tok::l_brace &&
883 couldBeInStructArrayInitializer() && CommaCount > 0) {
884 Contexts.back().ContextType = Context::StructArrayInitializer;
890 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
892 updateParameterCount(&OpeningBrace, CurrentToken);
893 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
894 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
895 if (
Previous->is(TT_JsTypeOptionalQuestion))
897 if ((CurrentToken->is(tok::colon) &&
898 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
901 OpeningBrace.setType(TT_DictLiteral);
902 if (
Previous->Tok.getIdentifierInfo() ||
903 Previous->is(tok::string_literal)) {
907 if (CurrentToken->is(tok::colon) && OpeningBrace.is(TT_Unknown))
908 OpeningBrace.setType(TT_DictLiteral);
909 else if (Style.isJavaScript())
910 OpeningBrace.overwriteFixedType(TT_DictLiteral);
912 if (CurrentToken->is(tok::comma)) {
913 if (Style.isJavaScript())
914 OpeningBrace.overwriteFixedType(TT_DictLiteral);
923 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
927 if (Current->is(tok::l_brace) && Current->is(
BK_Block))
928 ++Left->BlockParameterCount;
929 if (Current->is(tok::comma)) {
930 ++Left->ParameterCount;
932 Left->Role.reset(
new CommaSeparatedList(Style));
933 Left->Role->CommaFound(Current);
934 }
else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
935 Left->ParameterCount = 1;
939 bool parseConditional() {
940 while (CurrentToken) {
941 if (CurrentToken->is(tok::colon)) {
942 CurrentToken->setType(TT_ConditionalExpr);
952 bool parseTemplateDeclaration() {
953 if (CurrentToken && CurrentToken->is(tok::less)) {
954 CurrentToken->setType(TT_TemplateOpener);
959 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
965 bool consumeToken() {
966 FormatToken *Tok = CurrentToken;
970 if (Tok->is(TT_VerilogTableItem))
972 switch (Tok->Tok.getKind()) {
975 if (!Tok->Previous && Line.MustBeDeclaration)
976 Tok->setType(TT_ObjCMethodSpecifier);
983 if (Tok->isTypeFinalized())
986 if (Style.isJavaScript()) {
987 if (Contexts.back().ColonIsForRangeExpr ||
988 (Contexts.size() == 1 &&
989 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
990 Contexts.back().ContextKind == tok::l_paren ||
991 Contexts.back().ContextKind == tok::l_square ||
992 (!Contexts.back().IsExpression &&
993 Contexts.back().ContextKind == tok::l_brace) ||
994 (Contexts.size() == 1 &&
995 Line.MustBeDeclaration)) {
996 Contexts.back().IsExpression =
false;
997 Tok->setType(TT_JsTypeColon);
1000 }
else if (Style.isCSharp()) {
1001 if (Contexts.back().InCSharpAttributeSpecifier) {
1002 Tok->setType(TT_AttributeColon);
1005 if (Contexts.back().ContextKind == tok::l_paren) {
1006 Tok->setType(TT_CSharpNamedArgumentColon);
1009 }
else if (Style.isVerilog() && Tok->isNot(TT_BinaryOperator)) {
1012 if (Keywords.isVerilogEnd(*Tok->Previous) ||
1013 Keywords.isVerilogBegin(*Tok->Previous)) {
1014 Tok->setType(TT_VerilogBlockLabelColon);
1015 }
else if (Contexts.back().ContextKind == tok::l_square) {
1016 Tok->setType(TT_BitFieldColon);
1017 }
else if (Contexts.back().ColonIsDictLiteral) {
1018 Tok->setType(TT_DictLiteral);
1019 }
else if (Contexts.size() == 1) {
1023 Tok->setType(TT_CaseLabelColon);
1024 if (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))
1029 if (Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) ||
1030 Line.First->startsSequence(tok::kw_export, Keywords.kw_module) ||
1031 Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) {
1032 Tok->setType(TT_ModulePartitionColon);
1033 }
else if (Contexts.back().ColonIsDictLiteral ||
1036 Tok->setType(TT_DictLiteral);
1038 if (FormatToken *
Previous = Tok->getPreviousNonComment())
1039 Previous->setType(TT_SelectorName);
1041 }
else if (Contexts.back().ColonIsObjCMethodExpr ||
1042 Line.startsWith(TT_ObjCMethodSpecifier)) {
1043 Tok->setType(TT_ObjCMethodExpr);
1044 const FormatToken *BeforePrevious = Tok->Previous->Previous;
1047 bool UnknownIdentifierInMethodDeclaration =
1048 Line.startsWith(TT_ObjCMethodSpecifier) &&
1049 Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
1050 if (!BeforePrevious ||
1052 !(BeforePrevious->is(TT_CastRParen) ||
1053 (BeforePrevious->is(TT_ObjCMethodExpr) &&
1054 BeforePrevious->is(tok::colon))) ||
1055 BeforePrevious->is(tok::r_square) ||
1056 Contexts.back().LongestObjCSelectorName == 0 ||
1057 UnknownIdentifierInMethodDeclaration) {
1058 Tok->Previous->setType(TT_SelectorName);
1059 if (!Contexts.back().FirstObjCSelectorName) {
1060 Contexts.back().FirstObjCSelectorName = Tok->Previous;
1061 }
else if (Tok->Previous->ColumnWidth >
1062 Contexts.back().LongestObjCSelectorName) {
1063 Contexts.back().LongestObjCSelectorName =
1064 Tok->Previous->ColumnWidth;
1066 Tok->Previous->ParameterIndex =
1067 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
1068 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
1070 }
else if (Contexts.back().ColonIsForRangeExpr) {
1071 Tok->setType(TT_RangeBasedForLoopColon);
1072 }
else if (Contexts.back().ContextType == Context::C11GenericSelection) {
1073 Tok->setType(TT_GenericSelectionColon);
1074 }
else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
1075 Tok->setType(TT_BitFieldColon);
1076 }
else if (Contexts.size() == 1 &&
1077 !Line.First->isOneOf(tok::kw_enum, tok::kw_case,
1079 FormatToken *Prev = Tok->getPreviousNonComment();
1082 if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept) ||
1083 Prev->ClosesRequiresClause) {
1084 Tok->setType(TT_CtorInitializerColon);
1085 }
else if (Prev->is(tok::kw_try)) {
1087 FormatToken *PrevPrev = Prev->getPreviousNonComment();
1090 if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept))
1091 Tok->setType(TT_CtorInitializerColon);
1093 Tok->setType(TT_InheritanceColon);
1095 }
else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
1096 (Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
1097 (canBeObjCSelectorComponent(*Tok->Next) && Tok->Next->Next &&
1098 Tok->Next->Next->is(tok::colon)))) {
1101 Tok->setType(TT_ObjCMethodExpr);
1102 }
else if (Contexts.back().ContextKind == tok::l_paren &&
1103 !Line.InPragmaDirective) {
1104 Tok->setType(TT_InlineASMColon);
1111 if (Style.isJavaScript() && !Contexts.back().IsExpression)
1112 Tok->setType(TT_JsTypeOperator);
1116 CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier)) {
1121 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
1123 if (!parseParens(
true))
1128 if (Style.isJavaScript()) {
1130 if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
1131 (Tok->Next && Tok->Next->is(tok::colon))) {
1135 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
1138 if (Style.isCpp() && CurrentToken && CurrentToken->is(tok::kw_co_await))
1140 Contexts.back().ColonIsForRangeExpr =
true;
1141 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1152 if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
1153 Tok->Previous->MatchingParen &&
1154 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
1155 Tok->Previous->setType(TT_OverloadedOperator);
1156 Tok->Previous->MatchingParen->setType(TT_OverloadedOperator);
1157 Tok->setType(TT_OverloadedOperatorLParen);
1160 if (Style.isVerilog()) {
1166 auto IsInstancePort = [&]() {
1167 const FormatToken *Prev = Tok->getPreviousNonComment();
1168 const FormatToken *PrevPrev;
1176 if (!Prev || !(PrevPrev = Prev->getPreviousNonComment()))
1179 if (Keywords.isVerilogIdentifier(*Prev) &&
1180 Keywords.isVerilogIdentifier(*PrevPrev)) {
1184 if (Prev->is(Keywords.kw_verilogHash) &&
1185 Keywords.isVerilogIdentifier(*PrevPrev)) {
1189 if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::r_paren))
1192 if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::comma)) {
1193 const FormatToken *PrevParen = PrevPrev->getPreviousNonComment();
1194 if (PrevParen->is(tok::r_paren) && PrevParen->MatchingParen &&
1195 PrevParen->MatchingParen->is(TT_VerilogInstancePortLParen)) {
1202 if (IsInstancePort())
1203 Tok->setFinalizedType(TT_VerilogInstancePortLParen);
1208 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
1209 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
1210 !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) {
1211 if (
const auto *
Previous = Tok->Previous;
1214 !
Previous->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation))) {
1215 Line.MightBeFunctionDecl =
true;
1225 FormatToken *
Previous = Tok->getPreviousNonComment();
1227 Previous->setType(TT_SelectorName);
1229 Scopes.push_back(getScopeType(*Tok));
1235 Tok->setType(TT_TemplateOpener);
1243 Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
1244 Tok->setType(TT_DictLiteral);
1245 FormatToken *
Previous = Tok->getPreviousNonComment();
1247 Previous->setType(TT_SelectorName);
1250 Tok->setType(TT_BinaryOperator);
1251 NonTemplateLess.insert(Tok);
1261 if (!Scopes.empty())
1269 Tok->setType(TT_BinaryOperator);
1270 if (Tok->Previous && Tok->Previous->is(TT_TemplateCloser))
1271 Tok->SpacesRequiredBefore = 1;
1273 case tok::kw_operator:
1278 while (CurrentToken &&
1279 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
1280 if (CurrentToken->isOneOf(tok::star, tok::amp))
1281 CurrentToken->setType(TT_PointerOrReference);
1282 auto Next = CurrentToken->getNextNonComment();
1285 if (Next->is(tok::less))
1291 auto Previous = CurrentToken->getPreviousNonComment();
1293 if (CurrentToken->is(tok::comma) &&
Previous->isNot(tok::kw_operator))
1295 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, tok::comma,
1296 tok::star, tok::arrow, tok::amp, tok::ampamp) ||
1298 Previous->TokenText.startswith(
"\"\"")) {
1299 Previous->setType(TT_OverloadedOperator);
1300 if (CurrentToken->isOneOf(tok::less, tok::greater))
1304 if (CurrentToken && CurrentToken->is(tok::l_paren))
1305 CurrentToken->setType(TT_OverloadedOperatorLParen);
1306 if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator))
1307 CurrentToken->Previous->setType(TT_OverloadedOperator);
1310 if (Style.isJavaScript() && Tok->Next &&
1311 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
1312 tok::r_brace, tok::r_square)) {
1317 Tok->setType(TT_JsTypeOptionalQuestion);
1322 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
1323 Style.isJavaScript()) {
1326 if (Style.isCSharp()) {
1332 (Tok->Next->startsSequence(tok::question, tok::r_paren) ||
1333 Tok->Next->startsSequence(tok::question, tok::greater) ||
1334 Tok->Next->startsSequence(tok::question, tok::identifier,
1336 Tok->setType(TT_CSharpNullable);
1341 if (Tok->Next && Tok->Next->is(tok::identifier) && Tok->Next->Next &&
1342 Tok->Next->Next->is(tok::equal)) {
1343 Tok->setType(TT_CSharpNullable);
1352 if (!Contexts.back().IsExpression && Line.MustBeDeclaration &&
1354 !Tok->Next->isOneOf(tok::identifier, tok::string_literal) ||
1356 !Tok->Next->Next->isOneOf(tok::colon, tok::question))) {
1357 Tok->setType(TT_CSharpNullable);
1363 case tok::kw_template:
1364 parseTemplateDeclaration();
1367 switch (Contexts.back().ContextType) {
1368 case Context::CtorInitializer:
1369 Tok->setType(TT_CtorInitializerComma);
1371 case Context::InheritanceList:
1372 Tok->setType(TT_InheritanceComma);
1374 case Context::VerilogInstancePortList:
1375 Tok->setFinalizedType(TT_VerilogInstancePortComma);
1378 if (Style.isVerilog() && Contexts.size() == 1 &&
1379 Line.startsWith(Keywords.kw_assign)) {
1380 Tok->setFinalizedType(TT_VerilogAssignComma);
1381 }
else if (Contexts.back().FirstStartOfName &&
1382 (Contexts.size() == 1 || startsWithInitStatement(Line))) {
1383 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
1384 Line.IsMultiVariableDeclStmt =
true;
1388 if (Contexts.back().ContextType == Context::ForEachMacro)
1389 Contexts.back().IsExpression =
true;
1391 case tok::kw_default:
1393 if (Style.isVerilog() && Keywords.isVerilogEndOfLabel(*Tok) &&
1394 (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))) {
1398 case tok::identifier:
1399 if (Tok->isOneOf(Keywords.kw___has_include,
1400 Keywords.kw___has_include_next)) {
1403 if (Style.isCSharp() && Tok->is(Keywords.kw_where) && Tok->Next &&
1404 Tok->Next->isNot(tok::l_paren)) {
1405 Tok->setType(TT_CSharpGenericTypeConstraint);
1406 parseCSharpGenericTypeConstraint();
1407 if (!Tok->getPreviousNonComment())
1408 Line.IsContinuation =
true;
1412 if (Tok->isNot(TT_LambdaArrow) && Tok->Previous &&
1413 Tok->Previous->is(tok::kw_noexcept)) {
1414 Tok->setType(TT_TrailingReturnArrow);
1418 if (Style.InsertNewlineAtEOF && Tok->NewlinesBefore == 0)
1419 Tok->NewlinesBefore = 1;
1427 void parseCSharpGenericTypeConstraint() {
1428 int OpenAngleBracketsCount = 0;
1429 while (CurrentToken) {
1430 if (CurrentToken->is(tok::less)) {
1432 CurrentToken->setType(TT_TemplateOpener);
1433 ++OpenAngleBracketsCount;
1435 }
else if (CurrentToken->is(tok::greater)) {
1436 CurrentToken->setType(TT_TemplateCloser);
1437 --OpenAngleBracketsCount;
1439 }
else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) {
1442 CurrentToken->setType(TT_CSharpGenericTypeConstraintComma);
1444 }
else if (CurrentToken->is(Keywords.kw_where)) {
1445 CurrentToken->setType(TT_CSharpGenericTypeConstraint);
1447 }
else if (CurrentToken->is(tok::colon)) {
1448 CurrentToken->setType(TT_CSharpGenericTypeConstraintColon);
1456 void parseIncludeDirective() {
1457 if (CurrentToken && CurrentToken->is(tok::less)) {
1459 while (CurrentToken) {
1462 if (CurrentToken->isNot(tok::comment) &&
1463 !CurrentToken->TokenText.startswith(
"//")) {
1464 CurrentToken->setType(TT_ImplicitStringLiteral);
1471 void parseWarningOrError() {
1476 while (CurrentToken) {
1477 CurrentToken->setType(TT_ImplicitStringLiteral);
1482 void parsePragma() {
1485 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option,
1486 Keywords.kw_region)) {
1487 bool IsMarkOrRegion =
1488 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_region);
1491 while (CurrentToken) {
1492 if (IsMarkOrRegion || CurrentToken->Previous->is(TT_BinaryOperator))
1493 CurrentToken->setType(TT_ImplicitStringLiteral);
1499 void parseHasInclude() {
1500 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1503 parseIncludeDirective();
1507 LineType parsePreprocessorDirective() {
1508 bool IsFirstToken = CurrentToken->IsFirst;
1514 if (Style.isJavaScript() && IsFirstToken) {
1518 while (CurrentToken) {
1520 CurrentToken->setType(TT_ImplicitStringLiteral);
1526 if (CurrentToken->is(tok::numeric_constant)) {
1527 CurrentToken->SpacesRequiredBefore = 1;
1532 if (!CurrentToken->Tok.getIdentifierInfo())
1536 if (Style.isVerilog() && !Keywords.isVerilogPPDirective(*CurrentToken))
1538 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1539 case tok::pp_include:
1540 case tok::pp_include_next:
1541 case tok::pp_import:
1543 parseIncludeDirective();
1547 case tok::pp_warning:
1548 parseWarningOrError();
1550 case tok::pp_pragma:
1555 Contexts.back().IsExpression =
true;
1562 while (CurrentToken) {
1563 FormatToken *Tok = CurrentToken;
1565 if (Tok->is(tok::l_paren)) {
1567 }
else if (Tok->isOneOf(Keywords.kw___has_include,
1568 Keywords.kw___has_include_next)) {
1579 NonTemplateLess.clear();
1580 if (!Line.InMacroBody && CurrentToken->is(tok::hash)) {
1584 auto Type = parsePreprocessorDirective();
1592 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
1594 CurrentToken->is(Keywords.kw_package)) ||
1595 (!Style.isVerilog() && Info &&
1596 Info->getPPKeywordID() == tok::pp_import && CurrentToken->Next &&
1597 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
1600 parseIncludeDirective();
1606 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
1607 parseIncludeDirective();
1614 CurrentToken->isOneOf(Keywords.kw_option, Keywords.kw_package)) {
1616 if (CurrentToken && CurrentToken->is(tok::identifier)) {
1617 while (CurrentToken)
1623 bool KeywordVirtualFound =
false;
1624 bool ImportStatement =
false;
1627 if (Style.isJavaScript() && CurrentToken->is(Keywords.kw_import))
1628 ImportStatement =
true;
1630 while (CurrentToken) {
1631 if (CurrentToken->is(tok::kw_virtual))
1632 KeywordVirtualFound =
true;
1633 if (Style.isJavaScript()) {
1640 if (Line.First->is(tok::kw_export) &&
1641 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
1642 CurrentToken->Next->isStringLiteral()) {
1643 ImportStatement =
true;
1645 if (isClosureImportStatement(*CurrentToken))
1646 ImportStatement =
true;
1648 if (!consumeToken())
1651 if (KeywordVirtualFound)
1653 if (ImportStatement)
1656 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
1657 if (Contexts.back().FirstObjCSelectorName) {
1658 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
1659 Contexts.back().LongestObjCSelectorName;
1664 for (
const auto &ctx : Contexts)
1665 if (ctx.ContextType == Context::StructArrayInitializer)
1672 bool isClosureImportStatement(
const FormatToken &Tok) {
1675 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
1677 (Tok.Next->Next->TokenText ==
"module" ||
1678 Tok.Next->Next->TokenText ==
"provide" ||
1679 Tok.Next->Next->TokenText ==
"require" ||
1680 Tok.Next->Next->TokenText ==
"requireType" ||
1681 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
1682 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
1685 void resetTokenMetadata() {
1691 if (!CurrentToken->isTypeFinalized() &&
1692 !CurrentToken->isOneOf(
1693 TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
1694 TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
1695 TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
1696 TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
1697 TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
1698 TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro,
1699 TT_FunctionLikeOrFreestandingMacro, TT_ClassLBrace, TT_EnumLBrace,
1700 TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,
1701 TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
1702 TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
1703 TT_BracedListLBrace)) {
1704 CurrentToken->setType(TT_Unknown);
1706 CurrentToken->Role.reset();
1707 CurrentToken->MatchingParen =
nullptr;
1708 CurrentToken->FakeLParens.clear();
1709 CurrentToken->FakeRParens = 0;
1716 CurrentToken->NestingLevel = Contexts.size() - 1;
1717 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
1718 modifyContext(*CurrentToken);
1719 determineTokenType(*CurrentToken);
1720 CurrentToken = CurrentToken->Next;
1722 resetTokenMetadata();
1762 StructArrayInitializer,
1766 C11GenericSelection,
1768 VerilogInstancePortList,
1774 struct ScopedContextCreator {
1775 AnnotatingParser &
P;
1781 P.Contexts.back().BindingStrength + Increase,
1782 P.Contexts.back().IsExpression));
1785 ~ScopedContextCreator() {
1787 if (
P.Contexts.back().ContextType == Context::StructArrayInitializer) {
1788 P.Contexts.pop_back();
1789 P.Contexts.back().ContextType = Context::StructArrayInitializer;
1793 P.Contexts.pop_back();
1797 void modifyContext(
const FormatToken &Current) {
1798 auto AssignmentStartsExpression = [&]() {
1802 if (Line.First->isOneOf(tok::kw_using, tok::kw_return))
1804 if (Line.First->is(tok::kw_template)) {
1805 assert(Current.Previous);
1806 if (Current.Previous->is(tok::kw_operator)) {
1812 const FormatToken *Tok = Line.First->getNextNonComment();
1814 if (Tok->isNot(TT_TemplateOpener)) {
1821 if (Contexts.back().ContextKind == tok::less) {
1822 assert(Current.Previous->Previous);
1823 return !Current.Previous->Previous->isOneOf(tok::kw_typename,
1827 Tok = Tok->MatchingParen;
1830 Tok = Tok->getNextNonComment();
1834 if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_struct,
1844 if (Style.isJavaScript() &&
1845 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
1846 Line.startsWith(tok::kw_export, Keywords.kw_type,
1847 tok::identifier))) {
1851 return !Current.Previous || Current.Previous->isNot(tok::kw_operator);
1854 if (AssignmentStartsExpression()) {
1855 Contexts.back().IsExpression =
true;
1856 if (!Line.startsWith(TT_UnaryOperator)) {
1857 for (FormatToken *
Previous = Current.Previous;
1859 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
1861 if (
Previous->isOneOf(tok::r_square, tok::r_paren, tok::greater)) {
1868 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1869 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1871 Previous->setType(TT_PointerOrReference);
1875 }
else if (Current.is(tok::lessless) &&
1876 (!Current.Previous ||
1877 Current.Previous->isNot(tok::kw_operator))) {
1878 Contexts.back().IsExpression =
true;
1879 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1880 Contexts.back().IsExpression =
true;
1881 }
else if (Current.is(TT_TrailingReturnArrow)) {
1882 Contexts.back().IsExpression =
false;
1883 }
else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1885 }
else if (Current.Previous &&
1886 Current.Previous->is(TT_CtorInitializerColon)) {
1887 Contexts.back().IsExpression =
true;
1888 Contexts.back().ContextType = Context::CtorInitializer;
1889 }
else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
1890 Contexts.back().ContextType = Context::InheritanceList;
1891 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1892 for (FormatToken *
Previous = Current.Previous;
1895 Previous->setType(TT_PointerOrReference);
1897 if (Line.MustBeDeclaration &&
1898 Contexts.front().ContextType != Context::CtorInitializer) {
1899 Contexts.back().IsExpression =
false;
1901 }
else if (Current.is(tok::kw_new)) {
1902 Contexts.back().CanBeExpression =
false;
1903 }
else if (Current.is(tok::semi) ||
1904 (Current.is(tok::exclaim) && Current.Previous &&
1905 Current.Previous->isNot(tok::kw_operator))) {
1909 Contexts.back().IsExpression =
true;
1913 static FormatToken *untilMatchingParen(FormatToken *Current) {
1917 if (Current->is(tok::l_paren))
1919 if (Current->is(tok::r_paren))
1923 Current = Current->Next;
1928 static bool isDeductionGuide(FormatToken &Current) {
1930 if (Current.Previous && Current.Previous->is(tok::r_paren) &&
1931 Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
1933 FormatToken *TemplateCloser = Current.Next->Next;
1934 int NestingLevel = 0;
1935 while (TemplateCloser) {
1937 if (TemplateCloser->is(tok::l_paren)) {
1939 TemplateCloser = untilMatchingParen(TemplateCloser);
1940 if (!TemplateCloser)
1943 if (TemplateCloser->is(tok::less))
1945 if (TemplateCloser->is(tok::greater))
1947 if (NestingLevel < 1)
1949 TemplateCloser = TemplateCloser->Next;
1953 if (TemplateCloser && TemplateCloser->Next &&
1954 TemplateCloser->Next->is(tok::semi) &&
1955 Current.Previous->MatchingParen) {
1958 FormatToken *LeadingIdentifier =
1959 Current.Previous->MatchingParen->Previous;
1961 return LeadingIdentifier &&
1962 LeadingIdentifier->TokenText == Current.Next->TokenText;
1968 void determineTokenType(FormatToken &Current) {
1969 if (Current.isNot(TT_Unknown)) {
1974 if ((Style.isJavaScript() || Style.isCSharp()) &&
1975 Current.is(tok::exclaim)) {
1976 if (Current.Previous) {
1978 Style.isJavaScript()
1979 ? Keywords.IsJavaScriptIdentifier(
1980 *Current.Previous,
true)
1981 : Current.Previous->is(tok::identifier);
1983 Current.Previous->isOneOf(
1984 tok::kw_default, tok::kw_namespace, tok::r_paren, tok::r_square,
1985 tok::r_brace, tok::kw_false, tok::kw_true, Keywords.kw_type,
1986 Keywords.kw_get, Keywords.kw_init, Keywords.kw_set) ||
1987 Current.Previous->Tok.isLiteral()) {
1988 Current.setType(TT_NonNullAssertion);
1993 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1994 Current.setType(TT_NonNullAssertion);
2002 if (Current.is(Keywords.kw_instanceof)) {
2003 Current.setType(TT_BinaryOperator);
2004 }
else if (isStartOfName(Current) &&
2005 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
2006 Contexts.back().FirstStartOfName = &Current;
2007 Current.setType(TT_StartOfName);
2008 }
else if (Current.is(tok::semi)) {
2012 Contexts.back().FirstStartOfName =
nullptr;
2013 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
2015 }
else if (Current.is(tok::arrow) &&
2017 Current.setType(TT_LambdaArrow);
2018 }
else if (Current.is(tok::arrow) && AutoFound &&
2019 (Line.MightBeFunctionDecl || Line.InPPDirective) &&
2020 Current.NestingLevel == 0 &&
2021 !Current.Previous->isOneOf(tok::kw_operator, tok::identifier)) {
2023 Current.setType(TT_TrailingReturnArrow);
2024 }
else if (Current.is(tok::arrow) && Current.Previous &&
2025 Current.Previous->is(tok::r_brace)) {
2028 Current.setType(TT_TrailingReturnArrow);
2029 }
else if (isDeductionGuide(Current)) {
2031 Current.setType(TT_TrailingReturnArrow);
2032 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
2033 Current.setType(determineStarAmpUsage(
2035 Contexts.back().CanBeExpression && Contexts.back().IsExpression,
2036 Contexts.back().ContextType == Context::TemplateArgument));
2037 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret) ||
2038 (Style.isVerilog() && Current.is(tok::pipe))) {
2039 Current.setType(determinePlusMinusCaretUsage(Current));
2040 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
2041 Contexts.back().CaretFound =
true;
2042 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
2043 Current.setType(determineIncrementUsage(Current));
2044 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
2045 Current.setType(TT_UnaryOperator);
2046 }
else if (Current.is(tok::question)) {
2047 if (Style.isJavaScript() && Line.MustBeDeclaration &&
2048 !Contexts.back().IsExpression) {
2051 Current.setType(TT_JsTypeOptionalQuestion);
2053 Current.setType(TT_ConditionalExpr);
2055 }
else if (Current.isBinaryOperator() &&
2056 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
2057 (Current.isNot(tok::greater) &&
2059 if (Style.isVerilog()) {
2060 if (Current.is(tok::lessequal) && Contexts.size() == 1 &&
2061 !Contexts.back().VerilogAssignmentFound) {
2065 Current.setFinalizedType(TT_BinaryOperator);
2068 Contexts.back().VerilogAssignmentFound =
true;
2070 Current.setType(TT_BinaryOperator);
2071 }
else if (Current.is(tok::comment)) {
2072 if (Current.TokenText.startswith(
"/*")) {
2073 if (Current.TokenText.endswith(
"*/")) {
2074 Current.setType(TT_BlockComment);
2078 Current.Tok.setKind(tok::unknown);
2081 Current.setType(TT_LineComment);
2083 }
else if (Current.is(tok::string_literal)) {
2084 if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&
2085 Current.getPreviousNonComment() &&
2086 Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&
2087 Current.getNextNonComment() &&
2088 Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
2089 Current.setType(TT_StringInConcatenation);
2091 }
else if (Current.is(tok::l_paren)) {
2092 if (lParenStartsCppCast(Current))
2093 Current.setType(TT_CppCastLParen);
2094 }
else if (Current.is(tok::r_paren)) {
2095 if (rParenEndsCast(Current))
2096 Current.setType(TT_CastRParen);
2097 if (Current.MatchingParen && Current.Next &&
2098 !Current.Next->isBinaryOperator() &&
2099 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
2100 tok::comma, tok::period, tok::arrow,
2101 tok::coloncolon, tok::kw_noexcept)) {
2102 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
2104 if (AfterParen->isNot(tok::caret)) {
2105 if (FormatToken *BeforeParen = Current.MatchingParen->Previous) {
2106 if (BeforeParen->is(tok::identifier) &&
2107 BeforeParen->isNot(TT_TypenameMacro) &&
2108 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
2109 (!BeforeParen->Previous ||
2110 BeforeParen->Previous->ClosesTemplateDeclaration)) {
2111 Current.setType(TT_FunctionAnnotationRParen);
2117 }
else if (Current.is(tok::at) && Current.Next && !Style.isJavaScript() &&
2121 switch (Current.Next->Tok.getObjCKeywordID()) {
2122 case tok::objc_interface:
2123 case tok::objc_implementation:
2124 case tok::objc_protocol:
2125 Current.setType(TT_ObjCDecl);
2127 case tok::objc_property:
2128 Current.setType(TT_ObjCProperty);
2133 }
else if (Current.is(tok::period)) {
2134 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
2135 if (PreviousNoComment &&
2136 PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) {
2137 Current.setType(TT_DesignatedInitializerPeriod);
2139 Current.Previous->isOneOf(TT_JavaAnnotation,
2140 TT_LeadingJavaAnnotation)) {
2141 Current.setType(Current.Previous->getType());
2143 }
else if (canBeObjCSelectorComponent(Current) &&
2146 Current.Previous && Current.Previous->is(TT_CastRParen) &&
2147 Current.Previous->MatchingParen &&
2148 Current.Previous->MatchingParen->Previous &&
2149 Current.Previous->MatchingParen->Previous->is(
2150 TT_ObjCMethodSpecifier)) {
2154 Current.setType(TT_SelectorName);
2155 }
else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept,
2156 tok::kw_requires) &&
2158 !Current.Previous->isOneOf(tok::equal, tok::at,
2159 TT_CtorInitializerComma,
2160 TT_CtorInitializerColon) &&
2161 Line.MightBeFunctionDecl && Contexts.size() == 1) {
2164 Current.setType(TT_TrailingAnnotation);
2166 Style.isJavaScript()) &&
2168 if (Current.Previous->is(tok::at) &&
2169 Current.isNot(Keywords.kw_interface)) {
2170 const FormatToken &AtToken = *Current.Previous;
2171 const FormatToken *
Previous = AtToken.getPreviousNonComment();
2173 Current.setType(TT_LeadingJavaAnnotation);
2175 Current.setType(TT_JavaAnnotation);
2176 }
else if (Current.Previous->is(tok::period) &&
2177 Current.Previous->isOneOf(TT_JavaAnnotation,
2178 TT_LeadingJavaAnnotation)) {
2179 Current.setType(Current.Previous->getType());
2189 bool isStartOfName(
const FormatToken &Tok) {
2191 if (Style.isVerilog())
2194 if (Tok.isNot(tok::identifier) || !Tok.Previous)
2197 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
2201 if (Style.isJavaScript() && Tok.Previous->is(Keywords.kw_in))
2205 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
2208 if (!Style.isJavaScript())
2209 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
2210 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
2212 if (!PreviousNotConst)
2215 if (PreviousNotConst->ClosesRequiresClause)
2218 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
2219 PreviousNotConst->Previous &&
2220 PreviousNotConst->Previous->is(tok::hash);
2222 if (PreviousNotConst->is(TT_TemplateCloser)) {
2223 return PreviousNotConst && PreviousNotConst->MatchingParen &&
2224 PreviousNotConst->MatchingParen->Previous &&
2225 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
2226 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
2229 if (PreviousNotConst->is(tok::r_paren) &&
2230 PreviousNotConst->is(TT_TypeDeclarationParen)) {
2239 if (PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto))
2243 if (PreviousNotConst->is(TT_PointerOrReference))
2247 if (PreviousNotConst->isSimpleTypeSpecifier())
2252 PreviousNotConst->is(tok::r_square)) {
2257 return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const);
2261 bool lParenStartsCppCast(
const FormatToken &Tok) {
2266 FormatToken *LeftOfParens = Tok.getPreviousNonComment();
2267 if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) &&
2268 LeftOfParens->MatchingParen) {
2269 auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment();
2271 Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast,
2272 tok::kw_reinterpret_cast, tok::kw_static_cast)) {
2282 bool rParenEndsCast(
const FormatToken &Tok) {
2284 if (!Style.isCSharp() && !Style.isCpp() &&
2290 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
2293 if (Tok.MatchingParen->is(TT_OverloadedOperatorLParen))
2296 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
2300 if (LeftOfParens->is(tok::r_paren) &&
2301 LeftOfParens->isNot(TT_CastRParen)) {
2302 if (!LeftOfParens->MatchingParen ||
2303 !LeftOfParens->MatchingParen->Previous) {
2306 LeftOfParens = LeftOfParens->MatchingParen->Previous;
2309 if (LeftOfParens->is(tok::r_square)) {
2311 auto MayBeArrayDelete = [](FormatToken *Tok) -> FormatToken * {
2312 if (Tok->isNot(tok::r_square))
2315 Tok = Tok->getPreviousNonComment();
2316 if (!Tok || Tok->isNot(tok::l_square))
2319 Tok = Tok->getPreviousNonComment();
2320 if (!Tok || Tok->isNot(tok::kw_delete))
2324 if (FormatToken *MaybeDelete = MayBeArrayDelete(LeftOfParens))
2325 LeftOfParens = MaybeDelete;
2331 if (LeftOfParens->Tok.getIdentifierInfo() && LeftOfParens->Previous &&
2332 LeftOfParens->Previous->is(tok::kw_operator)) {
2338 if (LeftOfParens->Tok.getIdentifierInfo() &&
2339 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
2340 tok::kw_delete, tok::kw_throw)) {
2346 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
2347 TT_TemplateCloser, tok::ellipsis)) {
2352 if (Tok.Next->is(tok::question))
2356 if (Tok.Next->is(Keywords.kw_in) && Style.isCSharp())
2361 if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
2362 tok::kw_requires, tok::kw_throw, tok::arrow,
2363 Keywords.kw_override, Keywords.kw_final) ||
2364 isCppAttribute(Style.isCpp(), *Tok.Next)) {
2374 if (Tok.Next->isNot(tok::string_literal) &&
2375 (Tok.Next->Tok.isLiteral() ||
2376 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof))) {
2381 auto IsQualifiedPointerOrReference = [](FormatToken *T) {
2383 assert(!T->isSimpleTypeSpecifier() &&
"Should have already been checked");
2387 if (T->is(TT_AttributeRParen)) {
2389 assert(T->is(tok::r_paren));
2390 assert(T->MatchingParen);
2391 assert(T->MatchingParen->is(tok::l_paren));
2392 assert(T->MatchingParen->is(TT_AttributeLParen));
2393 if (
const auto *Tok = T->MatchingParen->Previous;
2394 Tok && Tok->isAttribute()) {
2398 }
else if (T->is(TT_AttributeSquare)) {
2400 if (T->MatchingParen && T->MatchingParen->Previous) {
2401 T = T->MatchingParen->Previous;
2404 }
else if (T->canBePointerOrReferenceQualifier()) {
2410 return T && T->is(TT_PointerOrReference);
2412 bool ParensAreType =
2414 Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) ||
2415 Tok.Previous->isSimpleTypeSpecifier() ||
2416 IsQualifiedPointerOrReference(Tok.Previous);
2417 bool ParensCouldEndDecl =
2418 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
2419 if (ParensAreType && !ParensCouldEndDecl)
2430 for (
const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
2431 Token = Token->Next) {
2432 if (Token->is(TT_BinaryOperator))
2438 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
2442 if (Tok.Next->is(tok::l_paren) && Tok.Previous && Tok.Previous->Previous) {
2443 if (Tok.Previous->is(tok::identifier) &&
2444 Tok.Previous->Previous->is(tok::l_paren)) {
2449 if (!Tok.Next->Next)
2455 const bool NextIsAmpOrStar = Tok.Next->isOneOf(tok::amp, tok::star);
2456 if (!(Tok.Next->isUnaryOperator() || NextIsAmpOrStar) ||
2457 Tok.Next->is(tok::plus) ||
2458 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant)) {
2461 if (NextIsAmpOrStar &&
2462 (Tok.Next->Next->is(tok::numeric_constant) || Line.InPPDirective)) {
2466 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
2467 Prev = Prev->Previous) {
2468 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
2475 bool determineUnaryOperatorByUsage(
const FormatToken &Tok) {
2476 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2486 if (PrevToken->isOneOf(
2487 TT_ConditionalExpr, tok::l_paren, tok::comma, tok::colon, tok::semi,
2488 tok::equal, tok::question, tok::l_square, tok::l_brace,
2489 tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,
2490 tok::kw_delete, tok::kw_return, tok::kw_throw)) {
2497 if (PrevToken->is(tok::kw_sizeof))
2501 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
2505 if (PrevToken->is(TT_BinaryOperator))
2513 bool InTemplateArgument) {
2514 if (Style.isJavaScript())
2515 return TT_BinaryOperator;
2518 if (Style.isCSharp() && Tok.is(tok::ampamp))
2519 return TT_BinaryOperator;
2521 if (Style.isVerilog()) {
2526 if (Tok.is(tok::star))
2527 return TT_BinaryOperator;
2528 return determineUnaryOperatorByUsage(Tok) ? TT_UnaryOperator
2529 : TT_BinaryOperator;
2532 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2534 return TT_UnaryOperator;
2535 if (PrevToken->is(TT_TypeName))
2536 return TT_PointerOrReference;
2538 const FormatToken *NextToken = Tok.getNextNonComment();
2540 if (InTemplateArgument && NextToken && NextToken->is(tok::kw_noexcept))
2541 return TT_BinaryOperator;
2544 NextToken->isOneOf(tok::arrow, tok::equal, tok::comma, tok::r_paren,
2545 TT_RequiresClause) ||
2547 NextToken->canBePointerOrReferenceQualifier() ||
2548 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) {
2549 return TT_PointerOrReference;
2552 if (PrevToken->is(tok::coloncolon))
2553 return TT_PointerOrReference;
2555 if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
2556 return TT_PointerOrReference;
2558 if (determineUnaryOperatorByUsage(Tok))
2559 return TT_UnaryOperator;
2561 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
2562 return TT_PointerOrReference;
2564 return TT_PointerOrReference;
2565 if (NextToken->isOneOf(tok::comma, tok::semi))
2566 return TT_PointerOrReference;
2578 if (PrevToken->is(tok::r_brace) && Tok.is(tok::star) &&
2579 !PrevToken->MatchingParen) {
2580 return TT_PointerOrReference;
2583 if (PrevToken->endsSequence(tok::r_square, tok::l_square, tok::kw_delete))
2584 return TT_UnaryOperator;
2586 if (PrevToken->Tok.isLiteral() ||
2587 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
2588 tok::kw_false, tok::r_brace)) {
2589 return TT_BinaryOperator;
2592 const FormatToken *NextNonParen = NextToken;
2593 while (NextNonParen && NextNonParen->is(tok::l_paren))
2594 NextNonParen = NextNonParen->getNextNonComment();
2595 if (NextNonParen && (NextNonParen->Tok.isLiteral() ||
2596 NextNonParen->isOneOf(tok::kw_true, tok::kw_false) ||
2597 NextNonParen->isUnaryOperator())) {
2598 return TT_BinaryOperator;
2604 if (InTemplateArgument && NextToken->Tok.isAnyIdentifier())
2605 return TT_BinaryOperator;
2609 if (Tok.is(tok::ampamp) &&
2610 NextToken->isOneOf(tok::l_paren, tok::star, tok::amp)) {
2611 return TT_BinaryOperator;
2616 if (NextToken->Tok.isAnyIdentifier()) {
2617 const FormatToken *NextNextToken = NextToken->getNextNonComment();
2618 if (NextNextToken && NextNextToken->is(tok::arrow))
2619 return TT_BinaryOperator;
2625 return TT_BinaryOperator;
2628 if (!Scopes.empty() && Scopes.back() ==
ST_Class)
2629 return TT_PointerOrReference;
2632 auto IsChainedOperatorAmpOrMember = [](
const FormatToken *token) {
2633 return !token || token->isOneOf(tok::amp, tok::period, tok::arrow,
2634 tok::arrowstar, tok::periodstar);
2639 if (Tok.is(tok::amp) && PrevToken && PrevToken->Tok.isAnyIdentifier() &&
2640 IsChainedOperatorAmpOrMember(PrevToken->getPreviousNonComment()) &&
2641 NextToken && NextToken->Tok.isAnyIdentifier()) {
2642 if (
auto NextNext = NextToken->getNextNonComment();
2644 (IsChainedOperatorAmpOrMember(NextNext) || NextNext->is(tok::semi))) {
2645 return TT_BinaryOperator;
2649 return TT_PointerOrReference;
2652 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
2653 if (determineUnaryOperatorByUsage(Tok))
2654 return TT_UnaryOperator;
2656 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2658 return TT_UnaryOperator;
2660 if (PrevToken->is(tok::at))
2661 return TT_UnaryOperator;
2664 return TT_BinaryOperator;
2668 TokenType determineIncrementUsage(
const FormatToken &Tok) {
2669 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2670 if (!PrevToken || PrevToken->is(TT_CastRParen))
2671 return TT_UnaryOperator;
2672 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
2673 return TT_TrailingUnaryOperator;
2675 return TT_UnaryOperator;
2678 SmallVector<Context, 8> Contexts;
2680 const FormatStyle &Style;
2681 AnnotatedLine &Line;
2682 FormatToken *CurrentToken;
2684 const AdditionalKeywords &Keywords;
2686 SmallVector<ScopeType> &Scopes;
2700class ExpressionParser {
2702 ExpressionParser(
const FormatStyle &Style,
const AdditionalKeywords &Keywords,
2703 AnnotatedLine &Line)
2704 : Style(Style), Keywords(Keywords), Line(Line), Current(Line.
First) {}
2707 void parse(
int Precedence = 0) {
2710 while (Current && (Current->is(tok::kw_return) ||
2711 (Current->is(tok::colon) &&
2712 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)))) {
2716 if (!Current || Precedence > PrecedenceArrowAndPeriod)
2721 parseConditionalExpr();
2727 if (Precedence == PrecedenceUnaryOperator) {
2728 parseUnaryOperator();
2732 FormatToken *Start = Current;
2733 FormatToken *LatestOperator =
nullptr;
2734 unsigned OperatorIndex = 0;
2736 FormatToken *VerilogFirstOfType =
nullptr;
2745 if (Style.isVerilog() && Precedence ==
prec::Comma) {
2746 VerilogFirstOfType =
2747 verilogGroupDecl(VerilogFirstOfType, LatestOperator);
2751 parse(Precedence + 1);
2757 if (Current && Current->MacroParent)
2760 int CurrentPrecedence = getCurrentPrecedence();
2762 if (Precedence == CurrentPrecedence && Current &&
2763 Current->is(TT_SelectorName)) {
2765 addFakeParenthesis(Start,
prec::Level(Precedence));
2769 if ((Style.isCSharp() || Style.isJavaScript() ||
2774 FormatToken *Prev = Current->getPreviousNonComment();
2775 if (Prev && Prev->is(tok::string_literal) &&
2776 (Prev == Start || Prev->endsSequence(tok::string_literal, tok::plus,
2777 TT_StringInConcatenation))) {
2778 Prev->setType(TT_StringInConcatenation);
2785 (Current->closesScope() &&
2786 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
2787 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
2796 if (Current->opensScope() ||
2797 Current->isOneOf(TT_RequiresClause,
2798 TT_RequiresClauseInARequiresExpression)) {
2801 while (Current && (!Current->closesScope() || Current->opensScope())) {
2808 if (CurrentPrecedence == Precedence) {
2810 LatestOperator->NextOperator = Current;
2811 LatestOperator = Current;
2812 Current->OperatorIndex = OperatorIndex;
2815 next(Precedence > 0);
2820 if (Style.isVerilog() && Precedence ==
prec::Comma && VerilogFirstOfType)
2821 addFakeParenthesis(VerilogFirstOfType,
prec::Comma);
2823 if (LatestOperator && (Current || Precedence > 0)) {
2829 Start->Previous->isOneOf(TT_RequiresClause,
2830 TT_RequiresClauseInARequiresExpression))
2832 auto Ret = Current ? Current : Line.Last;
2833 while (!
Ret->ClosesRequiresClause &&
Ret->Previous)
2839 if (Precedence == PrecedenceArrowAndPeriod) {
2843 addFakeParenthesis(Start,
prec::Level(Precedence), End);
2851 int getCurrentPrecedence() {
2853 const FormatToken *NextNonComment = Current->getNextNonComment();
2854 if (Current->is(TT_ConditionalExpr))
2856 if (NextNonComment && Current->is(TT_SelectorName) &&
2857 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
2860 NextNonComment->is(tok::less)))) {
2863 if (Current->is(TT_JsComputedPropertyName))
2865 if (Current->is(TT_LambdaArrow))
2867 if (Current->is(TT_FatArrow))
2869 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
2870 (Current->is(tok::comment) && NextNonComment &&
2871 NextNonComment->is(TT_SelectorName))) {
2874 if (Current->is(TT_RangeBasedForLoopColon))
2877 Current->is(Keywords.kw_instanceof)) {
2880 if (Style.isJavaScript() &&
2881 Current->isOneOf(Keywords.kw_in, Keywords.kw_as)) {
2884 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
2885 return Current->getPrecedence();
2886 if (Current->isOneOf(tok::period, tok::arrow) &&
2887 Current->isNot(TT_TrailingReturnArrow)) {
2888 return PrecedenceArrowAndPeriod;
2891 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
2892 Keywords.kw_throws)) {
2897 if (Style.isVerilog() && Current->is(tok::colon))
2903 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence,
2904 FormatToken *End =
nullptr) {
2905 Start->FakeLParens.push_back(Precedence);
2907 Start->StartsBinaryExpression =
true;
2908 if (!End && Current)
2909 End = Current->getPreviousNonComment();
2913 End->EndsBinaryExpression =
true;
2919 void parseUnaryOperator() {
2921 while (Current && Current->is(TT_UnaryOperator)) {
2922 Tokens.push_back(Current);
2925 parse(PrecedenceArrowAndPeriod);
2926 for (FormatToken *Token : llvm::reverse(Tokens)) {
2932 void parseConditionalExpr() {
2933 while (Current && Current->isTrailingComment())
2935 FormatToken *Start = Current;
2937 if (!Current || Current->isNot(tok::question))
2941 if (!Current || Current->isNot(TT_ConditionalExpr))
2948 void next(
bool SkipPastLeadingComments =
true) {
2950 Current = Current->Next;
2952 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
2953 Current->isTrailingComment()) {
2954 Current = Current->Next;
2960 FormatToken *verilogGroupDecl(FormatToken *FirstOfType,
2961 FormatToken *PreviousComma) {
2965 FormatToken *Start = Current;
2968 while (Start->startsSequence(tok::l_paren, tok::star)) {
2969 if (!(Start = Start->MatchingParen) ||
2970 !(Start = Start->getNextNonComment())) {
2975 FormatToken *Tok = Start;
2977 if (Tok->is(Keywords.kw_assign))
2978 Tok = Tok->getNextNonComment();
2986 FormatToken *
First =
nullptr;
2988 FormatToken *Next = Tok->getNextNonComment();
2990 if (Tok->is(tok::hash)) {
2995 Tok = Tok->getNextNonComment();
2996 }
else if (Tok->is(tok::hashhash)) {
3000 Tok = Tok->getNextNonComment();
3001 }
else if (Keywords.isVerilogQualifier(*Tok) ||
3002 Keywords.isVerilogIdentifier(*Tok)) {
3006 while (Tok && Tok->isOneOf(tok::period, tok::coloncolon) &&
3007 (Tok = Tok->getNextNonComment())) {
3008 if (Keywords.isVerilogIdentifier(*Tok))
3009 Tok = Tok->getNextNonComment();
3013 }
else if (Tok->is(tok::l_paren)) {
3018 Keywords.kw_highz0, Keywords.kw_highz1, Keywords.kw_large,
3019 Keywords.kw_medium, Keywords.kw_pull0, Keywords.kw_pull1,
3020 Keywords.kw_small, Keywords.kw_strong0, Keywords.kw_strong1,
3021 Keywords.kw_supply0, Keywords.kw_supply1, Keywords.kw_weak0,
3022 Keywords.kw_weak1)) {
3023 Tok->setType(TT_VerilogStrength);
3024 Tok = Tok->MatchingParen;
3026 Tok->setType(TT_VerilogStrength);
3027 Tok = Tok->getNextNonComment();
3032 }
else if (Tok->is(tok::hash)) {
3033 if (Next->is(tok::l_paren))
3034 Next = Next->MatchingParen;
3036 Tok = Next->getNextNonComment();
3043 FormatToken *Second =
nullptr;
3045 while (Tok && Tok->is(tok::l_square) && (Tok = Tok->MatchingParen))
3046 Tok = Tok->getNextNonComment();
3047 if (Tok && (Tok->is(tok::hash) || Keywords.isVerilogIdentifier(*Tok)))
3052 FormatToken *TypedName =
nullptr;
3056 First->setType(TT_VerilogDimensionedTypeName);
3057 }
else if (
First != Start) {
3065 if (TypedName->is(TT_Unknown))
3066 TypedName->setType(TT_StartOfName);
3068 if (FirstOfType && PreviousComma) {
3069 PreviousComma->setType(TT_VerilogTypeComma);
3070 addFakeParenthesis(FirstOfType,
prec::Comma, PreviousComma->Previous);
3073 FirstOfType = TypedName;
3080 while (Current && Current != FirstOfType) {
3081 if (Current->opensScope()) {
3092 const FormatStyle &Style;
3093 const AdditionalKeywords &Keywords;
3094 const AnnotatedLine &Line;
3095 FormatToken *Current;
3104 assert(Line->First);
3108 if (NextNonCommentLine && !NextNonCommentLine->
First->
Finalized &&
3111 Line->First->OriginalColumn) {
3112 const bool PPDirectiveOrImportStmt =
3115 if (PPDirectiveOrImportStmt)
3121 PPDirectiveOrImportStmt
3123 : NextNonCommentLine->
Level;
3125 NextNonCommentLine = Line->First->isNot(tok::r_brace) ? Line :
nullptr;
3134 for (
const auto *Tok = Line.
First; Tok; Tok = Tok->
Next)
3143 Tok = Tok->getNextNonComment()) {
3145 if (Tok->is(tok::l_square) && Tok->is(TT_AttributeSquare)) {
3154 return Tok->
is(tok::l_paren) && Tok->isNot(TT_FunctionTypeLParen) &&
3161 if (Tok->isOneOf(tok::kw_friend, tok::kw_inline, tok::kw_virtual,
3162 tok::kw_constexpr, tok::kw_consteval, tok::kw_explicit)) {
3167 if (Tok->is(tok::coloncolon)) {
3174 while (Tok->startsSequence(tok::identifier, tok::coloncolon)) {
3176 Tok = Tok->Next->Next;
3182 if (Tok->is(tok::tilde)) {
3189 if (Tok->isNot(tok::identifier) || Tok->isNot(TT_Unknown))
3200 assert(Tok && Tok->
is(tok::identifier));
3203 if (Prev && Prev->is(tok::tilde))
3206 if (!Prev || !Prev->endsSequence(tok::coloncolon, tok::identifier))
3209 assert(Prev->Previous);
3210 return Prev->Previous->TokenText == Tok->
TokenText;
3214 for (
auto &Child : Line.Children)
3217 AnnotatingParser
Parser(Style, Line, Keywords, Scopes);
3218 Line.Type =
Parser.parseLine();
3230 ExpressionParser ExprParser(Style, Keywords, Line);
3233 if (Style.isCpp()) {
3235 if (Tok && ((!Scopes.empty() && Scopes.back() ==
ST_Class) ||
3237 Tok->setFinalizedType(TT_FunctionDeclarationName);
3241 if (Line.startsWith(TT_ObjCMethodSpecifier))
3243 else if (Line.startsWith(TT_ObjCDecl))
3245 else if (Line.startsWith(TT_ObjCProperty))
3248 Line.First->SpacesRequiredBefore = 1;
3249 Line.First->CanBreakBefore = Line.First->MustBreakBefore;
3258 if (Current.
is(TT_FunctionDeclarationName))
3265 for (; Next; Next = Next->Next) {
3266 if (Next->is(TT_OverloadedOperatorLParen))
3268 if (Next->is(TT_OverloadedOperator))
3270 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
3273 Next->Next->startsSequence(tok::l_square, tok::r_square)) {
3274 Next = Next->Next->Next;
3278 if (Next->startsSequence(tok::l_square, tok::r_square)) {
3283 if ((Next->isSimpleTypeSpecifier() || Next->is(tok::identifier)) &&
3284 Next->Next && Next->Next->isOneOf(tok::star, tok::amp, tok::ampamp)) {
3289 if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
3290 Next = Next->MatchingParen;
3301 if (Current.
is(tok::kw_operator)) {
3303 if (
Previous->Tok.getIdentifierInfo() &&
3304 !
Previous->isOneOf(tok::kw_return, tok::kw_co_return)) {
3309 assert(
Previous->MatchingParen->is(tok::l_paren));
3310 assert(
Previous->MatchingParen->is(TT_TypeDeclarationParen));
3313 if (!
Previous->isOneOf(tok::star, tok::amp, tok::ampamp, TT_TemplateCloser))
3315 Next = skipOperatorName(Next);
3319 for (; Next; Next = Next->Next) {
3320 if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
3321 Next = Next->MatchingParen;
3322 }
else if (Next->is(tok::coloncolon)) {
3326 if (Next->is(tok::kw_operator)) {
3327 Next = skipOperatorName(Next->Next);
3330 if (Next->isNot(tok::identifier))
3332 }
else if (isCppAttribute(IsCpp, *Next)) {
3333 Next = Next->MatchingParen;
3336 }
else if (Next->is(tok::l_paren)) {
3345 if (!Next || Next->isNot(tok::l_paren) || !Next->MatchingParen)
3348 if (Line.
Last->
is(tok::l_brace))
3350 if (Next->Next == Next->MatchingParen)
3353 if (Next->MatchingParen->Next &&
3354 Next->MatchingParen->Next->is(TT_PointerOrReference)) {
3368 if (IsCpp && Next->Next && Next->Next->is(tok::identifier) &&
3373 for (
const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen;
3375 if (Tok->is(TT_TypeDeclarationParen))
3377 if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) {
3378 Tok = Tok->MatchingParen;
3381 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
3382 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
3385 if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
3386 Tok->Tok.isLiteral()) {
3393bool TokenAnnotator::mustBreakForReturnType(
const AnnotatedLine &Line)
const {
3394 assert(Line.MightBeFunctionDecl);
3397 Style.AlwaysBreakAfterReturnType ==
3403 switch (Style.AlwaysBreakAfterReturnType) {
3411 return Line.mightBeFunctionDefinition();
3433 Line.First->TotalLength =
3434 Line.First->IsMultiline ? Style.ColumnLimit
3435 : Line.FirstStartColumn + Line.First->ColumnWidth;
3437 bool InFunctionDecl = Line.MightBeFunctionDecl;
3438 bool AlignArrayOfStructures =
3441 if (AlignArrayOfStructures)
3442 calculateArrayInitializerColumnList(Line);
3444 bool LineIsFunctionDeclaration =
false;
3445 for (
FormatToken *Tok = Current, *AfterLastAttribute =
nullptr; Tok;
3447 if (Tok->Previous->EndsCppAttributeGroup)
3448 AfterLastAttribute = Tok;
3450 LineIsFunctionDeclaration =
true;
3451 Tok->setFinalizedType(TT_FunctionDeclarationName);
3452 if (AfterLastAttribute &&
3454 AfterLastAttribute->MustBreakBefore =
true;
3455 Line.ReturnTypeWrapped =
true;
3461 if (Style.isCpp() && !LineIsFunctionDeclaration) {
3463 for (
const auto *Tok = Line.First; Tok; Tok = Tok->Next) {
3464 if (Tok->isNot(tok::kw_operator))
3468 }
while (Tok && Tok->isNot(TT_OverloadedOperatorLParen));
3471 const auto *LeftParen = Tok;
3472 for (Tok = Tok->Next; Tok && Tok != LeftParen->MatchingParen;
3474 if (Tok->isNot(tok::identifier))
3476 auto *Next = Tok->Next;
3477 const bool NextIsBinaryOperator =
3478 Next && Next->isOneOf(tok::star, tok::amp, tok::ampamp) &&
3479 Next->Next && Next->Next->is(tok::identifier);
3480 if (!NextIsBinaryOperator)
3482 Next->setType(TT_BinaryOperator);
3490 if (Current->is(TT_LineComment)) {
3492 Current->SpacesRequiredBefore =
3493 (Style.Cpp11BracedListStyle && !Style.SpacesInParensOptions.Other)
3496 }
else if (Prev->
is(TT_VerilogMultiLineListLParen)) {
3497 Current->SpacesRequiredBefore = 0;
3499 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
3509 if (!Current->HasUnescapedNewline) {
3512 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
3515 if (
Parameter->Previous->isNot(TT_CtorInitializerComma) &&
3523 }
else if (Current->SpacesRequiredBefore == 0 &&
3524 spaceRequiredBefore(Line, *Current)) {
3525 Current->SpacesRequiredBefore = 1;
3528 const auto &Children = Prev->
Children;
3529 if (!Children.empty() && Children.back()->Last->is(TT_LineComment)) {
3530 Current->MustBreakBefore =
true;
3532 Current->MustBreakBefore =
3533 Current->MustBreakBefore || mustBreakBefore(Line, *Current);
3534 if (!Current->MustBreakBefore && InFunctionDecl &&
3535 Current->is(TT_FunctionDeclarationName)) {
3536 Current->MustBreakBefore = mustBreakForReturnType(Line);
3540 Current->CanBreakBefore =
3541 Current->MustBreakBefore || canBreakBefore(Line, *Current);
3542 unsigned ChildSize = 0;
3548 if (Current->MustBreakBefore || Prev->
Children.size() > 1 ||
3550 Prev->
Children[0]->First->MustBreakBefore) ||
3551 Current->IsMultiline) {
3552 Current->TotalLength = Prev->
TotalLength + Style.ColumnLimit;
3554 Current->TotalLength = Prev->
TotalLength + Current->ColumnWidth +
3555 ChildSize + Current->SpacesRequiredBefore;
3558 if (Current->is(TT_CtorInitializerColon))
3559 InFunctionDecl =
false;
3570 Current->SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
3572 Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {
3573 if (Current->ParameterIndex == 1)
3574 Current->SplitPenalty += 5 * Current->BindingStrength;
3576 Current->SplitPenalty += 20 * Current->BindingStrength;
3579 Current = Current->Next;
3582 calculateUnbreakableTailLengths(Line);
3583 unsigned IndentLevel = Line.Level;
3584 for (Current = Line.First; Current; Current = Current->Next) {
3586 Current->Role->precomputeFormattingInfos(Current);
3587 if (Current->MatchingParen &&
3588 Current->MatchingParen->opensBlockOrBlockTypeList(Style) &&
3592 Current->IndentLevel = IndentLevel;
3593 if (Current->opensBlockOrBlockTypeList(Style))
3597 LLVM_DEBUG({ printDebugInfo(Line); });
3600void TokenAnnotator::calculateUnbreakableTailLengths(
3602 unsigned UnbreakableTailLength = 0;
3605 Current->UnbreakableTailLength = UnbreakableTailLength;
3606 if (Current->CanBreakBefore ||
3607 Current->isOneOf(tok::comment, tok::string_literal)) {
3608 UnbreakableTailLength = 0;
3610 UnbreakableTailLength +=
3611 Current->ColumnWidth + Current->SpacesRequiredBefore;
3613 Current = Current->Previous;
3617void TokenAnnotator::calculateArrayInitializerColumnList(
3618 AnnotatedLine &Line)
const {
3619 if (Line.First == Line.Last)
3621 auto *CurrentToken = Line.First;
3622 CurrentToken->ArrayInitializerLineStart =
true;
3624 while (CurrentToken && CurrentToken != Line.Last) {
3625 if (CurrentToken->is(tok::l_brace)) {
3626 CurrentToken->IsArrayInitializer =
true;
3627 if (CurrentToken->Next)
3628 CurrentToken->Next->MustBreakBefore =
true;
3630 calculateInitializerColumnList(Line, CurrentToken->Next, Depth + 1);
3632 CurrentToken = CurrentToken->Next;
3637FormatToken *TokenAnnotator::calculateInitializerColumnList(
3638 AnnotatedLine &Line, FormatToken *CurrentToken,
unsigned Depth)
const {
3639 while (CurrentToken && CurrentToken != Line.Last) {
3640 if (CurrentToken->is(tok::l_brace))
3642 else if (CurrentToken->is(tok::r_brace))
3644 if (Depth == 2 && CurrentToken->isOneOf(tok::l_brace, tok::comma)) {
3645 CurrentToken = CurrentToken->Next;
3648 CurrentToken->StartsColumn =
true;
3649 CurrentToken = CurrentToken->Previous;
3651 CurrentToken = CurrentToken->Next;
3653 return CurrentToken;
3656unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &Line,
3657 const FormatToken &Tok,
3658 bool InFunctionDecl)
const {
3659 const FormatToken &Left = *Tok.Previous;
3660 const FormatToken &Right = Tok;
3662 if (Left.is(tok::semi))
3667 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
3669 if (Right.is(Keywords.kw_implements))
3671 if (Left.is(tok::comma) && Left.NestingLevel == 0)
3673 }
else if (Style.isJavaScript()) {
3674 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))
3676 if (Left.is(TT_JsTypeColon))
3678 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith(
"${")) ||
3679 (Right.is(TT_TemplateString) && Right.TokenText.startswith(
"}"))) {
3683 if (Left.opensScope() && Right.closesScope())
3685 }
else if (Style.isProto()) {
3686 if (Right.is(tok::l_square))
3688 if (Right.is(tok::period))
3692 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
3694 if (Right.is(tok::l_square)) {
3695 if (Left.is(tok::r_square))
3698 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
3700 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
3701 TT_ArrayInitializerLSquare,
3702 TT_DesignatedInitializerLSquare, TT_AttributeSquare)) {
3707 if (Left.is(tok::coloncolon))
3709 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
3710 Right.is(tok::kw_operator)) {
3711 if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
3713 if (Left.is(TT_StartOfName))
3715 if (InFunctionDecl && Right.NestingLevel == 0)
3716 return Style.PenaltyReturnTypeOnItsOwnLine;
3719 if (Right.is(TT_PointerOrReference))
3721 if (Right.is(TT_LambdaArrow))
3723 if (Left.is(tok::equal) && Right.is(tok::l_brace))
3725 if (Left.is(TT_CastRParen))
3727 if (Left.isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union))
3729 if (Left.is(tok::comment))
3732 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
3733 TT_CtorInitializerColon)) {
3737 if (Right.isMemberAccess()) {
3757 return !Right.NextOperator || !Right.NextOperator->Previous->closesScope()
3762 if (Right.is(TT_TrailingAnnotation) &&
3763 (!Right.Next || Right.Next->isNot(tok::l_paren))) {
3766 if (Line.startsWith(TT_ObjCMethodSpecifier))
3773 bool is_short_annotation = Right.TokenText.size() < 10;
3774 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
3778 if (Line.startsWith(tok::kw_for) && Left.is(tok::equal))
3783 if (Right.is(TT_SelectorName))
3785 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
3786 return Line.MightBeFunctionDecl ? 50 : 500;
3791 if (Line.Type ==
LT_ObjCDecl && Left.is(tok::l_paren) && Left.Previous &&
3792 Left.Previous->isOneOf(tok::identifier, tok::greater)) {
3796 if (Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0)
3797 return Style.PenaltyBreakOpenParenthesis;
3798 if (Left.is(tok::l_paren) && InFunctionDecl &&
3802 if (Left.is(tok::l_paren) && Left.Previous &&
3803 (Left.Previous->isOneOf(tok::kw_for, tok::kw__Generic) ||
3804 Left.Previous->isIf())) {
3807 if (Left.is(tok::equal) && InFunctionDecl)
3809 if (Right.is(tok::r_brace))
3811 if (Left.is(TT_TemplateOpener))
3813 if (Left.opensScope()) {
3818 (Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) {
3821 if (Left.is(tok::l_brace) && !Style.Cpp11BracedListStyle)
3823 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
3826 if (Left.is(TT_JavaAnnotation))
3829 if (Left.is(TT_UnaryOperator))
3831 if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&
3832 Left.Previous->isLabelString() &&
3833 (Left.NextOperator || Left.OperatorIndex != 0)) {
3836 if (Right.is(tok::plus) && Left.isLabelString() &&
3837 (Right.NextOperator || Right.OperatorIndex != 0)) {
3840 if (Left.is(tok::comma))
3842 if (Right.is(tok::lessless) && Left.isLabelString() &&
3843 (Right.NextOperator || Right.OperatorIndex != 1)) {
3846 if (Right.is(tok::lessless)) {
3848 if (Left.isNot(tok::r_paren) || Right.OperatorIndex > 0) {
3854 if (Left.ClosesTemplateDeclaration)
3855 return Style.PenaltyBreakTemplateDeclaration;
3856 if (Left.ClosesRequiresClause)
3858 if (Left.is(TT_ConditionalExpr))
3862 Level = Right.getPrecedence();
3864 return Style.PenaltyBreakAssignment;
3871bool TokenAnnotator::spaceRequiredBeforeParens(
const FormatToken &Right)
const {
3874 if (Right.is(TT_OverloadedOperatorLParen) &&
3875 Style.SpaceBeforeParensOptions.AfterOverloadedOperator) {
3878 if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
3879 Right.ParameterCount > 0) {
3885bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &Line,
3886 const FormatToken &Left,
3887 const FormatToken &Right)
const {
3888 if (Left.is(tok::kw_return) &&
3889 !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
3892 if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen &&
3893 Right.MatchingParen->is(TT_CastRParen)) {
3899 Left.Tok.getObjCKeywordID() == tok::objc_property) {
3902 if (Right.is(tok::hashhash))
3903 return Left.is(tok::hash);
3904 if (Left.isOneOf(tok::hashhash, tok::hash))
3905 return Right.is(tok::hash);
3906 if ((Left.is(tok::l_paren) && Right.is(tok::r_paren)) ||
3907 (Left.is(tok::l_brace) && Left.isNot(
BK_Block) &&
3908 Right.is(tok::r_brace) && Right.isNot(
BK_Block))) {
3909 return Style.SpacesInParensOptions.InEmptyParentheses;
3911 if (Style.SpacesInParensOptions.InConditionalStatements) {
3912 const FormatToken *LeftParen =
nullptr;
3913 if (Left.is(tok::l_paren))
3915 else if (Right.is(tok::r_paren) && Right.MatchingParen)
3916 LeftParen = Right.MatchingParen;
3918 if (LeftParen->is(TT_ConditionLParen))
3920 if (LeftParen->Previous && isKeywordWithCondition(*LeftParen->Previous))
3926 if (Left.is(tok::kw_auto) && Right.isOneOf(TT_LambdaLBrace, TT_FunctionLBrace,
3928 TT_FunctionTypeLParen)) {
3933 if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))
3937 if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && Left.Previous &&
3938 Left.Previous->is(tok::kw_operator)) {
3942 if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&
3943 !Right.isOneOf(tok::semi, tok::r_paren)) {
3947 if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
3948 return (Right.is(TT_CastRParen) ||
3949 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
3950 ? Style.SpacesInParensOptions.InCStyleCasts
3951 : Style.SpacesInParensOptions.Other;
3953 if (Right.isOneOf(tok::semi, tok::comma))
3955 if (Right.is(tok::less) && Line.Type ==
LT_ObjCDecl) {
3956 bool IsLightweightGeneric = Right.MatchingParen &&
3957 Right.MatchingParen->Next &&
3958 Right.MatchingParen->Next->is(tok::colon);
3959 return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
3961 if (Right.is(tok::less) && Left.is(tok::kw_template))
3962 return Style.SpaceAfterTemplateKeyword;
3963 if (Left.isOneOf(tok::exclaim, tok::tilde))
3965 if (Left.is(tok::at) &&
3966 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
3967 tok::numeric_constant, tok::l_paren, tok::l_brace,
3968 tok::kw_true, tok::kw_false)) {
3971 if (Left.is(tok::colon))
3972 return Left.isNot(TT_ObjCMethodExpr);
3973 if (Left.is(tok::coloncolon))
3975 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
3978 (Left.is(TT_DictLiteral) || Right.is(TT_DictLiteral)))) {
3980 if (Left.is(tok::less) && Right.is(tok::greater))
3982 return !Style.Cpp11BracedListStyle;
3985 if (Right.isNot(TT_OverloadedOperatorLParen))
3988 if (Right.is(tok::ellipsis)) {
3989 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
3990 Left.Previous->is(tok::kw_case));
3992 if (Left.is(tok::l_square) && Right.is(tok::amp))
3993 return Style.SpacesInSquareBrackets;
3994 if (Right.is(TT_PointerOrReference)) {
3995 if (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) {
3996 if (!Left.MatchingParen)
3998 FormatToken *TokenBeforeMatchingParen =
3999 Left.MatchingParen->getPreviousNonComment();
4000 if (!TokenBeforeMatchingParen || Left.isNot(TT_TypeDeclarationParen))
4008 (Left.is(TT_AttributeRParen) ||
4009 Left.canBePointerOrReferenceQualifier())) {
4012 if (Left.Tok.isLiteral())
4015 if (Left.isTypeOrIdentifier() && Right.Next && Right.Next->Next &&
4016 Right.Next->Next->is(TT_RangeBasedForLoopColon)) {
4017 return getTokenPointerOrReferenceAlignment(Right) !=
4020 return !Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
4021 (getTokenPointerOrReferenceAlignment(Right) !=
4023 (Line.IsMultiVariableDeclStmt &&
4024 (Left.NestingLevel == 0 ||
4025 (Left.NestingLevel == 1 && startsWithInitStatement(Line)))));
4027 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
4028 (Left.isNot(TT_PointerOrReference) ||
4030 !Line.IsMultiVariableDeclStmt))) {
4033 if (Left.is(TT_PointerOrReference)) {
4038 Right.canBePointerOrReferenceQualifier()) {
4042 if (Right.Tok.isLiteral())
4045 if (Right.is(TT_BlockComment))
4049 if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final, tok::kw_noexcept,
4050 TT_RequiresClause) &&
4051 Right.isNot(TT_StartOfName)) {
4055 if (Right.is(tok::l_brace) && Right.is(
BK_Block))
4058 if (Left.Previous && Left.Previous->isTypeOrIdentifier() && Right.Next &&
4059 Right.Next->is(TT_RangeBasedForLoopColon)) {
4060 return getTokenPointerOrReferenceAlignment(Left) !=
4063 if (Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
4075 if (Line.IsMultiVariableDeclStmt &&
4076 (Left.NestingLevel == Line.First->NestingLevel ||
4077 ((Left.NestingLevel == Line.First->NestingLevel + 1) &&
4078 startsWithInitStatement(Line)))) {
4081 return Left.Previous && !Left.Previous->isOneOf(
4082 tok::l_paren, tok::coloncolon, tok::l_square);
4085 if (Left.is(tok::ellipsis) && Left.Previous &&
4086 Left.Previous->isOneOf(tok::star, tok::amp, tok::ampamp)) {
4090 if (Right.is(tok::star) && Left.is(tok::l_paren))
4092 if (Left.is(tok::star) && Right.isOneOf(tok::star, tok::amp, tok::ampamp))
4094 if (Right.isOneOf(tok::star, tok::amp, tok::ampamp)) {
4095 const FormatToken *
Previous = &Left;
4105 if (
Previous->is(tok::coloncolon)) {
4124 if (
Previous->endsSequence(tok::kw_operator))
4128 (Style.SpaceAroundPointerQualifiers ==
4134 if (Style.isCSharp() && Left.is(Keywords.kw_is) && Right.is(tok::l_square))
4136 const auto SpaceRequiredForArrayInitializerLSquare =
4137 [](
const FormatToken &LSquareTok,
const FormatStyle &Style) {
4138 return Style.SpacesInContainerLiterals ||
4141 !Style.Cpp11BracedListStyle &&
4142 LSquareTok.endsSequence(tok::l_square, tok::colon,
4145 if (Left.is(tok::l_square)) {
4146 return (Left.is(TT_ArrayInitializerLSquare) && Right.isNot(tok::r_square) &&
4147 SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||
4148 (Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
4149 TT_LambdaLSquare) &&
4150 Style.SpacesInSquareBrackets && Right.isNot(tok::r_square));
4152 if (Right.is(tok::r_square)) {
4153 return Right.MatchingParen &&
4154 ((Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&
4155 SpaceRequiredForArrayInitializerLSquare(*Right.MatchingParen,
4157 (Style.SpacesInSquareBrackets &&
4158 Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
4159 TT_StructuredBindingLSquare,
4160 TT_LambdaLSquare)));
4162 if (Right.is(tok::l_square) &&
4163 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
4164 TT_DesignatedInitializerLSquare,
4165 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
4166 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral) &&
4167 !(Left.isNot(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
4168 Right.is(TT_ArraySubscriptLSquare))) {
4171 if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
4172 return !Left.Children.empty();
4173 if ((Left.is(tok::l_brace) && Left.isNot(
BK_Block)) ||
4174 (Right.is(tok::r_brace) && Right.MatchingParen &&
4175 Right.MatchingParen->isNot(
BK_Block))) {
4176 return Style.Cpp11BracedListStyle ? Style.SpacesInParensOptions.Other
4179 if (Left.is(TT_BlockComment)) {
4181 return Style.isJavaScript() || !Left.TokenText.endswith(
"=*/");
4186 if (Left.is(TT_TemplateCloser) && Right.is(TT_AttributeSquare))
4189 if (Right.is(tok::l_paren)) {
4190 if (Left.is(TT_TemplateCloser) && Right.isNot(TT_FunctionTypeLParen))
4191 return spaceRequiredBeforeParens(Right);
4192 if (Left.isOneOf(TT_RequiresClause,
4193 TT_RequiresClauseInARequiresExpression)) {
4194 return Style.SpaceBeforeParensOptions.AfterRequiresInClause ||
4195 spaceRequiredBeforeParens(Right);
4197 if (Left.is(TT_RequiresExpression)) {
4198 return Style.SpaceBeforeParensOptions.AfterRequiresInExpression ||
4199 spaceRequiredBeforeParens(Right);
4201 if (Left.is(TT_AttributeRParen) ||
4202 (Left.is(tok::r_square) && Left.is(TT_AttributeSquare))) {
4205 if (Left.is(TT_ForEachMacro)) {
4206 return Style.SpaceBeforeParensOptions.AfterForeachMacros ||
4207 spaceRequiredBeforeParens(Right);
4209 if (Left.is(TT_IfMacro)) {
4210 return Style.SpaceBeforeParensOptions.AfterIfMacros ||
4211 spaceRequiredBeforeParens(Right);
4215 if (Left.is(tok::semi))
4217 if (Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch,
4218 tok::kw_case, TT_ForEachMacro, TT_ObjCForIn) ||
4220 Right.is(TT_ConditionLParen)) {
4221 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4222 spaceRequiredBeforeParens(Right);
4227 if (Right.is(TT_OverloadedOperatorLParen))
4228 return spaceRequiredBeforeParens(Right);
4230 if (Line.MightBeFunctionDecl && (Left.is(TT_FunctionDeclarationName))) {
4231 if (Line.mightBeFunctionDefinition()) {
4232 return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
4233 spaceRequiredBeforeParens(Right);
4235 return Style.SpaceBeforeParensOptions.AfterFunctionDeclarationName ||
4236 spaceRequiredBeforeParens(Right);
4241 Left.MatchingParen && Left.MatchingParen->is(TT_LambdaLSquare)) {
4242 return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
4243 spaceRequiredBeforeParens(Right);
4245 if (!Left.Previous || Left.Previous->isNot(tok::period)) {
4246 if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
4247 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4248 spaceRequiredBeforeParens(Right);
4250 if (Left.isOneOf(tok::kw_new, tok::kw_delete)) {
4251 return ((!Line.MightBeFunctionDecl || !Left.Previous) &&
4253 spaceRequiredBeforeParens(Right);
4256 if (Left.is(tok::r_square) && Left.MatchingParen &&
4257 Left.MatchingParen->Previous &&
4258 Left.MatchingParen->Previous->is(tok::kw_delete)) {
4260 spaceRequiredBeforeParens(Right);
4265 (Left.Tok.getIdentifierInfo() || Left.is(tok::r_paren))) {
4266 return spaceRequiredBeforeParens(Right);
4270 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
4272 if (Right.is(TT_UnaryOperator)) {
4273 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
4274 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
4280 if (!Style.isVerilog() &&
4281 (Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
4283 Left.isSimpleTypeSpecifier()) &&
4284 Right.is(tok::l_brace) && Right.getNextNonComment() &&
4288 if (Left.is(tok::period) || Right.is(tok::period))
4292 if (Right.is(tok::hash) && Left.is(tok::identifier) &&
4293 (Left.TokenText ==
"L" || Left.TokenText ==
"u" ||
4294 Left.TokenText ==
"U" || Left.TokenText ==
"u8" ||
4295 Left.TokenText ==
"LR" || Left.TokenText ==
"uR" ||
4296 Left.TokenText ==
"UR" || Left.TokenText ==
"u8R")) {
4299 if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
4300 Left.MatchingParen->Previous &&
4301 (Left.MatchingParen->Previous->is(tok::period) ||
4302 Left.MatchingParen->Previous->is(tok::coloncolon))) {
4308 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
4310 if (Left.is(tok::l_brace) && Left.endsSequence(TT_DictLiteral, tok::at)) {
4314 if (Right.is(tok::r_brace) && Right.MatchingParen &&
4315 Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at)) {
4319 if (Right.getType() == TT_TrailingAnnotation &&
4320 Right.isOneOf(tok::amp, tok::ampamp) &&
4321 Left.isOneOf(tok::kw_const, tok::kw_volatile) &&
4322 (!Right.Next || Right.Next->is(tok::semi))) {
4332bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &Line,
4333 const FormatToken &Right)
const {
4334 const FormatToken &Left = *Right.Previous;
4339 return Right.hasWhitespaceBefore();
4342 if (Keywords.isWordLike(Right) && Keywords.isWordLike(Left))
4347 if (Left.is(tok::star) && Right.is(tok::comment))
4350 if (Style.isCpp()) {
4351 if (Left.is(TT_OverloadedOperator) &&
4352 Right.isOneOf(TT_TemplateOpener, TT_TemplateCloser)) {
4356 if (Right.is(tok::period) && Left.is(tok::numeric_constant))
4360 if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis))
4363 if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&
4364 Right.is(TT_ModulePartitionColon)) {
4368 if (Left.is(tok::identifier) && Right.is(TT_ModulePartitionColon))
4371 if (Left.is(TT_ModulePartitionColon) &&
4372 Right.isOneOf(tok::identifier, tok::kw_private)) {
4375 if (Left.is(tok::ellipsis) && Right.is(tok::identifier) &&
4376 Line.First->is(Keywords.kw_import)) {
4380 if (Left.is(TT_AttributeRParen) && Right.is(tok::coloncolon))
4383 if (Left.is(tok::kw_operator))
4384 return Right.is(tok::coloncolon);
4386 !Left.opensScope() && Style.SpaceBeforeCpp11BracedList) {
4389 if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) &&
4390 Right.is(TT_TemplateOpener)) {
4395 if (Right.is(tok::period) &&
4396 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
4397 Keywords.kw_repeated, Keywords.kw_extend)) {
4400 if (Right.is(tok::l_paren) &&
4401 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) {
4404 if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
4407 if (Left.is(tok::slash) || Right.is(tok::slash))
4409 if (Left.MatchingParen &&
4410 Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
4411 Right.isOneOf(tok::l_brace, tok::less)) {
4412 return !Style.Cpp11BracedListStyle;
4415 if (Left.is(tok::percent))
4419 if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
4420 return Right.hasWhitespaceBefore();
4421 }
else if (Style.isJson()) {
4422 if (Right.is(tok::colon) && Left.is(tok::string_literal))
4423 return Style.SpaceBeforeJsonColon;
4424 }
else if (Style.isCSharp()) {
4430 if (Left.is(tok::kw_this) && Right.is(tok::l_square))
4434 if (Left.is(tok::kw_new) && Right.is(tok::l_paren))
4438 if (Right.is(tok::l_brace))
4442 if (Left.is(tok::l_brace) && Right.isNot(tok::r_brace))
4445 if (Left.isNot(tok::l_brace) && Right.is(tok::r_brace))
4449 if (Left.is(TT_FatArrow) || Right.is(TT_FatArrow))
4453 if (Left.is(TT_AttributeColon) || Right.is(TT_AttributeColon))
4457 if (Left.is(TT_TemplateCloser) && Right.is(TT_StartOfName))
4461 if (Left.is(tok::l_square) || Right.is(tok::r_square))
4462 return Style.SpacesInSquareBrackets;
4465 if (Right.is(TT_CSharpNullable))
4469 if (Right.is(TT_NonNullAssertion))
4473 if (Left.is(tok::comma) && Right.is(tok::comma))
4477 if (Left.is(Keywords.kw_var) && Right.is(tok::l_paren))
4481 if (Right.is(tok::l_paren)) {
4482 if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when,
4483 Keywords.kw_lock)) {
4484 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4485 spaceRequiredBeforeParens(Right);
4491 if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
4492 tok::kw_virtual, tok::kw_extern, tok::kw_static,
4493 Keywords.kw_internal, Keywords.kw_abstract,
4494 Keywords.kw_sealed, Keywords.kw_override,
4495 Keywords.kw_async, Keywords.kw_unsafe) &&
4496 Right.is(tok::l_paren)) {
4499 }
else if (Style.isJavaScript()) {
4500 if (Left.is(TT_FatArrow))
4503 if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && Left.Previous &&
4504 Left.Previous->is(tok::kw_for)) {
4507 if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
4508 Right.MatchingParen) {
4509 const FormatToken *Next = Right.MatchingParen->getNextNonComment();
4512 if (Next && Next->is(TT_FatArrow))
4515 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith(
"${")) ||
4516 (Right.is(TT_TemplateString) && Right.TokenText.startswith(
"}"))) {
4521 if (Keywords.IsJavaScriptIdentifier(Left,
4523 Right.is(TT_TemplateString)) {
4526 if (Right.is(tok::star) &&
4527 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) {
4530 if (Right.isOneOf(tok::l_brace, tok::l_square) &&
4531 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,
4532 Keywords.kw_extends, Keywords.kw_implements)) {
4535 if (Right.is(tok::l_paren)) {
4537 if (Line.MustBeDeclaration && Left.Tok.getIdentifierInfo())
4541 if (Left.Previous && Left.Previous->is(tok::period) &&
4542 Left.Tok.getIdentifierInfo()) {
4546 if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
4552 if (Left.endsSequence(tok::kw_const, Keywords.kw_as))
4554 if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
4559 (Left.is(Keywords.kw_of) && Left.Previous &&
4560 (Left.Previous->is(tok::identifier) ||
4561 Left.Previous->isOneOf(tok::r_square, tok::r_brace)))) &&
4562 (!Left.Previous || Left.Previous->isNot(tok::period))) {
4565 if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous &&
4566 Left.Previous->is(tok::period) && Right.is(tok::l_paren)) {
4569 if (Left.is(Keywords.kw_as) &&
4570 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) {
4573 if (Left.is(tok::kw_default) && Left.Previous &&
4574 Left.Previous->is(tok::kw_export)) {
4577 if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
4579 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
4581 if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
4583 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
4584 Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) {
4587 if (Left.is(tok::ellipsis))
4589 if (Left.is(TT_TemplateCloser) &&
4590 !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
4591 Keywords.kw_implements, Keywords.kw_extends)) {
4597 if (Right.is(TT_NonNullAssertion))
4599 if (Left.is(TT_NonNullAssertion) &&
4600 Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) {
4604 if (Left.is(tok::r_square) && Right.is(tok::l_brace))
4606 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) {
4607 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4608 spaceRequiredBeforeParens(Right);
4610 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
4611 tok::kw_protected) ||
4612 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract,
4613 Keywords.kw_native)) &&
4614 Right.is(TT_TemplateOpener)) {
4617 }
else if (Style.isVerilog()) {
4619 if (Style.isVerilog() && Left.is(tok::identifier) &&
4620 Left.TokenText[0] ==
'\\') {
4625 if ((Left.is(TT_VerilogTableItem) &&
4626 !Right.isOneOf(tok::r_paren, tok::semi)) ||
4627 (Right.is(TT_VerilogTableItem) && Left.isNot(tok::l_paren))) {
4628 const FormatToken *Next = Right.getNextNonComment();
4629 return !(Next && Next->is(tok::r_paren));
4632 if (Left.isNot(TT_BinaryOperator) &&
4633 Left.isOneOf(Keywords.kw_verilogHash, Keywords.kw_verilogHashHash)) {
4637 if (Right.isNot(tok::semi) &&
4638 (Left.endsSequence(tok::numeric_constant, Keywords.kw_verilogHash) ||
4639 Left.endsSequence(tok::numeric_constant,
4640 Keywords.kw_verilogHashHash) ||
4641 (Left.is(tok::r_paren) && Left.MatchingParen &&
4642 Left.MatchingParen->endsSequence(tok::l_paren, tok::at)))) {
4647 if (Left.is(Keywords.kw_apostrophe) ||
4648 (Left.is(TT_VerilogNumberBase) && Right.is(tok::numeric_constant))) {
4654 if (Left.is(tok::at) && Right.isOneOf(tok::l_paren, tok::star, tok::at))
4657 if (Right.is(tok::l_square) &&
4658 Left.isOneOf(TT_VerilogDimensionedTypeName, Keywords.kw_function)) {
4663 if ((Right.is(Keywords.kw_apostrophe) ||
4665 !(Left.isOneOf(Keywords.kw_assign, Keywords.kw_unique) ||
4666 Keywords.isVerilogWordOperator(Left)) &&
4667 (Left.isOneOf(tok::r_square, tok::r_paren, tok::r_brace,
4668 tok::numeric_constant) ||
4669 Keywords.isWordLike(Left))) {
4673 if ((Right.is(tok::star) && Left.is(tok::coloncolon)) ||
4674 (Left.is(tok::star) && Right.is(tok::semi))) {
4678 if (Left.endsSequence(tok::star, tok::l_paren) && Right.is(tok::identifier))
4681 if (Right.is(tok::l_paren) && Right.is(TT_VerilogStrength))
4684 if ((Left.is(tok::l_brace) &&
4685 Right.isOneOf(tok::lessless, tok::greatergreater)) ||
4686 (Left.endsSequence(tok::lessless, tok::l_brace) ||
4687 Left.endsSequence(tok::greatergreater, tok::l_brace))) {
4691 if (Left.is(TT_ImplicitStringLiteral))
4692 return Right.hasWhitespaceBefore();
4694 if (Left.is(TT_ObjCMethodSpecifier))
4696 if (Left.is(tok::r_paren) && canBeObjCSelectorComponent(Right)) {
4704 (Right.is(tok::equal) || Left.is(tok::equal))) {
4708 if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
4709 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) {
4712 if (Left.is(tok::comma) && Right.isNot(TT_OverloadedOperatorLParen) &&
4715 (Left.Children.empty() || !Left.MacroParent)) {
4718 if (Right.is(tok::comma))
4720 if (Right.is(TT_ObjCBlockLParen))
4722 if (Right.is(TT_CtorInitializerColon))
4723 return Style.SpaceBeforeCtorInitializerColon;
4724 if (Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)
4726 if (Right.is(TT_RangeBasedForLoopColon) &&
4727 !Style.SpaceBeforeRangeBasedForLoopColon) {
4730 if (Left.is(TT_BitFieldColon)) {
4734 if (Right.is(tok::colon)) {
4735 if (Right.is(TT_CaseLabelColon))
4736 return Style.SpaceBeforeCaseColon;
4737 if (Right.is(TT_GotoLabelColon))
4740 if (!Right.getNextNonComment())
4742 if (Right.is(TT_ObjCMethodExpr))
4744 if (Left.is(tok::question))
4746 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))
4748 if (Right.is(TT_DictLiteral))
4749 return Style.SpacesInContainerLiterals;
4750 if (Right.is(TT_AttributeColon))
4752 if (Right.is(TT_CSharpNamedArgumentColon))
4754 if (Right.is(TT_GenericSelectionColon))
4756 if (Right.is(TT_BitFieldColon)) {
4763 if ((Left.isOneOf(tok::minus, tok::minusminus) &&
4764 Right.isOneOf(tok::minus, tok::minusminus)) ||
4765 (Left.isOneOf(tok::plus, tok::plusplus) &&
4766 Right.isOneOf(tok::plus, tok::plusplus))) {
4769 if (Left.is(TT_UnaryOperator)) {
4770 if (Right.isNot(tok::l_paren)) {
4774 if (Left.is(tok::exclaim) && Left.TokenText ==
"not")
4776 if (Left.is(tok::tilde) && Left.TokenText ==
"compl")
4780 if (Left.is(tok::amp) && Right.is(tok::r_square))
4781 return Style.SpacesInSquareBrackets;
4783 return (Style.SpaceAfterLogicalNot && Left.is(tok::exclaim)) ||
4784 Right.is(TT_BinaryOperator);
4789 if (Left.is(TT_CastRParen)) {
4790 return Style.SpaceAfterCStyleCast ||
4791 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
4794 auto ShouldAddSpacesInAngles = [
this, &Right]() {
4798 return Right.hasWhitespaceBefore();
4802 if (Left.is(tok::greater) && Right.is(tok::greater)) {
4805 return !Style.Cpp11BracedListStyle;
4807 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
4809 ShouldAddSpacesInAngles());
4811 if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
4812 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
4813 (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod))) {
4816 if (!Style.SpaceBeforeAssignmentOperators && Left.isNot(TT_TemplateCloser) &&
4821 (Left.is(tok::identifier) || Left.is(tok::kw_this))) {
4824 if (Right.is(tok::coloncolon) && Left.is(tok::identifier)) {
4828 return Right.hasWhitespaceBefore();
4830 if (Right.is(tok::coloncolon) &&
4831 !Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren)) {
4833 return (Left.is(TT_TemplateOpener) &&
4835 ShouldAddSpacesInAngles())) ||
4836 !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
4837 tok::kw___super, TT_TemplateOpener,
4838 TT_TemplateCloser)) ||
4839 (Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other);
4841 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
4842 return ShouldAddSpacesInAngles();
4844 if (Right.is(TT_StructuredBindingLSquare)) {
4845 return !Left.isOneOf(tok::amp, tok::ampamp) ||
4849 if (Right.Next && Right.Next->is(TT_StructuredBindingLSquare) &&
4850 Right.isOneOf(tok::amp, tok::ampamp)) {
4853 if ((Right.is(TT_BinaryOperator) && Left.isNot(tok::l_paren)) ||
4854 (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
4855 Right.isNot(tok::r_paren))) {
4858 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
4859 Left.MatchingParen &&
4860 Left.MatchingParen->is(TT_OverloadedOperatorLParen)) {
4863 if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
4867 if (Right.is(TT_TrailingUnaryOperator))
4869 if (Left.is(TT_RegexLiteral))
4871 return spaceRequiredBetween(Line, Left, Right);
4877 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
4894 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
4897bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &Line,
4898 const FormatToken &Right)
const {
4899 const FormatToken &Left = *Right.Previous;
4900 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
4903 if (Style.isCSharp()) {
4904 if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) &&
4905 Style.BraceWrapping.AfterFunction) {
4908 if (Right.is(TT_CSharpNamedArgumentColon) ||
4909 Left.is(TT_CSharpNamedArgumentColon)) {
4912 if (Right.is(TT_CSharpGenericTypeConstraint))
4914 if (Right.Next && Right.Next->is(TT_FatArrow) &&
4915 (Right.is(tok::numeric_constant) ||
4916 (Right.is(tok::identifier) && Right.TokenText ==
"_"))) {
4921 if (Left.is(TT_AttributeSquare) && Left.is(tok::r_square) &&
4922 (Right.isAccessSpecifier(
false) ||
4923 Right.is(Keywords.kw_internal))) {
4927 if (Left.is(TT_AttributeSquare) && Right.is(TT_AttributeSquare) &&
4928 Left.is(tok::r_square) && Right.is(tok::l_square)) {
4932 }
else if (Style.isJavaScript()) {
4934 if (Right.is(tok::string_literal) && Left.is(tok::plus) && Left.Previous &&
4935 Left.Previous->is(tok::string_literal)) {
4938 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 &&
4939 Left.Previous && Left.Previous->is(tok::equal) &&
4940 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
4944 !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let)) {
4949 if (Left.is(tok::l_brace) && Line.Level == 0 &&
4950 (Line.startsWith(tok::kw_enum) ||
4951 Line.startsWith(tok::kw_const, tok::kw_enum) ||
4952 Line.startsWith(tok::kw_export, tok::kw_enum) ||
4953 Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum))) {
4958 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) && Left.Previous &&
4959 Left.Previous->is(TT_FatArrow)) {
4961 switch (Style.AllowShortLambdasOnASingleLine) {
4967 return !Left.Children.empty();
4971 return (Left.NestingLevel == 0 && Line.Level == 0) &&
4972 !Left.Children.empty();
4974 llvm_unreachable(
"Unknown FormatStyle::ShortLambdaStyle enum");
4977 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
4978 !Left.Children.empty()) {
4982 (Left.NestingLevel == 0 && Line.Level == 0 &&
4983 Style.AllowShortFunctionsOnASingleLine &
4987 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&
4988 Right.Next->is(tok::string_literal)) {
4991 }
else if (Style.isVerilog()) {
4993 if (Left.is(TT_VerilogAssignComma))
4996 if (Left.is(TT_VerilogTypeComma))
5000 if (Style.VerilogBreakBetweenInstancePorts &&
5001 (Left.is(TT_VerilogInstancePortComma) ||
5002 (Left.is(tok::r_paren) && Keywords.isVerilogIdentifier(Right) &&
5003 Left.MatchingParen &&
5004 Left.MatchingParen->is(TT_VerilogInstancePortLParen)))) {
5009 if (!Keywords.isVerilogBegin(Right) && Keywords.isVerilogEndOfLabel(Left))
5016 if (Left.isStringLiteral() && Right.isStringLiteral())
5021 if (Style.isJson()) {
5025 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace))
5028 if ((Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&
5029 Right.isNot(tok::r_square)) ||
5030 Left.is(tok::comma)) {
5031 if (Right.is(tok::l_brace))
5035 for (
const auto *Tok = &Right; Tok; Tok = Tok->Next) {
5036 if (Tok->isOneOf(tok::l_brace, tok::l_square))
5038 if (Tok->isOneOf(tok::r_brace, tok::r_square))
5041 return Style.BreakArrays;
5045 if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) &&
5055 const FormatToken *BeforeClosingBrace =
nullptr;
5056 if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
5057 (Style.isJavaScript() && Left.is(tok::l_paren))) &&
5058 Left.isNot(
BK_Block) && Left.MatchingParen) {
5059 BeforeClosingBrace = Left.MatchingParen->Previous;
5060 }
else if (Right.MatchingParen &&
5061 (Right.MatchingParen->isOneOf(tok::l_brace,
5062 TT_ArrayInitializerLSquare) ||
5063 (Style.isJavaScript() &&
5064 Right.MatchingParen->is(tok::l_paren)))) {
5065 BeforeClosingBrace = &Left;
5067 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
5068 BeforeClosingBrace->isTrailingComment())) {
5073 if (Right.is(tok::comment)) {
5074 return Left.isNot(
BK_BracedInit) && Left.isNot(TT_CtorInitializerColon) &&
5075 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
5077 if (Left.isTrailingComment())
5079 if (Left.IsUnterminatedLiteral)
5081 if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
5082 Right.Next->is(tok::string_literal)) {
5085 if (Right.is(TT_RequiresClause)) {
5086 switch (Style.RequiresClausePosition) {
5095 if (Left.ClosesTemplateDeclaration && Left.MatchingParen &&
5096 Left.MatchingParen->NestingLevel == 0) {
5100 if (Right.is(tok::kw_concept))
5104 if (Left.ClosesRequiresClause && Right.isNot(tok::semi)) {
5105 switch (Style.RequiresClausePosition) {
5115 (Left.is(TT_CtorInitializerComma) ||
5116 Right.is(TT_CtorInitializerColon))) {
5121 Left.isOneOf(TT_CtorInitializerColon, TT_CtorInitializerComma)) {
5127 Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) {
5133 Right.is(TT_CtorInitializerColon)) {
5138 Left.is(TT_CtorInitializerColon)) {
5144 Right.is(TT_InheritanceComma)) {
5148 Left.is(TT_InheritanceComma)) {
5151 if (Right.is(tok::string_literal) && Right.TokenText.startswith(
"R\"")) {
5155 return Right.IsMultiline && Right.NewlinesBefore > 0;
5157 if ((Left.is(tok::l_brace) || (Left.is(tok::less) && Left.Previous &&
5158 Left.Previous->is(tok::equal))) &&
5164 if (Right.is(TT_InlineASMBrace))
5165 return Right.HasUnescapedNewline;
5168 auto *FirstNonComment = Line.getFirstNonComment();
5171 FirstNonComment->isOneOf(Keywords.kw_internal, tok::kw_public,
5172 tok::kw_private, tok::kw_protected);
5174 if (Style.BraceWrapping.AfterEnum) {
5175 if (Line.startsWith(tok::kw_enum) ||
5176 Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
5181 FirstNonComment->Next->is(tok::kw_enum)) {
5187 if (Style.BraceWrapping.AfterClass &&
5189 FirstNonComment->Next->is(Keywords.kw_interface)) ||
5190 Line.startsWith(Keywords.kw_interface))) {
5195 if (Right.isNot(TT_FunctionLBrace)) {
5196 return (Line.startsWith(tok::kw_class) &&
5197 Style.BraceWrapping.AfterClass) ||
5198 (Line.startsWith(tok::kw_struct) &&
5199 Style.BraceWrapping.AfterStruct);
5203 if (Left.is(TT_ObjCBlockLBrace) &&
5209 if (Left.is(TT_AttributeRParen) && Right.is(TT_ObjCDecl))
5212 if (Left.is(TT_LambdaLBrace)) {
5220 (!Left.Children.empty() &&
5226 if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace) &&
5227 Left.isOneOf(tok::star, tok::amp, tok::ampamp, TT_TemplateCloser)) {
5233 Left.is(TT_LeadingJavaAnnotation) &&
5234 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
5235 (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) {
5239 if (Right.is(TT_ProtoExtensionLSquare))
5271 Right.is(TT_SelectorName) && Right.isNot(tok::r_square) && Right.Next) {
5274 if (Left.is(tok::at))
5280 FormatToken *LBrace = Right.Next;
5281 if (LBrace && LBrace->is(tok::colon)) {
5282 LBrace = LBrace->Next;
5283 if (LBrace && LBrace->is(tok::at)) {
5284 LBrace = LBrace->Next;
5286 LBrace = LBrace->Next;
5298 ((LBrace->is(tok::l_brace) &&
5299 (LBrace->is(TT_DictLiteral) ||
5300 (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||
5301 LBrace->is(TT_ArrayInitializerLSquare) || LBrace->is(tok::less))) {
5308 if (Left.ParameterCount == 0)
5323 if (Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))
5330bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &Line,
5331 const FormatToken &Right)
const {
5332 const FormatToken &Left = *Right.Previous;
5334 if (Style.isCSharp()) {
5335 if (Left.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon) ||
5336 Right.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon)) {
5340 if (Line.First->is(TT_CSharpGenericTypeConstraint))
5341 return Left.is(TT_CSharpGenericTypeConstraintComma);
5343 if (Right.is(TT_CSharpNullable))
5346 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
5347 Keywords.kw_implements)) {
5350 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
5351 Keywords.kw_implements)) {
5354 }
else if (Style.isJavaScript()) {
5355 const FormatToken *NonComment = Right.getPreviousNonComment();
5357 NonComment->isOneOf(
5358 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
5359 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
5360 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
5361 Keywords.kw_readonly, Keywords.kw_override, Keywords.kw_abstract,
5362 Keywords.kw_get, Keywords.kw_set, Keywords.kw_async,
5363 Keywords.kw_await)) {
5366 if (Right.NestingLevel == 0 &&
5367 (Left.Tok.getIdentifierInfo() ||
5368 Left.isOneOf(tok::r_square, tok::r_paren)) &&
5369 Right.isOneOf(tok::l_square, tok::l_paren)) {
5372 if (NonComment && NonComment->is(tok::identifier) &&
5373 NonComment->TokenText ==
"asserts") {
5376 if (Left.is(TT_FatArrow) && Right.is(tok::l_brace))
5378 if (Left.is(TT_JsTypeColon))
5381 if (Left.is(tok::exclaim) && Right.is(tok::colon))
5386 if (Right.is(Keywords.kw_is)) {
5387 const FormatToken *Next = Right.getNextNonComment();
5395 if (!Next || Next->isNot(tok::colon))
5398 if (Left.is(Keywords.kw_in))
5400 if (Right.is(Keywords.kw_in))
5402 if (Right.is(Keywords.kw_as))
5404 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
5410 if (Left.is(Keywords.kw_as))
5412 if (Left.is(TT_NonNullAssertion))
5414 if (Left.is(Keywords.kw_declare) &&
5415 Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
5416 Keywords.kw_function, tok::kw_class, tok::kw_enum,
5417 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
5418 Keywords.kw_let, tok::kw_const)) {
5423 if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
5424 Right.isOneOf(tok::identifier, tok::string_literal)) {
5427 if (Right.is(TT_TemplateString) && Right.closesScope())
5431 if (Left.is(tok::identifier) && Right.is(TT_TemplateString))
5433 if (Left.is(TT_TemplateString) && Left.opensScope())
5437 if (Left.is(tok::at))
5439 if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
5441 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
5442 return Right.isNot(tok::l_paren);
5443 if (Right.is(TT_PointerOrReference)) {
5444 return Line.IsMultiVariableDeclStmt ||
5445 (getTokenPointerOrReferenceAlignment(Right) ==
5447 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
5449 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
5450 Right.is(tok::kw_operator)) {
5453 if (Left.is(TT_PointerOrReference))
5455 if (Right.isTrailingComment()) {
5462 (Left.is(TT_CtorInitializerColon) && Right.NewlinesBefore > 0 &&
5465 if (Left.is(tok::question) && Right.is(tok::colon))
5467 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
5468 return Style.BreakBeforeTernaryOperators;
5469 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question))
5470 return !Style.BreakBeforeTernaryOperators;
5471 if (Left.is(TT_InheritanceColon))
5473 if (Right.is(TT_InheritanceColon))
5475 if (Right.is(TT_ObjCMethodExpr) && Right.isNot(tok::r_square) &&
5476 Left.isNot(TT_SelectorName)) {
5480 if (Right.is(tok::colon) &&
5481 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon)) {
5484 if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
5487 if (!Style.AlwaysBreakBeforeMultilineStrings && Right.isStringLiteral())
5513 if (((Right.is(tok::l_brace) || Right.is(tok::less)) &&
5514 Right.is(TT_DictLiteral)) ||
5515 Right.is(TT_ArrayInitializerLSquare)) {
5521 if (Right.is(tok::r_square) && Right.MatchingParen &&
5522 Right.MatchingParen->is(TT_ProtoExtensionLSquare)) {
5525 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&
5526 Right.Next->is(TT_ObjCMethodExpr))) {
5527 return Left.isNot(tok::period);
5531 if (Right.is(tok::kw_concept))
5533 if (Right.is(TT_RequiresClause))
5535 if (Left.ClosesTemplateDeclaration || Left.is(TT_FunctionAnnotationRParen))
5537 if (Left.ClosesRequiresClause)
5539 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
5540 TT_OverloadedOperator)) {
5543 if (Left.is(TT_RangeBasedForLoopColon))
5545 if (Right.is(TT_RangeBasedForLoopColon))
5547 if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener))
5549 if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
5550 (Left.is(tok::less) && Right.is(tok::less))) {
5553 if (Right.is(TT_BinaryOperator) &&
5559 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
5560 Left.is(tok::kw_operator)) {
5563 if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) &&
5567 if (Left.is(tok::equal) && Right.is(tok::l_brace) &&
5568 !Style.Cpp11BracedListStyle) {
5571 if (Left.is(TT_AttributeLParen) ||
5572 (Left.is(tok::l_paren) && Left.is(TT_TypeDeclarationParen))) {
5575 if (Left.is(tok::l_paren) && Left.Previous &&
5576 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) {
5579 if (Right.is(TT_ImplicitStringLiteral))
5582 if (Right.is(TT_TemplateCloser))
5584 if (Right.is(tok::r_square) && Right.MatchingParen &&
5585 Right.MatchingParen->is(TT_LambdaLSquare)) {
5591 if (Right.is(tok::r_brace)) {
5592 return Right.MatchingParen && (Right.MatchingParen->is(
BK_Block) ||
5593 (Right.isBlockIndentedInitRBrace(Style)));
5597 if (Right.is(tok::r_paren)) {
5599 !Right.MatchingParen) {
5602 auto Next = Right.Next;
5603 if (Next && Next->is(tok::r_paren))
5605 if (Next && Next->is(tok::l_paren))
5607 const FormatToken *
Previous = Right.MatchingParen->Previous;
5613 if (Left.is(TT_TrailingAnnotation)) {
5614 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
5615 tok::less, tok::coloncolon);
5618 if (Right.isAttribute())
5621 if (Right.is(tok::l_square) && Right.is(TT_AttributeSquare))
5622 return Left.isNot(TT_AttributeSquare);
5624 if (Left.is(tok::identifier) && Right.is(tok::string_literal))
5627 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
5630 if (Left.is(TT_CtorInitializerColon)) {
5632 (!Right.isTrailingComment() || Right.NewlinesBefore > 0);
5634 if (Right.is(TT_CtorInitializerColon))
5636 if (Left.is(TT_CtorInitializerComma) &&
5640 if (Right.is(TT_CtorInitializerComma) &&
5644 if (Left.is(TT_InheritanceComma) &&
5648 if (Right.is(TT_InheritanceComma) &&
5652 if (Left.is(TT_ArrayInitializerLSquare))
5654 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
5656 if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
5657 !Left.isOneOf(tok::arrowstar, tok::lessless) &&
5663 if ((Left.is(TT_AttributeSquare) && Right.is(tok::l_square)) ||
5664 (Left.is(tok::r_square) && Right.is(TT_AttributeSquare))) {
5668 auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
5669 if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace)) {
5676 if (Right.is(tok::kw_noexcept) && Right.is(TT_TrailingAnnotation)) {
5677 switch (Style.AllowBreakBeforeNoexceptSpecifier) {
5683 return Right.Next && Right.Next->is(tok::l_paren);
5687 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
5688 tok::kw_class, tok::kw_struct, tok::comment) ||
5689 Right.isMemberAccess() ||
5690 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
5691 tok::colon, tok::l_square, tok::at) ||
5692 (Left.is(tok::r_paren) &&
5693 Right.isOneOf(tok::identifier, tok::kw_const)) ||
5694 (Left.is(tok::l_paren) && Right.isNot(tok::r_paren)) ||
5695 (Left.is(TT_TemplateOpener) && Right.isNot(TT_TemplateCloser));
5698void TokenAnnotator::printDebugInfo(
const AnnotatedLine &Line)
const {
5699 llvm::errs() <<
"AnnotatedTokens(L=" << Line.Level <<
", P=" << Line.PPLevel
5700 <<
", T=" << Line.Type <<
", C=" << Line.IsContinuation
5702 const FormatToken *Tok = Line.First;
5704 llvm::errs() <<
" M=" << Tok->MustBreakBefore
5705 <<
" C=" << Tok->CanBreakBefore
5707 <<
" S=" << Tok->SpacesRequiredBefore
5708 <<
" F=" << Tok->Finalized <<
" B=" << Tok->BlockParameterCount
5709 <<
" BK=" << Tok->getBlockKind() <<
" P=" << Tok->SplitPenalty
5710 <<
" Name=" << Tok->Tok.getName() <<
" L=" << Tok->TotalLength
5711 <<
" PPK=" << Tok->getPackingKind() <<
" FakeLParens=";
5713 llvm::errs() << LParen <<
"/";
5714 llvm::errs() <<
" FakeRParens=" << Tok->FakeRParens;
5715 llvm::errs() <<
" II=" << Tok->Tok.getIdentifierInfo();
5716 llvm::errs() <<
" Text='" << Tok->TokenText <<
"'\n";
5718 assert(Tok == Line.Last);
5721 llvm::errs() <<
"----\n";
5725TokenAnnotator::getTokenReferenceAlignment(
const FormatToken &Reference)
const {
5726 assert(
Reference.isOneOf(tok::amp, tok::ampamp));
5727 switch (Style.ReferenceAlignment) {
5729 return Style.PointerAlignment;
5738 return Style.PointerAlignment;
5742TokenAnnotator::getTokenPointerOrReferenceAlignment(
5743 const FormatToken &PointerOrReference)
const {
5744 if (PointerOrReference.isOneOf(tok::amp, tok::ampamp)) {
5745 switch (Style.ReferenceAlignment) {
5747 return Style.PointerAlignment;
5756 assert(PointerOrReference.is(tok::star));
5757 return Style.PointerAlignment;
Defines the SourceManager interface.
bool ColonIsObjCMethodExpr
FormatToken * FirstStartOfName
bool InCpp11AttributeSpecifier
unsigned LongestObjCSelectorName
bool VerilogAssignmentFound
bool InCSharpAttributeSpecifier
enum clang::format::@1210::AnnotatingParser::Context::@327 ContextType
tok::TokenKind ContextKind
FormatToken * FirstObjCSelectorName
bool VerilogMayBeConcatenation
This file implements a token annotator, i.e.
Defines the clang::TokenKind enum and support functions.
#define TRANSFORM_TYPE_TRAIT_DEF(Enum, _)
Parser - This implements a parser for the C family of languages.
IdentifierInfo * getIdentifierInfo() const
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...