18#include "llvm/ADT/SmallPtrSet.h"
19#include "llvm/Support/Debug.h"
21#define DEBUG_TYPE "format-token-annotator"
42static bool startsWithInitStatement(
const AnnotatedLine &
Line) {
43 return Line.startsWith(tok::kw_for) ||
Line.startsWith(tok::kw_if) ||
44 Line.startsWith(tok::kw_switch);
58static bool canBeObjCSelectorComponent(
const FormatToken &Tok) {
59 return Tok.Tok.getIdentifierInfo();
65static bool isLambdaParameterList(
const FormatToken *Left) {
67 if (
Left->Previous &&
Left->Previous->is(tok::greater) &&
68 Left->Previous->MatchingParen &&
69 Left->Previous->MatchingParen->is(TT_TemplateOpener)) {
70 Left =
Left->Previous->MatchingParen;
74 return Left->Previous &&
Left->Previous->is(tok::r_square) &&
75 Left->Previous->MatchingParen &&
76 Left->Previous->MatchingParen->is(TT_LambdaLSquare);
81static bool isKeywordWithCondition(
const FormatToken &Tok) {
82 return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
83 tok::kw_constexpr, tok::kw_catch);
87static bool isCppAttribute(
bool IsCpp,
const FormatToken &Tok) {
88 if (!IsCpp || !Tok.startsSequence(tok::l_square, tok::l_square))
91 if (Tok.Previous && Tok.Previous->is(tok::at))
93 const FormatToken *AttrTok = Tok.Next->Next;
98 if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))
100 if (AttrTok->isNot(tok::identifier))
102 while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {
106 if (AttrTok->is(tok::colon) ||
107 AttrTok->startsSequence(tok::identifier, tok::identifier) ||
108 AttrTok->startsSequence(tok::r_paren, tok::identifier)) {
111 if (AttrTok->is(tok::ellipsis))
113 AttrTok = AttrTok->Next;
115 return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
123class AnnotatingParser {
125 AnnotatingParser(
const FormatStyle &Style, AnnotatedLine &Line,
126 const AdditionalKeywords &Keywords,
127 SmallVector<ScopeType> &Scopes)
128 : Style(Style), Line(Line), CurrentToken(Line.
First), AutoFound(
false),
130 Keywords(Keywords), Scopes(Scopes), TemplateDeclarationDepth(0) {
131 Contexts.push_back(Context(tok::unknown, 1,
false));
132 resetTokenMetadata();
136 ScopeType getScopeType(
const FormatToken &Token)
const {
137 switch (Token.getType()) {
139 case TT_StructLBrace:
142 case TT_CompoundRequirementLBrace:
153 auto *
Left = CurrentToken->Previous;
157 if (NonTemplateLess.count(Left) > 0)
160 const auto *BeforeLess =
Left->Previous;
163 if (BeforeLess->Tok.isLiteral())
165 if (BeforeLess->is(tok::r_brace))
167 if (BeforeLess->is(tok::r_paren) && Contexts.size() > 1 &&
168 !(BeforeLess->MatchingParen &&
169 BeforeLess->MatchingParen->is(TT_OverloadedOperatorLParen))) {
172 if (BeforeLess->is(tok::kw_operator) && CurrentToken->is(tok::l_paren))
176 Left->ParentBracket = Contexts.back().ContextKind;
177 ScopedContextCreator ContextCreator(*
this, tok::less, 12);
178 Contexts.back().IsExpression =
false;
182 if (BeforeLess && BeforeLess->isNot(tok::kw_template))
183 Contexts.back().ContextType = Context::TemplateArgument;
185 if (Style.isJava() && CurrentToken->is(tok::question))
188 for (
bool SeenTernaryOperator =
false, MaybeAngles =
true; CurrentToken;) {
189 const bool InExpr = Contexts[Contexts.size() - 2].IsExpression;
190 if (CurrentToken->is(tok::greater)) {
191 const auto *Next = CurrentToken->Next;
192 if (CurrentToken->isNot(TT_TemplateCloser)) {
199 if (Next && Next->is(tok::greater) &&
200 Left->ParentBracket != tok::less &&
201 CurrentToken->getStartOfNonWhitespace() ==
202 Next->getStartOfNonWhitespace().getLocWithOffset(-1)) {
205 if (InExpr && SeenTernaryOperator &&
206 (!Next || !Next->isOneOf(tok::l_paren, tok::l_brace))) {
212 Left->MatchingParen = CurrentToken;
213 CurrentToken->MatchingParen =
Left;
219 if (Style.isTextProto() ||
221 BeforeLess->isOneOf(TT_SelectorName, TT_DictLiteral))) {
222 CurrentToken->setType(TT_DictLiteral);
224 CurrentToken->setType(TT_TemplateCloser);
225 CurrentToken->Tok.setLength(1);
227 if (Next && Next->Tok.isLiteral())
232 if (BeforeLess && BeforeLess->is(TT_TemplateName)) {
236 if (CurrentToken->is(tok::question) && Style.isJava()) {
240 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
242 const auto &Prev = *CurrentToken->Previous;
249 if (MaybeAngles && InExpr && !Line.startsWith(tok::kw_template) &&
250 Prev.is(TT_BinaryOperator) &&
251 Prev.isOneOf(tok::pipepipe, tok::ampamp)) {
254 if (Prev.isOneOf(tok::question, tok::colon) && !Style.isProto())
255 SeenTernaryOperator =
true;
256 updateParameterCount(Left, CurrentToken);
258 if (FormatToken *
Previous = CurrentToken->getPreviousNonComment()) {
259 if (CurrentToken->is(tok::colon) ||
260 (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
265 }
else if (Style.isTableGen()) {
266 if (CurrentToken->isOneOf(tok::comma, tok::equal)) {
273 if (!parseTableGenValue())
283 bool parseUntouchableParens() {
284 while (CurrentToken) {
285 CurrentToken->Finalized =
true;
286 switch (CurrentToken->Tok.getKind()) {
289 if (!parseUntouchableParens())
304 bool parseParens(
bool IsIf =
false) {
307 assert(CurrentToken->Previous &&
"Unknown previous token");
308 FormatToken &OpeningParen = *CurrentToken->Previous;
309 assert(OpeningParen.is(tok::l_paren));
310 FormatToken *PrevNonComment = OpeningParen.getPreviousNonComment();
311 OpeningParen.ParentBracket = Contexts.back().ContextKind;
312 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 1);
315 Contexts.back().ColonIsForRangeExpr =
316 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
318 if (OpeningParen.Previous &&
319 OpeningParen.Previous->is(TT_UntouchableMacroFunc)) {
320 OpeningParen.Finalized =
true;
321 return parseUntouchableParens();
324 bool StartsObjCMethodExpr =
false;
325 if (!Style.isVerilog()) {
326 if (FormatToken *MaybeSel = OpeningParen.Previous) {
328 if (MaybeSel->is(tok::objc_selector) && MaybeSel->Previous &&
329 MaybeSel->Previous->is(tok::at)) {
330 StartsObjCMethodExpr =
true;
335 if (OpeningParen.is(TT_OverloadedOperatorLParen)) {
337 FormatToken *Prev = &OpeningParen;
338 while (Prev->isNot(tok::kw_operator)) {
339 Prev = Prev->Previous;
340 assert(Prev &&
"Expect a kw_operator prior to the OperatorLParen!");
346 bool OperatorCalledAsMemberFunction =
347 Prev->Previous && Prev->Previous->isOneOf(tok::period, tok::arrow);
348 Contexts.back().IsExpression = OperatorCalledAsMemberFunction;
349 }
else if (OpeningParen.is(TT_VerilogInstancePortLParen)) {
350 Contexts.back().IsExpression =
true;
351 Contexts.back().ContextType = Context::VerilogInstancePortList;
352 }
else if (Style.isJavaScript() &&
353 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
354 Line.startsWith(tok::kw_export, Keywords.kw_type,
358 Contexts.back().IsExpression =
false;
359 }
else if (OpeningParen.Previous &&
360 (OpeningParen.Previous->isOneOf(
361 tok::kw_static_assert, tok::kw_noexcept, tok::kw_explicit,
362 tok::kw_while, tok::l_paren, tok::comma, TT_CastRParen,
363 TT_BinaryOperator) ||
364 OpeningParen.Previous->isIf())) {
366 Contexts.back().IsExpression =
true;
367 }
else if (Style.isJavaScript() && OpeningParen.Previous &&
368 (OpeningParen.Previous->is(Keywords.kw_function) ||
369 (OpeningParen.Previous->endsSequence(tok::identifier,
370 Keywords.kw_function)))) {
372 Contexts.back().IsExpression =
false;
373 }
else if (Style.isJavaScript() && OpeningParen.Previous &&
374 OpeningParen.Previous->is(TT_JsTypeColon)) {
376 Contexts.back().IsExpression =
false;
377 }
else if (isLambdaParameterList(&OpeningParen)) {
379 OpeningParen.setType(TT_LambdaDefinitionLParen);
380 Contexts.back().IsExpression =
false;
381 }
else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
382 Contexts.back().IsExpression =
false;
383 }
else if (OpeningParen.Previous &&
384 OpeningParen.Previous->is(tok::kw__Generic)) {
385 Contexts.back().ContextType = Context::C11GenericSelection;
386 Contexts.back().IsExpression =
true;
387 }
else if (Line.InPPDirective &&
388 (!OpeningParen.Previous ||
389 OpeningParen.Previous->isNot(tok::identifier))) {
390 Contexts.back().IsExpression =
true;
391 }
else if (Contexts[Contexts.size() - 2].CaretFound) {
393 Contexts.back().IsExpression =
false;
394 }
else if (OpeningParen.Previous &&
395 OpeningParen.Previous->is(TT_ForEachMacro)) {
397 Contexts.back().ContextType = Context::ForEachMacro;
398 Contexts.back().IsExpression =
false;
399 }
else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
400 OpeningParen.Previous->MatchingParen->isOneOf(
401 TT_ObjCBlockLParen, TT_FunctionTypeLParen)) {
402 Contexts.back().IsExpression =
false;
403 }
else if (!Line.MustBeDeclaration &&
404 (!Line.InPPDirective || (Line.InMacroBody && !Scopes.empty()))) {
406 OpeningParen.Previous &&
407 OpeningParen.Previous->isOneOf(tok::kw_for, tok::kw_catch);
408 Contexts.back().IsExpression = !IsForOrCatch;
411 if (Style.isTableGen()) {
412 if (FormatToken *Prev = OpeningParen.Previous) {
413 if (Prev->is(TT_TableGenCondOperator)) {
414 Contexts.back().IsTableGenCondOpe =
true;
415 Contexts.back().IsExpression =
true;
416 }
else if (Contexts.size() > 1 &&
417 Contexts[Contexts.size() - 2].IsTableGenBangOpe) {
422 Contexts.back().IsTableGenBangOpe =
true;
423 Contexts.back().IsExpression =
true;
426 if (!parseTableGenDAGArg())
428 return parseTableGenDAGArgAndList(&OpeningParen);
435 if (PrevNonComment && OpeningParen.is(TT_Unknown)) {
436 if (PrevNonComment->isAttribute()) {
437 OpeningParen.setType(TT_AttributeLParen);
438 }
else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
441#include
"clang/Basic/TransformTypeTraits.def"
443 OpeningParen.setType(TT_TypeDeclarationParen);
445 if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))
446 Contexts.back().IsExpression =
true;
450 if (StartsObjCMethodExpr) {
451 Contexts.back().ColonIsObjCMethodExpr =
true;
452 OpeningParen.setType(TT_ObjCMethodExpr);
463 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
464 bool ProbablyFunctionType =
465 CurrentToken->isPointerOrReference() || CurrentToken->is(tok::caret);
466 bool HasMultipleLines =
false;
467 bool HasMultipleParametersOnALine =
false;
468 bool MightBeObjCForRangeLoop =
469 OpeningParen.Previous && OpeningParen.Previous->is(tok::kw_for);
470 FormatToken *PossibleObjCForInToken =
nullptr;
471 while (CurrentToken) {
472 const auto &Prev = *CurrentToken->Previous;
473 const auto *PrevPrev = Prev.Previous;
474 if (Prev.is(TT_PointerOrReference) &&
475 PrevPrev->isOneOf(tok::l_paren, tok::coloncolon)) {
476 ProbablyFunctionType =
true;
478 if (CurrentToken->is(tok::comma))
479 MightBeFunctionType =
false;
480 if (Prev.is(TT_BinaryOperator))
481 Contexts.back().IsExpression =
true;
482 if (CurrentToken->is(tok::r_paren)) {
483 if (Prev.is(TT_PointerOrReference) &&
484 (PrevPrev == &OpeningParen || PrevPrev->is(tok::coloncolon))) {
485 MightBeFunctionType =
true;
487 if (OpeningParen.isNot(TT_CppCastLParen) && MightBeFunctionType &&
488 ProbablyFunctionType && CurrentToken->Next &&
489 (CurrentToken->Next->is(tok::l_paren) ||
490 (CurrentToken->Next->is(tok::l_square) &&
491 (Line.MustBeDeclaration ||
492 (PrevNonComment && PrevNonComment->isTypeName(LangOpts)))))) {
493 OpeningParen.setType(OpeningParen.Next->is(tok::caret)
495 : TT_FunctionTypeLParen);
497 OpeningParen.MatchingParen = CurrentToken;
498 CurrentToken->MatchingParen = &OpeningParen;
500 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
501 OpeningParen.Previous && OpeningParen.Previous->is(tok::l_paren)) {
505 for (FormatToken *Tok = &OpeningParen; Tok != CurrentToken;
507 if (Tok->is(TT_BinaryOperator) && Tok->isPointerOrReference())
508 Tok->setType(TT_PointerOrReference);
512 if (StartsObjCMethodExpr) {
513 CurrentToken->setType(TT_ObjCMethodExpr);
514 if (Contexts.back().FirstObjCSelectorName) {
515 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
516 Contexts.back().LongestObjCSelectorName;
520 if (OpeningParen.is(TT_AttributeLParen))
521 CurrentToken->setType(TT_AttributeRParen);
522 if (OpeningParen.is(TT_TypeDeclarationParen))
523 CurrentToken->setType(TT_TypeDeclarationParen);
524 if (OpeningParen.Previous &&
525 OpeningParen.Previous->is(TT_JavaAnnotation)) {
526 CurrentToken->setType(TT_JavaAnnotation);
528 if (OpeningParen.Previous &&
529 OpeningParen.Previous->is(TT_LeadingJavaAnnotation)) {
530 CurrentToken->setType(TT_LeadingJavaAnnotation);
532 if (OpeningParen.Previous &&
533 OpeningParen.Previous->is(TT_AttributeSquare)) {
534 CurrentToken->setType(TT_AttributeSquare);
537 if (!HasMultipleLines)
539 else if (HasMultipleParametersOnALine)
547 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
550 if (CurrentToken->is(tok::l_brace) && OpeningParen.is(TT_ObjCBlockLParen))
551 OpeningParen.setType(TT_Unknown);
552 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
553 !CurrentToken->Next->HasUnescapedNewline &&
554 !CurrentToken->Next->isTrailingComment()) {
555 HasMultipleParametersOnALine =
true;
557 bool ProbablyFunctionTypeLParen =
558 (CurrentToken->is(tok::l_paren) && CurrentToken->Next &&
559 CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret));
560 if ((Prev.isOneOf(tok::kw_const, tok::kw_auto) ||
561 Prev.isTypeName(LangOpts)) &&
562 !(CurrentToken->is(tok::l_brace) ||
563 (CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) {
564 Contexts.back().IsExpression =
false;
566 if (CurrentToken->isOneOf(tok::semi, tok::colon)) {
567 MightBeObjCForRangeLoop =
false;
568 if (PossibleObjCForInToken) {
569 PossibleObjCForInToken->setType(TT_Unknown);
570 PossibleObjCForInToken =
nullptr;
573 if (IsIf && CurrentToken->is(tok::semi)) {
574 for (
auto *Tok = OpeningParen.Next;
575 Tok != CurrentToken &&
576 !Tok->isOneOf(tok::equal, tok::l_paren, tok::l_brace);
578 if (Tok->isPointerOrReference())
579 Tok->setFinalizedType(TT_PointerOrReference);
582 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
583 PossibleObjCForInToken = CurrentToken;
584 PossibleObjCForInToken->setType(TT_ObjCForIn);
588 if (CurrentToken->is(tok::comma))
589 Contexts.back().CanBeExpression =
true;
591 if (Style.isTableGen()) {
592 if (CurrentToken->is(tok::comma)) {
593 if (Contexts.back().IsTableGenCondOpe)
594 CurrentToken->setType(TT_TableGenCondOperatorComma);
596 }
else if (CurrentToken->is(tok::colon)) {
597 if (Contexts.back().IsTableGenCondOpe)
598 CurrentToken->setType(TT_TableGenCondOperatorColon);
602 if (!parseTableGenValue())
607 FormatToken *Tok = CurrentToken;
610 updateParameterCount(&OpeningParen, Tok);
611 if (CurrentToken && CurrentToken->HasUnescapedNewline)
612 HasMultipleLines =
true;
617 bool isCSharpAttributeSpecifier(
const FormatToken &Tok) {
618 if (!Style.isCSharp())
622 if (Tok.Previous && Tok.Previous->is(tok::identifier))
626 if (Tok.Previous && Tok.Previous->is(tok::r_square)) {
627 auto *MatchingParen = Tok.Previous->MatchingParen;
628 if (!MatchingParen || MatchingParen->is(TT_ArraySubscriptLSquare))
632 const FormatToken *AttrTok = Tok.Next;
637 if (AttrTok->is(tok::r_square))
641 while (AttrTok && AttrTok->isNot(tok::r_square))
642 AttrTok = AttrTok->Next;
648 AttrTok = AttrTok->Next;
653 if (AttrTok->isAccessSpecifierKeyword() ||
654 AttrTok->isOneOf(tok::comment, tok::kw_class, tok::kw_static,
655 tok::l_square, Keywords.kw_internal)) {
661 AttrTok->Next->startsSequence(tok::identifier, tok::l_paren)) {
676 FormatToken *
Left = CurrentToken->Previous;
677 Left->ParentBracket = Contexts.back().ContextKind;
678 FormatToken *
Parent =
Left->getPreviousNonComment();
683 bool CppArrayTemplates =
685 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
686 Contexts.back().ContextType == Context::TemplateArgument);
688 const bool IsInnerSquare = Contexts.back().InCpp11AttributeSpecifier;
689 const bool IsCpp11AttributeSpecifier =
690 isCppAttribute(IsCpp, *Left) || IsInnerSquare;
693 bool IsCSharpAttributeSpecifier =
694 isCSharpAttributeSpecifier(*Left) ||
695 Contexts.back().InCSharpAttributeSpecifier;
697 bool InsideInlineASM = Line.startsWith(tok::kw_asm);
698 bool IsCppStructuredBinding =
Left->isCppStructuredBinding(IsCpp);
699 bool StartsObjCMethodExpr =
700 !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
701 IsCpp && !IsCpp11AttributeSpecifier && !IsCSharpAttributeSpecifier &&
702 Contexts.back().CanBeExpression &&
Left->isNot(TT_LambdaLSquare) &&
703 !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
705 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
706 tok::kw_return, tok::kw_throw) ||
707 Parent->isUnaryOperator() ||
709 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
712 bool ColonFound =
false;
714 unsigned BindingIncrease = 1;
715 if (IsCppStructuredBinding) {
716 Left->setType(TT_StructuredBindingLSquare);
717 }
else if (
Left->is(TT_Unknown)) {
718 if (StartsObjCMethodExpr) {
719 Left->setType(TT_ObjCMethodExpr);
720 }
else if (InsideInlineASM) {
721 Left->setType(TT_InlineASMSymbolicNameLSquare);
722 }
else if (IsCpp11AttributeSpecifier) {
723 Left->setType(TT_AttributeSquare);
724 if (!IsInnerSquare &&
Left->Previous)
725 Left->Previous->EndsCppAttributeGroup =
false;
726 }
else if (Style.isJavaScript() &&
Parent &&
727 Contexts.back().ContextKind == tok::l_brace &&
728 Parent->isOneOf(tok::l_brace, tok::comma)) {
729 Left->setType(TT_JsComputedPropertyName);
730 }
else if (IsCpp && Contexts.back().ContextKind == tok::l_brace &&
732 Left->setType(TT_DesignatedInitializerLSquare);
733 }
else if (IsCSharpAttributeSpecifier) {
734 Left->setType(TT_AttributeSquare);
735 }
else if (CurrentToken->is(tok::r_square) &&
Parent &&
736 Parent->is(TT_TemplateCloser)) {
737 Left->setType(TT_ArraySubscriptLSquare);
738 }
else if (Style.isProto()) {
765 Left->setType(TT_ArrayInitializerLSquare);
766 if (!
Left->endsSequence(tok::l_square, tok::numeric_constant,
768 !
Left->endsSequence(tok::l_square, tok::numeric_constant,
770 !
Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
771 Left->setType(TT_ProtoExtensionLSquare);
772 BindingIncrease = 10;
774 }
else if (!CppArrayTemplates &&
Parent &&
775 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
776 tok::comma, tok::l_paren, tok::l_square,
777 tok::question, tok::colon, tok::kw_return,
780 Left->setType(TT_ArrayInitializerLSquare);
782 BindingIncrease = 10;
783 Left->setType(TT_ArraySubscriptLSquare);
787 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
788 Contexts.back().IsExpression =
true;
789 if (Style.isJavaScript() &&
Parent &&
Parent->is(TT_JsTypeColon))
790 Contexts.back().IsExpression =
false;
792 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
793 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
794 Contexts.back().InCSharpAttributeSpecifier = IsCSharpAttributeSpecifier;
796 while (CurrentToken) {
797 if (CurrentToken->is(tok::r_square)) {
798 if (IsCpp11AttributeSpecifier) {
799 CurrentToken->setType(TT_AttributeSquare);
801 CurrentToken->EndsCppAttributeGroup =
true;
803 if (IsCSharpAttributeSpecifier) {
804 CurrentToken->setType(TT_AttributeSquare);
805 }
else if (((CurrentToken->Next &&
806 CurrentToken->Next->is(tok::l_paren)) ||
807 (CurrentToken->Previous &&
808 CurrentToken->Previous->Previous == Left)) &&
809 Left->is(TT_ObjCMethodExpr)) {
814 StartsObjCMethodExpr =
false;
815 Left->setType(TT_Unknown);
817 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
818 CurrentToken->setType(TT_ObjCMethodExpr);
821 if (!ColonFound && CurrentToken->Previous &&
822 CurrentToken->Previous->is(TT_Unknown) &&
823 canBeObjCSelectorComponent(*CurrentToken->Previous)) {
824 CurrentToken->Previous->setType(TT_SelectorName);
830 Parent->overwriteFixedType(TT_BinaryOperator);
833 if (CurrentToken->is(TT_ObjCMethodExpr) && CurrentToken->Next &&
834 CurrentToken->Next->is(TT_LambdaArrow)) {
835 CurrentToken->Next->overwriteFixedType(TT_Unknown);
837 Left->MatchingParen = CurrentToken;
838 CurrentToken->MatchingParen =
Left;
843 if (!Contexts.back().FirstObjCSelectorName) {
844 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
846 Previous->ObjCSelectorNameParts = 1;
847 Contexts.back().FirstObjCSelectorName =
Previous;
850 Left->ParameterCount =
851 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
853 if (Contexts.back().FirstObjCSelectorName) {
854 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
855 Contexts.back().LongestObjCSelectorName;
856 if (
Left->BlockParameterCount > 1)
857 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
859 if (Style.isTableGen() &&
Left->is(TT_TableGenListOpener))
860 CurrentToken->setType(TT_TableGenListCloser);
864 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
866 if (CurrentToken->is(tok::colon)) {
867 if (IsCpp11AttributeSpecifier &&
868 CurrentToken->endsSequence(tok::colon, tok::identifier,
872 CurrentToken->setType(TT_AttributeColon);
873 }
else if (!Style.isVerilog() && !Line.InPragmaDirective &&
874 Left->isOneOf(TT_ArraySubscriptLSquare,
875 TT_DesignatedInitializerLSquare)) {
876 Left->setType(TT_ObjCMethodExpr);
877 StartsObjCMethodExpr =
true;
878 Contexts.back().ColonIsObjCMethodExpr =
true;
881 Parent->setType(TT_CastRParen);
886 if (CurrentToken->is(tok::comma) &&
Left->is(TT_ObjCMethodExpr) &&
888 Left->setType(TT_ArrayInitializerLSquare);
890 FormatToken *Tok = CurrentToken;
891 if (Style.isTableGen()) {
892 if (CurrentToken->isOneOf(tok::comma, tok::minus, tok::ellipsis)) {
898 if (!parseTableGenValue())
901 updateParameterCount(Left, Tok);
906 updateParameterCount(Left, Tok);
911 void skipToNextNonComment() {
913 while (CurrentToken && CurrentToken->is(tok::comment))
922 bool parseTableGenValue(
bool ParseNameMode =
false) {
925 while (CurrentToken->is(tok::comment))
927 if (!parseTableGenSimpleValue())
932 if (CurrentToken->is(tok::hash)) {
933 if (CurrentToken->Next &&
934 CurrentToken->Next->isOneOf(tok::colon, tok::semi, tok::l_brace)) {
937 CurrentToken->setType(TT_TableGenTrailingPasteOperator);
941 FormatToken *HashTok = CurrentToken;
942 skipToNextNonComment();
943 HashTok->setType(TT_Unknown);
944 if (!parseTableGenValue(ParseNameMode))
951 if (ParseNameMode && CurrentToken->is(tok::l_brace))
954 if (CurrentToken->isOneOf(tok::l_brace, tok::l_square, tok::period)) {
955 CurrentToken->setType(TT_TableGenValueSuffix);
956 FormatToken *Suffix = CurrentToken;
957 skipToNextNonComment();
958 if (Suffix->is(tok::l_square))
959 return parseSquare();
960 if (Suffix->is(tok::l_brace)) {
961 Scopes.push_back(getScopeType(*Suffix));
971 bool tryToParseTableGenTokVar() {
974 if (CurrentToken->is(tok::identifier) &&
975 CurrentToken->TokenText.front() ==
'$') {
976 skipToNextNonComment();
984 bool parseTableGenDAGArg(
bool AlignColon =
false) {
985 if (tryToParseTableGenTokVar())
987 if (parseTableGenValue()) {
988 if (CurrentToken && CurrentToken->is(tok::colon)) {
990 CurrentToken->setType(TT_TableGenDAGArgListColonToAlign);
992 CurrentToken->setType(TT_TableGenDAGArgListColon);
993 skipToNextNonComment();
994 return tryToParseTableGenTokVar();
1004 bool isTableGenDAGArgBreakingOperator(
const FormatToken &Tok) {
1005 auto &Opes = Style.TableGenBreakingDAGArgOperators;
1010 if (Tok.isNot(tok::identifier) ||
1011 Tok.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
1015 if (!Tok.Next || Tok.Next->is(tok::colon))
1017 return llvm::is_contained(Opes, Tok.TokenText.str());
1022 bool parseTableGenDAGArgAndList(FormatToken *Opener) {
1023 FormatToken *FirstTok = CurrentToken;
1024 if (!parseTableGenDAGArg())
1026 bool BreakInside =
false;
1030 if (isTableGenDAGArgBreakingOperator(*FirstTok)) {
1033 Opener->setType(TT_TableGenDAGArgOpenerToBreak);
1034 if (FirstTok->isOneOf(TT_TableGenBangOperator,
1035 TT_TableGenCondOperator)) {
1038 CurrentToken->Previous->setType(TT_TableGenDAGArgOperatorToBreak);
1039 }
else if (FirstTok->is(tok::identifier)) {
1041 FirstTok->setType(TT_TableGenDAGArgOperatorToBreak);
1043 FirstTok->setType(TT_TableGenDAGArgOperatorID);
1048 return parseTableGenDAGArgList(Opener, BreakInside);
1053 bool parseTableGenDAGArgList(FormatToken *Opener,
bool BreakInside) {
1054 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 0);
1055 Contexts.back().IsTableGenDAGArgList =
true;
1056 bool FirstDAGArgListElm =
true;
1057 while (CurrentToken) {
1058 if (!FirstDAGArgListElm && CurrentToken->is(tok::comma)) {
1059 CurrentToken->setType(BreakInside ? TT_TableGenDAGArgListCommaToBreak
1060 : TT_TableGenDAGArgListComma);
1061 skipToNextNonComment();
1063 if (CurrentToken && CurrentToken->is(tok::r_paren)) {
1064 CurrentToken->setType(TT_TableGenDAGArgCloser);
1065 Opener->MatchingParen = CurrentToken;
1066 CurrentToken->MatchingParen = Opener;
1067 skipToNextNonComment();
1070 if (!parseTableGenDAGArg(
1072 Style.AlignConsecutiveTableGenBreakingDAGArgColons.Enabled)) {
1075 FirstDAGArgListElm =
false;
1080 bool parseTableGenSimpleValue() {
1081 assert(Style.isTableGen());
1084 FormatToken *Tok = CurrentToken;
1085 skipToNextNonComment();
1087 if (Tok->isOneOf(tok::numeric_constant, tok::string_literal,
1088 TT_TableGenMultiLineString, tok::kw_true, tok::kw_false,
1089 tok::question, tok::kw_int)) {
1093 if (Tok->is(tok::l_brace)) {
1094 Scopes.push_back(getScopeType(*Tok));
1095 return parseBrace();
1098 if (Tok->is(tok::l_square)) {
1099 Tok->setType(TT_TableGenListOpener);
1102 if (Tok->is(tok::less)) {
1103 CurrentToken->setType(TT_TemplateOpener);
1104 return parseAngle();
1110 if (Tok->is(tok::l_paren)) {
1111 Tok->setType(TT_TableGenDAGArgOpener);
1113 if (Contexts.back().IsTableGenDAGArgList)
1114 Tok->SpacesRequiredBefore = 1;
1115 return parseTableGenDAGArgAndList(Tok);
1118 if (Tok->is(TT_TableGenBangOperator)) {
1119 if (CurrentToken && CurrentToken->is(tok::less)) {
1120 CurrentToken->setType(TT_TemplateOpener);
1121 skipToNextNonComment();
1125 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1129 Contexts.back().IsTableGenBangOpe =
true;
1130 bool Result = parseParens();
1131 Contexts.back().IsTableGenBangOpe =
false;
1135 if (Tok->is(TT_TableGenCondOperator)) {
1136 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1139 return parseParens();
1144 if (Tok->is(tok::identifier)) {
1146 if (CurrentToken && CurrentToken->is(tok::less)) {
1147 CurrentToken->setType(TT_TemplateOpener);
1148 skipToNextNonComment();
1149 return parseAngle();
1157 bool couldBeInStructArrayInitializer()
const {
1158 if (Contexts.size() < 2)
1162 const auto End = std::next(Contexts.rbegin(), 2);
1163 auto Last = Contexts.rbegin();
1166 if (
Last->ContextKind == tok::l_brace)
1168 return Depth == 2 &&
Last->ContextKind != tok::l_brace;
1175 assert(CurrentToken->Previous);
1176 FormatToken &OpeningBrace = *CurrentToken->Previous;
1177 assert(OpeningBrace.is(tok::l_brace));
1178 OpeningBrace.ParentBracket = Contexts.back().ContextKind;
1180 if (Contexts.back().CaretFound)
1181 OpeningBrace.overwriteFixedType(TT_ObjCBlockLBrace);
1182 Contexts.back().CaretFound =
false;
1184 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
1185 Contexts.back().ColonIsDictLiteral =
true;
1187 Contexts.back().IsExpression =
true;
1188 if (Style.isJavaScript() && OpeningBrace.Previous &&
1189 OpeningBrace.Previous->is(TT_JsTypeColon)) {
1190 Contexts.back().IsExpression =
false;
1192 if (Style.isVerilog() &&
1193 (!OpeningBrace.getPreviousNonComment() ||
1194 OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
1195 Contexts.back().VerilogMayBeConcatenation =
true;
1197 if (Style.isTableGen())
1198 Contexts.back().ColonIsDictLiteral =
false;
1200 unsigned CommaCount = 0;
1201 while (CurrentToken) {
1202 if (CurrentToken->is(tok::r_brace)) {
1203 assert(!Scopes.empty());
1204 assert(Scopes.back() == getScopeType(OpeningBrace));
1206 assert(OpeningBrace.Optional == CurrentToken->Optional);
1207 OpeningBrace.MatchingParen = CurrentToken;
1208 CurrentToken->MatchingParen = &OpeningBrace;
1210 if (OpeningBrace.ParentBracket == tok::l_brace &&
1211 couldBeInStructArrayInitializer() && CommaCount > 0) {
1212 Contexts.back().ContextType = Context::StructArrayInitializer;
1218 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
1220 updateParameterCount(&OpeningBrace, CurrentToken);
1221 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
1222 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
1223 if (
Previous->is(TT_JsTypeOptionalQuestion))
1225 if ((CurrentToken->is(tok::colon) && !Style.isTableGen() &&
1226 (!Contexts.back().ColonIsDictLiteral || !IsCpp)) ||
1228 OpeningBrace.setType(TT_DictLiteral);
1229 if (
Previous->Tok.getIdentifierInfo() ||
1230 Previous->is(tok::string_literal)) {
1231 Previous->setType(TT_SelectorName);
1234 if (CurrentToken->is(tok::colon) && OpeningBrace.is(TT_Unknown) &&
1235 !Style.isTableGen()) {
1236 OpeningBrace.setType(TT_DictLiteral);
1237 }
else if (Style.isJavaScript()) {
1238 OpeningBrace.overwriteFixedType(TT_DictLiteral);
1241 if (CurrentToken->is(tok::comma)) {
1242 if (Style.isJavaScript())
1243 OpeningBrace.overwriteFixedType(TT_DictLiteral);
1246 if (!consumeToken())
1252 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
1256 if (Current->is(tok::l_brace) && Current->is(
BK_Block))
1257 ++
Left->BlockParameterCount;
1258 if (Current->is(tok::comma)) {
1259 ++
Left->ParameterCount;
1261 Left->Role.reset(
new CommaSeparatedList(Style));
1262 Left->Role->CommaFound(Current);
1263 }
else if (
Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
1264 Left->ParameterCount = 1;
1268 bool parseConditional() {
1269 while (CurrentToken) {
1270 if (CurrentToken->is(tok::colon) && CurrentToken->is(TT_Unknown)) {
1271 CurrentToken->setType(TT_ConditionalExpr);
1275 if (!consumeToken())
1281 bool parseTemplateDeclaration() {
1282 if (!CurrentToken || CurrentToken->isNot(tok::less))
1285 CurrentToken->setType(TT_TemplateOpener);
1288 TemplateDeclarationDepth++;
1289 const bool WellFormed = parseAngle();
1290 TemplateDeclarationDepth--;
1294 if (CurrentToken && TemplateDeclarationDepth == 0)
1295 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
1300 bool consumeToken() {
1302 const auto *Prev = CurrentToken->getPreviousNonComment();
1303 if (Prev && Prev->is(tok::r_square) && Prev->is(TT_AttributeSquare) &&
1304 CurrentToken->isOneOf(tok::kw_if, tok::kw_switch, tok::kw_case,
1305 tok::kw_default, tok::kw_for, tok::kw_while) &&
1307 CurrentToken->MustBreakBefore =
true;
1310 FormatToken *Tok = CurrentToken;
1314 if (Tok->is(TT_VerilogTableItem))
1317 if (Tok->is(TT_TableGenMultiLineString))
1319 auto *Prev = Tok->getPreviousNonComment();
1320 auto *Next = Tok->getNextNonComment();
1321 switch (
bool IsIf =
false; Tok->Tok.getKind()) {
1324 if (!Prev && Line.MustBeDeclaration)
1325 Tok->setType(TT_ObjCMethodSpecifier);
1332 if (Tok->isTypeFinalized())
1335 if (Style.isJavaScript()) {
1336 if (Contexts.back().ColonIsForRangeExpr ||
1337 (Contexts.size() == 1 &&
1338 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
1339 Contexts.back().ContextKind == tok::l_paren ||
1340 Contexts.back().ContextKind == tok::l_square ||
1341 (!Contexts.back().IsExpression &&
1342 Contexts.back().ContextKind == tok::l_brace) ||
1343 (Contexts.size() == 1 &&
1344 Line.MustBeDeclaration)) {
1345 Contexts.back().IsExpression =
false;
1346 Tok->setType(TT_JsTypeColon);
1349 }
else if (Style.isCSharp()) {
1350 if (Contexts.back().InCSharpAttributeSpecifier) {
1351 Tok->setType(TT_AttributeColon);
1354 if (Contexts.back().ContextKind == tok::l_paren) {
1355 Tok->setType(TT_CSharpNamedArgumentColon);
1358 }
else if (Style.isVerilog() && Tok->isNot(TT_BinaryOperator)) {
1361 if (Keywords.isVerilogEnd(*Prev) || Keywords.isVerilogBegin(*Prev)) {
1362 Tok->setType(TT_VerilogBlockLabelColon);
1363 }
else if (Contexts.back().ContextKind == tok::l_square) {
1364 Tok->setType(TT_BitFieldColon);
1365 }
else if (Contexts.back().ColonIsDictLiteral) {
1366 Tok->setType(TT_DictLiteral);
1367 }
else if (Contexts.size() == 1) {
1371 Tok->setType(TT_CaseLabelColon);
1372 if (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))
1377 if (Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) ||
1378 Line.First->startsSequence(tok::kw_export, Keywords.kw_module) ||
1379 Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) {
1380 Tok->setType(TT_ModulePartitionColon);
1381 }
else if (Line.First->is(tok::kw_asm)) {
1382 Tok->setType(TT_InlineASMColon);
1383 }
else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) {
1384 Tok->setType(TT_DictLiteral);
1385 if (Style.isTextProto())
1386 Prev->setType(TT_SelectorName);
1387 }
else if (Contexts.back().ColonIsObjCMethodExpr ||
1388 Line.startsWith(TT_ObjCMethodSpecifier)) {
1389 Tok->setType(TT_ObjCMethodExpr);
1390 const auto *PrevPrev = Prev->Previous;
1393 bool UnknownIdentifierInMethodDeclaration =
1394 Line.startsWith(TT_ObjCMethodSpecifier) &&
1395 Prev->is(tok::identifier) && Prev->is(TT_Unknown);
1398 !(PrevPrev->is(TT_CastRParen) ||
1399 (PrevPrev->is(TT_ObjCMethodExpr) && PrevPrev->is(tok::colon))) ||
1400 PrevPrev->is(tok::r_square) ||
1401 Contexts.back().LongestObjCSelectorName == 0 ||
1402 UnknownIdentifierInMethodDeclaration) {
1403 Prev->setType(TT_SelectorName);
1404 if (!Contexts.back().FirstObjCSelectorName)
1405 Contexts.back().FirstObjCSelectorName = Prev;
1406 else if (Prev->ColumnWidth > Contexts.back().LongestObjCSelectorName)
1407 Contexts.back().LongestObjCSelectorName = Prev->ColumnWidth;
1408 Prev->ParameterIndex =
1409 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
1410 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
1412 }
else if (Contexts.back().ColonIsForRangeExpr) {
1413 Tok->setType(TT_RangeBasedForLoopColon);
1414 for (
auto *Token = Prev;
1415 Token && !Token->isOneOf(tok::semi, tok::l_paren);
1416 Token = Token->Previous) {
1417 if (Token->isPointerOrReference())
1418 Token->setFinalizedType(TT_PointerOrReference);
1420 }
else if (Contexts.back().ContextType == Context::C11GenericSelection) {
1421 Tok->setType(TT_GenericSelectionColon);
1422 if (Prev->isPointerOrReference())
1423 Prev->setFinalizedType(TT_PointerOrReference);
1424 }
else if ((CurrentToken && CurrentToken->is(tok::numeric_constant)) ||
1425 (Prev->is(TT_StartOfName) && !Scopes.empty() &&
1427 Tok->setType(TT_BitFieldColon);
1428 }
else if (Contexts.size() == 1 &&
1429 !Line.getFirstNonComment()->isOneOf(tok::kw_enum, tok::kw_case,
1431 !Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
1432 if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept) ||
1433 Prev->ClosesRequiresClause) {
1434 Tok->setType(TT_CtorInitializerColon);
1435 }
else if (Prev->is(tok::kw_try)) {
1437 FormatToken *PrevPrev = Prev->getPreviousNonComment();
1440 if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept))
1441 Tok->setType(TT_CtorInitializerColon);
1443 Tok->setType(TT_InheritanceColon);
1444 if (Prev->isAccessSpecifierKeyword())
1447 }
else if (canBeObjCSelectorComponent(*Prev) && Next &&
1448 (Next->isOneOf(tok::r_paren, tok::comma) ||
1449 (canBeObjCSelectorComponent(*Next) && Next->Next &&
1450 Next->Next->is(tok::colon)))) {
1453 Tok->setType(TT_ObjCMethodExpr);
1460 if (Style.isJavaScript() && !Contexts.back().IsExpression)
1461 Tok->setType(TT_JsTypeOperator);
1464 if (Style.isTableGen()) {
1466 if (!parseTableGenValue())
1468 if (CurrentToken && CurrentToken->is(Keywords.kw_then))
1473 CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier)) {
1479 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
1481 if (!parseParens(IsIf))
1486 if (Style.isJavaScript()) {
1488 if ((Prev && Prev->is(tok::period)) || (Next && Next->is(tok::colon)))
1491 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
1494 if (IsCpp && CurrentToken && CurrentToken->is(tok::kw_co_await))
1496 Contexts.back().ColonIsForRangeExpr =
true;
1497 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1508 if (Prev && Prev->is(tok::r_paren) && Prev->MatchingParen &&
1509 Prev->MatchingParen->is(TT_OverloadedOperatorLParen)) {
1510 Prev->setType(TT_OverloadedOperator);
1511 Prev->MatchingParen->setType(TT_OverloadedOperator);
1512 Tok->setType(TT_OverloadedOperatorLParen);
1515 if (Style.isVerilog()) {
1521 auto IsInstancePort = [&]() {
1522 const FormatToken *PrevPrev;
1530 if (!Prev || !(PrevPrev = Prev->getPreviousNonComment()))
1533 if (Keywords.isVerilogIdentifier(*Prev) &&
1534 Keywords.isVerilogIdentifier(*PrevPrev)) {
1538 if (Prev->is(Keywords.kw_verilogHash) &&
1539 Keywords.isVerilogIdentifier(*PrevPrev)) {
1543 if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::r_paren))
1546 if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::comma)) {
1547 const FormatToken *PrevParen = PrevPrev->getPreviousNonComment();
1548 if (PrevParen && PrevParen->is(tok::r_paren) &&
1549 PrevParen->MatchingParen &&
1550 PrevParen->MatchingParen->is(TT_VerilogInstancePortLParen)) {
1557 if (IsInstancePort())
1558 Tok->setType(TT_VerilogInstancePortLParen);
1563 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
1564 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
1565 !Line.startsWith(tok::l_paren) &&
1566 !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) {
1568 (!Prev->isAttribute() &&
1569 !Prev->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation,
1570 TT_BinaryOperator))) {
1571 Line.MightBeFunctionDecl =
true;
1572 Tok->MightBeFunctionDeclParen =
true;
1577 if (Style.isTableGen())
1578 Tok->setType(TT_TableGenListOpener);
1584 if (Tok->is(TT_RequiresExpressionLBrace))
1586 }
else if (Style.isTextProto()) {
1587 if (Prev && Prev->isNot(TT_DictLiteral))
1588 Prev->setType(TT_SelectorName);
1590 Scopes.push_back(getScopeType(*Tok));
1596 Tok->setType(TT_TemplateOpener);
1602 if (Style.isTextProto() ||
1604 Prev->isOneOf(TT_SelectorName, TT_DictLiteral))) {
1605 Tok->setType(TT_DictLiteral);
1606 if (Prev && Prev->isNot(TT_DictLiteral))
1607 Prev->setType(TT_SelectorName);
1609 if (Style.isTableGen())
1610 Tok->setType(TT_TemplateOpener);
1612 Tok->setType(TT_BinaryOperator);
1613 NonTemplateLess.insert(Tok);
1623 if (!Scopes.empty())
1630 if (!Style.isTextProto() && Tok->is(TT_Unknown))
1631 Tok->setType(TT_BinaryOperator);
1632 if (Prev && Prev->is(TT_TemplateCloser))
1633 Tok->SpacesRequiredBefore = 1;
1635 case tok::kw_operator:
1636 if (Style.isProto())
1639 if (IsCpp && CurrentToken) {
1640 const auto *Info = CurrentToken->Tok.getIdentifierInfo();
1642 if (Info && !(CurrentToken->isPlacementOperator() ||
1643 CurrentToken->is(tok::kw_co_await) ||
1644 Info->isCPlusPlusOperatorKeyword())) {
1645 FormatToken *LParen;
1646 if (CurrentToken->startsSequence(tok::kw_decltype, tok::l_paren,
1647 tok::kw_auto, tok::r_paren)) {
1649 LParen = CurrentToken->Next->Next->Next->Next;
1652 for (LParen = CurrentToken->Next;
1653 LParen && LParen->isNot(tok::l_paren); LParen = LParen->Next) {
1654 if (LParen->isPointerOrReference())
1655 LParen->setFinalizedType(TT_PointerOrReference);
1658 if (LParen && LParen->is(tok::l_paren)) {
1659 if (!Contexts.back().IsExpression) {
1660 Tok->setFinalizedType(TT_FunctionDeclarationName);
1661 LParen->setFinalizedType(TT_FunctionDeclarationLParen);
1667 while (CurrentToken &&
1668 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
1669 if (CurrentToken->isOneOf(tok::star, tok::amp))
1670 CurrentToken->setType(TT_PointerOrReference);
1671 auto Next = CurrentToken->getNextNonComment();
1674 if (Next->is(tok::less))
1680 auto Previous = CurrentToken->getPreviousNonComment();
1682 if (CurrentToken->is(tok::comma) &&
Previous->isNot(tok::kw_operator))
1684 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, tok::comma,
1686 Previous->isPointerOrReference() ||
1688 Previous->TokenText.starts_with(
"\"\"")) {
1689 Previous->setType(TT_OverloadedOperator);
1690 if (CurrentToken->isOneOf(tok::less, tok::greater))
1694 if (CurrentToken && CurrentToken->is(tok::l_paren))
1695 CurrentToken->setType(TT_OverloadedOperatorLParen);
1696 if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator))
1697 CurrentToken->Previous->setType(TT_OverloadedOperator);
1700 if (Style.isJavaScript() && Next &&
1701 Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
1702 tok::r_brace, tok::r_square)) {
1707 Tok->setType(TT_JsTypeOptionalQuestion);
1712 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
1713 Style.isJavaScript()) {
1716 if (Style.isCSharp()) {
1719 if (Next && (Next->isOneOf(tok::r_paren, tok::greater) ||
1720 Next->startsSequence(tok::identifier, tok::semi) ||
1721 Next->startsSequence(tok::identifier, tok::equal))) {
1722 Tok->setType(TT_CSharpNullable);
1731 if (!Contexts.back().IsExpression && Line.MustBeDeclaration &&
1732 (!Next || !Next->isOneOf(tok::identifier, tok::string_literal) ||
1733 !Next->Next || !Next->Next->isOneOf(tok::colon, tok::question))) {
1734 Tok->setType(TT_CSharpNullable);
1740 case tok::kw_template:
1741 parseTemplateDeclaration();
1744 switch (Contexts.back().ContextType) {
1745 case Context::CtorInitializer:
1746 Tok->setType(TT_CtorInitializerComma);
1748 case Context::InheritanceList:
1749 Tok->setType(TT_InheritanceComma);
1751 case Context::VerilogInstancePortList:
1752 Tok->setType(TT_VerilogInstancePortComma);
1755 if (Style.isVerilog() && Contexts.size() == 1 &&
1756 Line.startsWith(Keywords.kw_assign)) {
1757 Tok->setFinalizedType(TT_VerilogAssignComma);
1758 }
else if (Contexts.back().FirstStartOfName &&
1759 (Contexts.size() == 1 || startsWithInitStatement(Line))) {
1760 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
1761 Line.IsMultiVariableDeclStmt =
true;
1765 if (Contexts.back().ContextType == Context::ForEachMacro)
1766 Contexts.back().IsExpression =
true;
1768 case tok::kw_default:
1770 if (Style.isVerilog() && Keywords.isVerilogEndOfLabel(*Tok) &&
1771 (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))) {
1775 case tok::identifier:
1776 if (Tok->isOneOf(Keywords.kw___has_include,
1777 Keywords.kw___has_include_next)) {
1781 if (Next && Next->is(tok::l_paren) && Prev &&
1782 Prev->isOneOf(tok::kw___cdecl, tok::kw___stdcall,
1783 tok::kw___fastcall, tok::kw___thiscall,
1784 tok::kw___regcall, tok::kw___vectorcall)) {
1785 Tok->setFinalizedType(TT_FunctionDeclarationName);
1786 Next->setFinalizedType(TT_FunctionDeclarationLParen);
1788 }
else if (Style.isCSharp()) {
1789 if (Tok->is(Keywords.kw_where) && Next && Next->isNot(tok::l_paren)) {
1790 Tok->setType(TT_CSharpGenericTypeConstraint);
1791 parseCSharpGenericTypeConstraint();
1793 Line.IsContinuation =
true;
1795 }
else if (Style.isTableGen()) {
1796 if (Tok->is(Keywords.kw_assert)) {
1797 if (!parseTableGenValue())
1799 }
else if (Tok->isOneOf(Keywords.kw_def, Keywords.kw_defm) &&
1800 (!Next || !Next->isOneOf(tok::colon, tok::l_brace))) {
1802 if (!parseTableGenValue(
true))
1808 if (Tok->isNot(TT_LambdaArrow) && Prev && Prev->is(tok::kw_noexcept))
1809 Tok->setType(TT_TrailingReturnArrow);
1813 if (Style.isTableGen() && !parseTableGenValue())
1822 void parseCSharpGenericTypeConstraint() {
1823 int OpenAngleBracketsCount = 0;
1824 while (CurrentToken) {
1825 if (CurrentToken->is(tok::less)) {
1827 CurrentToken->setType(TT_TemplateOpener);
1828 ++OpenAngleBracketsCount;
1830 }
else if (CurrentToken->is(tok::greater)) {
1831 CurrentToken->setType(TT_TemplateCloser);
1832 --OpenAngleBracketsCount;
1834 }
else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) {
1837 CurrentToken->setType(TT_CSharpGenericTypeConstraintComma);
1839 }
else if (CurrentToken->is(Keywords.kw_where)) {
1840 CurrentToken->setType(TT_CSharpGenericTypeConstraint);
1842 }
else if (CurrentToken->is(tok::colon)) {
1843 CurrentToken->setType(TT_CSharpGenericTypeConstraintColon);
1851 void parseIncludeDirective() {
1852 if (CurrentToken && CurrentToken->is(tok::less)) {
1854 while (CurrentToken) {
1857 if (CurrentToken->isNot(tok::comment) &&
1858 !CurrentToken->TokenText.starts_with(
"//")) {
1859 CurrentToken->setType(TT_ImplicitStringLiteral);
1866 void parseWarningOrError() {
1871 while (CurrentToken) {
1872 CurrentToken->setType(TT_ImplicitStringLiteral);
1877 void parsePragma() {
1880 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option,
1881 Keywords.kw_region)) {
1882 bool IsMarkOrRegion =
1883 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_region);
1886 while (CurrentToken) {
1887 if (IsMarkOrRegion || CurrentToken->Previous->is(TT_BinaryOperator))
1888 CurrentToken->setType(TT_ImplicitStringLiteral);
1894 void parseHasInclude() {
1895 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1898 parseIncludeDirective();
1902 LineType parsePreprocessorDirective() {
1903 bool IsFirstToken = CurrentToken->IsFirst;
1909 if (Style.isJavaScript() && IsFirstToken) {
1913 while (CurrentToken) {
1915 CurrentToken->setType(TT_ImplicitStringLiteral);
1921 if (CurrentToken->is(tok::numeric_constant)) {
1922 CurrentToken->SpacesRequiredBefore = 1;
1927 if (!CurrentToken->Tok.getIdentifierInfo())
1931 if (Style.isVerilog() && !Keywords.isVerilogPPDirective(*CurrentToken))
1933 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1934 case tok::pp_include:
1935 case tok::pp_include_next:
1936 case tok::pp_import:
1938 parseIncludeDirective();
1942 case tok::pp_warning:
1943 parseWarningOrError();
1945 case tok::pp_pragma:
1950 Contexts.back().IsExpression =
true;
1953 CurrentToken->SpacesRequiredBefore = 1;
1959 while (CurrentToken) {
1960 FormatToken *Tok = CurrentToken;
1962 if (Tok->is(tok::l_paren)) {
1964 }
else if (Tok->isOneOf(Keywords.kw___has_include,
1965 Keywords.kw___has_include_next)) {
1976 NonTemplateLess.clear();
1977 if (!Line.InMacroBody && CurrentToken->is(tok::hash)) {
1981 auto Type = parsePreprocessorDirective();
1989 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
1990 if ((Style.isJava() && CurrentToken->is(Keywords.kw_package)) ||
1991 (!Style.isVerilog() && Info &&
1992 Info->getPPKeywordID() == tok::pp_import && CurrentToken->Next &&
1993 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
1996 parseIncludeDirective();
2002 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
2003 parseIncludeDirective();
2010 CurrentToken->isOneOf(Keywords.kw_option, Keywords.kw_package)) {
2012 if (CurrentToken && CurrentToken->is(tok::identifier)) {
2013 while (CurrentToken)
2019 bool KeywordVirtualFound =
false;
2020 bool ImportStatement =
false;
2023 if (Style.isJavaScript() && CurrentToken->is(Keywords.kw_import))
2024 ImportStatement =
true;
2026 while (CurrentToken) {
2027 if (CurrentToken->is(tok::kw_virtual))
2028 KeywordVirtualFound =
true;
2029 if (Style.isJavaScript()) {
2036 if (Line.First->is(tok::kw_export) &&
2037 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
2038 CurrentToken->Next->isStringLiteral()) {
2039 ImportStatement =
true;
2041 if (isClosureImportStatement(*CurrentToken))
2042 ImportStatement =
true;
2044 if (!consumeToken())
2052 if (KeywordVirtualFound)
2054 if (ImportStatement)
2057 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
2058 if (Contexts.back().FirstObjCSelectorName) {
2059 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
2060 Contexts.back().LongestObjCSelectorName;
2065 for (
const auto &ctx : Contexts)
2066 if (ctx.ContextType == Context::StructArrayInitializer)
2073 bool isClosureImportStatement(
const FormatToken &Tok) {
2076 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
2078 (Tok.Next->Next->TokenText ==
"module" ||
2079 Tok.Next->Next->TokenText ==
"provide" ||
2080 Tok.Next->Next->TokenText ==
"require" ||
2081 Tok.Next->Next->TokenText ==
"requireType" ||
2082 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
2083 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
2086 void resetTokenMetadata() {
2092 if (!CurrentToken->isTypeFinalized() &&
2093 !CurrentToken->isOneOf(
2094 TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
2095 TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
2096 TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
2097 TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
2098 TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
2099 TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro,
2100 TT_FunctionLikeOrFreestandingMacro, TT_ClassLBrace, TT_EnumLBrace,
2101 TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,
2102 TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
2103 TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
2104 TT_CompoundRequirementLBrace, TT_BracedListLBrace,
2105 TT_FunctionLikeMacro)) {
2106 CurrentToken->setType(TT_Unknown);
2108 CurrentToken->Role.reset();
2109 CurrentToken->MatchingParen =
nullptr;
2110 CurrentToken->FakeLParens.clear();
2111 CurrentToken->FakeRParens = 0;
2118 CurrentToken->NestingLevel = Contexts.size() - 1;
2119 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
2120 modifyContext(*CurrentToken);
2121 determineTokenType(*CurrentToken);
2122 CurrentToken = CurrentToken->Next;
2124 resetTokenMetadata();
2167 StructArrayInitializer,
2171 C11GenericSelection,
2173 VerilogInstancePortList,
2179 struct ScopedContextCreator {
2180 AnnotatingParser &
P;
2186 P.Contexts.back().BindingStrength + Increase,
2187 P.Contexts.back().IsExpression));
2190 ~ScopedContextCreator() {
2192 if (
P.Contexts.back().ContextType == Context::StructArrayInitializer) {
2193 P.Contexts.pop_back();
2194 P.Contexts.back().ContextType = Context::StructArrayInitializer;
2198 P.Contexts.pop_back();
2202 void modifyContext(
const FormatToken &Current) {
2203 auto AssignmentStartsExpression = [&]() {
2207 if (Line.First->isOneOf(tok::kw_using, tok::kw_return))
2209 if (Line.First->is(tok::kw_template)) {
2210 assert(Current.Previous);
2211 if (Current.Previous->is(tok::kw_operator)) {
2217 const FormatToken *Tok = Line.First->getNextNonComment();
2219 if (Tok->isNot(TT_TemplateOpener)) {
2226 if (Contexts.back().ContextKind == tok::less) {
2227 assert(Current.Previous->Previous);
2228 return !Current.Previous->Previous->isOneOf(tok::kw_typename,
2232 Tok = Tok->MatchingParen;
2235 Tok = Tok->getNextNonComment();
2239 if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_struct,
2249 if (Style.isJavaScript() &&
2250 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
2251 Line.startsWith(tok::kw_export, Keywords.kw_type,
2252 tok::identifier))) {
2256 return !Current.Previous || Current.Previous->isNot(tok::kw_operator);
2259 if (AssignmentStartsExpression()) {
2260 Contexts.back().IsExpression =
true;
2261 if (!Line.startsWith(TT_UnaryOperator)) {
2262 for (FormatToken *
Previous = Current.Previous;
2264 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
2266 if (
Previous->isOneOf(tok::r_square, tok::r_paren, tok::greater)) {
2273 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
2275 Previous->Previous->isNot(tok::equal)) {
2276 Previous->setType(TT_PointerOrReference);
2280 }
else if (Current.is(tok::lessless) &&
2281 (!Current.Previous ||
2282 Current.Previous->isNot(tok::kw_operator))) {
2283 Contexts.back().IsExpression =
true;
2284 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
2285 Contexts.back().IsExpression =
true;
2286 }
else if (Current.is(TT_TrailingReturnArrow)) {
2287 Contexts.back().IsExpression =
false;
2288 }
else if (Current.isOneOf(TT_LambdaArrow, Keywords.kw_assert)) {
2289 Contexts.back().IsExpression = Style.isJava();
2290 }
else if (Current.Previous &&
2291 Current.Previous->is(TT_CtorInitializerColon)) {
2292 Contexts.back().IsExpression =
true;
2293 Contexts.back().ContextType = Context::CtorInitializer;
2294 }
else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
2295 Contexts.back().ContextType = Context::InheritanceList;
2296 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
2297 for (FormatToken *
Previous = Current.Previous;
2300 Previous->setType(TT_PointerOrReference);
2302 if (Line.MustBeDeclaration &&
2303 Contexts.front().ContextType != Context::CtorInitializer) {
2304 Contexts.back().IsExpression =
false;
2306 }
else if (Current.is(tok::kw_new)) {
2307 Contexts.back().CanBeExpression =
false;
2308 }
else if (Current.is(tok::semi) ||
2309 (Current.is(tok::exclaim) && Current.Previous &&
2310 Current.Previous->isNot(tok::kw_operator))) {
2314 Contexts.back().IsExpression =
true;
2318 static FormatToken *untilMatchingParen(FormatToken *Current) {
2322 if (Current->is(tok::l_paren))
2324 if (Current->is(tok::r_paren))
2328 Current = Current->Next;
2333 static bool isDeductionGuide(FormatToken &Current) {
2335 if (Current.Previous && Current.Previous->is(tok::r_paren) &&
2336 Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
2338 FormatToken *TemplateCloser = Current.Next->Next;
2339 int NestingLevel = 0;
2340 while (TemplateCloser) {
2342 if (TemplateCloser->is(tok::l_paren)) {
2344 TemplateCloser = untilMatchingParen(TemplateCloser);
2345 if (!TemplateCloser)
2348 if (TemplateCloser->is(tok::less))
2350 if (TemplateCloser->is(tok::greater))
2352 if (NestingLevel < 1)
2354 TemplateCloser = TemplateCloser->Next;
2358 if (TemplateCloser && TemplateCloser->Next &&
2359 TemplateCloser->Next->is(tok::semi) &&
2360 Current.Previous->MatchingParen) {
2363 FormatToken *LeadingIdentifier =
2364 Current.Previous->MatchingParen->Previous;
2366 return LeadingIdentifier &&
2367 LeadingIdentifier->TokenText == Current.Next->TokenText;
2373 void determineTokenType(FormatToken &Current) {
2374 if (Current.isNot(TT_Unknown)) {
2379 if ((Style.isJavaScript() || Style.isCSharp()) &&
2380 Current.is(tok::exclaim)) {
2381 if (Current.Previous) {
2383 Style.isJavaScript()
2384 ? Keywords.isJavaScriptIdentifier(
2385 *Current.Previous,
true)
2386 : Current.Previous->is(tok::identifier);
2388 Current.Previous->isOneOf(
2389 tok::kw_default, tok::kw_namespace, tok::r_paren, tok::r_square,
2390 tok::r_brace, tok::kw_false, tok::kw_true, Keywords.kw_type,
2391 Keywords.kw_get, Keywords.kw_init, Keywords.kw_set) ||
2392 Current.Previous->Tok.isLiteral()) {
2393 Current.setType(TT_NonNullAssertion);
2398 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
2399 Current.setType(TT_NonNullAssertion);
2407 if ((Style.isJavaScript() || Style.isJava()) &&
2408 Current.is(Keywords.kw_instanceof)) {
2409 Current.setType(TT_BinaryOperator);
2410 }
else if (isStartOfName(Current) &&
2411 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
2412 Contexts.back().FirstStartOfName = &Current;
2413 Current.setType(TT_StartOfName);
2414 }
else if (Current.is(tok::semi)) {
2418 Contexts.back().FirstStartOfName =
nullptr;
2419 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
2421 }
else if (Current.is(tok::arrow) && Style.isJava()) {
2422 Current.setType(TT_LambdaArrow);
2423 }
else if (Current.is(tok::arrow) && Style.isVerilog()) {
2425 Current.setType(TT_BinaryOperator);
2426 }
else if (Current.is(tok::arrow) && AutoFound &&
2427 Line.MightBeFunctionDecl && Current.NestingLevel == 0 &&
2428 !Current.Previous->isOneOf(tok::kw_operator, tok::identifier)) {
2430 Current.setType(TT_TrailingReturnArrow);
2431 }
else if (Current.is(tok::arrow) && Current.Previous &&
2432 Current.Previous->is(tok::r_brace) &&
2436 Current.setType(TT_TrailingReturnArrow);
2437 }
else if (isDeductionGuide(Current)) {
2439 Current.setType(TT_TrailingReturnArrow);
2440 }
else if (Current.isPointerOrReference()) {
2441 Current.setType(determineStarAmpUsage(
2443 Contexts.back().CanBeExpression && Contexts.back().IsExpression,
2444 Contexts.back().ContextType == Context::TemplateArgument));
2445 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret) ||
2446 (Style.isVerilog() && Current.is(tok::pipe))) {
2447 Current.setType(determinePlusMinusCaretUsage(Current));
2448 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
2449 Contexts.back().CaretFound =
true;
2450 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
2451 Current.setType(determineIncrementUsage(Current));
2452 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
2453 Current.setType(TT_UnaryOperator);
2454 }
else if (Current.is(tok::question)) {
2455 if (Style.isJavaScript() && Line.MustBeDeclaration &&
2456 !Contexts.back().IsExpression) {
2459 Current.setType(TT_JsTypeOptionalQuestion);
2460 }
else if (Style.isTableGen()) {
2462 Current.setType(TT_Unknown);
2464 Current.setType(TT_ConditionalExpr);
2466 }
else if (Current.isBinaryOperator() &&
2467 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
2468 (Current.isNot(tok::greater) && !Style.isTextProto())) {
2469 if (Style.isVerilog()) {
2470 if (Current.is(tok::lessequal) && Contexts.size() == 1 &&
2471 !Contexts.back().VerilogAssignmentFound) {
2475 Current.setFinalizedType(TT_BinaryOperator);
2478 Contexts.back().VerilogAssignmentFound =
true;
2480 Current.setType(TT_BinaryOperator);
2481 }
else if (Current.is(tok::comment)) {
2482 if (Current.TokenText.starts_with(
"/*")) {
2483 if (Current.TokenText.ends_with(
"*/")) {
2484 Current.setType(TT_BlockComment);
2488 Current.Tok.setKind(tok::unknown);
2491 Current.setType(TT_LineComment);
2493 }
else if (Current.is(tok::string_literal)) {
2494 if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&
2495 Current.getPreviousNonComment() &&
2496 Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&
2497 Current.getNextNonComment() &&
2498 Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
2499 Current.setType(TT_StringInConcatenation);
2501 }
else if (Current.is(tok::l_paren)) {
2502 if (lParenStartsCppCast(Current))
2503 Current.setType(TT_CppCastLParen);
2504 }
else if (Current.is(tok::r_paren)) {
2505 if (rParenEndsCast(Current))
2506 Current.setType(TT_CastRParen);
2507 if (Current.MatchingParen && Current.Next &&
2508 !Current.Next->isBinaryOperator() &&
2509 !Current.Next->isOneOf(
2510 tok::semi, tok::colon, tok::l_brace, tok::l_paren, tok::comma,
2511 tok::period, tok::arrow, tok::coloncolon, tok::kw_noexcept)) {
2512 if (FormatToken *AfterParen = Current.MatchingParen->Next;
2513 AfterParen && AfterParen->isNot(tok::caret)) {
2515 if (FormatToken *BeforeParen = Current.MatchingParen->Previous;
2516 BeforeParen && BeforeParen->is(tok::identifier) &&
2517 BeforeParen->isNot(TT_TypenameMacro) &&
2518 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
2519 (!BeforeParen->Previous ||
2520 BeforeParen->Previous->ClosesTemplateDeclaration ||
2521 BeforeParen->Previous->ClosesRequiresClause)) {
2522 Current.setType(TT_FunctionAnnotationRParen);
2526 }
else if (Current.is(tok::at) && Current.Next && !Style.isJavaScript() &&
2530 switch (Current.Next->Tok.getObjCKeywordID()) {
2531 case tok::objc_interface:
2532 case tok::objc_implementation:
2533 case tok::objc_protocol:
2534 Current.setType(TT_ObjCDecl);
2536 case tok::objc_property:
2537 Current.setType(TT_ObjCProperty);
2542 }
else if (Current.is(tok::period)) {
2543 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
2544 if (PreviousNoComment &&
2545 PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) {
2546 Current.setType(TT_DesignatedInitializerPeriod);
2547 }
else if (Style.isJava() && Current.Previous &&
2548 Current.Previous->isOneOf(TT_JavaAnnotation,
2549 TT_LeadingJavaAnnotation)) {
2550 Current.setType(Current.Previous->getType());
2552 }
else if (canBeObjCSelectorComponent(Current) &&
2555 Current.Previous && Current.Previous->is(TT_CastRParen) &&
2556 Current.Previous->MatchingParen &&
2557 Current.Previous->MatchingParen->Previous &&
2558 Current.Previous->MatchingParen->Previous->is(
2559 TT_ObjCMethodSpecifier)) {
2563 Current.setType(TT_SelectorName);
2564 }
else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept,
2565 tok::kw_requires) &&
2567 !Current.Previous->isOneOf(tok::equal, tok::at,
2568 TT_CtorInitializerComma,
2569 TT_CtorInitializerColon) &&
2570 Line.MightBeFunctionDecl && Contexts.size() == 1) {
2573 Current.setType(TT_TrailingAnnotation);
2574 }
else if ((Style.isJava() || Style.isJavaScript()) && Current.Previous) {
2575 if (Current.Previous->is(tok::at) &&
2576 Current.isNot(Keywords.kw_interface)) {
2577 const FormatToken &AtToken = *Current.Previous;
2578 const FormatToken *
Previous = AtToken.getPreviousNonComment();
2580 Current.setType(TT_LeadingJavaAnnotation);
2582 Current.setType(TT_JavaAnnotation);
2583 }
else if (Current.Previous->is(tok::period) &&
2584 Current.Previous->isOneOf(TT_JavaAnnotation,
2585 TT_LeadingJavaAnnotation)) {
2586 Current.setType(Current.Previous->getType());
2596 bool isStartOfName(
const FormatToken &Tok) {
2598 if (Style.isVerilog())
2601 if (!Tok.Previous || Tok.isNot(tok::identifier) || Tok.is(TT_ClassHeadName))
2604 if (Tok.endsSequence(Keywords.kw_final, TT_ClassHeadName))
2607 if ((Style.isJavaScript() || Style.isJava()) && Tok.is(Keywords.kw_extends))
2610 if (
const auto *NextNonComment = Tok.getNextNonComment();
2611 (!NextNonComment && !Line.InMacroBody) ||
2613 (NextNonComment->isPointerOrReference() ||
2614 NextNonComment->isOneOf(TT_ClassHeadName, tok::string_literal) ||
2615 (Line.InPragmaDirective && NextNonComment->is(tok::identifier))))) {
2619 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
2623 if (Style.isJavaScript() && Tok.Previous->is(Keywords.kw_in))
2627 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
2630 if (!Style.isJavaScript())
2631 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
2632 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
2634 if (!PreviousNotConst)
2637 if (PreviousNotConst->ClosesRequiresClause)
2640 if (Style.isTableGen()) {
2642 if (Keywords.isTableGenDefinition(*PreviousNotConst))
2645 if (Contexts.back().ContextKind != tok::l_brace)
2649 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
2650 PreviousNotConst->Previous &&
2651 PreviousNotConst->Previous->is(tok::hash);
2653 if (PreviousNotConst->is(TT_TemplateCloser)) {
2654 return PreviousNotConst && PreviousNotConst->MatchingParen &&
2655 PreviousNotConst->MatchingParen->Previous &&
2656 !PreviousNotConst->MatchingParen->Previous->isOneOf(
2657 tok::period, tok::kw_template);
2660 if ((PreviousNotConst->is(tok::r_paren) &&
2661 PreviousNotConst->is(TT_TypeDeclarationParen)) ||
2662 PreviousNotConst->is(TT_AttributeRParen)) {
2671 if (PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto) &&
2672 PreviousNotConst->isNot(TT_StatementAttributeLikeMacro)) {
2677 if (PreviousNotConst->is(TT_PointerOrReference))
2681 if (PreviousNotConst->isTypeName(LangOpts))
2685 if (Style.isJava() && PreviousNotConst->is(tok::r_square))
2689 return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const);
2693 bool lParenStartsCppCast(
const FormatToken &Tok) {
2698 FormatToken *LeftOfParens = Tok.getPreviousNonComment();
2699 if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) &&
2700 LeftOfParens->MatchingParen) {
2701 auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment();
2703 Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast,
2704 tok::kw_reinterpret_cast, tok::kw_static_cast)) {
2714 bool rParenEndsCast(
const FormatToken &Tok) {
2715 assert(Tok.is(tok::r_paren));
2717 if (!Tok.MatchingParen || !Tok.Previous)
2721 if (!IsCpp && !Style.isCSharp() && !Style.isJava())
2724 const auto *LParen = Tok.MatchingParen;
2725 const auto *BeforeRParen = Tok.Previous;
2726 const auto *AfterRParen = Tok.Next;
2729 if (BeforeRParen == LParen || !AfterRParen)
2732 if (LParen->is(TT_OverloadedOperatorLParen))
2735 auto *LeftOfParens = LParen->getPreviousNonComment();
2739 if (LeftOfParens->is(tok::r_paren) &&
2740 LeftOfParens->isNot(TT_CastRParen)) {
2741 if (!LeftOfParens->MatchingParen ||
2742 !LeftOfParens->MatchingParen->Previous) {
2745 LeftOfParens = LeftOfParens->MatchingParen->Previous;
2748 if (LeftOfParens->is(tok::r_square)) {
2750 auto MayBeArrayDelete = [](FormatToken *Tok) -> FormatToken * {
2751 if (Tok->isNot(tok::r_square))
2754 Tok = Tok->getPreviousNonComment();
2755 if (!Tok || Tok->isNot(tok::l_square))
2758 Tok = Tok->getPreviousNonComment();
2759 if (!Tok || Tok->isNot(tok::kw_delete))
2763 if (FormatToken *MaybeDelete = MayBeArrayDelete(LeftOfParens))
2764 LeftOfParens = MaybeDelete;
2770 if (LeftOfParens->Tok.getIdentifierInfo() && LeftOfParens->Previous &&
2771 LeftOfParens->Previous->is(tok::kw_operator)) {
2777 if (LeftOfParens->Tok.getIdentifierInfo() &&
2778 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
2779 tok::kw_delete, tok::kw_throw)) {
2785 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
2786 TT_TemplateCloser, tok::ellipsis)) {
2791 if (AfterRParen->is(tok::question) ||
2792 (AfterRParen->is(tok::ampamp) && !BeforeRParen->isTypeName(LangOpts))) {
2797 if (AfterRParen->is(Keywords.kw_in) && Style.isCSharp())
2802 if (AfterRParen->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
2803 tok::kw_requires, tok::kw_throw, tok::arrow,
2804 Keywords.kw_override, Keywords.kw_final) ||
2805 isCppAttribute(IsCpp, *AfterRParen)) {
2811 if (Style.isJava() && AfterRParen->is(tok::l_paren))
2815 if (AfterRParen->isOneOf(tok::kw_sizeof, tok::kw_alignof) ||
2816 (AfterRParen->Tok.isLiteral() &&
2817 AfterRParen->isNot(tok::string_literal))) {
2821 auto IsNonVariableTemplate = [](
const FormatToken &Tok) {
2822 if (Tok.isNot(TT_TemplateCloser))
2824 const auto *
Less = Tok.MatchingParen;
2827 const auto *BeforeLess =
Less->getPreviousNonComment();
2828 return BeforeLess && BeforeLess->isNot(TT_VariableTemplate);
2832 auto IsQualifiedPointerOrReference = [](
const FormatToken *
T,
2833 const LangOptions &LangOpts) {
2835 assert(!
T->isTypeName(LangOpts) &&
"Should have already been checked");
2839 if (
T->is(TT_AttributeRParen)) {
2841 assert(
T->is(tok::r_paren));
2842 assert(
T->MatchingParen);
2843 assert(
T->MatchingParen->is(tok::l_paren));
2844 assert(
T->MatchingParen->is(TT_AttributeLParen));
2845 if (
const auto *Tok =
T->MatchingParen->Previous;
2846 Tok && Tok->isAttribute()) {
2850 }
else if (
T->is(TT_AttributeSquare)) {
2852 if (
T->MatchingParen &&
T->MatchingParen->Previous) {
2853 T =
T->MatchingParen->Previous;
2856 }
else if (
T->canBePointerOrReferenceQualifier()) {
2862 return T &&
T->is(TT_PointerOrReference);
2865 bool ParensAreType = IsNonVariableTemplate(*BeforeRParen) ||
2866 BeforeRParen->is(TT_TypeDeclarationParen) ||
2867 BeforeRParen->isTypeName(LangOpts) ||
2868 IsQualifiedPointerOrReference(BeforeRParen, LangOpts);
2869 bool ParensCouldEndDecl =
2870 AfterRParen->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
2871 if (ParensAreType && !ParensCouldEndDecl)
2882 for (
const auto *Token = LParen->Next; Token != &Tok; Token = Token->Next)
2883 if (Token->is(TT_BinaryOperator))
2888 if (AfterRParen->isOneOf(tok::identifier, tok::kw_this))
2892 if (AfterRParen->is(tok::l_paren)) {
2893 for (
const auto *Prev = BeforeRParen; Prev->is(tok::identifier);) {
2894 Prev = Prev->Previous;
2895 if (Prev->is(tok::coloncolon))
2896 Prev = Prev->Previous;
2902 if (!AfterRParen->Next)
2905 if (AfterRParen->is(tok::l_brace) &&
2913 const bool NextIsAmpOrStar = AfterRParen->isOneOf(tok::amp, tok::star);
2914 if (!(AfterRParen->isUnaryOperator() || NextIsAmpOrStar) ||
2915 AfterRParen->is(tok::plus) ||
2916 !AfterRParen->Next->isOneOf(tok::identifier, tok::numeric_constant)) {
2920 if (NextIsAmpOrStar &&
2921 (AfterRParen->Next->is(tok::numeric_constant) || Line.InPPDirective)) {
2925 if (Line.InPPDirective && AfterRParen->is(tok::minus))
2928 const auto *Prev = BeforeRParen;
2931 if (Prev->is(tok::r_paren)) {
2932 if (Prev->is(TT_CastRParen))
2934 Prev = Prev->MatchingParen;
2937 Prev = Prev->Previous;
2938 if (!Prev || Prev->isNot(tok::r_paren))
2940 Prev = Prev->MatchingParen;
2941 return Prev && Prev->is(TT_FunctionTypeLParen);
2945 for (Prev = BeforeRParen; Prev != LParen; Prev = Prev->Previous)
2946 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
2953 bool determineUnaryOperatorByUsage(
const FormatToken &Tok) {
2954 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2964 if (PrevToken->isOneOf(
2965 TT_ConditionalExpr, tok::l_paren, tok::comma, tok::colon, tok::semi,
2966 tok::equal, tok::question, tok::l_square, tok::l_brace,
2967 tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,
2968 tok::kw_delete, tok::kw_return, tok::kw_throw)) {
2975 if (PrevToken->is(tok::kw_sizeof))
2979 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
2983 if (PrevToken->is(TT_BinaryOperator))
2991 bool InTemplateArgument) {
2992 if (Style.isJavaScript())
2993 return TT_BinaryOperator;
2996 if (Style.isCSharp() && Tok.is(tok::ampamp))
2997 return TT_BinaryOperator;
2999 if (Style.isVerilog()) {
3004 if (Tok.is(tok::star))
3005 return TT_BinaryOperator;
3006 return determineUnaryOperatorByUsage(Tok) ? TT_UnaryOperator
3007 : TT_BinaryOperator;
3010 const FormatToken *PrevToken = Tok.getPreviousNonComment();
3012 return TT_UnaryOperator;
3013 if (PrevToken->isTypeName(LangOpts))
3014 return TT_PointerOrReference;
3015 if (PrevToken->isPlacementOperator() && Tok.is(tok::ampamp))
3016 return TT_BinaryOperator;
3018 auto *NextToken = Tok.getNextNonComment();
3020 return TT_PointerOrReference;
3021 if (NextToken->is(tok::greater)) {
3022 NextToken->setFinalizedType(TT_TemplateCloser);
3023 return TT_PointerOrReference;
3026 if (InTemplateArgument && NextToken->is(tok::kw_noexcept))
3027 return TT_BinaryOperator;
3029 if (NextToken->isOneOf(tok::arrow, tok::equal, tok::comma, tok::r_paren,
3030 TT_RequiresClause) ||
3032 NextToken->canBePointerOrReferenceQualifier() ||
3033 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) {
3034 return TT_PointerOrReference;
3037 if (PrevToken->is(tok::coloncolon))
3038 return TT_PointerOrReference;
3040 if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
3041 return TT_PointerOrReference;
3043 if (determineUnaryOperatorByUsage(Tok))
3044 return TT_UnaryOperator;
3046 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
3047 return TT_PointerOrReference;
3049 return TT_PointerOrReference;
3050 if (NextToken->isOneOf(tok::comma, tok::semi))
3051 return TT_PointerOrReference;
3063 if (PrevToken->is(tok::r_brace) && Tok.is(tok::star) &&
3064 !PrevToken->MatchingParen) {
3065 return TT_PointerOrReference;
3068 if (PrevToken->endsSequence(tok::r_square, tok::l_square, tok::kw_delete))
3069 return TT_UnaryOperator;
3071 if (PrevToken->Tok.isLiteral() ||
3072 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
3073 tok::kw_false, tok::r_brace)) {
3074 return TT_BinaryOperator;
3077 const FormatToken *NextNonParen = NextToken;
3078 while (NextNonParen && NextNonParen->is(tok::l_paren))
3079 NextNonParen = NextNonParen->getNextNonComment();
3080 if (NextNonParen && (NextNonParen->Tok.isLiteral() ||
3081 NextNonParen->isOneOf(tok::kw_true, tok::kw_false) ||
3082 NextNonParen->isUnaryOperator())) {
3083 return TT_BinaryOperator;
3089 if (InTemplateArgument && NextToken->Tok.isAnyIdentifier())
3090 return TT_BinaryOperator;
3094 if (Tok.is(tok::ampamp) &&
3095 NextToken->isOneOf(tok::l_paren, tok::star, tok::amp)) {
3096 return TT_BinaryOperator;
3103 if (NextToken->Tok.isAnyIdentifier()) {
3104 auto *NextNextToken = NextToken->getNextNonComment();
3105 if (NextNextToken) {
3106 if (NextNextToken->is(tok::arrow))
3107 return TT_BinaryOperator;
3108 if (NextNextToken->isPointerOrReference() &&
3109 !NextToken->isObjCLifetimeQualifier(Style)) {
3110 NextNextToken->setFinalizedType(TT_BinaryOperator);
3111 return TT_BinaryOperator;
3119 return TT_BinaryOperator;
3122 if (!Scopes.empty() && Scopes.back() ==
ST_Class)
3123 return TT_PointerOrReference;
3126 auto IsChainedOperatorAmpOrMember = [](
const FormatToken *token) {
3127 return !token || token->isOneOf(tok::amp, tok::period, tok::arrow,
3128 tok::arrowstar, tok::periodstar);
3133 if (Tok.is(tok::amp) && PrevToken->Tok.isAnyIdentifier() &&
3134 IsChainedOperatorAmpOrMember(PrevToken->getPreviousNonComment()) &&
3135 NextToken && NextToken->Tok.isAnyIdentifier()) {
3136 if (
auto NextNext = NextToken->getNextNonComment();
3138 (IsChainedOperatorAmpOrMember(NextNext) || NextNext->is(tok::semi))) {
3139 return TT_BinaryOperator;
3145 return TT_BinaryOperator;
3148 return TT_PointerOrReference;
3151 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
3152 if (determineUnaryOperatorByUsage(Tok))
3153 return TT_UnaryOperator;
3155 const FormatToken *PrevToken = Tok.getPreviousNonComment();
3157 return TT_UnaryOperator;
3159 if (PrevToken->is(tok::at))
3160 return TT_UnaryOperator;
3163 return TT_BinaryOperator;
3167 TokenType determineIncrementUsage(
const FormatToken &Tok) {
3168 const FormatToken *PrevToken = Tok.getPreviousNonComment();
3169 if (!PrevToken || PrevToken->is(TT_CastRParen))
3170 return TT_UnaryOperator;
3171 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
3172 return TT_TrailingUnaryOperator;
3174 return TT_UnaryOperator;
3177 SmallVector<Context, 8> Contexts;
3179 const FormatStyle &Style;
3180 AnnotatedLine &Line;
3181 FormatToken *CurrentToken;
3184 LangOptions LangOpts;
3185 const AdditionalKeywords &Keywords;
3187 SmallVector<ScopeType> &Scopes;
3195 int TemplateDeclarationDepth;
3203class ExpressionParser {
3205 ExpressionParser(
const FormatStyle &Style,
const AdditionalKeywords &Keywords,
3206 AnnotatedLine &Line)
3207 : Style(Style), Keywords(Keywords), Line(Line), Current(Line.
First) {}
3210 void parse(
int Precedence = 0) {
3213 while (Current && (Current->is(tok::kw_return) ||
3214 (Current->is(tok::colon) &&
3215 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)))) {
3219 if (!Current || Precedence > PrecedenceArrowAndPeriod)
3224 parseConditionalExpr();
3230 if (Precedence == PrecedenceUnaryOperator) {
3231 parseUnaryOperator();
3235 FormatToken *Start = Current;
3236 FormatToken *LatestOperator =
nullptr;
3237 unsigned OperatorIndex = 0;
3239 FormatToken *VerilogFirstOfType =
nullptr;
3248 if (Style.isVerilog() && Precedence ==
prec::Comma) {
3249 VerilogFirstOfType =
3250 verilogGroupDecl(VerilogFirstOfType, LatestOperator);
3254 parse(Precedence + 1);
3256 int CurrentPrecedence = getCurrentPrecedence();
3267 if (Precedence == CurrentPrecedence && Current &&
3268 Current->is(TT_SelectorName)) {
3270 addFakeParenthesis(Start,
prec::Level(Precedence));
3274 if ((Style.isCSharp() || Style.isJavaScript() || Style.isJava()) &&
3278 FormatToken *Prev = Current->getPreviousNonComment();
3279 if (Prev && Prev->is(tok::string_literal) &&
3280 (Prev == Start || Prev->endsSequence(tok::string_literal, tok::plus,
3281 TT_StringInConcatenation))) {
3282 Prev->setType(TT_StringInConcatenation);
3289 (Current->closesScope() &&
3290 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
3291 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
3300 if (Current->opensScope() ||
3301 Current->isOneOf(TT_RequiresClause,
3302 TT_RequiresClauseInARequiresExpression)) {
3305 while (Current && (!Current->closesScope() || Current->opensScope())) {
3312 if (CurrentPrecedence == Precedence) {
3314 LatestOperator->NextOperator = Current;
3315 LatestOperator = Current;
3316 Current->OperatorIndex = OperatorIndex;
3319 next(Precedence > 0);
3324 if (Style.isVerilog() && Precedence ==
prec::Comma && VerilogFirstOfType)
3325 addFakeParenthesis(VerilogFirstOfType,
prec::Comma);
3327 if (LatestOperator && (Current || Precedence > 0)) {
3333 Start->Previous->isOneOf(TT_RequiresClause,
3334 TT_RequiresClauseInARequiresExpression))
3336 auto Ret = Current ? Current : Line.Last;
3337 while (!
Ret->ClosesRequiresClause &&
Ret->Previous)
3343 if (Precedence == PrecedenceArrowAndPeriod) {
3347 addFakeParenthesis(Start,
prec::Level(Precedence), End);
3355 int getCurrentPrecedence() {
3357 const FormatToken *NextNonComment = Current->getNextNonComment();
3358 if (Current->is(TT_ConditionalExpr))
3360 if (NextNonComment && Current->is(TT_SelectorName) &&
3361 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
3362 (Style.isProto() && NextNonComment->is(tok::less)))) {
3365 if (Current->is(TT_JsComputedPropertyName))
3367 if (Current->is(TT_LambdaArrow))
3369 if (Current->is(TT_FatArrow))
3371 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
3372 (Current->is(tok::comment) && NextNonComment &&
3373 NextNonComment->is(TT_SelectorName))) {
3376 if (Current->is(TT_RangeBasedForLoopColon))
3378 if ((Style.isJava() || Style.isJavaScript()) &&
3379 Current->is(Keywords.kw_instanceof)) {
3382 if (Style.isJavaScript() &&
3383 Current->isOneOf(Keywords.kw_in, Keywords.kw_as)) {
3386 if (Current->isOneOf(TT_BinaryOperator, tok::comma))
3387 return Current->getPrecedence();
3388 if (Current->isOneOf(tok::period, tok::arrow) &&
3389 Current->isNot(TT_TrailingReturnArrow)) {
3390 return PrecedenceArrowAndPeriod;
3392 if ((Style.isJava() || Style.isJavaScript()) &&
3393 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
3394 Keywords.kw_throws)) {
3399 if (Style.isVerilog() && Current->is(tok::colon))
3405 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence,
3406 FormatToken *End =
nullptr) {
3411 if (Start->MacroParent)
3414 Start->FakeLParens.push_back(Precedence);
3416 Start->StartsBinaryExpression =
true;
3417 if (!End && Current)
3418 End = Current->getPreviousNonComment();
3422 End->EndsBinaryExpression =
true;
3428 void parseUnaryOperator() {
3429 SmallVector<FormatToken *, 2> Tokens;
3430 while (Current && Current->is(TT_UnaryOperator)) {
3431 Tokens.push_back(Current);
3434 parse(PrecedenceArrowAndPeriod);
3435 for (FormatToken *Token : reverse(Tokens)) {
3441 void parseConditionalExpr() {
3442 while (Current && Current->isTrailingComment())
3444 FormatToken *Start = Current;
3446 if (!Current || Current->isNot(tok::question))
3450 if (!Current || Current->isNot(TT_ConditionalExpr))
3457 void next(
bool SkipPastLeadingComments =
true) {
3459 Current = Current->Next;
3461 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
3462 Current->isTrailingComment()) {
3463 Current = Current->Next;
3469 FormatToken *verilogGroupDecl(FormatToken *FirstOfType,
3470 FormatToken *PreviousComma) {
3474 FormatToken *Start = Current;
3477 while (Start->startsSequence(tok::l_paren, tok::star)) {
3478 if (!(Start = Start->MatchingParen) ||
3479 !(Start = Start->getNextNonComment())) {
3484 FormatToken *Tok = Start;
3486 if (Tok->is(Keywords.kw_assign))
3487 Tok = Tok->getNextNonComment();
3495 FormatToken *
First =
nullptr;
3497 FormatToken *Next = Tok->getNextNonComment();
3499 if (Tok->is(tok::hash)) {
3504 Tok = Tok->getNextNonComment();
3505 }
else if (Tok->is(tok::hashhash)) {
3509 Tok = Tok->getNextNonComment();
3510 }
else if (Keywords.isVerilogQualifier(*Tok) ||
3511 Keywords.isVerilogIdentifier(*Tok)) {
3515 while (Tok && Tok->isOneOf(tok::period, tok::coloncolon) &&
3516 (Tok = Tok->getNextNonComment())) {
3517 if (Keywords.isVerilogIdentifier(*Tok))
3518 Tok = Tok->getNextNonComment();
3522 }
else if (Tok->is(tok::l_paren)) {
3527 Keywords.kw_highz0, Keywords.kw_highz1, Keywords.kw_large,
3528 Keywords.kw_medium, Keywords.kw_pull0, Keywords.kw_pull1,
3529 Keywords.kw_small, Keywords.kw_strong0, Keywords.kw_strong1,
3530 Keywords.kw_supply0, Keywords.kw_supply1, Keywords.kw_weak0,
3531 Keywords.kw_weak1)) {
3532 Tok->setType(TT_VerilogStrength);
3533 Tok = Tok->MatchingParen;
3535 Tok->setType(TT_VerilogStrength);
3536 Tok = Tok->getNextNonComment();
3541 }
else if (Tok->is(Keywords.kw_verilogHash)) {
3543 if (Next->is(tok::l_paren))
3544 Next = Next->MatchingParen;
3546 Tok = Next->getNextNonComment();
3553 FormatToken *Second =
nullptr;
3555 while (Tok && Tok->is(tok::l_square) && (Tok = Tok->MatchingParen))
3556 Tok = Tok->getNextNonComment();
3557 if (Tok && (Tok->is(tok::hash) || Keywords.isVerilogIdentifier(*Tok)))
3562 FormatToken *TypedName =
nullptr;
3566 First->setType(TT_VerilogDimensionedTypeName);
3567 }
else if (
First != Start) {
3575 if (TypedName->is(TT_Unknown))
3576 TypedName->setType(TT_StartOfName);
3578 if (FirstOfType && PreviousComma) {
3579 PreviousComma->setType(TT_VerilogTypeComma);
3580 addFakeParenthesis(FirstOfType,
prec::Comma, PreviousComma->Previous);
3583 FirstOfType = TypedName;
3590 while (Current && Current != FirstOfType) {
3591 if (Current->opensScope()) {
3602 const FormatStyle &Style;
3603 const AdditionalKeywords &Keywords;
3604 const AnnotatedLine &Line;
3605 FormatToken *Current;
3614 assert(
Line->First);
3621 Line->First->OriginalColumn) {
3622 const bool PPDirectiveOrImportStmt =
3625 if (PPDirectiveOrImportStmt)
3631 PPDirectiveOrImportStmt
3633 : NextNonCommentLine->
Level;
3635 NextNonCommentLine =
Line->First->isNot(tok::r_brace) ?
Line :
nullptr;
3644 for (
const auto *Tok =
Line.First; Tok; Tok = Tok->Next)
3653 for (
FormatToken *Tok =
Line.getFirstNonComment(), *Name =
nullptr; Tok;
3654 Tok = Tok->getNextNonComment()) {
3656 if (Tok->is(tok::l_square) && Tok->is(TT_AttributeSquare)) {
3665 if (Tok->is(tok::l_paren) && Tok->is(TT_Unknown) && Tok->MatchingParen) {
3673 if (Tok->isOneOf(tok::kw_friend, tok::kw_inline, tok::kw_virtual,
3674 tok::kw_constexpr, tok::kw_consteval, tok::kw_explicit)) {
3679 if (Tok->is(tok::coloncolon)) {
3686 while (Tok->startsSequence(tok::identifier, tok::coloncolon)) {
3688 Tok = Tok->Next->Next;
3694 if (Tok->is(tok::tilde)) {
3701 if (Tok->isNot(tok::identifier) || Tok->isNot(TT_Unknown))
3712 assert(Tok && Tok->
is(tok::identifier));
3715 if (Prev && Prev->is(tok::tilde))
3718 if (!Prev || !Prev->endsSequence(tok::coloncolon, tok::identifier))
3721 assert(Prev->Previous);
3722 return Prev->Previous->TokenText == Tok->
TokenText;
3726 if (!
Line.InMacroBody)
3727 MacroBodyScopes.clear();
3729 auto &ScopeStack =
Line.InMacroBody ? MacroBodyScopes : Scopes;
3730 AnnotatingParser
Parser(Style,
Line, Keywords, ScopeStack);
3733 if (!
Line.Children.empty()) {
3736 for (
auto &Child :
Line.Children) {
3737 if (InRequiresExpression &&
3738 !Child->First->isOneOf(tok::kw_typename, tok::kw_requires,
3739 TT_CompoundRequirementLBrace)) {
3745 if (!ScopeStack.empty())
3746 ScopeStack.pop_back();
3759 ExpressionParser ExprParser(Style, Keywords,
Line);
3765 if (Tok && ((!ScopeStack.empty() && ScopeStack.back() ==
ST_Class) ||
3767 Tok->setFinalizedType(TT_CtorDtorDeclName);
3768 assert(OpeningParen);
3773 if (
Line.startsWith(TT_ObjCMethodSpecifier))
3775 else if (
Line.startsWith(TT_ObjCDecl))
3777 else if (
Line.startsWith(TT_ObjCProperty))
3781 First->SpacesRequiredBefore = 1;
3782 First->CanBreakBefore =
First->MustBreakBefore;
3791 if (Current.
is(TT_FunctionDeclarationName))
3800 if (Prev->is(tok::coloncolon))
3801 Prev = Prev->Previous;
3808 if (
const auto *PrevPrev =
Previous.getPreviousNonComment();
3809 PrevPrev && PrevPrev->is(TT_ObjCDecl)) {
3813 auto skipOperatorName =
3815 for (; Next; Next = Next->Next) {
3816 if (Next->is(TT_OverloadedOperatorLParen))
3818 if (Next->is(TT_OverloadedOperator))
3820 if (Next->isPlacementOperator() || Next->is(tok::kw_co_await)) {
3823 Next->Next->startsSequence(tok::l_square, tok::r_square)) {
3824 Next = Next->Next->Next;
3828 if (Next->startsSequence(tok::l_square, tok::r_square)) {
3833 if ((Next->isTypeName(LangOpts) || Next->is(tok::identifier)) &&
3834 Next->Next && Next->Next->isPointerOrReference()) {
3839 if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
3840 Next = Next->MatchingParen;
3849 const auto *Next = Current.
Next;
3850 const bool IsCpp = LangOpts.CXXOperatorNames || LangOpts.C11;
3853 if (Current.
is(tok::kw_operator)) {
3854 if (
Previous.Tok.getIdentifierInfo() &&
3855 !
Previous.isOneOf(tok::kw_return, tok::kw_co_return)) {
3860 assert(
Previous.MatchingParen->is(tok::l_paren));
3861 assert(
Previous.MatchingParen->is(TT_TypeDeclarationParen));
3866 Next = skipOperatorName(Next);
3870 while (Next && Next->startsSequence(tok::hashhash, tok::identifier))
3871 Next = Next->Next->Next;
3872 for (; Next; Next = Next->Next) {
3873 if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
3874 Next = Next->MatchingParen;
3875 }
else if (Next->is(tok::coloncolon)) {
3879 if (Next->is(tok::kw_operator)) {
3880 Next = skipOperatorName(Next->Next);
3883 if (Next->isNot(tok::identifier))
3885 }
else if (isCppAttribute(IsCpp, *Next)) {
3886 Next = Next->MatchingParen;
3889 }
else if (Next->is(tok::l_paren)) {
3898 if (!Next || Next->isNot(tok::l_paren) || !Next->MatchingParen)
3900 ClosingParen = Next->MatchingParen;
3901 assert(ClosingParen->
is(tok::r_paren));
3903 if (
Line.Last->is(tok::l_brace))
3905 if (Next->Next == ClosingParen)
3908 if (ClosingParen->
Next && ClosingParen->
Next->
is(TT_PointerOrReference))
3921 if (IsCpp && Next->Next && Next->Next->is(tok::identifier) &&
3922 !
Line.endsWith(tok::semi)) {
3926 for (
const FormatToken *Tok = Next->Next; Tok && Tok != ClosingParen;
3928 if (Tok->is(TT_TypeDeclarationParen))
3930 if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) {
3931 Tok = Tok->MatchingParen;
3934 if (Tok->is(tok::kw_const) || Tok->isTypeName(LangOpts) ||
3935 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
3938 if (Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) || Tok->Tok.isLiteral())
3944bool TokenAnnotator::mustBreakForReturnType(
const AnnotatedLine &
Line)
const {
3945 assert(
Line.MightBeFunctionDecl);
3953 switch (Style.BreakAfterReturnType) {
3963 return Line.mightBeFunctionDefinition();
3973 Line.Computed =
true;
3981 :
Line.FirstStartColumn +
First->ColumnWidth;
3982 bool AlignArrayOfStructures =
3985 if (AlignArrayOfStructures)
3986 calculateArrayInitializerColumnList(
Line);
3988 const auto *FirstNonComment =
Line.getFirstNonComment();
3989 bool SeenName =
false;
3990 bool LineIsFunctionDeclaration =
false;
3994 for (
auto *Tok = FirstNonComment && FirstNonComment->isNot(tok::kw_using)
3995 ? FirstNonComment->Next
3998 if (Tok->is(TT_StartOfName))
4000 if (Tok->Previous->EndsCppAttributeGroup)
4001 AfterLastAttribute = Tok;
4002 if (
const bool IsCtorOrDtor = Tok->is(TT_CtorDtorDeclName);
4007 LineIsFunctionDeclaration =
true;
4011 assert(OpeningParen);
4012 if (OpeningParen->is(TT_Unknown))
4013 OpeningParen->setType(TT_FunctionDeclarationLParen);
4020 (LineIsFunctionDeclaration ||
4021 (FirstNonComment && FirstNonComment->is(TT_CtorDtorDeclName))) &&
4022 Line.endsWith(tok::semi, tok::r_brace)) {
4023 auto *Tok =
Line.Last->Previous;
4024 while (Tok->isNot(tok::r_brace))
4025 Tok = Tok->Previous;
4026 if (
auto *LBrace = Tok->MatchingParen; LBrace && LBrace->is(TT_Unknown)) {
4027 assert(LBrace->is(tok::l_brace));
4030 LBrace->setFinalizedType(TT_FunctionLBrace);
4034 if (IsCpp && SeenName && AfterLastAttribute &&
4037 if (LineIsFunctionDeclaration)
4038 Line.ReturnTypeWrapped =
true;
4042 if (!LineIsFunctionDeclaration) {
4044 for (
const auto *Tok = FirstNonComment; Tok; Tok = Tok->Next) {
4045 if (Tok->isNot(tok::kw_operator))
4049 }
while (Tok && Tok->isNot(TT_OverloadedOperatorLParen));
4050 if (!Tok || !Tok->MatchingParen)
4052 const auto *LeftParen = Tok;
4053 for (Tok = Tok->Next; Tok && Tok != LeftParen->MatchingParen;
4055 if (Tok->isNot(tok::identifier))
4057 auto *Next = Tok->Next;
4058 const bool NextIsBinaryOperator =
4059 Next && Next->isPointerOrReference() && Next->Next &&
4060 Next->Next->is(tok::identifier);
4061 if (!NextIsBinaryOperator)
4063 Next->setType(TT_BinaryOperator);
4067 }
else if (ClosingParen) {
4068 for (
auto *Tok = ClosingParen->
Next; Tok; Tok = Tok->
Next) {
4069 if (Tok->is(TT_CtorInitializerColon))
4071 if (Tok->is(tok::arrow)) {
4072 Tok->setType(TT_TrailingReturnArrow);
4075 if (Tok->isNot(TT_TrailingAnnotation))
4077 const auto *Next = Tok->Next;
4078 if (!Next || Next->isNot(tok::l_paren))
4080 Tok = Next->MatchingParen;
4087 bool InFunctionDecl =
Line.MightBeFunctionDecl;
4088 bool InParameterList =
false;
4089 for (
auto *Current =
First->Next; Current; Current = Current->Next) {
4091 if (Current->is(TT_LineComment)) {
4093 Current->SpacesRequiredBefore =
4094 (Style.Cpp11BracedListStyle && !Style.SpacesInParensOptions.Other)
4097 }
else if (Prev->
is(TT_VerilogMultiLineListLParen)) {
4098 Current->SpacesRequiredBefore = 0;
4100 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
4110 if (!Current->HasUnescapedNewline) {
4113 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
4116 if (
Parameter->Previous->isNot(TT_CtorInitializerComma) &&
4124 }
else if (!Current->Finalized && Current->SpacesRequiredBefore == 0 &&
4125 spaceRequiredBefore(
Line, *Current)) {
4126 Current->SpacesRequiredBefore = 1;
4129 const auto &Children = Prev->
Children;
4130 if (!Children.empty() && Children.back()->Last->is(TT_LineComment)) {
4131 Current->MustBreakBefore =
true;
4133 Current->MustBreakBefore =
4134 Current->MustBreakBefore || mustBreakBefore(
Line, *Current);
4135 if (!Current->MustBreakBefore && InFunctionDecl &&
4136 Current->is(TT_FunctionDeclarationName)) {
4137 Current->MustBreakBefore = mustBreakForReturnType(
Line);
4141 Current->CanBreakBefore =
4142 Current->MustBreakBefore || canBreakBefore(
Line, *Current);
4144 if (Current->is(TT_FunctionDeclarationLParen)) {
4145 InParameterList =
true;
4146 }
else if (Current->is(tok::r_paren)) {
4147 const auto *LParen = Current->MatchingParen;
4148 if (LParen && LParen->is(TT_FunctionDeclarationLParen))
4149 InParameterList =
false;
4150 }
else if (InParameterList &&
4151 Current->endsSequence(TT_AttributeMacro,
4152 TT_PointerOrReference)) {
4153 Current->CanBreakBefore =
false;
4156 unsigned ChildSize = 0;
4162 if (Current->MustBreakBefore || Prev->
Children.size() > 1 ||
4164 Prev->
Children[0]->First->MustBreakBefore) ||
4165 Current->IsMultiline) {
4166 Current->TotalLength = Prev->
TotalLength + Style.ColumnLimit;
4168 Current->TotalLength = Prev->
TotalLength + Current->ColumnWidth +
4169 ChildSize + Current->SpacesRequiredBefore;
4172 if (Current->is(TT_ControlStatementLBrace)) {
4173 if (Style.ColumnLimit > 0 &&
4174 Style.BraceWrapping.AfterControlStatement ==
4176 Line.Level * Style.IndentWidth +
Line.Last->TotalLength >
4177 Style.ColumnLimit) {
4178 Current->CanBreakBefore =
true;
4179 Current->MustBreakBefore =
true;
4181 }
else if (Current->is(TT_CtorInitializerColon)) {
4182 InFunctionDecl =
false;
4194 Current->SplitPenalty = splitPenalty(
Line, *Current, InFunctionDecl);
4196 Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {
4197 if (Current->ParameterIndex == 1)
4198 Current->SplitPenalty += 5 * Current->BindingStrength;
4200 Current->SplitPenalty += 20 * Current->BindingStrength;
4204 calculateUnbreakableTailLengths(
Line);
4205 unsigned IndentLevel =
Line.Level;
4206 for (
auto *Current =
First; Current; Current = Current->Next) {
4208 Current->Role->precomputeFormattingInfos(Current);
4209 if (Current->MatchingParen &&
4210 Current->MatchingParen->opensBlockOrBlockTypeList(Style) &&
4214 Current->IndentLevel = IndentLevel;
4215 if (Current->opensBlockOrBlockTypeList(Style))
4219 LLVM_DEBUG({ printDebugInfo(
Line); });
4222void TokenAnnotator::calculateUnbreakableTailLengths(
4224 unsigned UnbreakableTailLength = 0;
4227 Current->UnbreakableTailLength = UnbreakableTailLength;
4228 if (Current->CanBreakBefore ||
4229 Current->isOneOf(tok::comment, tok::string_literal)) {
4230 UnbreakableTailLength = 0;
4232 UnbreakableTailLength +=
4233 Current->ColumnWidth + Current->SpacesRequiredBefore;
4235 Current = Current->Previous;
4239void TokenAnnotator::calculateArrayInitializerColumnList(
4240 AnnotatedLine &
Line)
const {
4243 auto *CurrentToken =
Line.First;
4244 CurrentToken->ArrayInitializerLineStart =
true;
4246 while (CurrentToken && CurrentToken !=
Line.Last) {
4247 if (CurrentToken->is(tok::l_brace)) {
4248 CurrentToken->IsArrayInitializer =
true;
4249 if (CurrentToken->Next)
4250 CurrentToken->Next->MustBreakBefore =
true;
4252 calculateInitializerColumnList(
Line, CurrentToken->Next, Depth + 1);
4254 CurrentToken = CurrentToken->Next;
4259FormatToken *TokenAnnotator::calculateInitializerColumnList(
4260 AnnotatedLine &
Line, FormatToken *CurrentToken,
unsigned Depth)
const {
4261 while (CurrentToken && CurrentToken !=
Line.Last) {
4262 if (CurrentToken->is(tok::l_brace))
4264 else if (CurrentToken->is(tok::r_brace))
4266 if (Depth == 2 && CurrentToken->isOneOf(tok::l_brace, tok::comma)) {
4267 CurrentToken = CurrentToken->Next;
4270 CurrentToken->StartsColumn =
true;
4271 CurrentToken = CurrentToken->Previous;
4273 CurrentToken = CurrentToken->Next;
4275 return CurrentToken;
4278unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &
Line,
4279 const FormatToken &Tok,
4280 bool InFunctionDecl)
const {
4281 const FormatToken &
Left = *Tok.Previous;
4282 const FormatToken &
Right = Tok;
4284 if (
Left.is(tok::semi))
4288 if (Style.isJava()) {
4289 if (
Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
4291 if (
Right.is(Keywords.kw_implements))
4293 if (
Left.is(tok::comma) &&
Left.NestingLevel == 0)
4295 }
else if (Style.isJavaScript()) {
4296 if (
Right.is(Keywords.kw_function) &&
Left.isNot(tok::comma))
4298 if (
Left.is(TT_JsTypeColon))
4300 if ((
Left.is(TT_TemplateString) &&
Left.TokenText.ends_with(
"${")) ||
4301 (
Right.is(TT_TemplateString) &&
Right.TokenText.starts_with(
"}"))) {
4305 if (
Left.opensScope() &&
Right.closesScope())
4308 if (
Right.is(tok::l_square))
4310 if (
Right.is(tok::period))
4314 if (
Right.is(tok::identifier) &&
Right.Next &&
Right.Next->is(TT_DictLiteral))
4316 if (
Right.is(tok::l_square)) {
4317 if (
Left.is(tok::r_square))
4320 if (
Right.is(TT_LambdaLSquare) &&
Left.is(tok::equal))
4322 if (!
Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
4323 TT_ArrayInitializerLSquare,
4324 TT_DesignatedInitializerLSquare, TT_AttributeSquare)) {
4329 if (
Left.is(tok::coloncolon))
4330 return Style.PenaltyBreakScopeResolution;
4331 if (
Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
4332 tok::kw_operator)) {
4333 if (
Line.startsWith(tok::kw_for) &&
Right.PartOfMultiVariableDeclStmt)
4335 if (
Left.is(TT_StartOfName))
4337 if (InFunctionDecl &&
Right.NestingLevel == 0)
4338 return Style.PenaltyReturnTypeOnItsOwnLine;
4341 if (
Right.is(TT_PointerOrReference))
4343 if (
Right.is(TT_LambdaArrow))
4345 if (
Left.is(tok::equal) &&
Right.is(tok::l_brace))
4347 if (
Left.is(TT_CastRParen))
4349 if (
Left.isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union))
4351 if (
Left.is(tok::comment))
4354 if (
Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
4355 TT_CtorInitializerColon)) {
4359 if (
Right.isMemberAccess()) {
4379 const auto *NextOperator =
Right.NextOperator;
4380 const auto Penalty = Style.PenaltyBreakBeforeMemberAccess;
4381 return NextOperator && NextOperator->Previous->closesScope()
4382 ? std::min(Penalty, 35u)
4386 if (
Right.is(TT_TrailingAnnotation) &&
4387 (!
Right.Next ||
Right.Next->isNot(tok::l_paren))) {
4390 if (
Line.startsWith(TT_ObjCMethodSpecifier))
4397 bool is_short_annotation =
Right.TokenText.size() < 10;
4398 return (
Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
4402 if (
Line.startsWith(tok::kw_for) &&
Left.is(tok::equal))
4407 if (
Right.is(TT_SelectorName))
4409 if (
Left.is(tok::colon) &&
Left.is(TT_ObjCMethodExpr))
4410 return Line.MightBeFunctionDecl ? 50 : 500;
4416 Left.Previous->isOneOf(tok::identifier, tok::greater)) {
4420 if (
Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0)
4421 return Style.PenaltyBreakOpenParenthesis;
4422 if (
Left.is(tok::l_paren) && InFunctionDecl &&
4426 if (
Left.is(tok::l_paren) &&
Left.Previous &&
4427 (
Left.Previous->isOneOf(tok::kw_for, tok::kw__Generic) ||
4428 Left.Previous->isIf())) {
4431 if (
Left.is(tok::equal) && InFunctionDecl)
4433 if (
Right.is(tok::r_brace))
4435 if (
Left.is(TT_TemplateOpener))
4437 if (
Left.opensScope()) {
4442 (
Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) {
4445 if (
Left.is(tok::l_brace) && !Style.Cpp11BracedListStyle)
4447 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
4450 if (
Left.is(TT_JavaAnnotation))
4453 if (
Left.is(TT_UnaryOperator))
4455 if (
Left.isOneOf(tok::plus, tok::comma) &&
Left.Previous &&
4456 Left.Previous->isLabelString() &&
4457 (
Left.NextOperator ||
Left.OperatorIndex != 0)) {
4460 if (
Right.is(tok::plus) &&
Left.isLabelString() &&
4461 (
Right.NextOperator ||
Right.OperatorIndex != 0)) {
4464 if (
Left.is(tok::comma))
4466 if (
Right.is(tok::lessless) &&
Left.isLabelString() &&
4467 (
Right.NextOperator ||
Right.OperatorIndex != 1)) {
4470 if (
Right.is(tok::lessless)) {
4472 if (
Left.isNot(tok::r_paren) ||
Right.OperatorIndex > 0) {
4478 if (
Left.ClosesTemplateDeclaration)
4479 return Style.PenaltyBreakTemplateDeclaration;
4480 if (
Left.ClosesRequiresClause)
4482 if (
Left.is(TT_ConditionalExpr))
4488 return Style.PenaltyBreakAssignment;
4495bool TokenAnnotator::spaceRequiredBeforeParens(
const FormatToken &Right)
const {
4498 if (
Right.is(TT_OverloadedOperatorLParen) &&
4499 Style.SpaceBeforeParensOptions.AfterOverloadedOperator) {
4502 if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
4503 Right.ParameterCount > 0) {
4509bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &
Line,
4510 const FormatToken &Left,
4511 const FormatToken &Right)
const {
4512 if (
Left.is(tok::kw_return) &&
4513 !
Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
4516 if (
Left.is(tok::kw_throw) &&
Right.is(tok::l_paren) &&
Right.MatchingParen &&
4517 Right.MatchingParen->is(TT_CastRParen)) {
4520 if (
Left.is(Keywords.kw_assert) && Style.isJava())
4523 Left.is(tok::objc_property)) {
4526 if (
Right.is(tok::hashhash))
4527 return Left.is(tok::hash);
4528 if (
Left.isOneOf(tok::hashhash, tok::hash))
4529 return Right.is(tok::hash);
4531 if (
Left.is(tok::l_paren) &&
Right.is(tok::r_paren))
4532 return Style.SpacesInParensOptions.InEmptyParentheses;
4533 if (Style.SpacesInParensOptions.ExceptDoubleParentheses &&
4534 Left.is(tok::r_paren) &&
Right.is(tok::r_paren)) {
4535 auto *InnerLParen =
Left.MatchingParen;
4536 if (InnerLParen && InnerLParen->Previous ==
Right.MatchingParen) {
4537 InnerLParen->SpacesRequiredBefore = 0;
4541 const FormatToken *LeftParen =
nullptr;
4542 if (
Left.is(tok::l_paren))
4544 else if (
Right.is(tok::r_paren) &&
Right.MatchingParen)
4545 LeftParen =
Right.MatchingParen;
4546 if (LeftParen && (LeftParen->is(TT_ConditionLParen) ||
4547 (LeftParen->Previous &&
4548 isKeywordWithCondition(*LeftParen->Previous)))) {
4549 return Style.SpacesInParensOptions.InConditionalStatements;
4554 if (
Left.is(tok::kw_auto) &&
Right.isOneOf(TT_LambdaLBrace, TT_FunctionLBrace,
4556 TT_FunctionTypeLParen)) {
4561 if (
Left.is(tok::kw_auto) &&
Right.isOneOf(tok::l_paren, tok::l_brace))
4564 const auto *BeforeLeft =
Left.Previous;
4567 if (
Right.is(tok::l_paren) &&
Left.is(tok::kw_co_await) && BeforeLeft &&
4568 BeforeLeft->is(tok::kw_operator)) {
4572 if (
Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&
4573 !
Right.isOneOf(tok::semi, tok::r_paren)) {
4577 if (
Left.is(tok::l_paren) ||
Right.is(tok::r_paren)) {
4578 return (
Right.is(TT_CastRParen) ||
4579 (
Left.MatchingParen &&
Left.MatchingParen->is(TT_CastRParen)))
4580 ? Style.SpacesInParensOptions.InCStyleCasts
4581 : Style.SpacesInParensOptions.Other;
4583 if (
Right.isOneOf(tok::semi, tok::comma))
4586 bool IsLightweightGeneric =
Right.MatchingParen &&
4587 Right.MatchingParen->Next &&
4588 Right.MatchingParen->Next->is(tok::colon);
4589 return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
4591 if (
Right.is(tok::less) &&
Left.is(tok::kw_template))
4592 return Style.SpaceAfterTemplateKeyword;
4593 if (
Left.isOneOf(tok::exclaim, tok::tilde))
4595 if (
Left.is(tok::at) &&
4596 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
4597 tok::numeric_constant, tok::l_paren, tok::l_brace,
4598 tok::kw_true, tok::kw_false)) {
4601 if (
Left.is(tok::colon))
4602 return Left.isNot(TT_ObjCMethodExpr);
4603 if (
Left.is(tok::coloncolon))
4605 if (
Left.is(tok::less) ||
Right.isOneOf(tok::greater, tok::less)) {
4606 if (Style.isTextProto() ||
4608 (
Left.is(TT_DictLiteral) ||
Right.is(TT_DictLiteral)))) {
4610 if (
Left.is(tok::less) &&
Right.is(tok::greater))
4612 return !Style.Cpp11BracedListStyle;
4615 if (
Right.isNot(TT_OverloadedOperatorLParen))
4618 if (
Right.is(tok::ellipsis)) {
4619 return Left.Tok.isLiteral() || (
Left.is(tok::identifier) && BeforeLeft &&
4620 BeforeLeft->is(tok::kw_case));
4622 if (
Left.is(tok::l_square) &&
Right.is(tok::amp))
4623 return Style.SpacesInSquareBrackets;
4624 if (
Right.is(TT_PointerOrReference)) {
4625 if (
Left.is(tok::r_paren) &&
Line.MightBeFunctionDecl) {
4626 if (!
Left.MatchingParen)
4628 FormatToken *TokenBeforeMatchingParen =
4629 Left.MatchingParen->getPreviousNonComment();
4630 if (!TokenBeforeMatchingParen ||
Left.isNot(TT_TypeDeclarationParen))
4638 (
Left.is(TT_AttributeRParen) ||
4639 Left.canBePointerOrReferenceQualifier())) {
4642 if (
Left.Tok.isLiteral())
4645 if (
Left.isTypeOrIdentifier(LangOpts) &&
Right.Next &&
Right.Next->Next &&
4646 Right.Next->Next->is(TT_RangeBasedForLoopColon)) {
4647 return getTokenPointerOrReferenceAlignment(Right) !=
4650 return !
Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
4651 (getTokenPointerOrReferenceAlignment(Right) !=
4653 (
Line.IsMultiVariableDeclStmt &&
4654 (
Left.NestingLevel == 0 ||
4655 (
Left.NestingLevel == 1 && startsWithInitStatement(
Line)))));
4657 if (
Right.is(TT_FunctionTypeLParen) &&
Left.isNot(tok::l_paren) &&
4658 (
Left.isNot(TT_PointerOrReference) ||
4660 !
Line.IsMultiVariableDeclStmt))) {
4663 if (
Left.is(TT_PointerOrReference)) {
4668 Right.canBePointerOrReferenceQualifier()) {
4672 if (
Right.Tok.isLiteral())
4675 if (
Right.is(TT_BlockComment))
4679 if (
Right.isOneOf(Keywords.kw_override, Keywords.kw_final, tok::kw_noexcept,
4680 TT_RequiresClause) &&
4681 Right.isNot(TT_StartOfName)) {
4688 if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(LangOpts) &&
Right.Next &&
4689 Right.Next->is(TT_RangeBasedForLoopColon)) {
4690 return getTokenPointerOrReferenceAlignment(Left) !=
4693 if (
Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
4705 if (
Line.IsMultiVariableDeclStmt &&
4706 (
Left.NestingLevel ==
Line.First->NestingLevel ||
4707 ((
Left.NestingLevel ==
Line.First->NestingLevel + 1) &&
4708 startsWithInitStatement(
Line)))) {
4713 if (BeforeLeft->is(tok::coloncolon)) {
4714 if (
Left.isNot(tok::star))
4717 if (!
Right.startsSequence(tok::identifier, tok::r_paren))
4720 const auto *LParen =
Right.Next->MatchingParen;
4721 return !LParen || LParen->isNot(TT_FunctionTypeLParen);
4723 return !BeforeLeft->isOneOf(tok::l_paren, tok::l_square);
4726 if (
Left.is(tok::ellipsis) && BeforeLeft &&
4727 BeforeLeft->isPointerOrReference()) {
4731 if (
Right.is(tok::star) &&
Left.is(tok::l_paren))
4733 if (
Left.is(tok::star) &&
Right.isPointerOrReference())
4735 if (
Right.isPointerOrReference()) {
4746 if (
Previous->is(tok::coloncolon)) {
4765 if (
Previous->endsSequence(tok::kw_operator))
4767 if (
Previous->isOneOf(tok::kw_const, tok::kw_volatile)) {
4769 (Style.SpaceAroundPointerQualifiers ==
4775 if (Style.isCSharp() &&
Left.is(Keywords.kw_is) &&
Right.is(tok::l_square))
4777 const auto SpaceRequiredForArrayInitializerLSquare =
4778 [](
const FormatToken &LSquareTok,
const FormatStyle &Style) {
4779 return Style.SpacesInContainerLiterals ||
4780 (Style.isProto() && !Style.Cpp11BracedListStyle &&
4781 LSquareTok.endsSequence(tok::l_square, tok::colon,
4784 if (
Left.is(tok::l_square)) {
4785 return (
Left.is(TT_ArrayInitializerLSquare) &&
Right.isNot(tok::r_square) &&
4786 SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||
4787 (
Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
4788 TT_LambdaLSquare) &&
4789 Style.SpacesInSquareBrackets &&
Right.isNot(tok::r_square));
4791 if (
Right.is(tok::r_square)) {
4792 return Right.MatchingParen &&
4793 ((
Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&
4794 SpaceRequiredForArrayInitializerLSquare(*
Right.MatchingParen,
4796 (Style.SpacesInSquareBrackets &&
4797 Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
4798 TT_StructuredBindingLSquare,
4799 TT_LambdaLSquare)));
4801 if (
Right.is(tok::l_square) &&
4802 !
Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
4803 TT_DesignatedInitializerLSquare,
4804 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
4805 !
Left.isOneOf(tok::numeric_constant, TT_DictLiteral) &&
4806 !(
Left.isNot(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
4807 Right.is(TT_ArraySubscriptLSquare))) {
4811 (
Right.is(tok::r_brace) &&
Right.MatchingParen &&
4813 return !Style.Cpp11BracedListStyle || Style.SpacesInParensOptions.Other;
4815 if (
Left.is(TT_BlockComment)) {
4817 return Style.isJavaScript() || !
Left.TokenText.ends_with(
"=*/");
4822 if (
Left.is(TT_TemplateCloser) &&
Right.is(TT_AttributeSquare))
4825 if (
Right.is(tok::l_paren)) {
4826 if (
Left.is(TT_TemplateCloser) &&
Right.isNot(TT_FunctionTypeLParen))
4827 return spaceRequiredBeforeParens(Right);
4828 if (
Left.isOneOf(TT_RequiresClause,
4829 TT_RequiresClauseInARequiresExpression)) {
4830 return Style.SpaceBeforeParensOptions.AfterRequiresInClause ||
4831 spaceRequiredBeforeParens(Right);
4833 if (
Left.is(TT_RequiresExpression)) {
4834 return Style.SpaceBeforeParensOptions.AfterRequiresInExpression ||
4835 spaceRequiredBeforeParens(Right);
4837 if (
Left.is(TT_AttributeRParen) ||
4838 (
Left.is(tok::r_square) &&
Left.is(TT_AttributeSquare))) {
4841 if (
Left.is(TT_ForEachMacro)) {
4842 return Style.SpaceBeforeParensOptions.AfterForeachMacros ||
4843 spaceRequiredBeforeParens(Right);
4845 if (
Left.is(TT_IfMacro)) {
4846 return Style.SpaceBeforeParensOptions.AfterIfMacros ||
4847 spaceRequiredBeforeParens(Right);
4850 Left.isPlacementOperator() &&
4851 Right.isNot(TT_OverloadedOperatorLParen) &&
4852 !(
Line.MightBeFunctionDecl &&
Left.is(TT_FunctionDeclarationName))) {
4853 const auto *RParen =
Right.MatchingParen;
4854 return Style.SpaceBeforeParensOptions.AfterPlacementOperator ||
4855 (RParen && RParen->is(TT_CastRParen));
4859 if (
Left.is(tok::semi))
4861 if (
Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch,
4862 tok::kw_case, TT_ForEachMacro, TT_ObjCForIn) ||
4864 Right.is(TT_ConditionLParen)) {
4865 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4866 spaceRequiredBeforeParens(Right);
4871 if (
Right.is(TT_OverloadedOperatorLParen))
4872 return spaceRequiredBeforeParens(Right);
4874 if (
Line.MightBeFunctionDecl &&
Right.is(TT_FunctionDeclarationLParen)) {
4875 if (spaceRequiredBeforeParens(Right))
4877 const auto &Options = Style.SpaceBeforeParensOptions;
4878 return Line.mightBeFunctionDefinition()
4879 ? Options.AfterFunctionDefinitionName
4880 : Options.AfterFunctionDeclarationName;
4884 Left.MatchingParen &&
Left.MatchingParen->is(TT_LambdaLSquare)) {
4885 return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
4886 spaceRequiredBeforeParens(Right);
4888 if (!BeforeLeft || !BeforeLeft->isOneOf(tok::period, tok::arrow)) {
4889 if (
Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
4890 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4891 spaceRequiredBeforeParens(Right);
4893 if (
Left.isPlacementOperator() ||
4894 (
Left.is(tok::r_square) &&
Left.MatchingParen &&
4895 Left.MatchingParen->Previous &&
4896 Left.MatchingParen->Previous->is(tok::kw_delete))) {
4898 spaceRequiredBeforeParens(Right);
4903 (
Left.Tok.getIdentifierInfo() ||
Left.is(tok::r_paren))) {
4904 return spaceRequiredBeforeParens(Right);
4908 if (
Left.is(tok::at) &&
Right.isNot(tok::objc_not_keyword))
4910 if (
Right.is(TT_UnaryOperator)) {
4911 return !
Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
4912 (
Left.isNot(tok::colon) ||
Left.isNot(TT_ObjCMethodExpr));
4918 if (!Style.isVerilog() &&
4919 (
Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
4921 Left.isTypeName(LangOpts)) &&
4922 Right.is(tok::l_brace) &&
Right.getNextNonComment() &&
4926 if (
Left.is(tok::period) ||
Right.is(tok::period))
4930 if (
Right.is(tok::hash) &&
Left.is(tok::identifier) &&
4931 (
Left.TokenText ==
"L" ||
Left.TokenText ==
"u" ||
4932 Left.TokenText ==
"U" ||
Left.TokenText ==
"u8" ||
4933 Left.TokenText ==
"LR" ||
Left.TokenText ==
"uR" ||
4934 Left.TokenText ==
"UR" ||
Left.TokenText ==
"u8R")) {
4937 if (
Left.is(TT_TemplateCloser) &&
Left.MatchingParen &&
4938 Left.MatchingParen->Previous &&
4939 Left.MatchingParen->Previous->isOneOf(tok::period, tok::coloncolon)) {
4945 if (
Left.is(TT_TemplateCloser) &&
Right.is(tok::l_square))
4947 if (
Left.is(tok::l_brace) &&
Left.endsSequence(TT_DictLiteral, tok::at)) {
4951 if (
Right.is(tok::r_brace) &&
Right.MatchingParen &&
4952 Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at)) {
4956 if (
Right.is(TT_TrailingAnnotation) &&
Right.isOneOf(tok::amp, tok::ampamp) &&
4957 Left.isOneOf(tok::kw_const, tok::kw_volatile) &&
4958 (!
Right.Next ||
Right.Next->is(tok::semi))) {
4968bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &
Line,
4969 const FormatToken &Right)
const {
4970 const FormatToken &
Left = *
Right.Previous;
4975 return Right.hasWhitespaceBefore();
4977 const bool IsVerilog = Style.isVerilog();
4978 assert(!IsVerilog || !IsCpp);
4981 if (Keywords.isWordLike(Right, IsVerilog) &&
4982 Keywords.isWordLike(Left, IsVerilog)) {
4988 if (
Left.is(tok::star) &&
Right.is(tok::comment))
4991 if (
Left.is(tok::l_brace) &&
Right.is(tok::r_brace) &&
4992 Left.Children.empty()) {
4995 if (Style.Cpp11BracedListStyle) {
4997 Style.SpacesInParensOptions.InEmptyParentheses;
5002 const auto *BeforeLeft =
Left.Previous;
5005 if (
Left.is(TT_OverloadedOperator) &&
5006 Right.isOneOf(TT_TemplateOpener, TT_TemplateCloser)) {
5010 if (
Right.is(tok::period) &&
Left.is(tok::numeric_constant))
5014 if (
Left.is(Keywords.kw_import) &&
Right.isOneOf(tok::less, tok::ellipsis))
5017 if (
Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&
5018 Right.is(TT_ModulePartitionColon)) {
5022 if (
Right.is(TT_AfterPPDirective))
5026 if (
Left.is(tok::identifier) &&
Right.is(TT_ModulePartitionColon))
5029 if (
Left.is(TT_ModulePartitionColon) &&
5030 Right.isOneOf(tok::identifier, tok::kw_private)) {
5033 if (
Left.is(tok::ellipsis) &&
Right.is(tok::identifier) &&
5034 Line.First->is(Keywords.kw_import)) {
5038 if (
Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&
5039 Right.is(tok::coloncolon)) {
5043 if (
Left.is(tok::kw_operator))
5044 return Right.is(tok::coloncolon) || Style.SpaceAfterOperatorKeyword;
5046 !
Left.opensScope() && Style.SpaceBeforeCpp11BracedList) {
5049 if (
Left.is(tok::less) &&
Left.is(TT_OverloadedOperator) &&
5050 Right.is(TT_TemplateOpener)) {
5054 if (
Left.is(tok::identifier) &&
Right.is(tok::numeric_constant))
5055 return Right.TokenText[0] !=
'.';
5057 if (
Left.Tok.getIdentifierInfo() &&
Right.Tok.isLiteral())
5059 }
else if (Style.isProto()) {
5060 if (
Right.is(tok::period) && !(BeforeLeft && BeforeLeft->is(tok::period)) &&
5061 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
5062 Keywords.kw_repeated, Keywords.kw_extend)) {
5065 if (
Right.is(tok::l_paren) &&
5066 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) {
5069 if (
Right.isOneOf(tok::l_brace, tok::less) &&
Left.is(TT_SelectorName))
5072 if (
Left.is(tok::slash) ||
Right.is(tok::slash))
5074 if (
Left.MatchingParen &&
5075 Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
5076 Right.isOneOf(tok::l_brace, tok::less)) {
5077 return !Style.Cpp11BracedListStyle;
5080 if (
Left.is(tok::percent))
5084 if (
Left.is(tok::numeric_constant) &&
Right.is(tok::percent))
5085 return Right.hasWhitespaceBefore();
5086 }
else if (Style.isJson()) {
5087 if (
Right.is(tok::colon) &&
Left.is(tok::string_literal))
5088 return Style.SpaceBeforeJsonColon;
5089 }
else if (Style.isCSharp()) {
5095 if (
Left.is(tok::kw_this) &&
Right.is(tok::l_square))
5099 if (
Left.is(tok::kw_new) &&
Right.is(tok::l_paren))
5103 if (
Right.is(tok::l_brace))
5107 if (
Left.is(tok::l_brace) &&
Right.isNot(tok::r_brace))
5110 if (
Left.isNot(tok::l_brace) &&
Right.is(tok::r_brace))
5114 if (
Left.is(TT_FatArrow) ||
Right.is(TT_FatArrow))
5118 if (
Left.is(TT_AttributeColon) ||
Right.is(TT_AttributeColon))
5122 if (
Left.is(TT_TemplateCloser) &&
Right.is(TT_StartOfName))
5126 if (
Left.is(tok::l_square) ||
Right.is(tok::r_square))
5127 return Style.SpacesInSquareBrackets;
5130 if (
Right.is(TT_CSharpNullable))
5134 if (
Right.is(TT_NonNullAssertion))
5138 if (
Left.is(tok::comma) &&
Right.is(tok::comma))
5142 if (
Left.is(Keywords.kw_var) &&
Right.is(tok::l_paren))
5146 if (
Right.is(tok::l_paren)) {
5147 if (
Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when,
5148 Keywords.kw_lock)) {
5149 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
5150 spaceRequiredBeforeParens(Right);
5156 if ((
Left.isAccessSpecifierKeyword() ||
5157 Left.isOneOf(tok::kw_virtual, tok::kw_extern, tok::kw_static,
5158 Keywords.kw_internal, Keywords.kw_abstract,
5159 Keywords.kw_sealed, Keywords.kw_override,
5160 Keywords.kw_async, Keywords.kw_unsafe)) &&
5161 Right.is(tok::l_paren)) {
5164 }
else if (Style.isJavaScript()) {
5165 if (
Left.is(TT_FatArrow))
5168 if (
Right.is(tok::l_paren) &&
Left.is(Keywords.kw_await) && BeforeLeft &&
5169 BeforeLeft->is(tok::kw_for)) {
5172 if (
Left.is(Keywords.kw_async) &&
Right.is(tok::l_paren) &&
5173 Right.MatchingParen) {
5174 const FormatToken *Next =
Right.MatchingParen->getNextNonComment();
5177 if (Next && Next->is(TT_FatArrow))
5180 if ((
Left.is(TT_TemplateString) &&
Left.TokenText.ends_with(
"${")) ||
5181 (
Right.is(TT_TemplateString) &&
Right.TokenText.starts_with(
"}"))) {
5186 if (Keywords.isJavaScriptIdentifier(Left,
5188 Right.is(TT_TemplateString)) {
5191 if (
Right.is(tok::star) &&
5192 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) {
5195 if (
Right.isOneOf(tok::l_brace, tok::l_square) &&
5196 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,
5197 Keywords.kw_extends, Keywords.kw_implements)) {
5200 if (
Right.is(tok::l_paren)) {
5202 if (
Line.MustBeDeclaration &&
Left.Tok.getIdentifierInfo())
5206 if (BeforeLeft && BeforeLeft->is(tok::period) &&
5207 Left.Tok.getIdentifierInfo()) {
5211 if (
Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
5217 if (
Left.endsSequence(tok::kw_const, Keywords.kw_as))
5219 if ((
Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
5224 (
Left.is(Keywords.kw_of) && BeforeLeft &&
5225 BeforeLeft->isOneOf(tok::identifier, tok::r_square, tok::r_brace))) &&
5226 (!BeforeLeft || BeforeLeft->isNot(tok::period))) {
5229 if (
Left.isOneOf(tok::kw_for, Keywords.kw_as) && BeforeLeft &&
5230 BeforeLeft->is(tok::period) &&
Right.is(tok::l_paren)) {
5233 if (
Left.is(Keywords.kw_as) &&
5234 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) {
5237 if (
Left.is(tok::kw_default) && BeforeLeft &&
5238 BeforeLeft->is(tok::kw_export)) {
5241 if (
Left.is(Keywords.kw_is) &&
Right.is(tok::l_brace))
5243 if (
Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
5245 if (
Left.is(TT_JsTypeOperator) ||
Right.is(TT_JsTypeOperator))
5247 if ((
Left.is(tok::l_brace) ||
Right.is(tok::r_brace)) &&
5248 Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) {
5251 if (
Left.is(tok::ellipsis))
5253 if (
Left.is(TT_TemplateCloser) &&
5254 !
Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
5255 Keywords.kw_implements, Keywords.kw_extends)) {
5261 if (
Right.is(TT_NonNullAssertion))
5263 if (
Left.is(TT_NonNullAssertion) &&
5264 Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) {
5267 }
else if (Style.isJava()) {
5268 if (
Left.is(TT_CaseLabelArrow) ||
Right.is(TT_CaseLabelArrow))
5270 if (
Left.is(tok::r_square) &&
Right.is(tok::l_brace))
5273 if (
Left.is(tok::l_square) ||
Right.is(tok::r_square))
5274 return Style.SpacesInSquareBrackets;
5276 if (
Left.is(Keywords.kw_synchronized) &&
Right.is(tok::l_paren)) {
5277 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
5278 spaceRequiredBeforeParens(Right);
5280 if ((
Left.isAccessSpecifierKeyword() ||
5281 Left.isOneOf(tok::kw_static, Keywords.kw_final, Keywords.kw_abstract,
5282 Keywords.kw_native)) &&
5283 Right.is(TT_TemplateOpener)) {
5286 }
else if (IsVerilog) {
5288 if (
Left.is(tok::identifier) &&
Left.TokenText[0] ==
'\\')
5292 if ((
Left.is(TT_VerilogTableItem) &&
5293 !
Right.isOneOf(tok::r_paren, tok::semi)) ||
5294 (
Right.is(TT_VerilogTableItem) &&
Left.isNot(tok::l_paren))) {
5295 const FormatToken *Next =
Right.getNextNonComment();
5296 return !(Next && Next->is(tok::r_paren));
5299 if (
Left.isNot(TT_BinaryOperator) &&
5300 Left.isOneOf(Keywords.kw_verilogHash, Keywords.kw_verilogHashHash)) {
5304 if (
Right.isNot(tok::semi) &&
5305 (
Left.endsSequence(tok::numeric_constant, Keywords.kw_verilogHash) ||
5306 Left.endsSequence(tok::numeric_constant,
5307 Keywords.kw_verilogHashHash) ||
5308 (
Left.is(tok::r_paren) &&
Left.MatchingParen &&
5309 Left.MatchingParen->endsSequence(tok::l_paren, tok::at)))) {
5314 if (
Left.is(Keywords.kw_apostrophe) ||
5315 (
Left.is(TT_VerilogNumberBase) &&
Right.is(tok::numeric_constant))) {
5319 if (
Left.is(tok::arrow) ||
Right.is(tok::arrow))
5324 if (
Left.is(tok::at) &&
Right.isOneOf(tok::l_paren, tok::star, tok::at))
5327 if (
Right.is(tok::l_square) &&
5328 Left.isOneOf(TT_VerilogDimensionedTypeName, Keywords.kw_function)) {
5332 if (
Right.isOneOf(tok::period, Keywords.kw_apostrophe) &&
5333 Keywords.isVerilogIdentifier(Left) &&
Left.getPreviousNonComment() &&
5334 Left.getPreviousNonComment()->is(Keywords.kw_tagged)) {
5340 if ((
Right.is(Keywords.kw_apostrophe) ||
5342 !(
Left.isOneOf(Keywords.kw_assign, Keywords.kw_unique) ||
5343 Keywords.isVerilogWordOperator(Left)) &&
5344 (
Left.isOneOf(tok::r_square, tok::r_paren, tok::r_brace,
5345 tok::numeric_constant) ||
5346 Keywords.isWordLike(Left))) {
5350 if ((
Right.is(tok::star) &&
Left.is(tok::coloncolon)) ||
5351 (
Left.is(tok::star) &&
Right.is(tok::semi))) {
5355 if (
Left.endsSequence(tok::star, tok::l_paren) &&
Right.is(tok::identifier))
5358 if (
Right.is(tok::l_paren) &&
Right.is(TT_VerilogStrength))
5361 if ((
Left.is(tok::l_brace) &&
5362 Right.isOneOf(tok::lessless, tok::greatergreater)) ||
5363 (
Left.endsSequence(tok::lessless, tok::l_brace) ||
5364 Left.endsSequence(tok::greatergreater, tok::l_brace))) {
5367 }
else if (Style.isTableGen()) {
5369 if (
Left.is(tok::l_square) &&
Right.is(tok::l_brace))
5371 if (
Left.is(tok::r_brace) &&
Right.is(tok::r_square))
5374 if (
Right.isOneOf(TT_TableGenDAGArgListColon,
5375 TT_TableGenDAGArgListColonToAlign) ||
5376 Left.isOneOf(TT_TableGenDAGArgListColon,
5377 TT_TableGenDAGArgListColonToAlign)) {
5380 if (
Right.is(TT_TableGenCondOperatorColon))
5382 if (
Left.isOneOf(TT_TableGenDAGArgOperatorID,
5383 TT_TableGenDAGArgOperatorToBreak) &&
5384 Right.isNot(TT_TableGenDAGArgCloser)) {
5388 if (
Right.isOneOf(tok::l_paren, tok::less) &&
5389 Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
5394 if (
Left.is(TT_TableGenTrailingPasteOperator) &&
5395 Right.isOneOf(tok::l_brace, tok::colon)) {
5399 if (
Left.is(tok::hash) ||
Right.is(tok::hash))
5402 if (Keywords.isTableGenDefinition(Left))
5406 if (
Left.is(TT_ImplicitStringLiteral))
5407 return Right.hasWhitespaceBefore();
5409 if (
Left.is(TT_ObjCMethodSpecifier))
5411 if (
Left.is(tok::r_paren) &&
Left.isNot(TT_AttributeRParen) &&
5412 canBeObjCSelectorComponent(Right)) {
5420 (
Right.is(tok::equal) ||
Left.is(tok::equal))) {
5424 if (
Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
5425 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) {
5428 if (
Left.is(tok::comma) &&
Right.isNot(TT_OverloadedOperatorLParen) &&
5431 (
Left.Children.empty() || !
Left.MacroParent)) {
5434 if (
Right.is(tok::comma))
5436 if (
Right.is(TT_ObjCBlockLParen))
5438 if (
Right.is(TT_CtorInitializerColon))
5439 return Style.SpaceBeforeCtorInitializerColon;
5440 if (
Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)
5442 if (
Right.is(TT_RangeBasedForLoopColon) &&
5443 !Style.SpaceBeforeRangeBasedForLoopColon) {
5446 if (
Left.is(TT_BitFieldColon)) {
5450 if (
Right.is(tok::colon)) {
5451 if (
Right.is(TT_CaseLabelColon))
5452 return Style.SpaceBeforeCaseColon;
5453 if (
Right.is(TT_GotoLabelColon))
5456 if (!
Right.getNextNonComment())
5458 if (
Right.is(TT_ObjCMethodExpr))
5460 if (
Left.is(tok::question))
5462 if (
Right.is(TT_InlineASMColon) &&
Left.is(tok::coloncolon))
5464 if (
Right.is(TT_DictLiteral))
5465 return Style.SpacesInContainerLiterals;
5466 if (
Right.is(TT_AttributeColon))
5468 if (
Right.is(TT_CSharpNamedArgumentColon))
5470 if (
Right.is(TT_GenericSelectionColon))
5472 if (
Right.is(TT_BitFieldColon)) {
5479 if ((
Left.isOneOf(tok::minus, tok::minusminus) &&
5480 Right.isOneOf(tok::minus, tok::minusminus)) ||
5481 (
Left.isOneOf(tok::plus, tok::plusplus) &&
5482 Right.isOneOf(tok::plus, tok::plusplus))) {
5485 if (
Left.is(TT_UnaryOperator)) {
5488 if (
Left.is(tok::amp) &&
Right.is(tok::r_square))
5489 return Style.SpacesInSquareBrackets;
5490 if (
Left.isNot(tok::exclaim))
5492 if (
Left.TokenText ==
"!")
5493 return Style.SpaceAfterLogicalNot;
5494 assert(
Left.TokenText ==
"not");
5495 return Right.isOneOf(tok::coloncolon, TT_UnaryOperator) ||
5496 (
Right.is(tok::l_paren) && Style.SpaceBeforeParensOptions.AfterNot);
5501 if (
Left.is(TT_CastRParen)) {
5502 return Style.SpaceAfterCStyleCast ||
5503 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
5506 auto ShouldAddSpacesInAngles = [
this, &
Right]() {
5510 return Right.hasWhitespaceBefore();
5514 if (
Left.is(tok::greater) &&
Right.is(tok::greater)) {
5515 if (Style.isTextProto() ||
5517 return !Style.Cpp11BracedListStyle;
5519 return Right.is(TT_TemplateCloser) &&
Left.is(TT_TemplateCloser) &&
5521 ShouldAddSpacesInAngles());
5523 if (
Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
5524 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
5525 (
Right.is(tok::period) &&
Right.isNot(TT_DesignatedInitializerPeriod))) {
5528 if (!Style.SpaceBeforeAssignmentOperators &&
Left.isNot(TT_TemplateCloser) &&
5532 if (Style.isJava() &&
Right.is(tok::coloncolon) &&
5533 Left.isOneOf(tok::identifier, tok::kw_this)) {
5536 if (
Right.is(tok::coloncolon) &&
Left.is(tok::identifier)) {
5540 return Right.hasWhitespaceBefore();
5542 if (
Right.is(tok::coloncolon) &&
5543 !
Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren)) {
5545 return (
Left.is(TT_TemplateOpener) &&
5547 ShouldAddSpacesInAngles())) ||
5548 !(
Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
5549 tok::kw___super, TT_TemplateOpener,
5550 TT_TemplateCloser)) ||
5551 (
Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other);
5553 if ((
Left.is(TT_TemplateOpener)) != (
Right.is(TT_TemplateCloser)))
5554 return ShouldAddSpacesInAngles();
5555 if (
Left.is(tok::r_paren) &&
Left.isNot(TT_TypeDeclarationParen) &&
5556 Right.is(TT_PointerOrReference) &&
Right.isOneOf(tok::amp, tok::ampamp)) {
5560 if (
Right.is(TT_StructuredBindingLSquare)) {
5561 return !
Left.isOneOf(tok::amp, tok::ampamp) ||
5565 if (
Right.Next &&
Right.Next->is(TT_StructuredBindingLSquare) &&
5566 Right.isOneOf(tok::amp, tok::ampamp)) {
5569 if ((
Right.is(TT_BinaryOperator) &&
Left.isNot(tok::l_paren)) ||
5570 (
Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
5571 Right.isNot(tok::r_paren))) {
5574 if (
Right.is(TT_TemplateOpener) &&
Left.is(tok::r_paren) &&
5575 Left.MatchingParen &&
5576 Left.MatchingParen->is(TT_OverloadedOperatorLParen)) {
5579 if (
Right.is(tok::less) &&
Left.isNot(tok::l_paren) &&
5583 if (
Right.is(TT_TrailingUnaryOperator))
5585 if (
Left.is(TT_RegexLiteral))
5587 return spaceRequiredBetween(
Line, Left, Right);
5593 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
5611 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
5614bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &
Line,
5615 const FormatToken &Right)
const {
5616 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
5617 (!Style.RemoveEmptyLinesInUnwrappedLines || &Right ==
Line.First)) {
5621 const FormatToken &Left = *Right.Previous;
5623 if (Style.BreakFunctionDefinitionParameters &&
Line.MightBeFunctionDecl &&
5624 Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
5625 Left.ParameterCount > 0) {
5632 Line.MightBeFunctionDecl && !
Left.opensScope() &&
5637 const auto *BeforeLeft =
Left.Previous;
5638 const auto *AfterRight =
Right.Next;
5640 if (Style.isCSharp()) {
5641 if (
Left.is(TT_FatArrow) &&
Right.is(tok::l_brace) &&
5642 Style.BraceWrapping.AfterFunction) {
5645 if (
Right.is(TT_CSharpNamedArgumentColon) ||
5646 Left.is(TT_CSharpNamedArgumentColon)) {
5649 if (
Right.is(TT_CSharpGenericTypeConstraint))
5651 if (AfterRight && AfterRight->is(TT_FatArrow) &&
5652 (
Right.is(tok::numeric_constant) ||
5653 (
Right.is(tok::identifier) &&
Right.TokenText ==
"_"))) {
5658 if (
Left.is(TT_AttributeSquare) &&
Left.is(tok::r_square) &&
5659 (
Right.isAccessSpecifier(
false) ||
5660 Right.is(Keywords.kw_internal))) {
5664 if (
Left.is(TT_AttributeSquare) &&
Right.is(TT_AttributeSquare) &&
5665 Left.is(tok::r_square) &&
Right.is(tok::l_square)) {
5668 }
else if (Style.isJavaScript()) {
5670 if (
Right.is(tok::string_literal) &&
Left.is(tok::plus) && BeforeLeft &&
5671 BeforeLeft->is(tok::string_literal)) {
5674 if (
Left.is(TT_DictLiteral) &&
Left.is(tok::l_brace) &&
Line.Level == 0 &&
5675 BeforeLeft && BeforeLeft->is(tok::equal) &&
5676 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
5680 !
Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let)) {
5685 if (
Left.is(tok::l_brace) &&
Line.Level == 0 &&
5686 (
Line.startsWith(tok::kw_enum) ||
5687 Line.startsWith(tok::kw_const, tok::kw_enum) ||
5688 Line.startsWith(tok::kw_export, tok::kw_enum) ||
5689 Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum))) {
5694 if (
Right.is(tok::r_brace) &&
Left.is(tok::l_brace) && BeforeLeft &&
5695 BeforeLeft->is(TT_FatArrow)) {
5697 switch (Style.AllowShortLambdasOnASingleLine) {
5703 return !
Left.Children.empty();
5707 return (
Left.NestingLevel == 0 &&
Line.Level == 0) &&
5708 !
Left.Children.empty();
5710 llvm_unreachable(
"Unknown FormatStyle::ShortLambdaStyle enum");
5713 if (
Right.is(tok::r_brace) &&
Left.is(tok::l_brace) &&
5714 !
Left.Children.empty()) {
5718 (
Left.NestingLevel == 0 &&
Line.Level == 0 &&
5719 Style.AllowShortFunctionsOnASingleLine &
5722 }
else if (Style.isJava()) {
5723 if (
Right.is(tok::plus) &&
Left.is(tok::string_literal) && AfterRight &&
5724 AfterRight->is(tok::string_literal)) {
5727 }
else if (Style.isVerilog()) {
5729 if (
Left.is(TT_VerilogAssignComma))
5732 if (
Left.is(TT_VerilogTypeComma))
5736 if (Style.VerilogBreakBetweenInstancePorts &&
5737 (
Left.is(TT_VerilogInstancePortComma) ||
5738 (
Left.is(tok::r_paren) && Keywords.isVerilogIdentifier(Right) &&
5739 Left.MatchingParen &&
5740 Left.MatchingParen->is(TT_VerilogInstancePortLParen)))) {
5745 if (!Keywords.isVerilogBegin(Right) && Keywords.isVerilogEndOfLabel(Left))
5747 }
else if (Style.BreakAdjacentStringLiterals &&
5748 (IsCpp || Style.isProto() || Style.isTableGen())) {
5749 if (
Left.isStringLiteral() &&
Right.isStringLiteral())
5754 if (Style.isJson()) {
5758 if (
Left.is(TT_DictLiteral) &&
Left.is(tok::l_brace))
5761 if ((
Left.is(TT_ArrayInitializerLSquare) &&
Left.is(tok::l_square) &&
5762 Right.isNot(tok::r_square)) ||
5763 Left.is(tok::comma)) {
5764 if (
Right.is(tok::l_brace))
5768 for (
const auto *Tok = &Right; Tok; Tok = Tok->Next) {
5769 if (Tok->isOneOf(tok::l_brace, tok::l_square))
5771 if (Tok->isOneOf(tok::r_brace, tok::r_square))
5774 return Style.BreakArrays;
5776 }
else if (Style.isTableGen()) {
5780 if (
Left.is(TT_TableGenCondOperatorComma))
5782 if (
Left.is(TT_TableGenDAGArgOperatorToBreak) &&
5783 Right.isNot(TT_TableGenDAGArgCloser)) {
5786 if (
Left.is(TT_TableGenDAGArgListCommaToBreak))
5788 if (
Right.is(TT_TableGenDAGArgCloser) &&
Right.MatchingParen &&
5789 Right.MatchingParen->is(TT_TableGenDAGArgOpenerToBreak) &&
5796 if (
Line.startsWith(tok::kw_asm) &&
Right.is(TT_InlineASMColon) &&
5806 const FormatToken *BeforeClosingBrace =
nullptr;
5807 if ((
Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
5808 (Style.isJavaScript() &&
Left.is(tok::l_paren))) &&
5810 BeforeClosingBrace =
Left.MatchingParen->Previous;
5811 }
else if (
Right.MatchingParen &&
5812 (
Right.MatchingParen->isOneOf(tok::l_brace,
5813 TT_ArrayInitializerLSquare) ||
5814 (Style.isJavaScript() &&
5815 Right.MatchingParen->is(tok::l_paren)))) {
5816 BeforeClosingBrace = &
Left;
5818 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
5819 BeforeClosingBrace->isTrailingComment())) {
5824 if (
Right.is(tok::comment)) {
5826 Right.NewlinesBefore > 0 &&
Right.HasUnescapedNewline;
5828 if (
Left.isTrailingComment())
5830 if (
Left.IsUnterminatedLiteral)
5833 if (BeforeLeft && BeforeLeft->is(tok::lessless) &&
5834 Left.is(tok::string_literal) &&
Right.is(tok::lessless) && AfterRight &&
5835 AfterRight->is(tok::string_literal)) {
5836 return Right.NewlinesBefore > 0;
5839 if (
Right.is(TT_RequiresClause)) {
5840 switch (Style.RequiresClausePosition) {
5850 if (
Left.ClosesTemplateDeclaration &&
Left.MatchingParen &&
5851 Left.MatchingParen->NestingLevel == 0) {
5855 if (
Right.is(tok::kw_concept))
5859 Right.NewlinesBefore > 0);
5861 if (
Left.ClosesRequiresClause) {
5862 switch (Style.RequiresClausePosition) {
5865 return Right.isNot(tok::semi);
5867 return !
Right.isOneOf(tok::semi, tok::l_brace);
5874 (
Left.is(TT_CtorInitializerComma) ||
5875 Right.is(TT_CtorInitializerColon))) {
5880 Left.isOneOf(TT_CtorInitializerColon, TT_CtorInitializerComma)) {
5886 Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) {
5892 Right.is(TT_CtorInitializerColon)) {
5897 Left.is(TT_CtorInitializerColon)) {
5903 Right.is(TT_InheritanceComma)) {
5907 Left.is(TT_InheritanceComma)) {
5910 if (
Right.is(tok::string_literal) &&
Right.TokenText.starts_with(
"R\"")) {
5914 return Right.IsMultiline &&
Right.NewlinesBefore > 0;
5916 if ((
Left.is(tok::l_brace) ||
5917 (
Left.is(tok::less) && BeforeLeft && BeforeLeft->is(tok::equal))) &&
5923 if (
Right.is(TT_InlineASMBrace))
5924 return Right.HasUnescapedNewline;
5927 auto *FirstNonComment =
Line.getFirstNonComment();
5929 FirstNonComment && (FirstNonComment->is(Keywords.kw_internal) ||
5930 FirstNonComment->isAccessSpecifierKeyword());
5932 if (Style.BraceWrapping.AfterEnum) {
5933 if (
Line.startsWith(tok::kw_enum) ||
5934 Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
5939 FirstNonComment->Next->is(tok::kw_enum)) {
5945 if (Style.BraceWrapping.AfterClass &&
5947 FirstNonComment->Next->is(Keywords.kw_interface)) ||
5948 Line.startsWith(Keywords.kw_interface))) {
5953 if (
Right.isNot(TT_FunctionLBrace)) {
5954 return (
Line.startsWith(tok::kw_class) &&
5955 Style.BraceWrapping.AfterClass) ||
5956 (
Line.startsWith(tok::kw_struct) &&
5957 Style.BraceWrapping.AfterStruct);
5961 if (
Left.is(TT_ObjCBlockLBrace) &&
5967 if (
Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&
5968 Right.is(TT_ObjCDecl)) {
5972 if (
Left.is(TT_LambdaLBrace)) {
5980 (!
Left.Children.empty() &&
5986 if (Style.BraceWrapping.BeforeLambdaBody &&
Right.is(TT_LambdaLBrace) &&
5987 (
Left.isPointerOrReference() ||
Left.is(TT_TemplateCloser))) {
5992 if ((Style.isJava() || Style.isJavaScript()) &&
5993 Left.is(TT_LeadingJavaAnnotation) &&
5994 !
Right.isOneOf(TT_LeadingJavaAnnotation, tok::l_paren) &&
5995 (
Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) {
5999 if (
Right.is(TT_ProtoExtensionLSquare))
6029 if (Style.isProto() &&
Right.is(TT_SelectorName) &&
6030 Right.isNot(tok::r_square) && AfterRight) {
6033 if (
Left.is(tok::at))
6039 const auto *LBrace = AfterRight;
6040 if (LBrace && LBrace->is(tok::colon)) {
6041 LBrace = LBrace->Next;
6042 if (LBrace && LBrace->is(tok::at)) {
6043 LBrace = LBrace->Next;
6045 LBrace = LBrace->Next;
6057 ((LBrace->is(tok::l_brace) &&
6058 (LBrace->is(TT_DictLiteral) ||
6059 (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||
6060 LBrace->isOneOf(TT_ArrayInitializerLSquare, tok::less))) {
6067 if (
Left.ParameterCount == 0)
6082 if (
Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))
6089bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &
Line,
6090 const FormatToken &Right)
const {
6091 const FormatToken &
Left = *
Right.Previous;
6093 if (Style.isCSharp()) {
6094 if (
Left.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon) ||
6095 Right.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon)) {
6099 if (
Line.First->is(TT_CSharpGenericTypeConstraint))
6100 return Left.is(TT_CSharpGenericTypeConstraintComma);
6102 if (
Right.is(TT_CSharpNullable))
6104 }
else if (Style.isJava()) {
6105 if (
Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
6106 Keywords.kw_implements)) {
6109 if (
Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
6110 Keywords.kw_implements)) {
6113 }
else if (Style.isJavaScript()) {
6114 const FormatToken *NonComment =
Right.getPreviousNonComment();
6116 (NonComment->isAccessSpecifierKeyword() ||
6117 NonComment->isOneOf(
6118 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
6119 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
6120 tok::kw_static, Keywords.kw_readonly, Keywords.kw_override,
6121 Keywords.kw_abstract, Keywords.kw_get, Keywords.kw_set,
6122 Keywords.kw_async, Keywords.kw_await))) {
6125 if (
Right.NestingLevel == 0 &&
6126 (
Left.Tok.getIdentifierInfo() ||
6127 Left.isOneOf(tok::r_square, tok::r_paren)) &&
6128 Right.isOneOf(tok::l_square, tok::l_paren)) {
6131 if (NonComment && NonComment->is(tok::identifier) &&
6132 NonComment->TokenText ==
"asserts") {
6135 if (
Left.is(TT_FatArrow) &&
Right.is(tok::l_brace))
6137 if (
Left.is(TT_JsTypeColon))
6140 if (
Left.is(tok::exclaim) &&
Right.is(tok::colon))
6145 if (
Right.is(Keywords.kw_is)) {
6146 const FormatToken *Next =
Right.getNextNonComment();
6154 if (!Next || Next->isNot(tok::colon))
6157 if (
Left.is(Keywords.kw_in))
6159 if (
Right.is(Keywords.kw_in))
6161 if (
Right.is(Keywords.kw_as))
6163 if (
Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
6169 if (
Left.is(Keywords.kw_as))
6171 if (
Left.is(TT_NonNullAssertion))
6173 if (
Left.is(Keywords.kw_declare) &&
6174 Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
6175 Keywords.kw_function, tok::kw_class, tok::kw_enum,
6176 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
6177 Keywords.kw_let, tok::kw_const)) {
6182 if (
Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
6183 Right.isOneOf(tok::identifier, tok::string_literal)) {
6186 if (
Right.is(TT_TemplateString) &&
Right.closesScope())
6190 if (
Left.is(tok::identifier) &&
Right.is(TT_TemplateString))
6192 if (
Left.is(TT_TemplateString) &&
Left.opensScope())
6194 }
else if (Style.isTableGen()) {
6196 if (Keywords.isTableGenDefinition(Left))
6199 if (
Right.is(tok::l_paren)) {
6200 return !
Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator,
6204 if (
Left.is(TT_TableGenValueSuffix))
6207 if (
Left.is(tok::hash) ||
Right.is(tok::hash))
6209 if (
Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator))
6216 if (
Right.is(tok::r_brace)) {
6218 (
Right.isBlockIndentedInitRBrace(Style)));
6222 if (
Right.is(tok::r_paren)) {
6224 !
Right.MatchingParen) {
6227 auto Next =
Right.Next;
6228 if (Next && Next->is(tok::r_paren))
6230 if (Next && Next->is(tok::l_paren))
6232 const FormatToken *
Previous =
Right.MatchingParen->Previous;
6236 if (
Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) &&
6237 Right.is(TT_TrailingAnnotation) &&
6242 if (
Right.is(TT_TemplateCloser))
6243 return Style.BreakBeforeTemplateCloser;
6245 if (
Left.isOneOf(tok::at, tok::objc_interface))
6247 if (
Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
6248 return Right.isNot(tok::l_paren);
6249 if (
Right.is(TT_PointerOrReference)) {
6250 return Line.IsMultiVariableDeclStmt ||
6251 (getTokenPointerOrReferenceAlignment(Right) ==
6254 Right.Next->isOneOf(TT_FunctionDeclarationName, tok::kw_const)));
6256 if (
Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
6257 TT_ClassHeadName, tok::kw_operator)) {
6260 if (
Left.is(TT_PointerOrReference))
6262 if (
Right.isTrailingComment()) {
6269 (
Left.is(TT_CtorInitializerColon) &&
Right.NewlinesBefore > 0 &&
6272 if (
Left.is(tok::question) &&
Right.is(tok::colon))
6274 if (
Right.isOneOf(TT_ConditionalExpr, tok::question))
6275 return Style.BreakBeforeTernaryOperators;
6276 if (
Left.isOneOf(TT_ConditionalExpr, tok::question))
6277 return !Style.BreakBeforeTernaryOperators;
6278 if (
Left.is(TT_InheritanceColon))
6280 if (
Right.is(TT_InheritanceColon))
6282 if (
Right.is(TT_ObjCMethodExpr) &&
Right.isNot(tok::r_square) &&
6283 Left.isNot(TT_SelectorName)) {
6287 if (
Right.is(tok::colon) &&
6288 !
Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon,
6289 TT_BitFieldColon)) {
6292 if (
Left.is(tok::colon) &&
Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
6293 if (Style.isProto()) {
6294 if (!Style.AlwaysBreakBeforeMultilineStrings &&
Right.isStringLiteral())
6320 if ((
Right.isOneOf(tok::l_brace, tok::less) &&
6321 Right.is(TT_DictLiteral)) ||
6322 Right.is(TT_ArrayInitializerLSquare)) {
6328 if (
Right.is(tok::r_square) &&
Right.MatchingParen &&
6329 Right.MatchingParen->is(TT_ProtoExtensionLSquare)) {
6332 if (
Right.is(TT_SelectorName) || (
Right.is(tok::identifier) &&
Right.Next &&
6333 Right.Next->is(TT_ObjCMethodExpr))) {
6334 return Left.isNot(tok::period);
6338 if (
Right.is(tok::kw_concept))
6340 if (
Right.is(TT_RequiresClause))
6342 if (
Left.ClosesTemplateDeclaration) {
6344 Right.NewlinesBefore > 0;
6346 if (
Left.is(TT_FunctionAnnotationRParen))
6348 if (
Left.ClosesRequiresClause)
6350 if (
Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
6351 TT_OverloadedOperator)) {
6354 if (
Left.is(TT_RangeBasedForLoopColon))
6356 if (
Right.is(TT_RangeBasedForLoopColon))
6358 if (
Left.is(TT_TemplateCloser) &&
Right.is(TT_TemplateOpener))
6360 if ((
Left.is(tok::greater) &&
Right.is(tok::greater)) ||
6361 (
Left.is(tok::less) &&
Right.is(tok::less))) {
6364 if (
Right.is(TT_BinaryOperator) &&
6370 if (
Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator, tok::kw_operator))
6372 if (
Left.is(tok::equal) && !
Right.isOneOf(tok::kw_default, tok::kw_delete) &&
6376 if (
Left.is(tok::equal) &&
Right.is(tok::l_brace) &&
6377 !Style.Cpp11BracedListStyle) {
6380 if (
Left.is(TT_AttributeLParen) ||
6381 (
Left.is(tok::l_paren) &&
Left.is(TT_TypeDeclarationParen))) {
6384 if (
Left.is(tok::l_paren) &&
Left.Previous &&
6385 (
Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) {
6388 if (
Right.is(TT_ImplicitStringLiteral))
6391 if (
Right.is(tok::r_square) &&
Right.MatchingParen &&
6392 Right.MatchingParen->is(TT_LambdaLSquare)) {
6398 if (
Left.is(TT_TrailingAnnotation)) {
6399 return !
Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
6400 tok::less, tok::coloncolon);
6403 if (
Right.isAttribute())
6406 if (
Right.is(tok::l_square) &&
Right.is(TT_AttributeSquare))
6407 return Left.isNot(TT_AttributeSquare);
6409 if (
Left.is(tok::identifier) &&
Right.is(tok::string_literal))
6412 if (
Right.is(tok::identifier) &&
Right.Next &&
Right.Next->is(TT_DictLiteral))
6415 if (
Left.is(TT_CtorInitializerColon)) {
6417 (!
Right.isTrailingComment() ||
Right.NewlinesBefore > 0);
6419 if (
Right.is(TT_CtorInitializerColon))
6421 if (
Left.is(TT_CtorInitializerComma) &&
6425 if (
Right.is(TT_CtorInitializerComma) &&
6429 if (
Left.is(TT_InheritanceComma) &&
6433 if (
Right.is(TT_InheritanceComma) &&
6437 if (
Left.is(TT_ArrayInitializerLSquare))
6439 if (
Right.is(tok::kw_typename) &&
Left.isNot(tok::kw_const))
6441 if ((
Left.isBinaryOperator() ||
Left.is(TT_BinaryOperator)) &&
6442 !
Left.isOneOf(tok::arrowstar, tok::lessless) &&
6448 if ((
Left.is(TT_AttributeSquare) &&
Right.is(tok::l_square)) ||
6449 (
Left.is(tok::r_square) &&
Right.is(TT_AttributeSquare))) {
6453 auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
6454 if (Style.BraceWrapping.BeforeLambdaBody &&
Right.is(TT_LambdaLBrace)) {
6461 if (
Right.is(tok::kw_noexcept) &&
Right.is(TT_TrailingAnnotation)) {
6462 switch (Style.AllowBreakBeforeNoexceptSpecifier) {
6468 return Right.Next &&
Right.Next->is(tok::l_paren);
6472 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
6473 tok::kw_class, tok::kw_struct, tok::comment) ||
6474 Right.isMemberAccess() ||
6475 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
6476 tok::colon, tok::l_square, tok::at) ||
6477 (
Left.is(tok::r_paren) &&
6478 Right.isOneOf(tok::identifier, tok::kw_const)) ||
6479 (
Left.is(tok::l_paren) &&
Right.isNot(tok::r_paren)) ||
6480 (
Left.is(TT_TemplateOpener) &&
Right.isNot(TT_TemplateCloser));
6483void TokenAnnotator::printDebugInfo(
const AnnotatedLine &
Line)
const {
6484 llvm::errs() <<
"AnnotatedTokens(L=" <<
Line.Level <<
", P=" <<
Line.PPLevel
6485 <<
", T=" <<
Line.Type <<
", C=" <<
Line.IsContinuation
6487 const FormatToken *Tok =
Line.First;
6489 llvm::errs() <<
" M=" << Tok->MustBreakBefore
6490 <<
" C=" << Tok->CanBreakBefore
6492 <<
" S=" << Tok->SpacesRequiredBefore
6493 <<
" F=" << Tok->Finalized <<
" B=" << Tok->BlockParameterCount
6494 <<
" BK=" << Tok->getBlockKind() <<
" P=" << Tok->SplitPenalty
6495 <<
" Name=" << Tok->Tok.getName() <<
" L=" << Tok->TotalLength
6496 <<
" PPK=" << Tok->getPackingKind() <<
" FakeLParens=";
6498 llvm::errs() << LParen <<
"/";
6499 llvm::errs() <<
" FakeRParens=" << Tok->FakeRParens;
6500 llvm::errs() <<
" II=" << Tok->Tok.getIdentifierInfo();
6501 llvm::errs() <<
" Text='" << Tok->TokenText <<
"'\n";
6503 assert(Tok ==
Line.Last);
6506 llvm::errs() <<
"----\n";
6510TokenAnnotator::getTokenReferenceAlignment(
const FormatToken &
Reference)
const {
6511 assert(
Reference.isOneOf(tok::amp, tok::ampamp));
6512 switch (Style.ReferenceAlignment) {
6514 return Style.PointerAlignment;
6523 return Style.PointerAlignment;
6527TokenAnnotator::getTokenPointerOrReferenceAlignment(
6528 const FormatToken &PointerOrReference)
const {
6529 if (PointerOrReference.isOneOf(tok::amp, tok::ampamp))
6530 return getTokenReferenceAlignment(PointerOrReference);
6531 assert(PointerOrReference.is(tok::star));
6532 return Style.PointerAlignment;
bool ColonIsObjCMethodExpr
bool IsTableGenDAGArgList
FormatToken * FirstStartOfName
bool InCpp11AttributeSpecifier
unsigned LongestObjCSelectorName
bool VerilogAssignmentFound
bool InCSharpAttributeSpecifier
tok::TokenKind ContextKind
FormatToken * FirstObjCSelectorName
bool VerilogMayBeConcatenation
enum clang::format::@1435::AnnotatingParser::Context::@359 ContextType
This file implements a token annotator, i.e.
Defines the clang::TokenKind enum and support functions.
#define TRANSFORM_TYPE_TRAIT_DEF(Enum, _)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Parser - This implements a parser for the C family of languages.
IdentifierInfo * getIdentifierInfo() const
bool Ret(InterpState &S, CodePtr &PC)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
@ 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.
const FunctionProtoType * T