18#include "llvm/ADT/SmallPtrSet.h"
19#include "llvm/Support/Debug.h"
21#define DEBUG_TYPE "format-token-annotator"
27 const FormatStyle &Style) {
28 switch (Style.BreakAfterAttributes) {
29 case FormatStyle::ABS_Always:
31 case FormatStyle::ABS_Leave:
32 return Tok.NewlinesBefore > 0;
42static bool startsWithInitStatement(
const AnnotatedLine &
Line) {
43 return Line.startsWith(tok::kw_for) ||
Line.startsWith(tok::kw_if) ||
44 Line.startsWith(tok::kw_switch);
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);
82 return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
83 tok::kw_constexpr, tok::kw_catch);
88 if (!IsCpp || !
Tok.startsSequence(tok::l_square, tok::l_square))
91 if (
Tok.Previous &&
Tok.Previous->is(tok::at))
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();
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->isNoneOf(tok::l_paren, tok::l_brace))) {
212 Left->MatchingParen = CurrentToken;
213 CurrentToken->MatchingParen =
Left;
219 if (Style.isTextProto() ||
220 (Style.Language == FormatStyle::LK_Proto && BeforeLess &&
221 BeforeLess->isOneOf(TT_SelectorName, TT_DictLiteral))) {
222 CurrentToken->setType(TT_DictLiteral);
224 CurrentToken->setType(TT_TemplateCloser);
225 CurrentToken->Tok.setLength(1);
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);
257 if (Style.Language == FormatStyle::LK_Proto) {
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 StartsObjCSelector =
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 StartsObjCSelector =
true;
335 if (OpeningParen.is(TT_OverloadedOperatorLParen)) {
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_noexcept, tok::kw_explicit, tok::kw_while,
362 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 (OpeningParen.Previous &&
388 OpeningParen.Previous->TokenText ==
"Q_PROPERTY") {
389 Contexts.back().ContextType = Context::QtProperty;
390 Contexts.back().IsExpression =
false;
391 }
else if (Line.InPPDirective &&
392 (!OpeningParen.Previous ||
393 OpeningParen.Previous->isNot(tok::identifier))) {
394 Contexts.back().IsExpression =
true;
395 }
else if (Contexts[Contexts.size() - 2].CaretFound) {
397 Contexts.back().IsExpression =
false;
398 }
else if (OpeningParen.Previous &&
399 OpeningParen.Previous->is(TT_ForEachMacro)) {
401 Contexts.back().ContextType = Context::ForEachMacro;
402 Contexts.back().IsExpression =
false;
403 }
else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
404 OpeningParen.Previous->MatchingParen->isOneOf(
405 TT_ObjCBlockLParen, TT_FunctionTypeLParen)) {
406 Contexts.back().IsExpression =
false;
407 }
else if (!Line.MustBeDeclaration &&
408 (!Line.InPPDirective || (Line.InMacroBody && !Scopes.empty()))) {
410 OpeningParen.Previous &&
411 OpeningParen.Previous->isOneOf(tok::kw_for, tok::kw_catch);
412 Contexts.back().IsExpression = !IsForOrCatch;
415 if (Style.isTableGen()) {
417 if (Prev->is(TT_TableGenCondOperator)) {
418 Contexts.back().IsTableGenCondOpe =
true;
419 Contexts.back().IsExpression =
true;
420 }
else if (Contexts.size() > 1 &&
421 Contexts[Contexts.size() - 2].IsTableGenBangOpe) {
426 Contexts.back().IsTableGenBangOpe =
true;
427 Contexts.back().IsExpression =
true;
430 if (!parseTableGenDAGArg())
432 return parseTableGenDAGArgAndList(&OpeningParen);
439 if (PrevNonComment && OpeningParen.is(TT_Unknown)) {
440 if (PrevNonComment->isAttribute()) {
441 OpeningParen.setType(TT_AttributeLParen);
442 }
else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
445#include
"clang/Basic/TransformTypeTraits.def"
447 OpeningParen.setType(TT_TypeDeclarationParen);
449 if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))
450 Contexts.back().IsExpression =
true;
454 if (StartsObjCSelector)
455 OpeningParen.setType(TT_ObjCSelector);
457 const bool IsStaticAssert =
458 PrevNonComment && PrevNonComment->is(tok::kw_static_assert);
460 Contexts.back().InStaticAssertFirstArgument =
true;
470 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
471 bool ProbablyFunctionType =
472 CurrentToken->isPointerOrReference() || CurrentToken->is(tok::caret);
473 bool HasMultipleLines =
false;
474 bool HasMultipleParametersOnALine =
false;
475 bool MightBeObjCForRangeLoop =
476 OpeningParen.Previous && OpeningParen.Previous->is(tok::kw_for);
478 while (CurrentToken) {
479 const auto &Prev = *CurrentToken->Previous;
480 const auto *PrevPrev = Prev.Previous;
481 if (Prev.is(TT_PointerOrReference) &&
482 PrevPrev->isOneOf(tok::l_paren, tok::coloncolon)) {
483 ProbablyFunctionType =
true;
485 if (CurrentToken->is(tok::comma))
486 MightBeFunctionType =
false;
487 if (Prev.is(TT_BinaryOperator))
488 Contexts.back().IsExpression =
true;
489 if (CurrentToken->is(tok::r_paren)) {
490 if (Prev.is(TT_PointerOrReference) &&
491 (PrevPrev == &OpeningParen || PrevPrev->is(tok::coloncolon))) {
492 MightBeFunctionType =
true;
494 if (OpeningParen.isNot(TT_CppCastLParen) && MightBeFunctionType &&
495 ProbablyFunctionType && CurrentToken->Next &&
496 (CurrentToken->Next->is(tok::l_paren) ||
497 (CurrentToken->Next->is(tok::l_square) &&
498 (Line.MustBeDeclaration ||
499 (PrevNonComment && PrevNonComment->isTypeName(LangOpts)))))) {
500 OpeningParen.setType(OpeningParen.Next->is(tok::caret)
502 : TT_FunctionTypeLParen);
504 OpeningParen.MatchingParen = CurrentToken;
505 CurrentToken->MatchingParen = &OpeningParen;
507 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
508 OpeningParen.Previous && OpeningParen.Previous->is(tok::l_paren)) {
514 if (
Tok->is(TT_BinaryOperator) &&
Tok->isPointerOrReference())
515 Tok->setType(TT_PointerOrReference);
519 if (StartsObjCSelector) {
520 CurrentToken->setType(TT_ObjCSelector);
521 if (Contexts.back().FirstObjCSelectorName) {
522 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
523 Contexts.back().LongestObjCSelectorName;
527 if (OpeningParen.is(TT_AttributeLParen))
528 CurrentToken->setType(TT_AttributeRParen);
529 if (OpeningParen.is(TT_TypeDeclarationParen))
530 CurrentToken->setType(TT_TypeDeclarationParen);
531 if (OpeningParen.Previous &&
532 OpeningParen.Previous->is(TT_JavaAnnotation)) {
533 CurrentToken->setType(TT_JavaAnnotation);
535 if (OpeningParen.Previous &&
536 OpeningParen.Previous->is(TT_LeadingJavaAnnotation)) {
537 CurrentToken->setType(TT_LeadingJavaAnnotation);
540 if (!HasMultipleLines)
542 else if (HasMultipleParametersOnALine)
550 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
553 if (CurrentToken->is(tok::l_brace) && OpeningParen.is(TT_ObjCBlockLParen))
554 OpeningParen.setType(TT_Unknown);
555 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
556 !CurrentToken->Next->HasUnescapedNewline &&
557 !CurrentToken->Next->isTrailingComment()) {
558 HasMultipleParametersOnALine =
true;
560 bool ProbablyFunctionTypeLParen =
561 (CurrentToken->is(tok::l_paren) && CurrentToken->Next &&
562 CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret));
563 if ((Prev.isOneOf(tok::kw_const, tok::kw_auto) ||
564 Prev.isTypeName(LangOpts)) &&
565 !(CurrentToken->is(tok::l_brace) ||
566 (CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) {
567 Contexts.back().IsExpression =
false;
569 if (CurrentToken->isOneOf(tok::semi, tok::colon)) {
570 MightBeObjCForRangeLoop =
false;
571 if (PossibleObjCForInToken) {
572 PossibleObjCForInToken->setType(TT_Unknown);
573 PossibleObjCForInToken =
nullptr;
576 if (IsIf && CurrentToken->is(tok::semi)) {
577 for (
auto *
Tok = OpeningParen.Next;
578 Tok != CurrentToken &&
579 Tok->isNoneOf(tok::equal, tok::l_paren, tok::l_brace);
581 if (
Tok->isPointerOrReference())
582 Tok->setFinalizedType(TT_PointerOrReference);
585 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
586 PossibleObjCForInToken = CurrentToken;
587 PossibleObjCForInToken->setType(TT_ObjCForIn);
591 if (CurrentToken->is(tok::comma)) {
593 Contexts.back().InStaticAssertFirstArgument =
false;
595 Contexts.back().CanBeExpression =
true;
598 if (Style.isTableGen()) {
599 if (CurrentToken->is(tok::comma)) {
600 if (Contexts.back().IsTableGenCondOpe)
601 CurrentToken->setType(TT_TableGenCondOperatorComma);
603 }
else if (CurrentToken->is(tok::colon)) {
604 if (Contexts.back().IsTableGenCondOpe)
605 CurrentToken->setType(TT_TableGenCondOperatorColon);
609 if (!parseTableGenValue())
617 updateParameterCount(&OpeningParen,
Tok);
618 if (CurrentToken && CurrentToken->HasUnescapedNewline)
619 HasMultipleLines =
true;
625 if (!Style.isCSharp())
629 if (
Tok.Previous &&
Tok.Previous->is(tok::identifier))
633 if (
Tok.Previous &&
Tok.Previous->is(tok::r_square)) {
644 if (AttrTok->is(tok::r_square))
648 while (AttrTok && AttrTok->isNot(tok::r_square))
649 AttrTok = AttrTok->Next;
655 AttrTok = AttrTok->Next;
660 if (AttrTok->isAccessSpecifierKeyword() ||
661 AttrTok->isOneOf(tok::comment, tok::kw_class, tok::kw_static,
662 tok::l_square, Keywords.kw_internal)) {
668 AttrTok->Next->startsSequence(tok::identifier, tok::l_paren)) {
684 Left->ParentBracket = Contexts.back().ContextKind;
690 bool CppArrayTemplates =
691 IsCpp && Parent && Parent->is(TT_TemplateCloser) &&
692 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
693 Contexts.back().ContextType == Context::TemplateArgument);
695 const bool IsInnerSquare = Contexts.back().InCpp11AttributeSpecifier;
696 const bool IsCpp11AttributeSpecifier =
697 isCppAttribute(IsCpp, *Left) || IsInnerSquare;
700 bool IsCSharpAttributeSpecifier =
701 isCSharpAttributeSpecifier(*Left) ||
702 Contexts.back().InCSharpAttributeSpecifier;
704 bool InsideInlineASM = Line.startsWith(tok::kw_asm);
705 bool IsCppStructuredBinding =
Left->isCppStructuredBinding(IsCpp);
706 bool StartsObjCMethodExpr =
707 !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
708 IsCpp && !IsCpp11AttributeSpecifier && !IsCSharpAttributeSpecifier &&
709 Contexts.back().CanBeExpression &&
Left->isNot(TT_LambdaLSquare) &&
710 CurrentToken->isNoneOf(tok::l_brace, tok::r_square) &&
714 (!Parent || !Parent->is(tok::comma) ||
715 Contexts.back().ContextKind != tok::l_brace) &&
717 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
718 tok::kw_return, tok::kw_throw) ||
719 Parent->isUnaryOperator() ||
721 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
724 bool ColonFound =
false;
726 unsigned BindingIncrease = 1;
727 if (IsCppStructuredBinding) {
728 Left->setType(TT_StructuredBindingLSquare);
729 }
else if (
Left->is(TT_Unknown)) {
730 if (StartsObjCMethodExpr) {
731 Left->setType(TT_ObjCMethodExpr);
732 }
else if (InsideInlineASM) {
733 Left->setType(TT_InlineASMSymbolicNameLSquare);
734 }
else if (IsCpp11AttributeSpecifier) {
735 if (!IsInnerSquare) {
736 Left->setType(TT_AttributeLSquare);
738 Left->Previous->EndsCppAttributeGroup =
false;
740 }
else if (Style.isJavaScript() && Parent &&
741 Contexts.back().ContextKind == tok::l_brace &&
742 Parent->isOneOf(tok::l_brace, tok::comma)) {
743 Left->setType(TT_JsComputedPropertyName);
744 }
else if (IsCpp && Contexts.back().ContextKind == tok::l_brace &&
745 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
746 Left->setType(TT_DesignatedInitializerLSquare);
747 }
else if (IsCSharpAttributeSpecifier) {
748 Left->setType(TT_AttributeLSquare);
749 }
else if (CurrentToken->is(tok::r_square) && Parent &&
750 Parent->is(TT_TemplateCloser)) {
751 Left->setType(TT_ArraySubscriptLSquare);
752 }
else if (Style.isProto()) {
779 Left->setType(TT_ArrayInitializerLSquare);
780 if (!
Left->endsSequence(tok::l_square, tok::numeric_constant,
782 !
Left->endsSequence(tok::l_square, tok::numeric_constant,
784 !
Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
785 Left->setType(TT_ProtoExtensionLSquare);
786 BindingIncrease = 10;
788 }
else if (!CppArrayTemplates && Parent &&
789 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
790 tok::comma, tok::l_paren, tok::l_square,
791 tok::question, tok::colon, tok::kw_return,
794 Left->setType(TT_ArrayInitializerLSquare);
796 BindingIncrease = 10;
797 Left->setType(TT_ArraySubscriptLSquare);
801 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
802 Contexts.back().IsExpression =
true;
803 if (Style.isJavaScript() && Parent && Parent->is(TT_JsTypeColon))
804 Contexts.back().IsExpression =
false;
806 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
807 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
808 Contexts.back().InCSharpAttributeSpecifier = IsCSharpAttributeSpecifier;
810 while (CurrentToken) {
811 if (CurrentToken->is(tok::r_square)) {
812 if (IsCpp11AttributeSpecifier && !IsInnerSquare) {
813 CurrentToken->setType(TT_AttributeRSquare);
814 CurrentToken->EndsCppAttributeGroup =
true;
816 if (IsCSharpAttributeSpecifier) {
817 CurrentToken->setType(TT_AttributeRSquare);
818 }
else if (((CurrentToken->Next &&
819 CurrentToken->Next->is(tok::l_paren)) ||
820 (CurrentToken->Previous &&
821 CurrentToken->Previous->Previous == Left)) &&
822 Left->is(TT_ObjCMethodExpr)) {
827 StartsObjCMethodExpr =
false;
828 Left->setType(TT_Unknown);
830 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
831 CurrentToken->setType(TT_ObjCMethodExpr);
834 if (!ColonFound && CurrentToken->Previous &&
835 CurrentToken->Previous->is(TT_Unknown) &&
836 canBeObjCSelectorComponent(*CurrentToken->Previous)) {
837 CurrentToken->Previous->setType(TT_SelectorName);
842 if (Parent && Parent->is(TT_PointerOrReference))
843 Parent->overwriteFixedType(TT_BinaryOperator);
845 Left->MatchingParen = CurrentToken;
846 CurrentToken->MatchingParen =
Left;
851 if (!Contexts.back().FirstObjCSelectorName) {
854 Previous->ObjCSelectorNameParts = 1;
855 Contexts.back().FirstObjCSelectorName =
Previous;
858 Left->ParameterCount =
859 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
861 if (Contexts.back().FirstObjCSelectorName) {
862 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
863 Contexts.back().LongestObjCSelectorName;
864 if (
Left->BlockParameterCount > 1)
865 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
867 if (Style.isTableGen() &&
Left->is(TT_TableGenListOpener))
868 CurrentToken->setType(TT_TableGenListCloser);
872 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
874 if (CurrentToken->is(tok::colon)) {
875 if (IsCpp11AttributeSpecifier &&
876 CurrentToken->endsSequence(tok::colon, tok::identifier,
880 CurrentToken->setType(TT_AttributeColon);
881 }
else if (!Style.isVerilog() && !Line.InPragmaDirective &&
882 Left->isOneOf(TT_ArraySubscriptLSquare,
883 TT_DesignatedInitializerLSquare)) {
884 Left->setType(TT_ObjCMethodExpr);
885 StartsObjCMethodExpr =
true;
886 Contexts.back().ColonIsObjCMethodExpr =
true;
887 if (Parent && Parent->is(tok::r_paren)) {
889 Parent->setType(TT_CastRParen);
894 if (CurrentToken->is(tok::comma) &&
Left->is(TT_ObjCMethodExpr) &&
896 Left->setType(TT_ArrayInitializerLSquare);
899 if (Style.isTableGen()) {
900 if (CurrentToken->isOneOf(tok::comma, tok::minus, tok::ellipsis)) {
906 if (!parseTableGenValue())
909 updateParameterCount(Left,
Tok);
914 updateParameterCount(Left,
Tok);
919 void skipToNextNonComment() {
921 while (CurrentToken && CurrentToken->is(tok::comment))
930 bool parseTableGenValue(
bool ParseNameMode =
false) {
933 while (CurrentToken->is(tok::comment))
935 if (!parseTableGenSimpleValue())
940 if (CurrentToken->is(tok::hash)) {
941 if (CurrentToken->Next &&
942 CurrentToken->Next->isOneOf(tok::colon, tok::semi, tok::l_brace)) {
945 CurrentToken->setType(TT_TableGenTrailingPasteOperator);
950 skipToNextNonComment();
951 HashTok->setType(TT_Unknown);
952 if (!parseTableGenValue(ParseNameMode))
959 if (ParseNameMode && CurrentToken->is(tok::l_brace))
962 if (CurrentToken->isOneOf(tok::l_brace, tok::l_square, tok::period)) {
963 CurrentToken->setType(TT_TableGenValueSuffix);
965 skipToNextNonComment();
966 if (Suffix->is(tok::l_square))
967 return parseSquare();
968 if (Suffix->is(tok::l_brace)) {
969 Scopes.push_back(getScopeType(*Suffix));
979 bool tryToParseTableGenTokVar() {
982 if (CurrentToken->is(tok::identifier) &&
983 CurrentToken->TokenText.front() ==
'$') {
984 skipToNextNonComment();
992 bool parseTableGenDAGArg(
bool AlignColon =
false) {
993 if (tryToParseTableGenTokVar())
995 if (parseTableGenValue()) {
996 if (CurrentToken && CurrentToken->is(tok::colon)) {
998 CurrentToken->setType(TT_TableGenDAGArgListColonToAlign);
1000 CurrentToken->setType(TT_TableGenDAGArgListColon);
1001 skipToNextNonComment();
1002 return tryToParseTableGenTokVar();
1013 auto &Opes = Style.TableGenBreakingDAGArgOperators;
1018 if (
Tok.isNot(tok::identifier) ||
1019 Tok.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
1023 if (!
Tok.Next ||
Tok.Next->is(tok::colon))
1025 return llvm::is_contained(Opes,
Tok.TokenText.str());
1030 bool parseTableGenDAGArgAndList(
FormatToken *Opener) {
1032 if (!parseTableGenDAGArg())
1034 bool BreakInside =
false;
1035 if (Style.TableGenBreakInsideDAGArg != FormatStyle::DAS_DontBreak) {
1038 if (isTableGenDAGArgBreakingOperator(*FirstTok)) {
1041 Opener->setType(TT_TableGenDAGArgOpenerToBreak);
1042 if (FirstTok->isOneOf(TT_TableGenBangOperator,
1043 TT_TableGenCondOperator)) {
1046 CurrentToken->Previous->setType(TT_TableGenDAGArgOperatorToBreak);
1047 }
else if (FirstTok->is(tok::identifier)) {
1048 if (Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll)
1049 FirstTok->setType(TT_TableGenDAGArgOperatorToBreak);
1051 FirstTok->setType(TT_TableGenDAGArgOperatorID);
1056 return parseTableGenDAGArgList(Opener, BreakInside);
1061 bool parseTableGenDAGArgList(
FormatToken *Opener,
bool BreakInside) {
1062 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 0);
1063 Contexts.back().IsTableGenDAGArgList =
true;
1064 bool FirstDAGArgListElm =
true;
1065 while (CurrentToken) {
1066 if (!FirstDAGArgListElm && CurrentToken->is(tok::comma)) {
1067 CurrentToken->setType(BreakInside ? TT_TableGenDAGArgListCommaToBreak
1068 : TT_TableGenDAGArgListComma);
1069 skipToNextNonComment();
1071 if (CurrentToken && CurrentToken->is(tok::r_paren)) {
1072 CurrentToken->setType(TT_TableGenDAGArgCloser);
1073 Opener->MatchingParen = CurrentToken;
1074 CurrentToken->MatchingParen = Opener;
1075 skipToNextNonComment();
1078 if (!parseTableGenDAGArg(
1080 Style.AlignConsecutiveTableGenBreakingDAGArgColons.Enabled)) {
1083 FirstDAGArgListElm =
false;
1088 bool parseTableGenSimpleValue() {
1089 assert(Style.isTableGen());
1093 skipToNextNonComment();
1095 if (
Tok->isOneOf(tok::numeric_constant, tok::string_literal,
1096 TT_TableGenMultiLineString, tok::kw_true, tok::kw_false,
1097 tok::question, tok::kw_int)) {
1101 if (
Tok->is(tok::l_brace)) {
1102 Scopes.push_back(getScopeType(*
Tok));
1103 return parseBrace();
1106 if (
Tok->is(tok::l_square)) {
1107 Tok->setType(TT_TableGenListOpener);
1110 if (
Tok->is(tok::less)) {
1111 CurrentToken->setType(TT_TemplateOpener);
1112 return parseAngle();
1118 if (
Tok->is(tok::l_paren)) {
1119 Tok->setType(TT_TableGenDAGArgOpener);
1121 if (Contexts.back().IsTableGenDAGArgList)
1122 Tok->SpacesRequiredBefore = 1;
1123 return parseTableGenDAGArgAndList(
Tok);
1126 if (
Tok->is(TT_TableGenBangOperator)) {
1127 if (CurrentToken && CurrentToken->is(tok::less)) {
1128 CurrentToken->setType(TT_TemplateOpener);
1129 skipToNextNonComment();
1133 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1137 Contexts.back().IsTableGenBangOpe =
true;
1138 bool Result = parseParens();
1139 Contexts.back().IsTableGenBangOpe =
false;
1143 if (
Tok->is(TT_TableGenCondOperator)) {
1144 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1147 return parseParens();
1152 if (
Tok->is(tok::identifier)) {
1154 if (CurrentToken && CurrentToken->is(tok::less)) {
1155 CurrentToken->setType(TT_TemplateOpener);
1156 skipToNextNonComment();
1157 return parseAngle();
1165 bool couldBeInStructArrayInitializer()
const {
1166 if (Contexts.size() < 2)
1170 const auto End = std::next(Contexts.rbegin(), 2);
1171 auto Last = Contexts.rbegin();
1174 if (
Last->ContextKind == tok::l_brace)
1176 return Depth == 2 &&
Last->ContextKind != tok::l_brace;
1183 assert(CurrentToken->Previous);
1184 FormatToken &OpeningBrace = *CurrentToken->Previous;
1185 assert(OpeningBrace.is(tok::l_brace));
1186 OpeningBrace.ParentBracket = Contexts.back().ContextKind;
1188 if (Contexts.back().CaretFound)
1189 OpeningBrace.overwriteFixedType(TT_ObjCBlockLBrace);
1190 Contexts.back().CaretFound =
false;
1192 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
1193 Contexts.back().ColonIsDictLiteral =
true;
1195 Contexts.back().IsExpression =
true;
1196 if (Style.isJavaScript() && OpeningBrace.Previous &&
1197 OpeningBrace.Previous->is(TT_JsTypeColon)) {
1198 Contexts.back().IsExpression =
false;
1200 if (Style.isVerilog() &&
1201 (!OpeningBrace.getPreviousNonComment() ||
1202 OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
1203 Contexts.back().VerilogMayBeConcatenation =
true;
1205 if (Style.isTableGen())
1206 Contexts.back().ColonIsDictLiteral =
false;
1208 unsigned CommaCount = 0;
1209 while (CurrentToken) {
1210 if (CurrentToken->is(tok::r_brace)) {
1211 assert(!Scopes.empty());
1212 assert(Scopes.back() == getScopeType(OpeningBrace));
1214 assert(OpeningBrace.Optional == CurrentToken->Optional);
1215 OpeningBrace.MatchingParen = CurrentToken;
1216 CurrentToken->MatchingParen = &OpeningBrace;
1217 if (Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {
1218 if (OpeningBrace.ParentBracket == tok::l_brace &&
1219 couldBeInStructArrayInitializer() && CommaCount > 0) {
1220 Contexts.back().ContextType = Context::StructArrayInitializer;
1226 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
1228 updateParameterCount(&OpeningBrace, CurrentToken);
1229 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
1231 if (
Previous->is(TT_JsTypeOptionalQuestion))
1233 if ((CurrentToken->is(tok::colon) && !Style.isTableGen() &&
1234 (!Contexts.back().ColonIsDictLiteral || !IsCpp)) ||
1236 OpeningBrace.setType(TT_DictLiteral);
1237 if (
Previous->Tok.getIdentifierInfo() ||
1238 Previous->is(tok::string_literal)) {
1239 Previous->setType(TT_SelectorName);
1242 if (CurrentToken->is(tok::colon) && OpeningBrace.is(TT_Unknown) &&
1243 !Style.isTableGen()) {
1244 OpeningBrace.setType(TT_DictLiteral);
1245 }
else if (Style.isJavaScript()) {
1246 OpeningBrace.overwriteFixedType(TT_DictLiteral);
1249 if (CurrentToken->is(tok::comma)) {
1250 if (Style.isJavaScript())
1251 OpeningBrace.overwriteFixedType(TT_DictLiteral);
1254 if (!consumeToken())
1264 if (Current->is(tok::l_brace) && Current->is(
BK_Block))
1265 ++
Left->BlockParameterCount;
1266 if (Current->is(tok::comma)) {
1267 ++
Left->ParameterCount;
1269 Left->Role.reset(
new CommaSeparatedList(Style));
1270 Left->Role->CommaFound(Current);
1271 }
else if (
Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
1272 Left->ParameterCount = 1;
1276 bool parseConditional() {
1277 while (CurrentToken) {
1278 if (CurrentToken->is(tok::colon) && CurrentToken->is(TT_Unknown)) {
1279 CurrentToken->setType(TT_ConditionalExpr);
1283 if (!consumeToken())
1289 bool parseTemplateDeclaration() {
1290 if (!CurrentToken || CurrentToken->isNot(tok::less))
1293 CurrentToken->setType(TT_TemplateOpener);
1296 TemplateDeclarationDepth++;
1297 const bool WellFormed = parseAngle();
1298 TemplateDeclarationDepth--;
1302 if (CurrentToken && TemplateDeclarationDepth == 0)
1303 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
1308 bool consumeToken() {
1310 const auto *Prev = CurrentToken->getPreviousNonComment();
1311 if (Prev && Prev->is(TT_AttributeRSquare) &&
1312 CurrentToken->isOneOf(tok::kw_if, tok::kw_switch, tok::kw_case,
1313 tok::kw_default, tok::kw_for, tok::kw_while) &&
1315 CurrentToken->MustBreakBefore =
true;
1322 if (
Tok->is(TT_VerilogTableItem))
1325 if (
Tok->is(TT_TableGenMultiLineString))
1327 auto *Prev =
Tok->getPreviousNonComment();
1328 auto *
Next =
Tok->getNextNonComment();
1329 switch (
bool IsIf =
false;
Tok->Tok.getKind()) {
1332 if (!Prev && Line.MustBeDeclaration)
1333 Tok->setType(TT_ObjCMethodSpecifier);
1340 if (
Tok->isTypeFinalized())
1343 if (Style.isJavaScript()) {
1344 if (Contexts.back().ColonIsForRangeExpr ||
1345 (Contexts.size() == 1 &&
1346 Line.First->isNoneOf(tok::kw_enum, tok::kw_case)) ||
1347 Contexts.back().ContextKind == tok::l_paren ||
1348 Contexts.back().ContextKind == tok::l_square ||
1349 (!Contexts.back().IsExpression &&
1350 Contexts.back().ContextKind == tok::l_brace) ||
1351 (Contexts.size() == 1 &&
1352 Line.MustBeDeclaration)) {
1353 Contexts.back().IsExpression =
false;
1354 Tok->setType(TT_JsTypeColon);
1357 }
else if (Style.isCSharp()) {
1358 if (Contexts.back().InCSharpAttributeSpecifier) {
1359 Tok->setType(TT_AttributeColon);
1362 if (Contexts.back().ContextKind == tok::l_paren) {
1363 Tok->setType(TT_CSharpNamedArgumentColon);
1366 }
else if (Style.isVerilog() &&
Tok->isNot(TT_BinaryOperator)) {
1369 if (Keywords.isVerilogEnd(*Prev) || Keywords.isVerilogBegin(*Prev)) {
1370 Tok->setType(TT_VerilogBlockLabelColon);
1371 }
else if (Contexts.back().ContextKind == tok::l_square) {
1372 Tok->setType(TT_BitFieldColon);
1373 }
else if (Contexts.back().ColonIsDictLiteral) {
1374 Tok->setType(TT_DictLiteral);
1375 }
else if (Contexts.size() == 1) {
1379 Tok->setType(TT_CaseLabelColon);
1380 if (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))
1385 if (Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) ||
1386 Line.First->startsSequence(tok::kw_export, Keywords.kw_module) ||
1387 Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) {
1388 Tok->setType(TT_ModulePartitionColon);
1389 }
else if (Line.First->is(tok::kw_asm)) {
1390 Tok->setType(TT_InlineASMColon);
1391 }
else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) {
1392 Tok->setType(TT_DictLiteral);
1393 if (Style.isTextProto())
1394 Prev->setType(TT_SelectorName);
1395 }
else if (Contexts.back().ColonIsObjCMethodExpr ||
1396 Line.startsWith(TT_ObjCMethodSpecifier)) {
1397 Tok->setType(TT_ObjCMethodExpr);
1398 const auto *PrevPrev = Prev->Previous;
1401 bool UnknownIdentifierInMethodDeclaration =
1402 Line.startsWith(TT_ObjCMethodSpecifier) &&
1403 Prev->is(tok::identifier) && Prev->is(TT_Unknown);
1406 !(PrevPrev->is(TT_CastRParen) ||
1407 (PrevPrev->is(TT_ObjCMethodExpr) && PrevPrev->is(tok::colon))) ||
1408 PrevPrev->is(tok::r_square) ||
1409 Contexts.back().LongestObjCSelectorName == 0 ||
1410 UnknownIdentifierInMethodDeclaration) {
1411 Prev->setType(TT_SelectorName);
1412 if (!Contexts.back().FirstObjCSelectorName)
1413 Contexts.back().FirstObjCSelectorName = Prev;
1414 else if (Prev->ColumnWidth > Contexts.back().LongestObjCSelectorName)
1415 Contexts.back().LongestObjCSelectorName = Prev->ColumnWidth;
1416 Prev->ParameterIndex =
1417 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
1418 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
1420 }
else if (Contexts.back().ColonIsForRangeExpr) {
1421 Tok->setType(TT_RangeBasedForLoopColon);
1422 for (
auto *Token = Prev;
1423 Token && Token->isNoneOf(tok::semi, tok::l_paren);
1424 Token = Token->Previous) {
1425 if (Token->isPointerOrReference())
1426 Token->setFinalizedType(TT_PointerOrReference);
1428 }
else if (Contexts.back().ContextType == Context::C11GenericSelection) {
1429 Tok->setType(TT_GenericSelectionColon);
1430 if (Prev->isPointerOrReference())
1431 Prev->setFinalizedType(TT_PointerOrReference);
1432 }
else if ((CurrentToken && CurrentToken->is(tok::numeric_constant)) ||
1433 (Prev->is(TT_StartOfName) && !Scopes.empty() &&
1435 Tok->setType(TT_BitFieldColon);
1436 }
else if (Contexts.size() == 1 &&
1437 Line.getFirstNonComment()->isNoneOf(tok::kw_enum, tok::kw_case,
1439 !Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
1440 if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept) ||
1441 Prev->ClosesRequiresClause) {
1442 Tok->setType(TT_CtorInitializerColon);
1443 }
else if (Prev->is(tok::kw_try)) {
1445 FormatToken *PrevPrev = Prev->getPreviousNonComment();
1448 if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept))
1449 Tok->setType(TT_CtorInitializerColon);
1451 Tok->setType(TT_InheritanceColon);
1452 if (Prev->isAccessSpecifierKeyword())
1455 }
else if (canBeObjCSelectorComponent(*Prev) &&
Next &&
1456 (
Next->isOneOf(tok::r_paren, tok::comma) ||
1457 (canBeObjCSelectorComponent(*
Next) &&
Next->Next &&
1458 Next->Next->is(tok::colon)))) {
1461 Tok->setType(TT_ObjCSelector);
1468 if (Style.isJavaScript() && !Contexts.back().IsExpression)
1469 Tok->setType(TT_JsTypeOperator);
1472 if (Style.isTableGen()) {
1474 if (!parseTableGenValue())
1476 if (CurrentToken && CurrentToken->is(Keywords.kw_then))
1481 CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier)) {
1487 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
1489 if (!parseParens(IsIf))
1494 if (Style.isJavaScript()) {
1496 if ((Prev && Prev->is(tok::period)) || (
Next &&
Next->is(tok::colon)))
1499 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
1502 if (IsCpp && CurrentToken && CurrentToken->is(tok::kw_co_await))
1504 Contexts.back().ColonIsForRangeExpr =
true;
1505 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1516 if (Prev && Prev->is(tok::r_paren) && Prev->MatchingParen &&
1517 Prev->MatchingParen->is(TT_OverloadedOperatorLParen)) {
1518 Prev->setType(TT_OverloadedOperator);
1519 Prev->MatchingParen->setType(TT_OverloadedOperator);
1520 Tok->setType(TT_OverloadedOperatorLParen);
1523 if (Style.isVerilog()) {
1529 auto IsInstancePort = [&]() {
1538 if (!Prev || !(PrevPrev = Prev->getPreviousNonComment()))
1541 if (Keywords.isVerilogIdentifier(*Prev) &&
1542 Keywords.isVerilogIdentifier(*PrevPrev)) {
1546 if (Prev->is(Keywords.kw_verilogHash) &&
1547 Keywords.isVerilogIdentifier(*PrevPrev)) {
1551 if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::r_paren))
1554 if (Keywords.isVerilogIdentifier(*Prev) && PrevPrev->is(tok::comma)) {
1555 const FormatToken *PrevParen = PrevPrev->getPreviousNonComment();
1556 if (PrevParen && PrevParen->is(tok::r_paren) &&
1557 PrevParen->MatchingParen &&
1558 PrevParen->MatchingParen->is(TT_VerilogInstancePortLParen)) {
1565 if (IsInstancePort())
1566 Tok->setType(TT_VerilogInstancePortLParen);
1571 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
1572 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
1573 !Line.startsWith(tok::l_paren) &&
1574 Tok->isNoneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) {
1576 (!Prev->isAttribute() &&
1577 Prev->isNoneOf(TT_RequiresClause, TT_LeadingJavaAnnotation,
1578 TT_BinaryOperator))) {
1579 Line.MightBeFunctionDecl =
true;
1580 Tok->MightBeFunctionDeclParen =
true;
1585 if (Style.isTableGen())
1586 Tok->setType(TT_TableGenListOpener);
1592 if (
Tok->is(TT_RequiresExpressionLBrace))
1594 }
else if (Style.isTextProto()) {
1595 if (Prev && Prev->isNot(TT_DictLiteral))
1596 Prev->setType(TT_SelectorName);
1598 Scopes.push_back(getScopeType(*
Tok));
1604 Tok->setType(TT_TemplateOpener);
1610 if (Style.isTextProto() ||
1611 (Style.Language == FormatStyle::LK_Proto && Prev &&
1612 Prev->isOneOf(TT_SelectorName, TT_DictLiteral))) {
1613 Tok->setType(TT_DictLiteral);
1614 if (Prev && Prev->isNot(TT_DictLiteral))
1615 Prev->setType(TT_SelectorName);
1617 if (Style.isTableGen())
1618 Tok->setType(TT_TemplateOpener);
1620 Tok->setType(TT_BinaryOperator);
1621 NonTemplateLess.insert(
Tok);
1631 if (!Scopes.empty())
1638 if (!Style.isTextProto() &&
Tok->is(TT_Unknown))
1639 Tok->setType(TT_BinaryOperator);
1640 if (Prev && Prev->is(TT_TemplateCloser))
1641 Tok->SpacesRequiredBefore = 1;
1643 case tok::kw_operator:
1644 if (Style.isProto())
1647 if (IsCpp && CurrentToken) {
1648 const auto *Info = CurrentToken->Tok.getIdentifierInfo();
1650 if (Info && !(CurrentToken->isPlacementOperator() ||
1651 CurrentToken->is(tok::kw_co_await) ||
1652 Info->isCPlusPlusOperatorKeyword())) {
1654 if (CurrentToken->startsSequence(tok::kw_decltype, tok::l_paren,
1655 tok::kw_auto, tok::r_paren)) {
1657 LParen = CurrentToken->Next->Next->Next->Next;
1660 for (LParen = CurrentToken->Next;
1661 LParen && LParen->isNot(tok::l_paren); LParen = LParen->Next) {
1662 if (LParen->isPointerOrReference())
1663 LParen->setFinalizedType(TT_PointerOrReference);
1666 if (LParen && LParen->is(tok::l_paren)) {
1667 if (!Contexts.back().IsExpression) {
1668 Tok->setFinalizedType(TT_FunctionDeclarationName);
1669 LParen->setFinalizedType(TT_FunctionDeclarationLParen);
1675 while (CurrentToken &&
1676 CurrentToken->isNoneOf(tok::l_paren, tok::semi, tok::r_paren)) {
1677 if (CurrentToken->isOneOf(tok::star, tok::amp))
1678 CurrentToken->setType(TT_PointerOrReference);
1679 auto Next = CurrentToken->getNextNonComment();
1682 if (
Next->is(tok::less))
1688 auto Previous = CurrentToken->getPreviousNonComment();
1690 if (CurrentToken->is(tok::comma) &&
Previous->isNot(tok::kw_operator))
1692 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, tok::comma,
1694 Previous->isPointerOrReference() ||
1696 Previous->TokenText.starts_with(
"\"\"")) {
1697 Previous->setType(TT_OverloadedOperator);
1698 if (CurrentToken->isOneOf(tok::less, tok::greater))
1702 if (CurrentToken && CurrentToken->is(tok::l_paren))
1703 CurrentToken->setType(TT_OverloadedOperatorLParen);
1704 if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator))
1705 CurrentToken->Previous->setType(TT_OverloadedOperator);
1708 if (Style.isJavaScript() &&
Next &&
1709 Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
1710 tok::r_brace, tok::r_square)) {
1715 Tok->setType(TT_JsTypeOptionalQuestion);
1720 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
1721 Style.isJavaScript()) {
1724 if (Style.isCSharp()) {
1727 if (
Next && (
Next->isOneOf(tok::r_paren, tok::greater) ||
1728 Next->startsSequence(tok::identifier, tok::semi) ||
1729 Next->startsSequence(tok::identifier, tok::equal))) {
1730 Tok->setType(TT_CSharpNullable);
1739 if (!Contexts.back().IsExpression && Line.MustBeDeclaration &&
1740 (!
Next ||
Next->isNoneOf(tok::identifier, tok::string_literal) ||
1741 !
Next->Next ||
Next->Next->isNoneOf(tok::colon, tok::question))) {
1742 Tok->setType(TT_CSharpNullable);
1748 case tok::kw_template:
1749 parseTemplateDeclaration();
1752 switch (Contexts.back().ContextType) {
1753 case Context::CtorInitializer:
1754 Tok->setType(TT_CtorInitializerComma);
1756 case Context::InheritanceList:
1757 Tok->setType(TT_InheritanceComma);
1759 case Context::VerilogInstancePortList:
1760 Tok->setType(TT_VerilogInstancePortComma);
1763 if (Style.isVerilog() && Contexts.size() == 1 &&
1764 Line.startsWith(Keywords.kw_assign)) {
1765 Tok->setFinalizedType(TT_VerilogAssignComma);
1766 }
else if (Contexts.back().FirstStartOfName &&
1767 (Contexts.size() == 1 || startsWithInitStatement(Line))) {
1768 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
1769 Line.IsMultiVariableDeclStmt =
true;
1773 if (Contexts.back().ContextType == Context::ForEachMacro)
1774 Contexts.back().IsExpression =
true;
1776 case tok::kw_default:
1778 if (Style.isVerilog() && Keywords.isVerilogEndOfLabel(*
Tok) &&
1779 (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))) {
1783 case tok::identifier:
1784 if (
Tok->isOneOf(Keywords.kw___has_include,
1785 Keywords.kw___has_include_next)) {
1789 if (
Next &&
Next->is(tok::l_paren) && Prev &&
1790 Prev->isOneOf(tok::kw___cdecl, tok::kw___stdcall,
1791 tok::kw___fastcall, tok::kw___thiscall,
1792 tok::kw___regcall, tok::kw___vectorcall)) {
1793 Tok->setFinalizedType(TT_FunctionDeclarationName);
1794 Next->setFinalizedType(TT_FunctionDeclarationLParen);
1796 }
else if (Style.isCSharp()) {
1797 if (
Tok->is(Keywords.kw_where) &&
Next &&
Next->isNot(tok::l_paren)) {
1798 Tok->setType(TT_CSharpGenericTypeConstraint);
1799 parseCSharpGenericTypeConstraint();
1801 Line.IsContinuation =
true;
1803 }
else if (Style.isTableGen()) {
1804 if (
Tok->is(Keywords.kw_assert)) {
1805 if (!parseTableGenValue())
1807 }
else if (
Tok->isOneOf(Keywords.kw_def, Keywords.kw_defm) &&
1808 (!
Next ||
Next->isNoneOf(tok::colon, tok::l_brace))) {
1810 if (!parseTableGenValue(
true))
1814 if (Style.AllowBreakBeforeQtProperty &&
1815 Contexts.back().ContextType == Context::QtProperty &&
1816 Tok->isQtProperty()) {
1817 Tok->setFinalizedType(TT_QtProperty);
1821 if (
Tok->isNot(TT_LambdaArrow) && Prev && Prev->is(tok::kw_noexcept))
1822 Tok->setType(TT_TrailingReturnArrow);
1826 if (Style.isTableGen() && !parseTableGenValue())
1835 void parseCSharpGenericTypeConstraint() {
1836 int OpenAngleBracketsCount = 0;
1837 while (CurrentToken) {
1838 if (CurrentToken->is(tok::less)) {
1840 CurrentToken->setType(TT_TemplateOpener);
1841 ++OpenAngleBracketsCount;
1843 }
else if (CurrentToken->is(tok::greater)) {
1844 CurrentToken->setType(TT_TemplateCloser);
1845 --OpenAngleBracketsCount;
1847 }
else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) {
1850 CurrentToken->setType(TT_CSharpGenericTypeConstraintComma);
1852 }
else if (CurrentToken->is(Keywords.kw_where)) {
1853 CurrentToken->setType(TT_CSharpGenericTypeConstraint);
1855 }
else if (CurrentToken->is(tok::colon)) {
1856 CurrentToken->setType(TT_CSharpGenericTypeConstraintColon);
1864 void parseIncludeDirective() {
1865 if (CurrentToken && CurrentToken->is(tok::less)) {
1867 while (CurrentToken) {
1870 if (CurrentToken->isNot(tok::comment) &&
1871 !CurrentToken->TokenText.starts_with(
"//")) {
1872 CurrentToken->setType(TT_ImplicitStringLiteral);
1879 void parseWarningOrError() {
1884 while (CurrentToken) {
1885 CurrentToken->setType(TT_ImplicitStringLiteral);
1890 void parsePragma() {
1893 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option,
1894 Keywords.kw_region)) {
1895 bool IsMarkOrRegion =
1896 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_region);
1899 while (CurrentToken) {
1900 if (IsMarkOrRegion || CurrentToken->Previous->is(TT_BinaryOperator))
1901 CurrentToken->setType(TT_ImplicitStringLiteral);
1907 void parseHasInclude() {
1908 if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
1911 parseIncludeDirective();
1915 LineType parsePreprocessorDirective() {
1916 bool IsFirstToken = CurrentToken->IsFirst;
1922 if (Style.isJavaScript() && IsFirstToken) {
1926 while (CurrentToken) {
1928 CurrentToken->setType(TT_ImplicitStringLiteral);
1934 if (CurrentToken->is(tok::numeric_constant)) {
1935 CurrentToken->SpacesRequiredBefore = 1;
1940 if (!CurrentToken->Tok.getIdentifierInfo())
1944 if (Style.isVerilog() && !Keywords.isVerilogPPDirective(*CurrentToken))
1946 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1947 case tok::pp_include:
1948 case tok::pp_include_next:
1949 case tok::pp_import:
1951 parseIncludeDirective();
1955 case tok::pp_warning:
1956 parseWarningOrError();
1958 case tok::pp_pragma:
1963 Contexts.back().IsExpression =
true;
1966 CurrentToken->SpacesRequiredBefore = 1;
1972 while (CurrentToken) {
1975 if (
Tok->is(tok::l_paren)) {
1977 }
else if (
Tok->isOneOf(Keywords.kw___has_include,
1978 Keywords.kw___has_include_next)) {
1989 NonTemplateLess.clear();
1990 if (!Line.InMacroBody && CurrentToken->is(tok::hash)) {
1994 auto Type = parsePreprocessorDirective();
2002 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
2003 if ((Style.isJava() && CurrentToken->is(Keywords.kw_package)) ||
2004 (!Style.isVerilog() && Info &&
2005 Info->getPPKeywordID() == tok::pp_import && CurrentToken->Next &&
2006 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
2009 parseIncludeDirective();
2015 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
2016 parseIncludeDirective();
2022 if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 &&
2023 CurrentToken->isOneOf(Keywords.kw_option, Keywords.kw_package)) {
2025 if (CurrentToken && CurrentToken->is(tok::identifier)) {
2026 while (CurrentToken)
2032 bool KeywordVirtualFound =
false;
2033 bool ImportStatement =
false;
2036 if (Style.isJavaScript() && CurrentToken->is(Keywords.kw_import))
2037 ImportStatement =
true;
2039 while (CurrentToken) {
2040 if (CurrentToken->is(tok::kw_virtual))
2041 KeywordVirtualFound =
true;
2042 if (Style.isJavaScript()) {
2049 if (Line.First->is(tok::kw_export) &&
2050 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
2051 CurrentToken->Next->isStringLiteral()) {
2052 ImportStatement =
true;
2054 if (isClosureImportStatement(*CurrentToken))
2055 ImportStatement =
true;
2057 if (!consumeToken())
2065 if (KeywordVirtualFound)
2067 if (ImportStatement)
2070 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
2071 if (Contexts.back().FirstObjCSelectorName) {
2072 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
2073 Contexts.back().LongestObjCSelectorName;
2078 for (
const auto &ctx : Contexts)
2079 if (ctx.ContextType == Context::StructArrayInitializer)
2089 return Tok.TokenText ==
"goog" &&
Tok.Next &&
Tok.Next->is(tok::period) &&
2091 (
Tok.Next->Next->TokenText ==
"module" ||
2092 Tok.Next->Next->TokenText ==
"provide" ||
2093 Tok.Next->Next->TokenText ==
"require" ||
2094 Tok.Next->Next->TokenText ==
"requireType" ||
2095 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
2096 Tok.Next->Next->Next &&
Tok.Next->Next->Next->is(tok::l_paren);
2099 void resetTokenMetadata() {
2105 if (!CurrentToken->isTypeFinalized() &&
2106 CurrentToken->isNoneOf(
2107 TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
2108 TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
2109 TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
2110 TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
2111 TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
2112 TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro,
2113 TT_FunctionLikeOrFreestandingMacro, TT_ClassLBrace, TT_EnumLBrace,
2114 TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,
2115 TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
2116 TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
2117 TT_CompoundRequirementLBrace, TT_BracedListLBrace,
2118 TT_FunctionLikeMacro)) {
2119 CurrentToken->setType(TT_Unknown);
2121 CurrentToken->Role.reset();
2122 CurrentToken->MatchingParen =
nullptr;
2123 CurrentToken->FakeLParens.clear();
2124 CurrentToken->FakeRParens = 0;
2131 CurrentToken->NestingLevel = Contexts.size() - 1;
2132 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
2133 modifyContext(*CurrentToken);
2134 determineTokenType(*CurrentToken);
2135 CurrentToken = CurrentToken->Next;
2137 resetTokenMetadata();
2145 : ContextKind(ContextKind), BindingStrength(BindingStrength),
2146 IsExpression(IsExpression) {}
2149 unsigned BindingStrength;
2151 unsigned LongestObjCSelectorName = 0;
2152 bool ColonIsForRangeExpr =
false;
2153 bool ColonIsDictLiteral =
false;
2154 bool ColonIsObjCMethodExpr =
false;
2157 bool CanBeExpression =
true;
2158 bool CaretFound =
false;
2159 bool InCpp11AttributeSpecifier =
false;
2160 bool InCSharpAttributeSpecifier =
false;
2161 bool InStaticAssertFirstArgument =
false;
2162 bool VerilogAssignmentFound =
false;
2165 bool VerilogMayBeConcatenation =
false;
2166 bool IsTableGenDAGArgList =
false;
2167 bool IsTableGenBangOpe =
false;
2168 bool IsTableGenCondOpe =
false;
2181 StructArrayInitializer,
2185 C11GenericSelection,
2188 VerilogInstancePortList,
2189 } ContextType = Unknown;
2194 struct ScopedContextCreator {
2195 AnnotatingParser &P;
2197 ScopedContextCreator(AnnotatingParser &P,
tok::TokenKind ContextKind,
2200 P.Contexts.push_back(Context(ContextKind,
2201 P.Contexts.back().BindingStrength + Increase,
2202 P.Contexts.back().IsExpression));
2205 ~ScopedContextCreator() {
2206 if (P.Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {
2207 if (P.Contexts.back().ContextType == Context::StructArrayInitializer) {
2208 P.Contexts.pop_back();
2209 P.Contexts.back().ContextType = Context::StructArrayInitializer;
2213 P.Contexts.pop_back();
2218 auto AssignmentStartsExpression = [&]() {
2222 if (Line.First->isOneOf(tok::kw_using, tok::kw_return))
2224 if (Line.First->is(tok::kw_template)) {
2225 assert(Current.Previous);
2226 if (Current.Previous->is(tok::kw_operator)) {
2234 if (
Tok->isNot(TT_TemplateOpener)) {
2241 if (Contexts.back().ContextKind == tok::less) {
2242 assert(Current.Previous->Previous);
2243 return Current.Previous->Previous->isNoneOf(tok::kw_typename,
2247 Tok =
Tok->MatchingParen;
2250 Tok =
Tok->getNextNonComment();
2254 if (
Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_struct,
2264 if (Style.isJavaScript() &&
2265 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
2266 Line.startsWith(tok::kw_export, Keywords.kw_type,
2267 tok::identifier))) {
2271 return !Current.Previous || Current.Previous->isNot(tok::kw_operator);
2274 if (AssignmentStartsExpression()) {
2275 Contexts.back().IsExpression =
true;
2276 if (!Line.startsWith(TT_UnaryOperator)) {
2279 Previous->Previous->isNoneOf(tok::comma, tok::semi);
2281 if (
Previous->isOneOf(tok::r_square, tok::r_paren, tok::greater)) {
2288 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
2290 Previous->Previous->isNot(tok::equal)) {
2291 Previous->setType(TT_PointerOrReference);
2295 }
else if (Current.is(tok::lessless) &&
2296 (!Current.Previous ||
2297 Current.Previous->isNot(tok::kw_operator))) {
2298 Contexts.back().IsExpression =
true;
2299 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
2300 Contexts.back().IsExpression =
true;
2301 }
else if (Current.is(TT_TrailingReturnArrow)) {
2302 Contexts.back().IsExpression =
false;
2303 }
else if (Current.isOneOf(TT_LambdaArrow, Keywords.kw_assert)) {
2304 Contexts.back().IsExpression = Style.isJava();
2305 }
else if (Current.Previous &&
2306 Current.Previous->is(TT_CtorInitializerColon)) {
2307 Contexts.back().IsExpression =
true;
2308 Contexts.back().ContextType = Context::CtorInitializer;
2309 }
else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
2310 Contexts.back().ContextType = Context::InheritanceList;
2311 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
2315 Previous->setType(TT_PointerOrReference);
2317 if (Line.MustBeDeclaration &&
2318 Contexts.front().ContextType != Context::CtorInitializer) {
2319 Contexts.back().IsExpression =
false;
2321 }
else if (Current.is(tok::kw_new)) {
2322 Contexts.back().CanBeExpression =
false;
2323 }
else if (Current.is(tok::semi) ||
2324 (Current.is(tok::exclaim) && Current.Previous &&
2325 Current.Previous->isNot(tok::kw_operator))) {
2329 Contexts.back().IsExpression =
true;
2337 if (Current->is(tok::l_paren))
2339 if (Current->is(tok::r_paren))
2343 Current = Current->Next;
2348 static bool isDeductionGuide(
FormatToken &Current) {
2350 if (Current.Previous && Current.Previous->is(tok::r_paren) &&
2351 Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
2355 while (TemplateCloser) {
2357 if (TemplateCloser->is(tok::l_paren)) {
2359 TemplateCloser = untilMatchingParen(TemplateCloser);
2360 if (!TemplateCloser)
2363 if (TemplateCloser->is(tok::less))
2365 if (TemplateCloser->is(tok::greater))
2369 TemplateCloser = TemplateCloser->Next;
2373 if (TemplateCloser && TemplateCloser->Next &&
2374 TemplateCloser->Next->is(tok::semi) &&
2375 Current.Previous->MatchingParen) {
2379 Current.Previous->MatchingParen->Previous;
2381 return LeadingIdentifier &&
2382 LeadingIdentifier->TokenText == Current.Next->TokenText;
2389 if (Current.isNot(TT_Unknown)) {
2394 if ((Style.isJavaScript() || Style.isCSharp()) &&
2395 Current.is(tok::exclaim)) {
2396 if (Current.Previous) {
2398 Style.isJavaScript()
2399 ? Keywords.isJavaScriptIdentifier(
2400 *Current.Previous,
true)
2401 : Current.Previous->is(tok::identifier);
2403 Current.Previous->isOneOf(
2404 tok::kw_default, tok::kw_namespace, tok::r_paren, tok::r_square,
2405 tok::r_brace, tok::kw_false, tok::kw_true, Keywords.kw_type,
2406 Keywords.kw_get, Keywords.kw_init, Keywords.kw_set) ||
2407 Current.Previous->Tok.isLiteral()) {
2408 Current.setType(TT_NonNullAssertion);
2413 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
2414 Current.setType(TT_NonNullAssertion);
2422 if ((Style.isJavaScript() || Style.isJava()) &&
2423 Current.is(Keywords.kw_instanceof)) {
2424 Current.setType(TT_BinaryOperator);
2425 }
else if (isStartOfName(Current) &&
2426 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
2427 Contexts.back().FirstStartOfName = &Current;
2428 Current.setType(TT_StartOfName);
2429 }
else if (Current.is(tok::semi)) {
2433 Contexts.back().FirstStartOfName =
nullptr;
2434 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
2436 }
else if (Current.is(tok::arrow) && Style.isJava()) {
2437 Current.setType(TT_LambdaArrow);
2438 }
else if (Current.is(tok::arrow) && Style.isVerilog()) {
2440 Current.setType(TT_BinaryOperator);
2441 }
else if (Current.is(tok::arrow) && AutoFound &&
2442 Line.MightBeFunctionDecl && Current.NestingLevel == 0 &&
2443 Current.Previous->isNoneOf(tok::kw_operator, tok::identifier)) {
2445 Current.setType(TT_TrailingReturnArrow);
2446 }
else if (Current.is(tok::arrow) && Current.Previous &&
2447 Current.Previous->is(tok::r_brace) &&
2451 Current.setType(TT_TrailingReturnArrow);
2452 }
else if (isDeductionGuide(Current)) {
2454 Current.setType(TT_TrailingReturnArrow);
2455 }
else if (Current.isPointerOrReference()) {
2456 Current.setType(determineStarAmpUsage(
2458 (Contexts.back().CanBeExpression && Contexts.back().IsExpression) ||
2459 Contexts.back().InStaticAssertFirstArgument,
2460 Contexts.back().ContextType == Context::TemplateArgument));
2461 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret) ||
2462 (Style.isVerilog() && Current.is(tok::pipe))) {
2463 Current.setType(determinePlusMinusCaretUsage(Current));
2464 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
2465 Contexts.back().CaretFound =
true;
2466 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
2467 Current.setType(determineIncrementUsage(Current));
2468 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
2469 Current.setType(TT_UnaryOperator);
2470 }
else if (Current.is(tok::question)) {
2471 if (Style.isJavaScript() && Line.MustBeDeclaration &&
2472 !Contexts.back().IsExpression) {
2475 Current.setType(TT_JsTypeOptionalQuestion);
2476 }
else if (Style.isTableGen()) {
2478 Current.setType(TT_Unknown);
2480 Current.setType(TT_ConditionalExpr);
2482 }
else if (Current.isBinaryOperator() &&
2483 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
2484 (Current.isNot(tok::greater) && !Style.isTextProto())) {
2485 if (Style.isVerilog()) {
2486 if (Current.is(tok::lessequal) && Contexts.size() == 1 &&
2487 !Contexts.back().VerilogAssignmentFound) {
2491 Current.setFinalizedType(TT_BinaryOperator);
2494 Contexts.back().VerilogAssignmentFound =
true;
2496 Current.setType(TT_BinaryOperator);
2497 }
else if (Current.is(tok::comment)) {
2498 if (Current.TokenText.starts_with(
"/*")) {
2499 if (Current.TokenText.ends_with(
"*/")) {
2500 Current.setType(TT_BlockComment);
2504 Current.Tok.setKind(tok::unknown);
2507 Current.setType(TT_LineComment);
2509 }
else if (Current.is(tok::string_literal)) {
2510 if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&
2511 Current.getPreviousNonComment() &&
2512 Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&
2513 Current.getNextNonComment() &&
2514 Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
2515 Current.setType(TT_StringInConcatenation);
2517 }
else if (Current.is(tok::l_paren)) {
2518 if (lParenStartsCppCast(Current))
2519 Current.setType(TT_CppCastLParen);
2520 }
else if (Current.is(tok::r_paren)) {
2521 if (rParenEndsCast(Current))
2522 Current.setType(TT_CastRParen);
2523 if (Current.MatchingParen && Current.Next &&
2524 !Current.Next->isBinaryOperator() &&
2525 Current.Next->isNoneOf(
2526 tok::semi, tok::colon, tok::l_brace, tok::l_paren, tok::comma,
2527 tok::period, tok::arrow, tok::coloncolon, tok::kw_noexcept)) {
2528 if (
FormatToken *AfterParen = Current.MatchingParen->Next;
2529 AfterParen && AfterParen->isNot(tok::caret)) {
2531 if (
FormatToken *BeforeParen = Current.MatchingParen->Previous;
2532 BeforeParen && BeforeParen->is(tok::identifier) &&
2533 BeforeParen->isNot(TT_TypenameMacro) &&
2534 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
2535 (!BeforeParen->Previous ||
2536 BeforeParen->Previous->ClosesTemplateDeclaration ||
2537 BeforeParen->Previous->ClosesRequiresClause)) {
2538 Current.setType(TT_FunctionAnnotationRParen);
2542 }
else if (Current.is(tok::at) && Current.Next && !Style.isJavaScript() &&
2546 switch (Current.Next->Tok.getObjCKeywordID()) {
2547 case tok::objc_interface:
2548 case tok::objc_implementation:
2549 case tok::objc_protocol:
2550 Current.setType(TT_ObjCDecl);
2552 case tok::objc_property:
2553 Current.setType(TT_ObjCProperty);
2558 }
else if (Current.is(tok::period)) {
2559 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
2560 if (PreviousNoComment &&
2561 PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) {
2562 Current.setType(TT_DesignatedInitializerPeriod);
2563 }
else if (Style.isJava() && Current.Previous &&
2564 Current.Previous->isOneOf(TT_JavaAnnotation,
2565 TT_LeadingJavaAnnotation)) {
2566 Current.setType(Current.Previous->getType());
2568 }
else if (canBeObjCSelectorComponent(Current) &&
2571 Current.Previous && Current.Previous->is(TT_CastRParen) &&
2572 Current.Previous->MatchingParen &&
2573 Current.Previous->MatchingParen->Previous &&
2574 Current.Previous->MatchingParen->Previous->is(
2575 TT_ObjCMethodSpecifier)) {
2579 Current.setType(TT_SelectorName);
2580 }
else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept,
2581 tok::kw_requires) &&
2583 Current.Previous->isNoneOf(tok::equal, tok::at,
2584 TT_CtorInitializerComma,
2585 TT_CtorInitializerColon) &&
2586 Line.MightBeFunctionDecl && Contexts.size() == 1) {
2589 Current.setType(TT_TrailingAnnotation);
2590 }
else if ((Style.isJava() || Style.isJavaScript()) && Current.Previous) {
2591 if (Current.Previous->is(tok::at) &&
2592 Current.isNot(Keywords.kw_interface)) {
2596 Current.setType(TT_LeadingJavaAnnotation);
2598 Current.setType(TT_JavaAnnotation);
2599 }
else if (Current.Previous->is(tok::period) &&
2600 Current.Previous->isOneOf(TT_JavaAnnotation,
2601 TT_LeadingJavaAnnotation)) {
2602 Current.setType(Current.Previous->getType());
2614 if (Style.isVerilog())
2617 if (!
Tok.Previous ||
Tok.isNot(tok::identifier) ||
Tok.is(TT_ClassHeadName))
2620 if (
Tok.endsSequence(Keywords.kw_final, TT_ClassHeadName))
2623 if ((Style.isJavaScript() || Style.isJava()) &&
Tok.is(Keywords.kw_extends))
2626 if (
const auto *NextNonComment =
Tok.getNextNonComment();
2627 (!NextNonComment && !Line.InMacroBody) ||
2629 (NextNonComment->isPointerOrReference() ||
2630 NextNonComment->isOneOf(TT_ClassHeadName, tok::string_literal) ||
2631 (Line.InPragmaDirective && NextNonComment->is(tok::identifier))))) {
2635 if (
Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
2639 if (Style.isJavaScript() &&
Tok.Previous->is(Keywords.kw_in))
2646 if (!Style.isJavaScript())
2647 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
2648 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
2650 if (!PreviousNotConst)
2653 if (PreviousNotConst->ClosesRequiresClause)
2656 if (Style.isTableGen()) {
2658 if (Keywords.isTableGenDefinition(*PreviousNotConst))
2661 if (Contexts.back().ContextKind != tok::l_brace)
2665 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
2666 PreviousNotConst->Previous &&
2667 PreviousNotConst->Previous->is(tok::hash);
2669 if (PreviousNotConst->is(TT_TemplateCloser)) {
2670 return PreviousNotConst && PreviousNotConst->MatchingParen &&
2671 PreviousNotConst->MatchingParen->Previous &&
2672 PreviousNotConst->MatchingParen->Previous->isNoneOf(
2673 tok::period, tok::kw_template);
2676 if ((PreviousNotConst->is(tok::r_paren) &&
2677 PreviousNotConst->is(TT_TypeDeclarationParen)) ||
2678 PreviousNotConst->is(TT_AttributeRParen)) {
2687 if (PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto) &&
2688 PreviousNotConst->isNot(TT_StatementAttributeLikeMacro)) {
2693 if (PreviousNotConst->is(TT_PointerOrReference) ||
2694 PreviousNotConst->endsSequence(tok::coloncolon,
2695 TT_PointerOrReference)) {
2700 if (PreviousNotConst->isTypeName(LangOpts))
2704 if (Style.isJava() && PreviousNotConst->is(tok::r_square))
2708 return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const);
2718 if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) &&
2719 LeftOfParens->MatchingParen) {
2720 auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment();
2722 Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast,
2723 tok::kw_reinterpret_cast, tok::kw_static_cast)) {
2734 assert(
Tok.is(tok::r_paren));
2736 if (!
Tok.MatchingParen || !
Tok.Previous)
2740 if (!IsCpp && !Style.isCSharp() && !Style.isJava())
2743 const auto *LParen =
Tok.MatchingParen;
2744 const auto *BeforeRParen =
Tok.Previous;
2745 const auto *AfterRParen =
Tok.Next;
2748 if (BeforeRParen == LParen || !AfterRParen)
2751 if (LParen->is(TT_OverloadedOperatorLParen))
2754 auto *LeftOfParens = LParen->getPreviousNonComment();
2758 if (LeftOfParens->is(tok::r_paren) &&
2759 LeftOfParens->isNot(TT_CastRParen)) {
2760 if (!LeftOfParens->MatchingParen ||
2761 !LeftOfParens->MatchingParen->Previous) {
2764 LeftOfParens = LeftOfParens->MatchingParen->Previous;
2767 if (LeftOfParens->is(tok::r_square)) {
2770 if (
Tok->isNot(tok::r_square))
2773 Tok =
Tok->getPreviousNonComment();
2774 if (!
Tok ||
Tok->isNot(tok::l_square))
2777 Tok =
Tok->getPreviousNonComment();
2778 if (!
Tok ||
Tok->isNot(tok::kw_delete))
2782 if (
FormatToken *MaybeDelete = MayBeArrayDelete(LeftOfParens))
2783 LeftOfParens = MaybeDelete;
2789 if (LeftOfParens->Tok.getIdentifierInfo() && LeftOfParens->Previous &&
2790 LeftOfParens->Previous->is(tok::kw_operator)) {
2796 if (LeftOfParens->Tok.getIdentifierInfo() &&
2797 LeftOfParens->isNoneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
2798 tok::kw_delete, tok::kw_throw)) {
2804 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
2805 TT_TemplateCloser, tok::ellipsis)) {
2810 if (AfterRParen->is(tok::question) ||
2811 (AfterRParen->is(tok::ampamp) && !BeforeRParen->isTypeName(LangOpts))) {
2816 if (AfterRParen->is(Keywords.kw_in) && Style.isCSharp())
2821 if (AfterRParen->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
2822 tok::kw_requires, tok::kw_throw, tok::arrow,
2823 Keywords.kw_override, Keywords.kw_final) ||
2824 isCppAttribute(IsCpp, *AfterRParen)) {
2830 if (Style.isJava() && AfterRParen->is(tok::l_paren))
2834 if (AfterRParen->isOneOf(tok::kw_sizeof, tok::kw_alignof) ||
2835 (AfterRParen->Tok.isLiteral() &&
2836 AfterRParen->isNot(tok::string_literal))) {
2841 if (
Tok.isNot(TT_TemplateCloser))
2843 const auto *
Less =
Tok.MatchingParen;
2846 const auto *BeforeLess =
Less->getPreviousNonComment();
2847 return BeforeLess && BeforeLess->isNot(TT_VariableTemplate);
2851 auto IsQualifiedPointerOrReference = [](
const FormatToken *
T,
2852 const LangOptions &LangOpts) {
2854 assert(!
T->isTypeName(LangOpts) &&
"Should have already been checked");
2858 if (
T->is(TT_AttributeRParen)) {
2860 assert(
T->is(tok::r_paren));
2861 assert(
T->MatchingParen);
2862 assert(
T->MatchingParen->is(tok::l_paren));
2863 assert(
T->MatchingParen->is(TT_AttributeLParen));
2864 if (
const auto *
Tok =
T->MatchingParen->Previous;
2865 Tok &&
Tok->isAttribute()) {
2869 }
else if (
T->is(TT_AttributeRSquare)) {
2871 if (
T->MatchingParen &&
T->MatchingParen->Previous) {
2872 T =
T->MatchingParen->Previous;
2875 }
else if (
T->canBePointerOrReferenceQualifier()) {
2881 return T &&
T->is(TT_PointerOrReference);
2884 bool ParensAreType = IsNonVariableTemplate(*BeforeRParen) ||
2885 BeforeRParen->is(TT_TypeDeclarationParen) ||
2886 BeforeRParen->isTypeName(LangOpts) ||
2887 IsQualifiedPointerOrReference(BeforeRParen, LangOpts);
2888 bool ParensCouldEndDecl =
2889 AfterRParen->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
2890 if (ParensAreType && !ParensCouldEndDecl)
2901 for (
const auto *Token = LParen->Next; Token != &
Tok; Token = Token->Next)
2902 if (Token->is(TT_BinaryOperator))
2907 if (AfterRParen->isOneOf(tok::identifier, tok::kw_this))
2911 if (AfterRParen->is(tok::l_paren)) {
2912 for (
const auto *Prev = BeforeRParen; Prev->is(tok::identifier);) {
2913 Prev = Prev->Previous;
2914 if (Prev->is(tok::coloncolon))
2915 Prev = Prev->Previous;
2921 if (!AfterRParen->Next)
2924 if (AfterRParen->is(tok::l_brace) &&
2932 const bool NextIsAmpOrStar = AfterRParen->isOneOf(tok::amp, tok::star);
2933 if (!(AfterRParen->isUnaryOperator() || NextIsAmpOrStar) ||
2934 AfterRParen->is(tok::plus) ||
2935 AfterRParen->Next->isNoneOf(tok::identifier, tok::numeric_constant)) {
2939 if (NextIsAmpOrStar &&
2940 (AfterRParen->Next->is(tok::numeric_constant) || Line.InPPDirective)) {
2944 if (Line.InPPDirective && AfterRParen->is(tok::minus))
2947 const auto *Prev = BeforeRParen;
2950 if (Prev->is(tok::r_paren)) {
2951 if (Prev->is(TT_CastRParen))
2953 Prev = Prev->MatchingParen;
2956 Prev = Prev->Previous;
2957 if (!Prev || Prev->isNot(tok::r_paren))
2959 Prev = Prev->MatchingParen;
2960 return Prev && Prev->is(TT_FunctionTypeLParen);
2964 for (Prev = BeforeRParen; Prev != LParen; Prev = Prev->Previous)
2965 if (Prev->isNoneOf(tok::kw_const, tok::identifier, tok::coloncolon))
2983 if (PrevToken->isOneOf(
2984 TT_ConditionalExpr, tok::l_paren, tok::comma, tok::colon, tok::semi,
2985 tok::equal, tok::question, tok::l_square, tok::l_brace,
2986 tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,
2987 tok::kw_delete, tok::kw_return, tok::kw_throw)) {
2994 if (PrevToken->is(tok::kw_sizeof))
2998 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
3002 if (PrevToken->is(TT_BinaryOperator))
3010 bool InTemplateArgument) {
3011 if (Style.isJavaScript())
3012 return TT_BinaryOperator;
3015 if (Style.isCSharp() &&
Tok.is(tok::ampamp))
3016 return TT_BinaryOperator;
3018 if (Style.isVerilog()) {
3023 if (
Tok.is(tok::star))
3024 return TT_BinaryOperator;
3025 return determineUnaryOperatorByUsage(
Tok) ? TT_UnaryOperator
3026 : TT_BinaryOperator;
3031 return TT_UnaryOperator;
3032 if (PrevToken->isTypeName(LangOpts))
3033 return TT_PointerOrReference;
3034 if (PrevToken->isPlacementOperator() &&
Tok.is(tok::ampamp))
3035 return TT_BinaryOperator;
3037 auto *NextToken =
Tok.getNextNonComment();
3039 return TT_PointerOrReference;
3040 if (NextToken->is(tok::greater))
3041 return TT_PointerOrReference;
3043 if (InTemplateArgument && NextToken->is(tok::kw_noexcept))
3044 return TT_BinaryOperator;
3046 if (NextToken->isOneOf(tok::arrow, tok::equal, tok::comma, tok::r_paren,
3047 TT_RequiresClause) ||
3048 (NextToken->is(tok::kw_noexcept) && !IsExpression) ||
3049 NextToken->canBePointerOrReferenceQualifier() ||
3050 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) {
3051 return TT_PointerOrReference;
3054 if (PrevToken->is(tok::coloncolon))
3055 return TT_PointerOrReference;
3057 if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
3058 return TT_PointerOrReference;
3060 if (determineUnaryOperatorByUsage(
Tok))
3061 return TT_UnaryOperator;
3063 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
3064 return TT_PointerOrReference;
3065 if (NextToken->is(tok::kw_operator) && !IsExpression)
3066 return TT_PointerOrReference;
3067 if (NextToken->isOneOf(tok::comma, tok::semi))
3068 return TT_PointerOrReference;
3080 if (PrevToken->is(tok::r_brace) &&
Tok.is(tok::star) &&
3081 !PrevToken->MatchingParen) {
3082 return TT_PointerOrReference;
3085 if (PrevToken->endsSequence(tok::r_square, tok::l_square, tok::kw_delete))
3086 return TT_UnaryOperator;
3088 if (PrevToken->Tok.isLiteral() ||
3089 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
3090 tok::kw_false, tok::r_brace)) {
3091 return TT_BinaryOperator;
3095 while (NextNonParen && NextNonParen->is(tok::l_paren))
3096 NextNonParen = NextNonParen->getNextNonComment();
3097 if (NextNonParen && (NextNonParen->Tok.isLiteral() ||
3098 NextNonParen->isOneOf(tok::kw_true, tok::kw_false) ||
3099 NextNonParen->isUnaryOperator())) {
3100 return TT_BinaryOperator;
3106 if (InTemplateArgument && NextToken->Tok.isAnyIdentifier())
3107 return TT_BinaryOperator;
3111 if (
Tok.is(tok::ampamp) &&
3112 NextToken->isOneOf(tok::l_paren, tok::star, tok::amp)) {
3113 return TT_BinaryOperator;
3120 if (NextToken->Tok.isAnyIdentifier()) {
3121 auto *NextNextToken = NextToken->getNextNonComment();
3122 if (NextNextToken) {
3123 if (NextNextToken->is(tok::arrow))
3124 return TT_BinaryOperator;
3125 if (NextNextToken->isPointerOrReference() &&
3126 !NextToken->isObjCLifetimeQualifier(Style)) {
3127 NextNextToken->setFinalizedType(TT_BinaryOperator);
3128 return TT_BinaryOperator;
3135 if (IsExpression && !Contexts.back().CaretFound &&
3136 Line.getFirstNonComment()->isNot(
3137 TT_RequiresClauseInARequiresExpression)) {
3138 return TT_BinaryOperator;
3142 if (!Scopes.empty() && Scopes.back() ==
ST_Class)
3143 return TT_PointerOrReference;
3146 auto IsChainedOperatorAmpOrMember = [](
const FormatToken *token) {
3147 return !token || token->isOneOf(tok::amp, tok::period, tok::arrow,
3148 tok::arrowstar, tok::periodstar);
3153 if (
Tok.is(tok::amp) && PrevToken->Tok.isAnyIdentifier() &&
3154 IsChainedOperatorAmpOrMember(PrevToken->getPreviousNonComment()) &&
3155 NextToken && NextToken->Tok.isAnyIdentifier()) {
3156 if (
auto NextNext = NextToken->getNextNonComment();
3158 (IsChainedOperatorAmpOrMember(NextNext) || NextNext->is(tok::semi))) {
3159 return TT_BinaryOperator;
3165 return TT_BinaryOperator;
3168 return TT_PointerOrReference;
3172 if (determineUnaryOperatorByUsage(
Tok))
3173 return TT_UnaryOperator;
3177 return TT_UnaryOperator;
3179 if (PrevToken->is(tok::at))
3180 return TT_UnaryOperator;
3183 return TT_BinaryOperator;
3189 if (!PrevToken || PrevToken->is(TT_CastRParen))
3190 return TT_UnaryOperator;
3191 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
3192 return TT_TrailingUnaryOperator;
3194 return TT_UnaryOperator;
3197 SmallVector<Context, 8> Contexts;
3199 const FormatStyle &Style;
3200 AnnotatedLine &Line;
3204 LangOptions LangOpts;
3205 const AdditionalKeywords &Keywords;
3207 SmallVector<ScopeType> &Scopes;
3213 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
3215 int TemplateDeclarationDepth;
3223class ExpressionParser {
3225 ExpressionParser(
const FormatStyle &Style,
const AdditionalKeywords &Keywords,
3226 AnnotatedLine &Line)
3227 : Style(Style), Keywords(Keywords), Line(Line), Current(Line.
First) {}
3230 void parse(
int Precedence = 0) {
3233 while (Current && (Current->is(tok::kw_return) ||
3234 (Current->is(tok::colon) &&
3235 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral)))) {
3239 if (!Current || Precedence > PrecedenceArrowAndPeriod)
3244 parseConditionalExpr();
3250 if (Precedence == PrecedenceUnaryOperator) {
3251 parseUnaryOperator();
3268 if (Style.isVerilog() && Precedence ==
prec::Comma) {
3269 VerilogFirstOfType =
3270 verilogGroupDecl(VerilogFirstOfType, LatestOperator);
3274 parse(Precedence + 1);
3276 int CurrentPrecedence = getCurrentPrecedence();
3277 if (Style.BreakBinaryOperations == FormatStyle::BBO_OnePerLine &&
3287 if (Precedence == CurrentPrecedence && Current &&
3288 Current->is(TT_SelectorName)) {
3290 addFakeParenthesis(Start,
prec::Level(Precedence));
3294 if ((Style.isCSharp() || Style.isJavaScript() || Style.isJava()) &&
3298 FormatToken *Prev = Current->getPreviousNonComment();
3299 if (Prev && Prev->is(tok::string_literal) &&
3300 (Prev == Start || Prev->endsSequence(tok::string_literal, tok::plus,
3301 TT_StringInConcatenation))) {
3302 Prev->setType(TT_StringInConcatenation);
3309 (Current->closesScope() &&
3310 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
3311 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
3320 if (Current->opensScope() ||
3321 Current->isOneOf(TT_RequiresClause,
3322 TT_RequiresClauseInARequiresExpression)) {
3325 while (Current && (!Current->closesScope() || Current->opensScope())) {
3332 if (CurrentPrecedence == Precedence) {
3334 LatestOperator->NextOperator = Current;
3335 LatestOperator = Current;
3339 next(Precedence > 0);
3344 if (Style.isVerilog() && Precedence ==
prec::Comma && VerilogFirstOfType)
3345 addFakeParenthesis(VerilogFirstOfType,
prec::Comma);
3347 if (LatestOperator && (Current || Precedence > 0)) {
3353 Start->Previous->isOneOf(TT_RequiresClause,
3354 TT_RequiresClauseInARequiresExpression))
3356 auto Ret = Current ? Current : Line.Last;
3357 while (!
Ret->ClosesRequiresClause &&
Ret->Previous)
3363 if (Precedence == PrecedenceArrowAndPeriod) {
3367 addFakeParenthesis(Start,
prec::Level(Precedence), End);
3375 int getCurrentPrecedence() {
3377 const FormatToken *NextNonComment = Current->getNextNonComment();
3378 if (Current->is(TT_ConditionalExpr))
3380 if (NextNonComment && Current->is(TT_SelectorName) &&
3381 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
3382 (Style.isProto() && NextNonComment->is(tok::less)))) {
3385 if (Current->is(TT_JsComputedPropertyName))
3387 if (Current->is(TT_LambdaArrow))
3389 if (Current->is(TT_FatArrow))
3391 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
3392 (Current->is(tok::comment) && NextNonComment &&
3393 NextNonComment->is(TT_SelectorName))) {
3396 if (Current->is(TT_RangeBasedForLoopColon))
3398 if ((Style.isJava() || Style.isJavaScript()) &&
3399 Current->is(Keywords.kw_instanceof)) {
3402 if (Style.isJavaScript() &&
3403 Current->isOneOf(Keywords.kw_in, Keywords.kw_as)) {
3406 if (Current->isOneOf(TT_BinaryOperator, tok::comma))
3407 return Current->getPrecedence();
3408 if (Current->isOneOf(tok::period, tok::arrow) &&
3409 Current->isNot(TT_TrailingReturnArrow)) {
3410 return PrecedenceArrowAndPeriod;
3412 if ((Style.isJava() || Style.isJavaScript()) &&
3413 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
3414 Keywords.kw_throws)) {
3419 if (Style.isVerilog() && Current->is(tok::colon))
3431 if (Start->MacroParent)
3434 Start->FakeLParens.push_back(Precedence);
3436 Start->StartsBinaryExpression =
true;
3437 if (!End && Current)
3438 End = Current->getPreviousNonComment();
3442 End->EndsBinaryExpression =
true;
3448 void parseUnaryOperator() {
3449 SmallVector<FormatToken *, 2> Tokens;
3450 while (Current && Current->is(TT_UnaryOperator)) {
3451 Tokens.push_back(Current);
3454 parse(PrecedenceArrowAndPeriod);
3461 void parseConditionalExpr() {
3462 while (Current && Current->isTrailingComment())
3466 if (!Current || Current->isNot(tok::question))
3470 if (!Current || Current->isNot(TT_ConditionalExpr))
3477 void next(
bool SkipPastLeadingComments =
true) {
3479 Current = Current->Next;
3481 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
3482 Current->isTrailingComment()) {
3483 Current = Current->Next;
3497 while (Start->startsSequence(tok::l_paren, tok::star)) {
3498 if (!(Start = Start->MatchingParen) ||
3499 !(Start = Start->getNextNonComment())) {
3506 if (
Tok->is(Keywords.kw_assign))
3507 Tok =
Tok->getNextNonComment();
3519 if (
Tok->is(tok::hash)) {
3524 Tok =
Tok->getNextNonComment();
3525 }
else if (
Tok->is(tok::hashhash)) {
3529 Tok =
Tok->getNextNonComment();
3530 }
else if (Keywords.isVerilogQualifier(*
Tok) ||
3531 Keywords.isVerilogIdentifier(*
Tok)) {
3535 while (
Tok &&
Tok->isOneOf(tok::period, tok::coloncolon) &&
3536 (
Tok =
Tok->getNextNonComment())) {
3537 if (Keywords.isVerilogIdentifier(*
Tok))
3538 Tok =
Tok->getNextNonComment();
3542 }
else if (
Tok->is(tok::l_paren)) {
3547 Keywords.kw_highz0, Keywords.kw_highz1, Keywords.kw_large,
3548 Keywords.kw_medium, Keywords.kw_pull0, Keywords.kw_pull1,
3549 Keywords.kw_small, Keywords.kw_strong0, Keywords.kw_strong1,
3550 Keywords.kw_supply0, Keywords.kw_supply1, Keywords.kw_weak0,
3551 Keywords.kw_weak1)) {
3552 Tok->setType(TT_VerilogStrength);
3553 Tok =
Tok->MatchingParen;
3555 Tok->setType(TT_VerilogStrength);
3556 Tok =
Tok->getNextNonComment();
3561 }
else if (
Tok->is(Keywords.kw_verilogHash)) {
3563 if (
Next->is(tok::l_paren))
3566 Tok =
Next->getNextNonComment();
3575 while (
Tok &&
Tok->is(tok::l_square) && (
Tok =
Tok->MatchingParen))
3576 Tok =
Tok->getNextNonComment();
3577 if (
Tok && (
Tok->is(tok::hash) || Keywords.isVerilogIdentifier(*
Tok)))
3586 First->setType(TT_VerilogDimensionedTypeName);
3587 }
else if (
First != Start) {
3595 if (TypedName->is(TT_Unknown))
3596 TypedName->setType(TT_StartOfName);
3598 if (FirstOfType && PreviousComma) {
3599 PreviousComma->setType(TT_VerilogTypeComma);
3600 addFakeParenthesis(FirstOfType,
prec::Comma, PreviousComma->Previous);
3603 FirstOfType = TypedName;
3610 while (Current && Current != FirstOfType) {
3611 if (Current->opensScope()) {
3622 const FormatStyle &Style;
3623 const AdditionalKeywords &Keywords;
3624 const AnnotatedLine &Line;
3634 assert(
Line->First);
3641 Line->First->OriginalColumn) {
3642 const bool PPDirectiveOrImportStmt =
3645 if (PPDirectiveOrImportStmt)
3650 Line->Level = Style.IndentPPDirectives < FormatStyle::PPDIS_BeforeHash &&
3651 PPDirectiveOrImportStmt
3653 : NextNonCommentLine->
Level;
3655 NextNonCommentLine =
Line->First->isNot(tok::r_brace) ?
Line :
nullptr;
3675 if (
Tok->isNot(tok::identifier))
3678 Tok =
Tok->getNextNonComment();
3684 if (
Tok->is(tok::coloncolon))
3685 return Tok->getNextNonComment();
3689 if (
Tok->is(TT_TemplateOpener)) {
3690 Tok =
Tok->MatchingParen;
3694 Tok =
Tok->getNextNonComment();
3699 return Tok->is(tok::coloncolon) ?
Tok->getNextNonComment() :
nullptr;
3707 Tok =
Tok->getNextNonComment()) {
3709 if (
Tok->is(TT_AttributeLSquare)) {
3710 Tok =
Tok->MatchingParen;
3718 if (
Tok->is(tok::l_paren) &&
Tok->is(TT_Unknown) &&
Tok->MatchingParen) {
3726 if (
Tok->isOneOf(tok::kw_friend, tok::kw_inline, tok::kw_virtual,
3727 tok::kw_constexpr, tok::kw_consteval, tok::kw_explicit)) {
3733 if (
Tok->is(tok::kw_template)) {
3734 Tok =
Tok->getNextNonComment();
3740 if (
Tok->isNot(TT_TemplateOpener))
3743 Tok =
Tok->MatchingParen;
3751 if (
Tok->is(tok::coloncolon)) {
3762 if (
Tok->is(tok::tilde)) {
3769 if (
Tok->isNot(tok::identifier) ||
Tok->isNot(TT_Unknown))
3780 assert(
Tok &&
Tok->is(tok::identifier));
3781 const auto *Prev =
Tok->Previous;
3783 if (Prev && Prev->is(tok::tilde))
3784 Prev = Prev->Previous;
3787 if (!Prev || (!Prev->endsSequence(tok::coloncolon, tok::identifier) &&
3788 !Prev->endsSequence(tok::coloncolon, TT_TemplateCloser))) {
3792 assert(Prev->Previous);
3793 if (Prev->Previous->is(TT_TemplateCloser) && Prev->Previous->MatchingParen) {
3794 Prev = Prev->Previous->MatchingParen;
3795 assert(Prev->Previous);
3798 return Prev->Previous->TokenText ==
Tok->TokenText;
3802 if (!
Line.InMacroBody)
3803 MacroBodyScopes.clear();
3805 auto &ScopeStack =
Line.InMacroBody ? MacroBodyScopes : Scopes;
3806 AnnotatingParser
Parser(Style,
Line, Keywords, ScopeStack);
3809 if (!
Line.Children.empty()) {
3812 for (
auto &Child :
Line.Children) {
3813 if (InRequiresExpression &&
3814 Child->First->isNoneOf(tok::kw_typename, tok::kw_requires,
3815 TT_CompoundRequirementLBrace)) {
3821 if (!ScopeStack.empty())
3822 ScopeStack.pop_back();
3835 ExpressionParser ExprParser(Style, Keywords,
Line);
3841 if (
Tok && ((!ScopeStack.empty() && ScopeStack.back() ==
ST_Class) ||
3843 Tok->setFinalizedType(TT_CtorDtorDeclName);
3844 assert(OpeningParen);
3849 if (
Line.startsWith(TT_ObjCMethodSpecifier))
3851 else if (
Line.startsWith(TT_ObjCDecl))
3853 else if (
Line.startsWith(TT_ObjCProperty))
3857 First->SpacesRequiredBefore = 1;
3858 First->CanBreakBefore =
First->MustBreakBefore;
3867 if (Current.
is(TT_FunctionDeclarationName))
3870 if (Current.
isNoneOf(tok::identifier, tok::kw_operator))
3873 const auto *Prev = Current.getPreviousNonComment();
3878 if (
const auto *PrevPrev =
Previous.getPreviousNonComment();
3879 PrevPrev && PrevPrev->is(TT_ObjCDecl)) {
3883 auto skipOperatorName =
3886 if (
Next->is(TT_OverloadedOperatorLParen))
3888 if (
Next->is(TT_OverloadedOperator))
3890 if (
Next->isPlacementOperator() ||
Next->is(tok::kw_co_await)) {
3893 Next->Next->startsSequence(tok::l_square, tok::r_square)) {
3898 if (
Next->startsSequence(tok::l_square, tok::r_square)) {
3903 if ((
Next->isTypeName(LangOpts) ||
Next->is(tok::identifier)) &&
3904 Next->Next &&
Next->Next->isPointerOrReference()) {
3909 if (
Next->is(TT_TemplateOpener) &&
Next->MatchingParen) {
3920 const bool IsCpp = LangOpts.CXXOperatorNames || LangOpts.C11;
3923 if (Current.
is(tok::kw_operator)) {
3924 if (
Line.startsWith(tok::kw_friend))
3926 if (
Previous.Tok.getIdentifierInfo() &&
3927 Previous.isNoneOf(tok::kw_return, tok::kw_co_return)) {
3932 assert(
Previous.MatchingParen->is(tok::l_paren));
3933 assert(
Previous.MatchingParen->is(TT_TypeDeclarationParen));
3942 while (
Next &&
Next->startsSequence(tok::hashhash, tok::identifier))
3945 if (
Next->is(TT_TemplateOpener) &&
Next->MatchingParen) {
3947 }
else if (
Next->is(tok::coloncolon)) {
3951 if (
Next->is(tok::kw_operator)) {
3952 Next = skipOperatorName(
Next->Next);
3955 if (
Next->isNot(tok::identifier))
3957 }
else if (isCppAttribute(IsCpp, *
Next)) {
3961 }
else if (
Next->is(tok::l_paren)) {
3970 if (!
Next ||
Next->isNot(tok::l_paren) || !
Next->MatchingParen)
3972 ClosingParen =
Next->MatchingParen;
3973 assert(ClosingParen->
is(tok::r_paren));
3975 if (
Line.Last->is(tok::l_brace))
3977 if (
Next->Next == ClosingParen)
3980 if (ClosingParen->
Next && ClosingParen->
Next->
is(TT_PointerOrReference))
3993 if (IsCpp &&
Next->Next &&
Next->Next->is(tok::identifier) &&
3994 !
Line.endsWith(tok::semi)) {
4000 if (
Tok->is(TT_TypeDeclarationParen))
4002 if (
Tok->isOneOf(tok::l_paren, TT_TemplateOpener) &&
Tok->MatchingParen) {
4003 Tok =
Tok->MatchingParen;
4006 if (
Tok->is(tok::kw_const) ||
Tok->isTypeName(LangOpts) ||
4007 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
4010 if (
Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) ||
Tok->Tok.isLiteral())
4016bool TokenAnnotator::mustBreakForReturnType(
const AnnotatedLine &
Line)
const {
4017 assert(
Line.MightBeFunctionDecl);
4019 if ((Style.BreakAfterReturnType == FormatStyle::RTBS_TopLevel ||
4020 Style.BreakAfterReturnType == FormatStyle::RTBS_TopLevelDefinitions) &&
4025 switch (Style.BreakAfterReturnType) {
4026 case FormatStyle::RTBS_None:
4027 case FormatStyle::RTBS_Automatic:
4028 case FormatStyle::RTBS_ExceptShortType:
4030 case FormatStyle::RTBS_All:
4031 case FormatStyle::RTBS_TopLevel:
4033 case FormatStyle::RTBS_AllDefinitions:
4034 case FormatStyle::RTBS_TopLevelDefinitions:
4035 return Line.mightBeFunctionDefinition();
4045 Line.Computed =
true;
4053 :
Line.FirstStartColumn +
First->ColumnWidth;
4054 bool AlignArrayOfStructures =
4055 (Style.AlignArrayOfStructures != FormatStyle::AIAS_None &&
4057 if (AlignArrayOfStructures)
4058 calculateArrayInitializerColumnList(
Line);
4060 const auto *FirstNonComment =
Line.getFirstNonComment();
4061 bool SeenName =
false;
4062 bool LineIsFunctionDeclaration =
false;
4066 for (
auto *
Tok = FirstNonComment && FirstNonComment->isNot(tok::kw_using)
4067 ? FirstNonComment->Next
4070 if (
Tok->is(TT_StartOfName))
4072 if (
Tok->Previous->EndsCppAttributeGroup)
4073 AfterLastAttribute =
Tok;
4074 if (
const bool IsCtorOrDtor =
Tok->is(TT_CtorDtorDeclName);
4078 Tok->setFinalizedType(TT_FunctionDeclarationName);
4079 LineIsFunctionDeclaration =
true;
4083 assert(OpeningParen);
4084 if (OpeningParen->is(TT_Unknown))
4085 OpeningParen->setType(TT_FunctionDeclarationLParen);
4092 if ((LineIsFunctionDeclaration ||
4093 (FirstNonComment && FirstNonComment->is(TT_CtorDtorDeclName))) &&
4094 Line.endsWith(tok::semi, tok::r_brace)) {
4095 auto *
Tok =
Line.Last->Previous;
4096 while (
Tok->isNot(tok::r_brace))
4098 if (
auto *LBrace =
Tok->MatchingParen; LBrace && LBrace->is(TT_Unknown)) {
4099 assert(LBrace->is(tok::l_brace));
4102 LBrace->setFinalizedType(TT_FunctionLBrace);
4106 if (SeenName && AfterLastAttribute &&
4109 if (LineIsFunctionDeclaration)
4110 Line.ReturnTypeWrapped =
true;
4113 if (!LineIsFunctionDeclaration) {
4115 for (
const auto *
Tok = FirstNonComment;
Tok;
Tok =
Tok->Next) {
4116 if (
Tok->isNot(tok::kw_operator))
4120 }
while (
Tok &&
Tok->isNot(TT_OverloadedOperatorLParen));
4121 if (!
Tok || !
Tok->MatchingParen)
4123 const auto *LeftParen =
Tok;
4124 for (
Tok =
Tok->Next;
Tok &&
Tok != LeftParen->MatchingParen;
4126 if (
Tok->isNot(tok::identifier))
4129 const bool NextIsBinaryOperator =
4131 Next->Next->is(tok::identifier);
4132 if (!NextIsBinaryOperator)
4134 Next->setType(TT_BinaryOperator);
4138 }
else if (ClosingParen) {
4140 if (
Tok->is(TT_CtorInitializerColon))
4142 if (
Tok->is(tok::arrow)) {
4143 Tok->setType(TT_TrailingReturnArrow);
4146 if (
Tok->isNot(TT_TrailingAnnotation))
4149 if (!
Next ||
Next->isNot(tok::l_paren))
4158 if (
First->is(TT_ElseLBrace)) {
4159 First->CanBreakBefore =
true;
4160 First->MustBreakBefore =
true;
4163 bool InFunctionDecl =
Line.MightBeFunctionDecl;
4164 bool InParameterList =
false;
4165 for (
auto *Current =
First->Next; Current; Current = Current->Next) {
4167 if (Current->is(TT_LineComment)) {
4169 Current->SpacesRequiredBefore =
4170 (Style.Cpp11BracedListStyle == FormatStyle::BLS_AlignFirstComment &&
4171 !Style.SpacesInParensOptions.Other)
4174 }
else if (Prev->
is(TT_VerilogMultiLineListLParen)) {
4175 Current->SpacesRequiredBefore = 0;
4177 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
4187 if (!Current->HasUnescapedNewline) {
4190 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
4193 if (
Parameter->Previous->isNot(TT_CtorInitializerComma) &&
4201 }
else if (!Current->Finalized && Current->SpacesRequiredBefore == 0 &&
4202 spaceRequiredBefore(
Line, *Current)) {
4203 Current->SpacesRequiredBefore = 1;
4208 Current->MustBreakBefore =
true;
4210 Current->MustBreakBefore =
4211 Current->MustBreakBefore || mustBreakBefore(
Line, *Current);
4212 if (!Current->MustBreakBefore && InFunctionDecl &&
4213 Current->is(TT_FunctionDeclarationName)) {
4214 Current->MustBreakBefore = mustBreakForReturnType(
Line);
4218 Current->CanBreakBefore =
4219 Current->MustBreakBefore || canBreakBefore(
Line, *Current);
4221 if (Current->is(TT_FunctionDeclarationLParen)) {
4222 InParameterList =
true;
4223 }
else if (Current->is(tok::r_paren)) {
4224 const auto *LParen = Current->MatchingParen;
4225 if (LParen && LParen->is(TT_FunctionDeclarationLParen))
4226 InParameterList =
false;
4227 }
else if (InParameterList &&
4228 Current->endsSequence(TT_AttributeMacro,
4229 TT_PointerOrReference)) {
4230 Current->CanBreakBefore =
false;
4233 unsigned ChildSize = 0;
4236 ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit
4239 if (Current->MustBreakBefore || Prev->
Children.size() > 1 ||
4241 Prev->
Children[0]->First->MustBreakBefore) ||
4242 Current->IsMultiline) {
4243 Current->TotalLength = Prev->
TotalLength + Style.ColumnLimit;
4245 Current->TotalLength = Prev->
TotalLength + Current->ColumnWidth +
4246 ChildSize + Current->SpacesRequiredBefore;
4249 if (Current->is(TT_ControlStatementLBrace)) {
4250 if (Style.ColumnLimit > 0 &&
4251 Style.BraceWrapping.AfterControlStatement ==
4252 FormatStyle::BWACS_MultiLine &&
4253 Line.Level * Style.IndentWidth +
Line.Last->TotalLength >
4254 Style.ColumnLimit) {
4255 Current->CanBreakBefore =
true;
4256 Current->MustBreakBefore =
true;
4258 }
else if (Current->is(TT_CtorInitializerColon)) {
4259 InFunctionDecl =
false;
4271 Current->SplitPenalty = splitPenalty(
Line, *Current, InFunctionDecl);
4272 if (Style.Language == FormatStyle::LK_ObjC &&
4273 Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {
4274 if (Current->ParameterIndex == 1)
4275 Current->SplitPenalty += 5 * Current->BindingStrength;
4277 Current->SplitPenalty += 20 * Current->BindingStrength;
4281 calculateUnbreakableTailLengths(
Line);
4283 for (
auto *Current =
First; Current; Current = Current->Next) {
4285 Current->Role->precomputeFormattingInfos(Current);
4286 if (Current->MatchingParen &&
4287 Current->MatchingParen->opensBlockOrBlockTypeList(Style) &&
4292 if (Current->opensBlockOrBlockTypeList(Style))
4296 LLVM_DEBUG({ printDebugInfo(
Line); });
4299void TokenAnnotator::calculateUnbreakableTailLengths(
4306 Current->
isOneOf(tok::comment, tok::string_literal)) {
4316void TokenAnnotator::calculateArrayInitializerColumnList(
4320 auto *CurrentToken =
Line.First;
4321 CurrentToken->ArrayInitializerLineStart =
true;
4323 while (CurrentToken && CurrentToken !=
Line.Last) {
4324 if (CurrentToken->is(tok::l_brace)) {
4325 CurrentToken->IsArrayInitializer =
true;
4326 if (CurrentToken->Next)
4327 CurrentToken->Next->MustBreakBefore =
true;
4329 calculateInitializerColumnList(
Line, CurrentToken->Next, Depth + 1);
4331 CurrentToken = CurrentToken->Next;
4336FormatToken *TokenAnnotator::calculateInitializerColumnList(
4338 while (CurrentToken && CurrentToken !=
Line.Last) {
4339 if (CurrentToken->is(tok::l_brace))
4341 else if (CurrentToken->is(tok::r_brace))
4343 if (Depth == 2 && CurrentToken->isOneOf(tok::l_brace, tok::comma)) {
4344 CurrentToken = CurrentToken->Next;
4347 CurrentToken->StartsColumn =
true;
4348 CurrentToken = CurrentToken->Previous;
4350 CurrentToken = CurrentToken->Next;
4352 return CurrentToken;
4357 bool InFunctionDecl)
const {
4361 if (
Left.is(tok::semi))
4365 if (Style.isJava()) {
4366 if (
Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
4368 if (
Right.is(Keywords.kw_implements))
4370 if (
Left.is(tok::comma) &&
Left.NestingLevel == 0)
4372 }
else if (Style.isJavaScript()) {
4373 if (
Right.is(Keywords.kw_function) &&
Left.isNot(tok::comma))
4375 if (
Left.is(TT_JsTypeColon))
4377 if ((
Left.is(TT_TemplateString) &&
Left.TokenText.ends_with(
"${")) ||
4378 (
Right.is(TT_TemplateString) &&
Right.TokenText.starts_with(
"}"))) {
4382 if (
Left.opensScope() &&
Right.closesScope())
4384 }
else if (Style.Language == FormatStyle::LK_Proto) {
4385 if (
Right.is(tok::l_square))
4387 if (
Right.is(tok::period))
4391 if (
Right.is(tok::identifier) &&
Right.Next &&
Right.Next->is(TT_DictLiteral))
4393 if (
Right.is(tok::l_square)) {
4394 if (
Left.is(tok::r_square))
4397 if (
Right.is(TT_LambdaLSquare) &&
Left.is(tok::equal))
4399 if (
Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
4400 TT_ArrayInitializerLSquare,
4401 TT_DesignatedInitializerLSquare, TT_AttributeLSquare)) {
4406 if (
Left.is(tok::coloncolon))
4407 return Style.PenaltyBreakScopeResolution;
4408 if (
Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
4409 tok::kw_operator)) {
4410 if (
Line.startsWith(tok::kw_for) &&
Right.PartOfMultiVariableDeclStmt)
4412 if (
Left.is(TT_StartOfName))
4414 if (InFunctionDecl &&
Right.NestingLevel == 0)
4415 return Style.PenaltyReturnTypeOnItsOwnLine;
4418 if (
Right.is(TT_PointerOrReference))
4420 if (
Right.is(TT_LambdaArrow))
4422 if (
Left.is(tok::equal) &&
Right.is(tok::l_brace))
4424 if (
Left.is(TT_CastRParen))
4426 if (
Left.isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union))
4428 if (
Left.is(tok::comment))
4431 if (
Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
4432 TT_CtorInitializerColon)) {
4436 if (
Right.isMemberAccess()) {
4457 const auto Penalty = Style.PenaltyBreakBeforeMemberAccess;
4459 ? std::min(Penalty, 35u)
4463 if (
Right.is(TT_TrailingAnnotation) &&
4464 (!
Right.Next ||
Right.Next->isNot(tok::l_paren))) {
4467 if (
Line.startsWith(TT_ObjCMethodSpecifier))
4474 bool is_short_annotation =
Right.TokenText.size() < 10;
4475 return (
Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
4479 if (
Line.startsWith(tok::kw_for) &&
Left.is(tok::equal))
4484 if (
Right.is(TT_SelectorName))
4486 if (
Left.is(tok::colon)) {
4487 if (
Left.is(TT_ObjCMethodExpr))
4488 return Line.MightBeFunctionDecl ? 50 : 500;
4489 if (
Left.is(TT_ObjCSelector))
4497 Left.Previous->isOneOf(tok::identifier, tok::greater)) {
4501 if (
Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0)
4502 return Style.PenaltyBreakOpenParenthesis;
4503 if (
Left.is(tok::l_paren) && InFunctionDecl && Style.AlignAfterOpenBracket)
4505 if (
Left.is(tok::l_paren) &&
Left.Previous &&
4506 (
Left.Previous->isOneOf(tok::kw_for, tok::kw__Generic) ||
4507 Left.Previous->isIf())) {
4510 if (
Left.is(tok::equal) && InFunctionDecl)
4512 if (
Right.is(tok::r_brace))
4514 if (
Left.is(TT_TemplateOpener))
4516 if (
Left.opensScope()) {
4520 if (!Style.AlignAfterOpenBracket &&
4521 (
Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) {
4524 if (
Left.is(tok::l_brace) &&
4525 Style.Cpp11BracedListStyle == FormatStyle::BLS_Block) {
4528 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
4531 if (
Left.is(TT_JavaAnnotation))
4534 if (
Left.is(TT_UnaryOperator))
4536 if (
Left.isOneOf(tok::plus, tok::comma) &&
Left.Previous &&
4537 Left.Previous->isLabelString() &&
4538 (
Left.NextOperator ||
Left.OperatorIndex != 0)) {
4541 if (
Right.is(tok::plus) &&
Left.isLabelString() &&
4542 (
Right.NextOperator ||
Right.OperatorIndex != 0)) {
4545 if (
Left.is(tok::comma))
4547 if (
Right.is(tok::lessless) &&
Left.isLabelString() &&
4548 (
Right.NextOperator ||
Right.OperatorIndex != 1)) {
4551 if (
Right.is(tok::lessless)) {
4553 if (
Left.isNot(tok::r_paren) ||
Right.OperatorIndex > 0) {
4559 if (
Left.ClosesTemplateDeclaration)
4560 return Style.PenaltyBreakTemplateDeclaration;
4561 if (
Left.ClosesRequiresClause)
4563 if (
Left.is(TT_ConditionalExpr))
4569 return Style.PenaltyBreakAssignment;
4576bool TokenAnnotator::spaceRequiredBeforeParens(
const FormatToken &Right)
const {
4577 if (Style.SpaceBeforeParens == FormatStyle::SBPO_Always)
4579 if (
Right.is(TT_OverloadedOperatorLParen) &&
4580 Style.SpaceBeforeParensOptions.AfterOverloadedOperator) {
4583 if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
4584 Right.ParameterCount > 0) {
4593 if (
Left.is(tok::kw_return) &&
4594 Right.isNoneOf(tok::semi, tok::r_paren, tok::hashhash)) {
4597 if (
Left.is(tok::kw_throw) &&
Right.is(tok::l_paren) &&
Right.MatchingParen &&
4598 Right.MatchingParen->is(TT_CastRParen)) {
4601 if (
Left.is(Keywords.kw_assert) && Style.isJava())
4604 Left.is(tok::objc_property)) {
4607 if (
Right.is(tok::hashhash))
4608 return Left.is(tok::hash);
4609 if (
Left.isOneOf(tok::hashhash, tok::hash))
4610 return Right.is(tok::hash);
4611 if (Style.SpacesInParens == FormatStyle::SIPO_Custom) {
4612 if (
Left.is(tok::l_paren) &&
Right.is(tok::r_paren))
4613 return Style.SpacesInParensOptions.InEmptyParentheses;
4614 if (Style.SpacesInParensOptions.ExceptDoubleParentheses &&
4615 Left.is(tok::r_paren) &&
Right.is(tok::r_paren)) {
4616 auto *InnerLParen =
Left.MatchingParen;
4617 if (InnerLParen && InnerLParen->Previous ==
Right.MatchingParen) {
4618 InnerLParen->SpacesRequiredBefore = 0;
4623 if (
Left.is(tok::l_paren))
4625 else if (
Right.is(tok::r_paren) &&
Right.MatchingParen)
4626 LeftParen =
Right.MatchingParen;
4627 if (LeftParen && (LeftParen->is(TT_ConditionLParen) ||
4628 (LeftParen->Previous &&
4629 isKeywordWithCondition(*LeftParen->Previous)))) {
4630 return Style.SpacesInParensOptions.InConditionalStatements;
4635 if (
Left.is(tok::kw_auto) &&
Right.isOneOf(TT_LambdaLBrace, TT_FunctionLBrace,
4637 TT_FunctionTypeLParen)) {
4642 if (
Left.is(tok::kw_auto) &&
Right.isOneOf(tok::l_paren, tok::l_brace))
4645 const auto *BeforeLeft =
Left.Previous;
4648 if (
Right.is(tok::l_paren) &&
Left.is(tok::kw_co_await) && BeforeLeft &&
4649 BeforeLeft->is(tok::kw_operator)) {
4653 if (
Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&
4654 Right.isNoneOf(tok::semi, tok::r_paren)) {
4658 if (
Left.is(tok::l_paren) ||
Right.is(tok::r_paren)) {
4659 return (
Right.is(TT_CastRParen) ||
4660 (
Left.MatchingParen &&
Left.MatchingParen->is(TT_CastRParen)))
4661 ? Style.SpacesInParensOptions.InCStyleCasts
4662 : Style.SpacesInParensOptions.Other;
4664 if (
Right.isOneOf(tok::semi, tok::comma))
4667 bool IsLightweightGeneric =
Right.MatchingParen &&
4668 Right.MatchingParen->Next &&
4669 Right.MatchingParen->Next->is(tok::colon);
4670 return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
4672 if (
Right.is(tok::less) &&
Left.is(tok::kw_template))
4673 return Style.SpaceAfterTemplateKeyword;
4674 if (
Left.isOneOf(tok::exclaim, tok::tilde))
4676 if (
Left.is(tok::at) &&
4677 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
4678 tok::numeric_constant, tok::l_paren, tok::l_brace,
4679 tok::kw_true, tok::kw_false)) {
4682 if (
Left.is(tok::colon))
4683 return Left.isNoneOf(TT_ObjCSelector, TT_ObjCMethodExpr);
4684 if (
Left.is(tok::coloncolon))
4686 if (
Left.is(tok::less) ||
Right.isOneOf(tok::greater, tok::less)) {
4687 if (Style.isTextProto() ||
4688 (Style.Language == FormatStyle::LK_Proto &&
4689 (
Left.is(TT_DictLiteral) ||
Right.is(TT_DictLiteral)))) {
4691 if (
Left.is(tok::less) &&
Right.is(tok::greater))
4693 return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;
4696 if (
Right.isNot(TT_OverloadedOperatorLParen))
4699 if (
Right.is(tok::ellipsis)) {
4700 return Left.Tok.isLiteral() || (
Left.is(tok::identifier) && BeforeLeft &&
4701 BeforeLeft->is(tok::kw_case));
4703 if (
Left.is(tok::l_square) &&
Right.is(tok::amp))
4704 return Style.SpacesInSquareBrackets;
4705 if (
Right.is(TT_PointerOrReference)) {
4706 if (
Left.is(tok::r_paren) &&
Line.MightBeFunctionDecl) {
4707 if (!
Left.MatchingParen)
4710 Left.MatchingParen->getPreviousNonComment();
4711 if (!TokenBeforeMatchingParen ||
Left.isNot(TT_TypeDeclarationParen))
4717 if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_After ||
4718 Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
4719 (
Left.is(TT_AttributeRParen) ||
4720 Left.canBePointerOrReferenceQualifier())) {
4723 if (
Left.Tok.isLiteral())
4726 if (
Left.isTypeOrIdentifier(LangOpts) &&
Right.Next &&
Right.Next->Next &&
4727 Right.Next->Next->is(TT_RangeBasedForLoopColon)) {
4728 return getTokenPointerOrReferenceAlignment(Right) !=
4729 FormatStyle::PAS_Left;
4731 return Left.isNoneOf(TT_PointerOrReference, tok::l_paren) &&
4732 (getTokenPointerOrReferenceAlignment(Right) !=
4733 FormatStyle::PAS_Left ||
4734 (
Line.IsMultiVariableDeclStmt &&
4735 (
Left.NestingLevel == 0 ||
4736 (
Left.NestingLevel == 1 && startsWithInitStatement(
Line)))));
4738 if (
Right.is(TT_FunctionTypeLParen) &&
Left.isNot(tok::l_paren) &&
4739 (
Left.isNot(TT_PointerOrReference) ||
4740 (getTokenPointerOrReferenceAlignment(Left) != FormatStyle::PAS_Right &&
4741 !
Line.IsMultiVariableDeclStmt))) {
4744 if (
Left.is(TT_PointerOrReference)) {
4747 if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Before ||
4748 Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
4749 Right.canBePointerOrReferenceQualifier()) {
4753 if (
Right.Tok.isLiteral())
4756 if (
Right.is(TT_BlockComment))
4760 if (
Right.isOneOf(Keywords.kw_override, Keywords.kw_final, tok::kw_noexcept,
4761 TT_RequiresClause) &&
4762 Right.isNot(TT_StartOfName)) {
4769 if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(LangOpts) &&
Right.Next &&
4770 Right.Next->is(TT_RangeBasedForLoopColon)) {
4771 return getTokenPointerOrReferenceAlignment(Left) !=
4772 FormatStyle::PAS_Right;
4774 if (
Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
4778 if (getTokenPointerOrReferenceAlignment(Left) == FormatStyle::PAS_Right)
4786 if (
Line.IsMultiVariableDeclStmt &&
4787 (
Left.NestingLevel ==
Line.First->NestingLevel ||
4788 ((
Left.NestingLevel ==
Line.First->NestingLevel + 1) &&
4789 startsWithInitStatement(
Line)))) {
4794 if (BeforeLeft->is(tok::coloncolon)) {
4795 if (
Left.isNot(tok::star))
4797 assert(Style.PointerAlignment != FormatStyle::PAS_Right);
4798 if (!
Right.startsSequence(tok::identifier, tok::r_paren))
4801 const auto *LParen =
Right.Next->MatchingParen;
4802 return !LParen || LParen->isNot(TT_FunctionTypeLParen);
4804 return BeforeLeft->isNoneOf(tok::l_paren, tok::l_square);
4807 if (
Left.is(tok::ellipsis) && BeforeLeft &&
4808 BeforeLeft->isPointerOrReference()) {
4809 return Style.PointerAlignment != FormatStyle::PAS_Right;
4812 if (
Right.is(tok::star) &&
Left.is(tok::l_paren))
4814 if (
Left.is(tok::star) &&
Right.isPointerOrReference())
4816 if (
Right.isPointerOrReference()) {
4827 if (
Previous->is(tok::coloncolon)) {
4846 if (
Previous->endsSequence(tok::kw_operator))
4847 return Style.PointerAlignment != FormatStyle::PAS_Left;
4848 if (
Previous->isOneOf(tok::kw_const, tok::kw_volatile)) {
4849 return (Style.PointerAlignment != FormatStyle::PAS_Left) ||
4850 (Style.SpaceAroundPointerQualifiers ==
4851 FormatStyle::SAPQ_After) ||
4852 (Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both);
4856 if (Style.isCSharp() &&
Left.is(Keywords.kw_is) &&
Right.is(tok::l_square))
4858 const auto SpaceRequiredForArrayInitializerLSquare =
4859 [](
const FormatToken &LSquareTok,
const FormatStyle &Style) {
4860 return Style.SpacesInContainerLiterals ||
4862 Style.Cpp11BracedListStyle == FormatStyle::BLS_Block &&
4863 LSquareTok.endsSequence(tok::l_square, tok::colon,
4866 if (
Left.is(tok::l_square)) {
4867 return (
Left.is(TT_ArrayInitializerLSquare) &&
Right.isNot(tok::r_square) &&
4868 SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||
4869 (
Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
4870 TT_LambdaLSquare) &&
4871 Style.SpacesInSquareBrackets &&
Right.isNot(tok::r_square));
4873 if (
Right.is(tok::r_square)) {
4874 return Right.MatchingParen &&
4875 ((
Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&
4876 SpaceRequiredForArrayInitializerLSquare(*
Right.MatchingParen,
4878 (Style.SpacesInSquareBrackets &&
4879 Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
4880 TT_StructuredBindingLSquare,
4881 TT_LambdaLSquare)));
4883 if (
Right.is(tok::l_square) &&
4884 Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
4885 TT_DesignatedInitializerLSquare,
4886 TT_StructuredBindingLSquare, TT_AttributeLSquare) &&
4887 Left.isNoneOf(tok::numeric_constant, TT_DictLiteral) &&
4888 !(
Left.isNot(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
4889 Right.is(TT_ArraySubscriptLSquare))) {
4893 (
Right.is(tok::r_brace) &&
Right.MatchingParen &&
4895 return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block ||
4896 Style.SpacesInParensOptions.Other;
4898 if (
Left.is(TT_BlockComment)) {
4900 return Style.isJavaScript() || !
Left.TokenText.ends_with(
"=*/");
4905 if (
Left.is(TT_TemplateCloser) &&
Right.is(TT_AttributeLSquare))
4908 if (
Right.is(tok::l_paren)) {
4909 if (
Left.is(TT_TemplateCloser) &&
Right.isNot(TT_FunctionTypeLParen))
4910 return spaceRequiredBeforeParens(Right);
4911 if (
Left.isOneOf(TT_RequiresClause,
4912 TT_RequiresClauseInARequiresExpression)) {
4913 return Style.SpaceBeforeParensOptions.AfterRequiresInClause ||
4914 spaceRequiredBeforeParens(Right);
4916 if (
Left.is(TT_RequiresExpression)) {
4917 return Style.SpaceBeforeParensOptions.AfterRequiresInExpression ||
4918 spaceRequiredBeforeParens(Right);
4920 if (
Left.isOneOf(TT_AttributeRParen, TT_AttributeRSquare))
4922 if (
Left.is(TT_ForEachMacro)) {
4923 return Style.SpaceBeforeParensOptions.AfterForeachMacros ||
4924 spaceRequiredBeforeParens(Right);
4926 if (
Left.is(TT_IfMacro)) {
4927 return Style.SpaceBeforeParensOptions.AfterIfMacros ||
4928 spaceRequiredBeforeParens(Right);
4930 if (Style.SpaceBeforeParens == FormatStyle::SBPO_Custom &&
4931 Left.isPlacementOperator() &&
4932 Right.isNot(TT_OverloadedOperatorLParen) &&
4933 !(
Line.MightBeFunctionDecl &&
Left.is(TT_FunctionDeclarationName))) {
4934 const auto *RParen =
Right.MatchingParen;
4935 return Style.SpaceBeforeParensOptions.AfterPlacementOperator ||
4936 (RParen && RParen->is(TT_CastRParen));
4940 if (
Left.is(tok::semi))
4942 if (
Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch,
4943 tok::kw_case, TT_ForEachMacro, TT_ObjCForIn) ||
4945 Right.is(TT_ConditionLParen)) {
4946 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4947 spaceRequiredBeforeParens(Right);
4952 if (
Right.is(TT_OverloadedOperatorLParen))
4953 return spaceRequiredBeforeParens(Right);
4955 if (
Line.MightBeFunctionDecl &&
Right.is(TT_FunctionDeclarationLParen)) {
4956 if (spaceRequiredBeforeParens(Right))
4958 const auto &Options = Style.SpaceBeforeParensOptions;
4959 return Line.mightBeFunctionDefinition()
4960 ? Options.AfterFunctionDefinitionName
4961 : Options.AfterFunctionDeclarationName;
4965 Left.MatchingParen &&
Left.MatchingParen->is(TT_LambdaLSquare)) {
4966 return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
4967 spaceRequiredBeforeParens(Right);
4969 if (!BeforeLeft || BeforeLeft->isNoneOf(tok::period, tok::arrow)) {
4970 if (
Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
4971 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4972 spaceRequiredBeforeParens(Right);
4974 if (
Left.isPlacementOperator() ||
4975 (
Left.is(tok::r_square) &&
Left.MatchingParen &&
4976 Left.MatchingParen->Previous &&
4977 Left.MatchingParen->Previous->is(tok::kw_delete))) {
4978 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never ||
4979 spaceRequiredBeforeParens(Right);
4984 (
Left.Tok.getIdentifierInfo() ||
Left.is(tok::r_paren))) {
4985 return spaceRequiredBeforeParens(Right);
4989 if (
Left.is(tok::at) &&
Right.isNot(tok::objc_not_keyword))
4991 if (
Right.is(TT_UnaryOperator)) {
4992 return Left.isNoneOf(tok::l_paren, tok::l_square, tok::at) &&
4993 (
Left.isNot(tok::colon) ||
Left.isNot(TT_ObjCMethodExpr));
4999 if (!Style.isVerilog() &&
5000 (
Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
5002 Left.isTypeName(LangOpts)) &&
5003 Right.is(tok::l_brace) &&
Right.getNextNonComment() &&
5007 if (
Left.is(tok::period) ||
Right.is(tok::period))
5011 if (
Right.is(tok::hash) &&
Left.is(tok::identifier) &&
5012 (
Left.TokenText ==
"L" ||
Left.TokenText ==
"u" ||
5013 Left.TokenText ==
"U" ||
Left.TokenText ==
"u8" ||
5014 Left.TokenText ==
"LR" ||
Left.TokenText ==
"uR" ||
5015 Left.TokenText ==
"UR" ||
Left.TokenText ==
"u8R")) {
5018 if (
Left.is(TT_TemplateCloser) &&
Left.MatchingParen &&
5019 Left.MatchingParen->Previous &&
5020 Left.MatchingParen->Previous->isOneOf(tok::period, tok::coloncolon)) {
5026 if (
Left.is(TT_TemplateCloser) &&
Right.is(tok::l_square))
5028 if (
Left.is(tok::l_brace) &&
Left.endsSequence(TT_DictLiteral, tok::at)) {
5032 if (
Right.is(tok::r_brace) &&
Right.MatchingParen &&
5033 Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at)) {
5037 if (
Right.is(TT_TrailingAnnotation) &&
Right.isOneOf(tok::amp, tok::ampamp) &&
5038 Left.isOneOf(tok::kw_const, tok::kw_volatile) &&
5039 (!
Right.Next ||
Right.Next->is(tok::semi))) {
5043 return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;
5056 return Right.hasWhitespaceBefore();
5058 const bool IsVerilog = Style.isVerilog();
5059 assert(!IsVerilog || !IsCpp);
5062 if (Keywords.isWordLike(Right, IsVerilog) &&
5063 Keywords.isWordLike(Left, IsVerilog)) {
5069 if (
Left.is(tok::star) &&
Right.is(tok::comment))
5072 if (
Left.is(tok::l_brace) &&
Right.is(tok::r_brace) &&
5073 Left.Children.empty()) {
5075 return Style.SpaceInEmptyBraces != FormatStyle::SIEB_Never;
5076 if (Style.Cpp11BracedListStyle != FormatStyle::BLS_Block) {
5077 return Style.SpacesInParens == FormatStyle::SIPO_Custom &&
5078 Style.SpacesInParensOptions.InEmptyParentheses;
5080 return Style.SpaceInEmptyBraces == FormatStyle::SIEB_Always;
5083 const auto *BeforeLeft =
Left.Previous;
5086 if (
Left.is(TT_OverloadedOperator) &&
5087 Right.isOneOf(TT_TemplateOpener, TT_TemplateCloser)) {
5091 if (
Right.is(tok::period) &&
Left.is(tok::numeric_constant))
5095 if (
Left.is(Keywords.kw_import) &&
5096 Right.isOneOf(tok::less, tok::ellipsis) &&
5097 (!BeforeLeft || BeforeLeft->is(tok::kw_export))) {
5101 if (
Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&
5102 Right.is(TT_ModulePartitionColon)) {
5106 if (
Right.is(TT_AfterPPDirective))
5110 if (
Left.is(tok::identifier) &&
Right.is(TT_ModulePartitionColon))
5113 if (
Left.is(TT_ModulePartitionColon) &&
5114 Right.isOneOf(tok::identifier, tok::kw_private)) {
5117 if (
Left.is(tok::ellipsis) &&
Right.is(tok::identifier) &&
5118 Line.First->is(Keywords.kw_import)) {
5122 if (
Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&
5123 Right.is(tok::coloncolon)) {
5127 if (
Left.is(tok::kw_operator))
5128 return Right.is(tok::coloncolon) || Style.SpaceAfterOperatorKeyword;
5130 !
Left.opensScope() && Style.SpaceBeforeCpp11BracedList) {
5133 if (
Left.is(tok::less) &&
Left.is(TT_OverloadedOperator) &&
5134 Right.is(TT_TemplateOpener)) {
5138 if (
Left.is(tok::identifier) &&
Right.is(tok::numeric_constant))
5139 return Right.TokenText[0] !=
'.';
5141 if (
Left.Tok.getIdentifierInfo() &&
Right.Tok.isLiteral())
5143 }
else if (Style.isProto()) {
5144 if (
Right.is(tok::period) && !(BeforeLeft && BeforeLeft->is(tok::period)) &&
5145 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
5146 Keywords.kw_repeated, Keywords.kw_extend)) {
5149 if (
Right.is(tok::l_paren) &&
5150 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) {
5153 if (
Right.isOneOf(tok::l_brace, tok::less) &&
Left.is(TT_SelectorName))
5156 if (
Left.is(tok::slash) ||
Right.is(tok::slash))
5158 if (
Left.MatchingParen &&
5159 Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
5160 Right.isOneOf(tok::l_brace, tok::less)) {
5161 return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;
5164 if (
Left.is(tok::percent))
5168 if (
Left.is(tok::numeric_constant) &&
Right.is(tok::percent))
5169 return Right.hasWhitespaceBefore();
5170 }
else if (Style.isJson()) {
5171 if (
Right.is(tok::colon) &&
Left.is(tok::string_literal))
5172 return Style.SpaceBeforeJsonColon;
5173 }
else if (Style.isCSharp()) {
5179 if (
Left.is(tok::kw_this) &&
Right.is(tok::l_square))
5183 if (
Left.is(tok::kw_new) &&
Right.is(tok::l_paren))
5187 if (
Right.is(tok::l_brace))
5191 if (
Left.is(tok::l_brace) &&
Right.isNot(tok::r_brace))
5194 if (
Left.isNot(tok::l_brace) &&
Right.is(tok::r_brace))
5198 if (
Left.is(TT_FatArrow) ||
Right.is(TT_FatArrow))
5202 if (
Left.is(TT_AttributeColon) ||
Right.is(TT_AttributeColon))
5206 if (
Left.is(TT_TemplateCloser) &&
Right.is(TT_StartOfName))
5210 if (
Left.is(tok::l_square) ||
Right.is(tok::r_square))
5211 return Style.SpacesInSquareBrackets;
5214 if (
Right.is(TT_CSharpNullable))
5218 if (
Right.is(TT_NonNullAssertion))
5222 if (
Left.is(tok::comma) &&
Right.is(tok::comma))
5226 if (
Left.is(Keywords.kw_var) &&
Right.is(tok::l_paren))
5230 if (
Right.is(tok::l_paren)) {
5231 if (
Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when,
5232 Keywords.kw_lock)) {
5233 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
5234 spaceRequiredBeforeParens(Right);
5240 if ((
Left.isAccessSpecifierKeyword() ||
5241 Left.isOneOf(tok::kw_virtual, tok::kw_extern, tok::kw_static,
5242 Keywords.kw_internal, Keywords.kw_abstract,
5243 Keywords.kw_sealed, Keywords.kw_override,
5244 Keywords.kw_async, Keywords.kw_unsafe)) &&
5245 Right.is(tok::l_paren)) {
5248 }
else if (Style.isJavaScript()) {
5249 if (
Left.is(TT_FatArrow))
5252 if (
Right.is(tok::l_paren) &&
Left.is(Keywords.kw_await) && BeforeLeft &&
5253 BeforeLeft->is(tok::kw_for)) {
5256 if (
Left.is(Keywords.kw_async) &&
Right.is(tok::l_paren) &&
5257 Right.MatchingParen) {
5264 if ((
Left.is(TT_TemplateString) &&
Left.TokenText.ends_with(
"${")) ||
5265 (
Right.is(TT_TemplateString) &&
Right.TokenText.starts_with(
"}"))) {
5270 if (Keywords.isJavaScriptIdentifier(Left,
5272 Right.is(TT_TemplateString)) {
5275 if (
Right.is(tok::star) &&
5276 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) {
5279 if (
Right.isOneOf(tok::l_brace, tok::l_square) &&
5280 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,
5281 Keywords.kw_extends, Keywords.kw_implements)) {
5284 if (
Right.is(tok::l_paren)) {
5286 if (
Line.MustBeDeclaration &&
Left.Tok.getIdentifierInfo())
5290 if (BeforeLeft && BeforeLeft->is(tok::period) &&
5291 Left.Tok.getIdentifierInfo()) {
5295 if (
Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
5301 if (
Left.endsSequence(tok::kw_const, Keywords.kw_as))
5303 if ((
Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
5308 (
Left.is(Keywords.kw_of) && BeforeLeft &&
5309 BeforeLeft->isOneOf(tok::identifier, tok::r_square, tok::r_brace))) &&
5310 (!BeforeLeft || BeforeLeft->isNot(tok::period))) {
5313 if (
Left.isOneOf(tok::kw_for, Keywords.kw_as) && BeforeLeft &&
5314 BeforeLeft->is(tok::period) &&
Right.is(tok::l_paren)) {
5317 if (
Left.is(Keywords.kw_as) &&
5318 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) {
5321 if (
Left.is(tok::kw_default) && BeforeLeft &&
5322 BeforeLeft->is(tok::kw_export)) {
5325 if (
Left.is(Keywords.kw_is) &&
Right.is(tok::l_brace))
5327 if (
Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
5329 if (
Left.is(TT_JsTypeOperator) ||
Right.is(TT_JsTypeOperator))
5331 if ((
Left.is(tok::l_brace) ||
Right.is(tok::r_brace)) &&
5332 Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) {
5335 if (
Left.is(tok::ellipsis))
5337 if (
Left.is(TT_TemplateCloser) &&
5338 Right.isNoneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
5339 Keywords.kw_implements, Keywords.kw_extends)) {
5345 if (
Right.is(TT_NonNullAssertion))
5347 if (
Left.is(TT_NonNullAssertion) &&
5348 Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) {
5351 }
else if (Style.isJava()) {
5352 if (
Left.is(TT_CaseLabelArrow) ||
Right.is(TT_CaseLabelArrow))
5354 if (
Left.is(tok::r_square) &&
Right.is(tok::l_brace))
5357 if (
Left.is(tok::l_square) ||
Right.is(tok::r_square))
5358 return Style.SpacesInSquareBrackets;
5360 if (
Left.is(Keywords.kw_synchronized) &&
Right.is(tok::l_paren)) {
5361 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
5362 spaceRequiredBeforeParens(Right);
5364 if ((
Left.isAccessSpecifierKeyword() ||
5365 Left.isOneOf(tok::kw_static, Keywords.kw_final, Keywords.kw_abstract,
5366 Keywords.kw_native)) &&
5367 Right.is(TT_TemplateOpener)) {
5370 }
else if (IsVerilog) {
5372 if (
Left.is(tok::identifier) &&
Left.TokenText[0] ==
'\\')
5376 if ((
Left.is(TT_VerilogTableItem) &&
5377 Right.isNoneOf(tok::r_paren, tok::semi)) ||
5378 (
Right.is(TT_VerilogTableItem) &&
Left.isNot(tok::l_paren))) {
5380 return !(
Next &&
Next->is(tok::r_paren));
5383 if (
Left.isNot(TT_BinaryOperator) &&
5384 Left.isOneOf(Keywords.kw_verilogHash, Keywords.kw_verilogHashHash)) {
5388 if (
Right.isNot(tok::semi) &&
5389 (
Left.endsSequence(tok::numeric_constant, Keywords.kw_verilogHash) ||
5390 Left.endsSequence(tok::numeric_constant,
5391 Keywords.kw_verilogHashHash) ||
5392 (
Left.is(tok::r_paren) &&
Left.MatchingParen &&
5393 Left.MatchingParen->endsSequence(tok::l_paren, tok::at)))) {
5398 if (
Left.is(Keywords.kw_apostrophe) ||
5399 (
Left.is(TT_VerilogNumberBase) &&
Right.is(tok::numeric_constant))) {
5403 if (
Left.is(tok::arrow) ||
Right.is(tok::arrow))
5408 if (
Left.is(tok::at) &&
Right.isOneOf(tok::l_paren, tok::star, tok::at))
5411 if (
Right.is(tok::l_square) &&
5412 Left.isOneOf(TT_VerilogDimensionedTypeName, Keywords.kw_function)) {
5416 if (
Right.isOneOf(tok::period, Keywords.kw_apostrophe) &&
5417 Keywords.isVerilogIdentifier(Left) &&
Left.getPreviousNonComment() &&
5418 Left.getPreviousNonComment()->is(Keywords.kw_tagged)) {
5424 if ((
Right.is(Keywords.kw_apostrophe) ||
5426 Left.isNoneOf(Keywords.kw_assign, Keywords.kw_unique) &&
5427 !Keywords.isVerilogWordOperator(Left) &&
5428 (
Left.isOneOf(tok::r_square, tok::r_paren, tok::r_brace,
5429 tok::numeric_constant) ||
5430 Keywords.isWordLike(Left))) {
5434 if ((
Right.is(tok::star) &&
Left.is(tok::coloncolon)) ||
5435 (
Left.is(tok::star) &&
Right.is(tok::semi))) {
5439 if (
Left.endsSequence(tok::star, tok::l_paren) &&
Right.is(tok::identifier))
5442 if (
Right.is(tok::l_paren) &&
Right.is(TT_VerilogStrength))
5445 if ((
Left.is(tok::l_brace) &&
5446 Right.isOneOf(tok::lessless, tok::greatergreater)) ||
5447 (
Left.endsSequence(tok::lessless, tok::l_brace) ||
5448 Left.endsSequence(tok::greatergreater, tok::l_brace))) {
5451 }
else if (Style.isTableGen()) {
5453 if (
Left.is(tok::l_square) &&
Right.is(tok::l_brace))
5455 if (
Left.is(tok::r_brace) &&
Right.is(tok::r_square))
5458 if (
Right.isOneOf(TT_TableGenDAGArgListColon,
5459 TT_TableGenDAGArgListColonToAlign) ||
5460 Left.isOneOf(TT_TableGenDAGArgListColon,
5461 TT_TableGenDAGArgListColonToAlign)) {
5464 if (
Right.is(TT_TableGenCondOperatorColon))
5466 if (
Left.isOneOf(TT_TableGenDAGArgOperatorID,
5467 TT_TableGenDAGArgOperatorToBreak) &&
5468 Right.isNot(TT_TableGenDAGArgCloser)) {
5472 if (
Right.isOneOf(tok::l_paren, tok::less) &&
5473 Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
5478 if (
Left.is(TT_TableGenTrailingPasteOperator) &&
5479 Right.isOneOf(tok::l_brace, tok::colon)) {
5483 if (
Left.is(tok::hash) ||
Right.is(tok::hash))
5486 if (Keywords.isTableGenDefinition(Left))
5490 if (
Left.is(TT_ImplicitStringLiteral))
5491 return Right.hasWhitespaceBefore();
5493 if (
Left.is(TT_ObjCMethodSpecifier))
5494 return Style.ObjCSpaceAfterMethodDeclarationPrefix;
5495 if (
Left.is(tok::r_paren) &&
Left.isNot(TT_AttributeRParen) &&
5496 canBeObjCSelectorComponent(Right)) {
5504 (
Right.is(tok::equal) ||
Left.is(tok::equal))) {
5508 if (
Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
5509 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) {
5512 if (
Left.is(tok::comma) &&
Right.isNot(TT_OverloadedOperatorLParen) &&
5515 (
Left.Children.empty() || !
Left.MacroParent)) {
5518 if (
Right.is(tok::comma))
5520 if (
Right.is(TT_ObjCBlockLParen))
5522 if (
Right.is(TT_CtorInitializerColon))
5523 return Style.SpaceBeforeCtorInitializerColon;
5524 if (
Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)
5526 if (
Right.is(TT_RangeBasedForLoopColon) &&
5527 !Style.SpaceBeforeRangeBasedForLoopColon) {
5530 if (
Left.is(TT_BitFieldColon)) {
5531 return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||
5532 Style.BitFieldColonSpacing == FormatStyle::BFCS_After;
5534 if (
Right.is(tok::colon)) {
5535 if (
Right.is(TT_CaseLabelColon))
5536 return Style.SpaceBeforeCaseColon;
5537 if (
Right.is(TT_GotoLabelColon))
5540 if (!
Right.getNextNonComment())
5542 if (
Right.isOneOf(TT_ObjCSelector, TT_ObjCMethodExpr))
5544 if (
Left.is(tok::question))
5546 if (
Right.is(TT_InlineASMColon) &&
Left.is(tok::coloncolon))
5548 if (
Right.is(TT_DictLiteral))
5549 return Style.SpacesInContainerLiterals;
5550 if (
Right.is(TT_AttributeColon))
5552 if (
Right.is(TT_CSharpNamedArgumentColon))
5554 if (
Right.is(TT_GenericSelectionColon))
5556 if (
Right.is(TT_BitFieldColon)) {
5557 return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||
5558 Style.BitFieldColonSpacing == FormatStyle::BFCS_Before;
5563 if ((
Left.isOneOf(tok::minus, tok::minusminus) &&
5564 Right.isOneOf(tok::minus, tok::minusminus)) ||
5565 (
Left.isOneOf(tok::plus, tok::plusplus) &&
5566 Right.isOneOf(tok::plus, tok::plusplus))) {
5569 if (
Left.is(TT_UnaryOperator)) {
5572 if (
Left.is(tok::amp) &&
Right.is(tok::r_square))
5573 return Style.SpacesInSquareBrackets;
5574 if (
Left.isNot(tok::exclaim))
5576 if (
Left.TokenText ==
"!")
5577 return Style.SpaceAfterLogicalNot;
5578 assert(
Left.TokenText ==
"not");
5579 return Right.isOneOf(tok::coloncolon, TT_UnaryOperator) ||
5580 (
Right.is(tok::l_paren) && Style.SpaceBeforeParensOptions.AfterNot);
5585 if (
Left.is(TT_CastRParen)) {
5586 return Style.SpaceAfterCStyleCast ||
5587 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
5590 auto ShouldAddSpacesInAngles = [
this, &
Right]() {
5591 if (this->Style.SpacesInAngles == FormatStyle::SIAS_Always)
5593 if (this->Style.SpacesInAngles == FormatStyle::SIAS_Leave)
5594 return Right.hasWhitespaceBefore();
5598 if (
Left.is(tok::greater) &&
Right.is(tok::greater)) {
5599 if (Style.isTextProto() ||
5600 (Style.Language == FormatStyle::LK_Proto &&
Left.is(TT_DictLiteral))) {
5601 return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;
5603 return Right.is(TT_TemplateCloser) &&
Left.is(TT_TemplateCloser) &&
5604 ((Style.Standard < FormatStyle::LS_Cpp11) ||
5605 ShouldAddSpacesInAngles());
5607 if (
Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
5608 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
5609 (
Right.is(tok::period) &&
Right.isNot(TT_DesignatedInitializerPeriod))) {
5612 if (!Style.SpaceBeforeAssignmentOperators &&
Left.isNot(TT_TemplateCloser) &&
5616 if (Style.isJava() &&
Right.is(tok::coloncolon) &&
5617 Left.isOneOf(tok::identifier, tok::kw_this)) {
5620 if (
Right.is(tok::coloncolon) &&
Left.is(tok::identifier)) {
5624 return Right.hasWhitespaceBefore();
5626 if (
Right.is(tok::coloncolon) &&
5627 Left.isNoneOf(tok::l_brace, tok::comment, tok::l_paren)) {
5629 return (
Left.is(TT_TemplateOpener) &&
5630 ((Style.Standard < FormatStyle::LS_Cpp11) ||
5631 ShouldAddSpacesInAngles())) ||
5632 Left.isNoneOf(tok::l_paren, tok::r_paren, tok::l_square,
5633 tok::kw___super, TT_TemplateOpener,
5634 TT_TemplateCloser) ||
5635 (
Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other);
5637 if ((
Left.is(TT_TemplateOpener)) != (
Right.is(TT_TemplateCloser)))
5638 return ShouldAddSpacesInAngles();
5639 if (
Left.is(tok::r_paren) &&
Left.isNot(TT_TypeDeclarationParen) &&
5640 Right.is(TT_PointerOrReference) &&
Right.isOneOf(tok::amp, tok::ampamp)) {
5644 if (
Right.is(TT_StructuredBindingLSquare)) {
5645 return Left.isNoneOf(tok::amp, tok::ampamp) ||
5646 getTokenReferenceAlignment(Left) != FormatStyle::PAS_Right;
5649 if (
Right.Next &&
Right.Next->is(TT_StructuredBindingLSquare) &&
5650 Right.isOneOf(tok::amp, tok::ampamp)) {
5651 return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;
5653 if ((
Right.is(TT_BinaryOperator) &&
Left.isNot(tok::l_paren)) ||
5654 (
Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
5655 Right.isNot(tok::r_paren))) {
5658 if (
Right.is(TT_TemplateOpener) &&
Left.is(tok::r_paren) &&
5659 Left.MatchingParen &&
5660 Left.MatchingParen->is(TT_OverloadedOperatorLParen)) {
5663 if (
Right.is(tok::less) &&
Left.isNot(tok::l_paren) &&
5667 if (
Right.is(TT_TrailingUnaryOperator))
5669 if (
Left.is(TT_RegexLiteral))
5671 return spaceRequiredBetween(
Line, Left, Right);
5677 Tok.isNoneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
5682 return Tok.MatchingParen &&
Tok.MatchingParen->Next &&
5683 Tok.MatchingParen->Next->isOneOf(tok::comma, tok::r_paren,
5689 FormatStyle::ShortLambdaStyle ShortLambdaOption) {
5690 return Tok.Children.empty() && ShortLambdaOption != FormatStyle::SLS_None;
5695 Tok.isNoneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
5698bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &
Line,
5700 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
5701 (!Style.RemoveEmptyLinesInUnwrappedLines || &Right ==
Line.First)) {
5707 if (Style.BreakFunctionDefinitionParameters &&
Line.MightBeFunctionDecl &&
5708 Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
5709 Left.ParameterCount > 0) {
5715 if (Style.BinPackParameters == FormatStyle::BPPS_AlwaysOnePerLine &&
5716 Line.MightBeFunctionDecl && !
Left.opensScope() &&
5721 const auto *BeforeLeft =
Left.Previous;
5722 const auto *AfterRight =
Right.Next;
5724 if (Style.isCSharp()) {
5725 if (
Left.is(TT_FatArrow) &&
Right.is(tok::l_brace) &&
5726 Style.BraceWrapping.AfterFunction) {
5729 if (
Right.is(TT_CSharpNamedArgumentColon) ||
5730 Left.is(TT_CSharpNamedArgumentColon)) {
5733 if (
Right.is(TT_CSharpGenericTypeConstraint))
5735 if (AfterRight && AfterRight->is(TT_FatArrow) &&
5736 (
Right.is(tok::numeric_constant) ||
5737 (
Right.is(tok::identifier) &&
Right.TokenText ==
"_"))) {
5742 if (
Left.is(TT_AttributeRSquare) &&
5743 (
Right.isAccessSpecifier(
false) ||
5744 Right.is(Keywords.kw_internal))) {
5748 if (
Left.is(TT_AttributeRSquare) &&
Right.is(TT_AttributeLSquare))
5750 }
else if (Style.isJavaScript()) {
5752 if (
Right.is(tok::string_literal) &&
Left.is(tok::plus) && BeforeLeft &&
5753 BeforeLeft->is(tok::string_literal)) {
5756 if (
Left.is(TT_DictLiteral) &&
Left.is(tok::l_brace) &&
Line.Level == 0 &&
5757 BeforeLeft && BeforeLeft->is(tok::equal) &&
5758 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
5762 Line.First->isNoneOf(Keywords.kw_var, Keywords.kw_let)) {
5767 if (
Left.is(tok::l_brace) &&
Line.Level == 0 &&
5768 (
Line.startsWith(tok::kw_enum) ||
5769 Line.startsWith(tok::kw_const, tok::kw_enum) ||
5770 Line.startsWith(tok::kw_export, tok::kw_enum) ||
5771 Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum))) {
5776 if (
Right.is(tok::r_brace) &&
Left.is(tok::l_brace) && BeforeLeft &&
5777 BeforeLeft->is(TT_FatArrow)) {
5779 switch (Style.AllowShortLambdasOnASingleLine) {
5780 case FormatStyle::SLS_All:
5782 case FormatStyle::SLS_None:
5784 case FormatStyle::SLS_Empty:
5785 return !
Left.Children.empty();
5786 case FormatStyle::SLS_Inline:
5789 return (
Left.NestingLevel == 0 &&
Line.Level == 0) &&
5790 !
Left.Children.empty();
5792 llvm_unreachable(
"Unknown FormatStyle::ShortLambdaStyle enum");
5795 if (
Right.is(tok::r_brace) &&
Left.is(tok::l_brace) &&
5796 !
Left.Children.empty()) {
5798 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
5799 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
5800 (
Left.NestingLevel == 0 &&
Line.Level == 0 &&
5801 Style.AllowShortFunctionsOnASingleLine &
5802 FormatStyle::SFS_InlineOnly);
5804 }
else if (Style.isJava()) {
5805 if (
Right.is(tok::plus) &&
Left.is(tok::string_literal) && AfterRight &&
5806 AfterRight->is(tok::string_literal)) {
5809 }
else if (Style.isVerilog()) {
5811 if (
Left.is(TT_VerilogAssignComma))
5814 if (
Left.is(TT_VerilogTypeComma))
5818 if (Style.VerilogBreakBetweenInstancePorts &&
5819 (
Left.is(TT_VerilogInstancePortComma) ||
5820 (
Left.is(tok::r_paren) && Keywords.isVerilogIdentifier(Right) &&
5821 Left.MatchingParen &&
5822 Left.MatchingParen->is(TT_VerilogInstancePortLParen)))) {
5827 if (!Keywords.isVerilogBegin(Right) && Keywords.isVerilogEndOfLabel(Left))
5829 }
else if (Style.BreakAdjacentStringLiterals &&
5830 (IsCpp || Style.isProto() || Style.isTableGen())) {
5831 if (
Left.isStringLiteral() &&
Right.isStringLiteral())
5836 if (Style.isJson()) {
5840 if (
Left.is(TT_DictLiteral) &&
Left.is(tok::l_brace))
5843 if ((
Left.is(TT_ArrayInitializerLSquare) &&
Left.is(tok::l_square) &&
5844 Right.isNot(tok::r_square)) ||
5845 Left.is(tok::comma)) {
5846 if (
Right.is(tok::l_brace))
5851 if (
Tok->isOneOf(tok::l_brace, tok::l_square))
5853 if (
Tok->isOneOf(tok::r_brace, tok::r_square))
5856 return Style.BreakArrays;
5858 }
else if (Style.isTableGen()) {
5862 if (
Left.is(TT_TableGenCondOperatorComma))
5864 if (
Left.is(TT_TableGenDAGArgOperatorToBreak) &&
5865 Right.isNot(TT_TableGenDAGArgCloser)) {
5868 if (
Left.is(TT_TableGenDAGArgListCommaToBreak))
5870 if (
Right.is(TT_TableGenDAGArgCloser) &&
Right.MatchingParen &&
5871 Right.MatchingParen->is(TT_TableGenDAGArgOpenerToBreak) &&
5872 &Left !=
Right.MatchingParen->Next) {
5874 return Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll;
5878 if (
Line.startsWith(tok::kw_asm) &&
Right.is(TT_InlineASMColon) &&
5879 Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always) {
5889 if ((
Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
5890 (Style.isJavaScript() &&
Left.is(tok::l_paren))) &&
5892 BeforeClosingBrace =
Left.MatchingParen->Previous;
5893 }
else if (
Right.MatchingParen &&
5894 (
Right.MatchingParen->isOneOf(tok::l_brace,
5895 TT_ArrayInitializerLSquare) ||
5896 (Style.isJavaScript() &&
5897 Right.MatchingParen->is(tok::l_paren)))) {
5898 BeforeClosingBrace = &
Left;
5900 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
5901 BeforeClosingBrace->isTrailingComment())) {
5906 if (
Right.is(tok::comment)) {
5908 Right.NewlinesBefore > 0 &&
Right.HasUnescapedNewline;
5910 if (
Left.isTrailingComment())
5912 if (
Left.IsUnterminatedLiteral)
5915 if (BeforeLeft && BeforeLeft->is(tok::lessless) &&
5916 Left.is(tok::string_literal) &&
Right.is(tok::lessless) && AfterRight &&
5917 AfterRight->is(tok::string_literal)) {
5918 return Right.NewlinesBefore > 0;
5921 if (
Right.is(TT_RequiresClause)) {
5922 switch (Style.RequiresClausePosition) {
5923 case FormatStyle::RCPS_OwnLine:
5924 case FormatStyle::RCPS_OwnLineWithBrace:
5925 case FormatStyle::RCPS_WithFollowing:
5932 if (
Left.ClosesTemplateDeclaration &&
Left.MatchingParen &&
5933 Left.MatchingParen->NestingLevel == 0) {
5937 if (
Right.is(tok::kw_concept))
5938 return Style.BreakBeforeConceptDeclarations == FormatStyle::BBCDS_Always;
5939 return Style.BreakTemplateDeclarations == FormatStyle::BTDS_Yes ||
5940 (Style.BreakTemplateDeclarations == FormatStyle::BTDS_Leave &&
5941 Right.NewlinesBefore > 0);
5943 if (
Left.ClosesRequiresClause) {
5944 switch (Style.RequiresClausePosition) {
5945 case FormatStyle::RCPS_OwnLine:
5946 case FormatStyle::RCPS_WithPreceding:
5947 return Right.isNot(tok::semi);
5948 case FormatStyle::RCPS_OwnLineWithBrace:
5949 return Right.isNoneOf(tok::semi, tok::l_brace);
5954 if (Style.PackConstructorInitializers == FormatStyle::PCIS_Never) {
5955 if (Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon &&
5956 (
Left.is(TT_CtorInitializerComma) ||
5957 Right.is(TT_CtorInitializerColon))) {
5961 if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&
5962 Left.isOneOf(TT_CtorInitializerColon, TT_CtorInitializerComma)) {
5966 if (Style.PackConstructorInitializers < FormatStyle::PCIS_CurrentLine &&
5967 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
5968 Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) {
5971 if (Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly) {
5972 if ((Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon ||
5973 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) &&
5974 Right.is(TT_CtorInitializerColon)) {
5978 if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&
5979 Left.is(TT_CtorInitializerColon)) {
5984 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
5985 Right.is(TT_InheritanceComma)) {
5988 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterComma &&
5989 Left.is(TT_InheritanceComma)) {
5992 if (
Right.is(tok::string_literal) &&
Right.TokenText.starts_with(
"R\"")) {
5996 return Right.IsMultiline &&
Right.NewlinesBefore > 0;
5998 if ((
Left.is(tok::l_brace) ||
5999 (
Left.is(tok::less) && BeforeLeft && BeforeLeft->is(tok::equal))) &&
6000 Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {
6005 if (
Right.is(TT_InlineASMBrace))
6006 return Right.HasUnescapedNewline;
6009 auto *FirstNonComment =
Line.getFirstNonComment();
6011 FirstNonComment && (FirstNonComment->is(Keywords.kw_internal) ||
6012 FirstNonComment->isAccessSpecifierKeyword());
6014 if (Style.BraceWrapping.AfterEnum) {
6015 if (
Line.startsWith(tok::kw_enum) ||
6016 Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
6021 FirstNonComment->Next->is(tok::kw_enum)) {
6027 if (Style.BraceWrapping.AfterClass &&
6029 FirstNonComment->Next->is(Keywords.kw_interface)) ||
6030 Line.startsWith(Keywords.kw_interface))) {
6035 if (
Right.isNot(TT_FunctionLBrace)) {
6036 return (
Line.startsWith(tok::kw_class) &&
6037 Style.BraceWrapping.AfterClass) ||
6038 (
Line.startsWith(tok::kw_struct) &&
6039 Style.BraceWrapping.AfterStruct);
6043 if (
Left.is(TT_ObjCBlockLBrace) &&
6044 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) {
6049 if (
Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&
6050 Right.is(TT_ObjCDecl)) {
6054 if (
Left.is(TT_LambdaLBrace)) {
6056 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline) {
6060 if (Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_None ||
6061 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline ||
6062 (!
Left.Children.empty() &&
6063 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Empty)) {
6068 if (Style.BraceWrapping.BeforeLambdaBody &&
Right.is(TT_LambdaLBrace) &&
6069 (
Left.isPointerOrReference() ||
Left.is(TT_TemplateCloser))) {
6074 if ((Style.isJava() || Style.isJavaScript()) &&
6075 Left.is(TT_LeadingJavaAnnotation) &&
6076 Right.isNoneOf(TT_LeadingJavaAnnotation, tok::l_paren) &&
6077 (
Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) {
6081 if (
Right.is(TT_ProtoExtensionLSquare))
6111 if (Style.isProto() &&
Right.is(TT_SelectorName) &&
6112 Right.isNot(tok::r_square) && AfterRight) {
6115 if (
Left.is(tok::at))
6121 const auto *LBrace = AfterRight;
6122 if (LBrace && LBrace->is(tok::colon)) {
6123 LBrace = LBrace->Next;
6124 if (LBrace && LBrace->is(tok::at)) {
6125 LBrace = LBrace->Next;
6127 LBrace = LBrace->Next;
6139 ((LBrace->is(tok::l_brace) &&
6140 (LBrace->is(TT_DictLiteral) ||
6141 (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||
6142 LBrace->isOneOf(TT_ArrayInitializerLSquare, tok::less))) {
6149 if (
Left.ParameterCount == 0)
6164 if (
Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))
6175 if (Style.isCSharp()) {
6176 if (
Left.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon) ||
6177 Right.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon)) {
6181 if (
Line.First->is(TT_CSharpGenericTypeConstraint))
6182 return Left.is(TT_CSharpGenericTypeConstraintComma);
6184 if (
Right.is(TT_CSharpNullable))
6186 }
else if (Style.isJava()) {
6187 if (
Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
6188 Keywords.kw_implements)) {
6191 if (
Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
6192 Keywords.kw_implements)) {
6195 }
else if (Style.isJavaScript()) {
6198 (NonComment->isAccessSpecifierKeyword() ||
6199 NonComment->isOneOf(
6200 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
6201 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
6202 tok::kw_static, Keywords.kw_readonly, Keywords.kw_override,
6203 Keywords.kw_abstract, Keywords.kw_get, Keywords.kw_set,
6204 Keywords.kw_async, Keywords.kw_await))) {
6207 if (
Right.NestingLevel == 0 &&
6208 (
Left.Tok.getIdentifierInfo() ||
6209 Left.isOneOf(tok::r_square, tok::r_paren)) &&
6210 Right.isOneOf(tok::l_square, tok::l_paren)) {
6213 if (NonComment && NonComment->is(tok::identifier) &&
6214 NonComment->TokenText ==
"asserts") {
6217 if (
Left.is(TT_FatArrow) &&
Right.is(tok::l_brace))
6219 if (
Left.is(TT_JsTypeColon))
6222 if (
Left.is(tok::exclaim) &&
Right.is(tok::colon))
6227 if (
Right.is(Keywords.kw_is)) {
6236 if (!
Next ||
Next->isNot(tok::colon))
6239 if (
Left.is(Keywords.kw_in))
6240 return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None;
6241 if (
Right.is(Keywords.kw_in))
6242 return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
6243 if (
Right.is(Keywords.kw_as))
6245 if (
Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
6251 if (
Left.is(Keywords.kw_as))
6253 if (
Left.is(TT_NonNullAssertion))
6255 if (
Left.is(Keywords.kw_declare) &&
6256 Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
6257 Keywords.kw_function, tok::kw_class, tok::kw_enum,
6258 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
6259 Keywords.kw_let, tok::kw_const)) {
6264 if (
Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
6265 Right.isOneOf(tok::identifier, tok::string_literal)) {
6268 if (
Right.is(TT_TemplateString) &&
Right.closesScope())
6272 if (
Left.is(tok::identifier) &&
Right.is(TT_TemplateString))
6274 if (
Left.is(TT_TemplateString) &&
Left.opensScope())
6276 }
else if (Style.isTableGen()) {
6278 if (Keywords.isTableGenDefinition(Left))
6281 if (
Right.is(tok::l_paren)) {
6282 return Left.isNoneOf(TT_TableGenBangOperator, TT_TableGenCondOperator,
6286 if (
Left.is(TT_TableGenValueSuffix))
6289 if (
Left.is(tok::hash) ||
Right.is(tok::hash))
6291 if (
Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator))
6298 if (
Right.is(tok::r_brace)) {
6300 (
Right.isBlockIndentedInitRBrace(Style)));
6305 if (
Right.is(tok::r_paren)) {
6306 if (!
Right.MatchingParen)
6309 if (
Next &&
Next->is(tok::r_paren))
6311 if (
Next &&
Next->is(tok::l_paren))
6317 return Style.BreakBeforeCloseBracketIf;
6319 return Style.BreakBeforeCloseBracketLoop;
6321 return Style.BreakBeforeCloseBracketSwitch;
6322 return Style.BreakBeforeCloseBracketFunction;
6325 if (
Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) &&
6326 Right.is(TT_TrailingAnnotation) &&
6327 Style.BreakBeforeCloseBracketFunction) {
6331 if (
Right.is(TT_TemplateCloser))
6332 return Style.BreakBeforeTemplateCloser;
6334 if (
Left.isOneOf(tok::at, tok::objc_interface))
6336 if (
Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
6337 return Right.isNot(tok::l_paren);
6338 if (
Right.is(TT_PointerOrReference)) {
6339 return Line.IsMultiVariableDeclStmt ||
6340 (getTokenPointerOrReferenceAlignment(Right) ==
6341 FormatStyle::PAS_Right &&
6343 Right.Next->isOneOf(TT_FunctionDeclarationName, tok::kw_const)));
6345 if (
Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
6346 TT_ClassHeadName, TT_QtProperty, tok::kw_operator)) {
6349 if (
Left.is(TT_PointerOrReference))
6351 if (
Right.isTrailingComment()) {
6358 (
Left.is(TT_CtorInitializerColon) &&
Right.NewlinesBefore > 0 &&
6359 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
6361 if (
Left.is(tok::question) &&
Right.is(tok::colon))
6363 if (
Right.isOneOf(TT_ConditionalExpr, tok::question))
6364 return Style.BreakBeforeTernaryOperators;
6365 if (
Left.isOneOf(TT_ConditionalExpr, tok::question))
6366 return !Style.BreakBeforeTernaryOperators;
6367 if (
Left.is(TT_InheritanceColon))
6368 return Style.BreakInheritanceList == FormatStyle::BILS_AfterColon;
6369 if (
Right.is(TT_InheritanceColon))
6370 return Style.BreakInheritanceList != FormatStyle::BILS_AfterColon;
6372 if (
Right.is(TT_ObjCMethodExpr) &&
Right.isNot(tok::r_square) &&
6373 Left.isNot(TT_SelectorName)) {
6377 if (
Right.is(tok::colon) &&
6378 Right.isNoneOf(TT_CtorInitializerColon, TT_InlineASMColon,
6379 TT_BitFieldColon)) {
6382 if (
Left.is(tok::colon) &&
Left.isOneOf(TT_ObjCSelector, TT_ObjCMethodExpr))
6384 if (
Left.is(tok::colon) &&
Left.is(TT_DictLiteral)) {
6385 if (Style.isProto()) {
6386 if (!Style.AlwaysBreakBeforeMultilineStrings &&
Right.isStringLiteral())
6412 if ((
Right.isOneOf(tok::l_brace, tok::less) &&
6413 Right.is(TT_DictLiteral)) ||
6414 Right.is(TT_ArrayInitializerLSquare)) {
6420 if (
Right.is(tok::r_square) &&
Right.MatchingParen &&
6421 Right.MatchingParen->is(TT_ProtoExtensionLSquare)) {
6424 if (
Right.is(TT_SelectorName) || (
Right.is(tok::identifier) &&
Right.Next &&
6425 Right.Next->is(TT_ObjCMethodExpr))) {
6426 return Left.isNot(tok::period);
6430 if (
Right.is(tok::kw_concept))
6431 return Style.BreakBeforeConceptDeclarations != FormatStyle::BBCDS_Never;
6432 if (
Right.is(TT_RequiresClause))
6434 if (
Left.ClosesTemplateDeclaration) {
6435 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
6436 Right.NewlinesBefore > 0;
6438 if (
Left.is(TT_FunctionAnnotationRParen))
6440 if (
Left.ClosesRequiresClause)
6442 if (
Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
6443 TT_OverloadedOperator)) {
6446 if (
Left.is(TT_RangeBasedForLoopColon))
6448 if (
Right.is(TT_RangeBasedForLoopColon))
6450 if (
Left.is(TT_TemplateCloser) &&
Right.is(TT_TemplateOpener))
6452 if ((
Left.is(tok::greater) &&
Right.is(tok::greater)) ||
6453 (
Left.is(tok::less) &&
Right.is(tok::less))) {
6456 if (
Right.is(TT_BinaryOperator) &&
6457 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&
6458 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
6462 if (
Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator, tok::kw_operator))
6464 if (
Left.is(tok::equal) &&
Right.isNoneOf(tok::kw_default, tok::kw_delete) &&
6468 if (
Left.is(tok::equal) &&
Right.is(tok::l_brace) &&
6469 Style.Cpp11BracedListStyle == FormatStyle::BLS_Block) {
6472 if (
Left.is(TT_AttributeLParen) ||
6473 (
Left.is(tok::l_paren) &&
Left.is(TT_TypeDeclarationParen))) {
6476 if (
Left.is(tok::l_paren) &&
Left.Previous &&
6477 (
Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) {
6480 if (
Right.is(TT_ImplicitStringLiteral))
6483 if (
Right.is(tok::r_square) &&
Right.MatchingParen &&
6484 Right.MatchingParen->is(TT_LambdaLSquare)) {
6490 if (
Left.is(TT_TrailingAnnotation)) {
6491 return Right.isNoneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
6492 tok::less, tok::coloncolon);
6495 if (
Right.isAttribute())
6498 if (
Right.is(TT_AttributeLSquare)) {
6499 assert(
Left.isNot(tok::l_square));
6503 if (
Left.is(tok::identifier) &&
Right.is(tok::string_literal))
6506 if (
Right.is(tok::identifier) &&
Right.Next &&
Right.Next->is(TT_DictLiteral))
6509 if (
Left.is(TT_CtorInitializerColon)) {
6510 return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&
6511 (!
Right.isTrailingComment() ||
Right.NewlinesBefore > 0);
6513 if (
Right.is(TT_CtorInitializerColon))
6514 return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon;
6515 if (
Left.is(TT_CtorInitializerComma) &&
6516 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {
6519 if (
Right.is(TT_CtorInitializerComma) &&
6520 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {
6523 if (
Left.is(TT_InheritanceComma) &&
6524 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma) {
6527 if (
Right.is(TT_InheritanceComma) &&
6528 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma) {
6531 if (
Left.is(TT_ArrayInitializerLSquare))
6533 if (
Right.is(tok::kw_typename) &&
Left.isNot(tok::kw_const))
6535 if ((
Left.isBinaryOperator() ||
Left.is(TT_BinaryOperator)) &&
6536 Left.isNoneOf(tok::arrowstar, tok::lessless) &&
6537 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
6538 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
6542 if (
Left.is(TT_AttributeLSquare) &&
Right.is(tok::l_square)) {
6543 assert(
Right.isNot(TT_AttributeLSquare));
6546 if (
Left.is(tok::r_square) &&
Right.is(TT_AttributeRSquare)) {
6547 assert(
Left.isNot(TT_AttributeRSquare));
6551 auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
6552 if (Style.BraceWrapping.BeforeLambdaBody &&
Right.is(TT_LambdaLBrace)) {
6559 if (
Right.is(tok::kw_noexcept) &&
Right.is(TT_TrailingAnnotation)) {
6560 switch (Style.AllowBreakBeforeNoexceptSpecifier) {
6561 case FormatStyle::BBNSS_Never:
6563 case FormatStyle::BBNSS_Always:
6565 case FormatStyle::BBNSS_OnlyWithParen:
6566 return Right.Next &&
Right.Next->is(tok::l_paren);
6570 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
6571 tok::kw_class, tok::kw_struct, tok::comment) ||
6572 Right.isMemberAccess() ||
6573 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
6574 tok::colon, tok::l_square, tok::at) ||
6575 (
Left.is(tok::r_paren) &&
6576 Right.isOneOf(tok::identifier, tok::kw_const)) ||
6577 (
Left.is(tok::l_paren) &&
Right.isNot(tok::r_paren)) ||
6578 (
Left.is(TT_TemplateOpener) &&
Right.isNot(TT_TemplateCloser));
6582 llvm::errs() <<
"AnnotatedTokens(L=" <<
Line.Level <<
", P=" <<
Line.PPLevel
6583 <<
", T=" <<
Line.Type <<
", C=" <<
Line.IsContinuation
6587 llvm::errs() <<
" I=" <<
Tok->IndentLevel <<
" M=" <<
Tok->MustBreakBefore
6588 <<
" C=" <<
Tok->CanBreakBefore
6590 <<
" S=" <<
Tok->SpacesRequiredBefore
6591 <<
" F=" <<
Tok->Finalized <<
" B=" <<
Tok->BlockParameterCount
6592 <<
" BK=" <<
Tok->getBlockKind() <<
" P=" <<
Tok->SplitPenalty
6593 <<
" Name=" <<
Tok->Tok.getName() <<
" N=" <<
Tok->NestingLevel
6594 <<
" L=" <<
Tok->TotalLength
6595 <<
" PPK=" <<
Tok->getPackingKind() <<
" FakeLParens=";
6597 llvm::errs() << LParen <<
"/";
6598 llvm::errs() <<
" FakeRParens=" <<
Tok->FakeRParens;
6599 llvm::errs() <<
" II=" <<
Tok->Tok.getIdentifierInfo();
6600 llvm::errs() <<
" Text='" <<
Tok->TokenText <<
"'\n";
6605 llvm::errs() <<
"----\n";
6608FormatStyle::PointerAlignmentStyle
6610 assert(
Reference.isOneOf(tok::amp, tok::ampamp));
6611 switch (Style.ReferenceAlignment) {
6612 case FormatStyle::RAS_Pointer:
6613 return Style.PointerAlignment;
6614 case FormatStyle::RAS_Left:
6615 return FormatStyle::PAS_Left;
6616 case FormatStyle::RAS_Right:
6617 return FormatStyle::PAS_Right;
6618 case FormatStyle::RAS_Middle:
6619 return FormatStyle::PAS_Middle;
6622 return Style.PointerAlignment;
6625FormatStyle::PointerAlignmentStyle
6626TokenAnnotator::getTokenPointerOrReferenceAlignment(
6628 if (PointerOrReference.isOneOf(tok::amp, tok::ampamp))
6629 return getTokenReferenceAlignment(PointerOrReference);
6630 assert(PointerOrReference.is(tok::star));
6631 return Style.PointerAlignment;
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.
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.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Type
The name was classified as a type.
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.