1 //===--- TokenAnnotator.cpp - Format C++ code -----------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file implements a token annotator, i.e. creates
11 /// \c AnnotatedTokens out of \c FormatTokens with required extra information.
13 //===----------------------------------------------------------------------===//
15 #include "TokenAnnotator.h"
16 #include "FormatToken.h"
17 #include "clang/Basic/SourceManager.h"
18 #include "clang/Basic/TokenKinds.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/Support/Debug.h"
22 #define DEBUG_TYPE "format-token-annotator"
27 static bool mustBreakAfterAttributes(const FormatToken
&Tok
,
28 const FormatStyle
&Style
) {
29 switch (Style
.BreakAfterAttributes
) {
30 case FormatStyle::ABS_Always
:
32 case FormatStyle::ABS_Leave
:
33 return Tok
.NewlinesBefore
> 0;
41 /// Returns \c true if the line starts with a token that can start a statement
42 /// with an initializer.
43 static bool startsWithInitStatement(const AnnotatedLine
&Line
) {
44 return Line
.startsWith(tok::kw_for
) || Line
.startsWith(tok::kw_if
) ||
45 Line
.startsWith(tok::kw_switch
);
48 /// Returns \c true if the token can be used as an identifier in
49 /// an Objective-C \c \@selector, \c false otherwise.
51 /// Because getFormattingLangOpts() always lexes source code as
52 /// Objective-C++, C++ keywords like \c new and \c delete are
53 /// lexed as tok::kw_*, not tok::identifier, even for Objective-C.
55 /// For Objective-C and Objective-C++, both identifiers and keywords
56 /// are valid inside @selector(...) (or a macro which
57 /// invokes @selector(...)). So, we allow treat any identifier or
58 /// keyword as a potential Objective-C selector component.
59 static bool canBeObjCSelectorComponent(const FormatToken
&Tok
) {
60 return Tok
.Tok
.getIdentifierInfo();
63 /// With `Left` being '(', check if we're at either `[...](` or
64 /// `[...]<...>(`, where the [ opens a lambda capture list.
65 // FIXME: this doesn't cover attributes/constraints before the l_paren.
66 static bool isLambdaParameterList(const FormatToken
*Left
) {
67 // Skip <...> if present.
68 if (Left
->Previous
&& Left
->Previous
->is(tok::greater
) &&
69 Left
->Previous
->MatchingParen
&&
70 Left
->Previous
->MatchingParen
->is(TT_TemplateOpener
)) {
71 Left
= Left
->Previous
->MatchingParen
;
75 return Left
->Previous
&& Left
->Previous
->is(tok::r_square
) &&
76 Left
->Previous
->MatchingParen
&&
77 Left
->Previous
->MatchingParen
->is(TT_LambdaLSquare
);
80 /// Returns \c true if the token is followed by a boolean condition, \c false
82 static bool isKeywordWithCondition(const FormatToken
&Tok
) {
83 return Tok
.isOneOf(tok::kw_if
, tok::kw_for
, tok::kw_while
, tok::kw_switch
,
84 tok::kw_constexpr
, tok::kw_catch
);
87 /// Returns \c true if the token starts a C++ attribute, \c false otherwise.
88 static bool isCppAttribute(bool IsCpp
, const FormatToken
&Tok
) {
89 if (!IsCpp
|| !Tok
.startsSequence(tok::l_square
, tok::l_square
))
91 // The first square bracket is part of an ObjC array literal
92 if (Tok
.Previous
&& Tok
.Previous
->is(tok::at
))
94 const FormatToken
*AttrTok
= Tok
.Next
->Next
;
97 // C++17 '[[using ns: foo, bar(baz, blech)]]'
98 // We assume nobody will name an ObjC variable 'using'.
99 if (AttrTok
->startsSequence(tok::kw_using
, tok::identifier
, tok::colon
))
101 if (AttrTok
->isNot(tok::identifier
))
103 while (AttrTok
&& !AttrTok
->startsSequence(tok::r_square
, tok::r_square
)) {
104 // ObjC message send. We assume nobody will use : in a C++11 attribute
105 // specifier parameter, although this is technically valid:
107 if (AttrTok
->is(tok::colon
) ||
108 AttrTok
->startsSequence(tok::identifier
, tok::identifier
) ||
109 AttrTok
->startsSequence(tok::r_paren
, tok::identifier
)) {
112 if (AttrTok
->is(tok::ellipsis
))
114 AttrTok
= AttrTok
->Next
;
116 return AttrTok
&& AttrTok
->startsSequence(tok::r_square
, tok::r_square
);
119 /// A parser that gathers additional information about tokens.
121 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
122 /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
123 /// into template parameter lists.
124 class AnnotatingParser
{
126 AnnotatingParser(const FormatStyle
&Style
, AnnotatedLine
&Line
,
127 const AdditionalKeywords
&Keywords
,
128 SmallVector
<ScopeType
> &Scopes
)
129 : Style(Style
), Line(Line
), CurrentToken(Line
.First
), AutoFound(false),
130 IsCpp(Style
.isCpp()), LangOpts(getFormattingLangOpts(Style
)),
131 Keywords(Keywords
), Scopes(Scopes
), TemplateDeclarationDepth(0) {
132 assert(IsCpp
== LangOpts
.CXXOperatorNames
);
133 Contexts
.push_back(Context(tok::unknown
, 1, /*IsExpression=*/false));
134 resetTokenMetadata();
138 ScopeType
getScopeType(const FormatToken
&Token
) const {
139 switch (Token
.getType()) {
140 case TT_LambdaLBrace
:
141 return ST_ChildBlock
;
143 case TT_StructLBrace
:
155 auto *Left
= CurrentToken
->Previous
; // The '<'.
159 if (NonTemplateLess
.count(Left
) > 0)
162 const auto *BeforeLess
= Left
->Previous
;
165 if (BeforeLess
->Tok
.isLiteral())
167 if (BeforeLess
->is(tok::r_brace
))
169 if (BeforeLess
->is(tok::r_paren
) && Contexts
.size() > 1 &&
170 !(BeforeLess
->MatchingParen
&&
171 BeforeLess
->MatchingParen
->is(TT_OverloadedOperatorLParen
))) {
174 if (BeforeLess
->is(tok::kw_operator
) && CurrentToken
->is(tok::l_paren
))
178 Left
->ParentBracket
= Contexts
.back().ContextKind
;
179 ScopedContextCreator
ContextCreator(*this, tok::less
, 12);
180 Contexts
.back().IsExpression
= false;
182 // If there's a template keyword before the opening angle bracket, this is a
183 // template parameter, not an argument.
184 if (BeforeLess
&& BeforeLess
->isNot(tok::kw_template
))
185 Contexts
.back().ContextType
= Context::TemplateArgument
;
187 if (Style
.Language
== FormatStyle::LK_Java
&&
188 CurrentToken
->is(tok::question
)) {
192 for (bool SeenTernaryOperator
= false, MaybeAngles
= true; CurrentToken
;) {
193 const bool InExpr
= Contexts
[Contexts
.size() - 2].IsExpression
;
194 if (CurrentToken
->is(tok::greater
)) {
195 const auto *Next
= CurrentToken
->Next
;
196 if (CurrentToken
->isNot(TT_TemplateCloser
)) {
197 // Try to do a better job at looking for ">>" within the condition of
198 // a statement. Conservatively insert spaces between consecutive ">"
199 // tokens to prevent splitting right shift operators and potentially
200 // altering program semantics. This check is overly conservative and
201 // will prevent spaces from being inserted in select nested template
202 // parameter cases, but should not alter program semantics.
203 if (Next
&& Next
->is(tok::greater
) &&
204 Left
->ParentBracket
!= tok::less
&&
205 CurrentToken
->getStartOfNonWhitespace() ==
206 Next
->getStartOfNonWhitespace().getLocWithOffset(-1)) {
209 if (InExpr
&& SeenTernaryOperator
&&
210 (!Next
|| !Next
->isOneOf(tok::l_paren
, tok::l_brace
))) {
216 Left
->MatchingParen
= CurrentToken
;
217 CurrentToken
->MatchingParen
= Left
;
218 // In TT_Proto, we must distignuish between:
220 // msg < item: data >
221 // msg: < item: data >
222 // In TT_TextProto, map<key, value> does not occur.
223 if (Style
.Language
== FormatStyle::LK_TextProto
||
224 (Style
.Language
== FormatStyle::LK_Proto
&& BeforeLess
&&
225 BeforeLess
->isOneOf(TT_SelectorName
, TT_DictLiteral
))) {
226 CurrentToken
->setType(TT_DictLiteral
);
228 CurrentToken
->setType(TT_TemplateCloser
);
229 CurrentToken
->Tok
.setLength(1);
231 if (Next
&& Next
->Tok
.isLiteral())
236 if (BeforeLess
&& BeforeLess
->is(TT_TemplateName
)) {
240 if (CurrentToken
->is(tok::question
) &&
241 Style
.Language
== FormatStyle::LK_Java
) {
245 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::r_brace
))
247 const auto &Prev
= *CurrentToken
->Previous
;
248 // If a && or || is found and interpreted as a binary operator, this set
249 // of angles is likely part of something like "a < b && c > d". If the
250 // angles are inside an expression, the ||/&& might also be a binary
251 // operator that was misinterpreted because we are parsing template
253 // FIXME: This is getting out of hand, write a decent parser.
254 if (MaybeAngles
&& InExpr
&& !Line
.startsWith(tok::kw_template
) &&
255 Prev
.is(TT_BinaryOperator
)) {
256 const auto Precedence
= Prev
.getPrecedence();
257 if (Precedence
> prec::Conditional
&& Precedence
< prec::Relational
)
260 if (Prev
.isOneOf(tok::question
, tok::colon
) && !Style
.isProto())
261 SeenTernaryOperator
= true;
262 updateParameterCount(Left
, CurrentToken
);
263 if (Style
.Language
== FormatStyle::LK_Proto
) {
264 if (FormatToken
*Previous
= CurrentToken
->getPreviousNonComment()) {
265 if (CurrentToken
->is(tok::colon
) ||
266 (CurrentToken
->isOneOf(tok::l_brace
, tok::less
) &&
267 Previous
->isNot(tok::colon
))) {
268 Previous
->setType(TT_SelectorName
);
272 if (Style
.isTableGen()) {
273 if (CurrentToken
->isOneOf(tok::comma
, tok::equal
)) {
274 // They appear as separators. Unless they are not in class definition.
278 // In angle, there must be Value like tokens. Types are also able to be
279 // parsed in the same way with Values.
280 if (!parseTableGenValue())
290 bool parseUntouchableParens() {
291 while (CurrentToken
) {
292 CurrentToken
->Finalized
= true;
293 switch (CurrentToken
->Tok
.getKind()) {
296 if (!parseUntouchableParens())
311 bool parseParens(bool IsIf
= false) {
314 assert(CurrentToken
->Previous
&& "Unknown previous token");
315 FormatToken
&OpeningParen
= *CurrentToken
->Previous
;
316 assert(OpeningParen
.is(tok::l_paren
));
317 FormatToken
*PrevNonComment
= OpeningParen
.getPreviousNonComment();
318 OpeningParen
.ParentBracket
= Contexts
.back().ContextKind
;
319 ScopedContextCreator
ContextCreator(*this, tok::l_paren
, 1);
321 // FIXME: This is a bit of a hack. Do better.
322 Contexts
.back().ColonIsForRangeExpr
=
323 Contexts
.size() == 2 && Contexts
[0].ColonIsForRangeExpr
;
325 if (OpeningParen
.Previous
&&
326 OpeningParen
.Previous
->is(TT_UntouchableMacroFunc
)) {
327 OpeningParen
.Finalized
= true;
328 return parseUntouchableParens();
331 bool StartsObjCMethodExpr
= false;
332 if (!Style
.isVerilog()) {
333 if (FormatToken
*MaybeSel
= OpeningParen
.Previous
) {
334 // @selector( starts a selector.
335 if (MaybeSel
->isObjCAtKeyword(tok::objc_selector
) &&
336 MaybeSel
->Previous
&& MaybeSel
->Previous
->is(tok::at
)) {
337 StartsObjCMethodExpr
= true;
342 if (OpeningParen
.is(TT_OverloadedOperatorLParen
)) {
343 // Find the previous kw_operator token.
344 FormatToken
*Prev
= &OpeningParen
;
345 while (Prev
->isNot(tok::kw_operator
)) {
346 Prev
= Prev
->Previous
;
347 assert(Prev
&& "Expect a kw_operator prior to the OperatorLParen!");
350 // If faced with "a.operator*(argument)" or "a->operator*(argument)",
351 // i.e. the operator is called as a member function,
352 // then the argument must be an expression.
353 bool OperatorCalledAsMemberFunction
=
354 Prev
->Previous
&& Prev
->Previous
->isOneOf(tok::period
, tok::arrow
);
355 Contexts
.back().IsExpression
= OperatorCalledAsMemberFunction
;
356 } else if (OpeningParen
.is(TT_VerilogInstancePortLParen
)) {
357 Contexts
.back().IsExpression
= true;
358 Contexts
.back().ContextType
= Context::VerilogInstancePortList
;
359 } else if (Style
.isJavaScript() &&
360 (Line
.startsWith(Keywords
.kw_type
, tok::identifier
) ||
361 Line
.startsWith(tok::kw_export
, Keywords
.kw_type
,
364 // export type X = (...);
365 Contexts
.back().IsExpression
= false;
366 } else if (OpeningParen
.Previous
&&
367 (OpeningParen
.Previous
->isOneOf(
368 tok::kw_static_assert
, tok::kw_noexcept
, tok::kw_explicit
,
369 tok::kw_while
, tok::l_paren
, tok::comma
, TT_CastRParen
,
370 TT_BinaryOperator
) ||
371 OpeningParen
.Previous
->isIf())) {
372 // static_assert, if and while usually contain expressions.
373 Contexts
.back().IsExpression
= true;
374 } else if (Style
.isJavaScript() && OpeningParen
.Previous
&&
375 (OpeningParen
.Previous
->is(Keywords
.kw_function
) ||
376 (OpeningParen
.Previous
->endsSequence(tok::identifier
,
377 Keywords
.kw_function
)))) {
378 // function(...) or function f(...)
379 Contexts
.back().IsExpression
= false;
380 } else if (Style
.isJavaScript() && OpeningParen
.Previous
&&
381 OpeningParen
.Previous
->is(TT_JsTypeColon
)) {
382 // let x: (SomeType);
383 Contexts
.back().IsExpression
= false;
384 } else if (isLambdaParameterList(&OpeningParen
)) {
385 // This is a parameter list of a lambda expression.
386 OpeningParen
.setType(TT_LambdaDefinitionLParen
);
387 Contexts
.back().IsExpression
= false;
388 } else if (OpeningParen
.is(TT_RequiresExpressionLParen
)) {
389 Contexts
.back().IsExpression
= false;
390 } else if (OpeningParen
.Previous
&&
391 OpeningParen
.Previous
->is(tok::kw__Generic
)) {
392 Contexts
.back().ContextType
= Context::C11GenericSelection
;
393 Contexts
.back().IsExpression
= true;
394 } else if (Line
.InPPDirective
&&
395 (!OpeningParen
.Previous
||
396 OpeningParen
.Previous
->isNot(tok::identifier
))) {
397 Contexts
.back().IsExpression
= true;
398 } else if (Contexts
[Contexts
.size() - 2].CaretFound
) {
399 // This is the parameter list of an ObjC block.
400 Contexts
.back().IsExpression
= false;
401 } else if (OpeningParen
.Previous
&&
402 OpeningParen
.Previous
->is(TT_ForEachMacro
)) {
403 // The first argument to a foreach macro is a declaration.
404 Contexts
.back().ContextType
= Context::ForEachMacro
;
405 Contexts
.back().IsExpression
= false;
406 } else if (OpeningParen
.Previous
&& OpeningParen
.Previous
->MatchingParen
&&
407 OpeningParen
.Previous
->MatchingParen
->isOneOf(
408 TT_ObjCBlockLParen
, TT_FunctionTypeLParen
)) {
409 Contexts
.back().IsExpression
= false;
410 } else if (!Line
.MustBeDeclaration
&&
411 (!Line
.InPPDirective
|| (Line
.InMacroBody
&& !Scopes
.empty()))) {
413 OpeningParen
.Previous
&&
414 OpeningParen
.Previous
->isOneOf(tok::kw_for
, tok::kw_catch
);
415 Contexts
.back().IsExpression
= !IsForOrCatch
;
418 if (Style
.isTableGen()) {
419 if (FormatToken
*Prev
= OpeningParen
.Previous
) {
420 if (Prev
->is(TT_TableGenCondOperator
)) {
421 Contexts
.back().IsTableGenCondOpe
= true;
422 Contexts
.back().IsExpression
= true;
423 } else if (Contexts
.size() > 1 &&
424 Contexts
[Contexts
.size() - 2].IsTableGenBangOpe
) {
425 // Hack to handle bang operators. The parent context's flag
426 // was set by parseTableGenSimpleValue().
427 // We have to specify the context outside because the prev of "(" may
428 // be ">", not the bang operator in this case.
429 Contexts
.back().IsTableGenBangOpe
= true;
430 Contexts
.back().IsExpression
= true;
432 // Otherwise, this paren seems DAGArg.
433 if (!parseTableGenDAGArg())
435 return parseTableGenDAGArgAndList(&OpeningParen
);
440 // Infer the role of the l_paren based on the previous token if we haven't
442 if (PrevNonComment
&& OpeningParen
.is(TT_Unknown
)) {
443 if (PrevNonComment
->isAttribute()) {
444 OpeningParen
.setType(TT_AttributeLParen
);
445 } else if (PrevNonComment
->isOneOf(TT_TypenameMacro
, tok::kw_decltype
,
447 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,
448 #include "clang/Basic/TransformTypeTraits.def"
450 OpeningParen
.setType(TT_TypeDeclarationParen
);
451 // decltype() and typeof() usually contain expressions.
452 if (PrevNonComment
->isOneOf(tok::kw_decltype
, tok::kw_typeof
))
453 Contexts
.back().IsExpression
= true;
457 if (StartsObjCMethodExpr
) {
458 Contexts
.back().ColonIsObjCMethodExpr
= true;
459 OpeningParen
.setType(TT_ObjCMethodExpr
);
462 // MightBeFunctionType and ProbablyFunctionType are used for
463 // function pointer and reference types as well as Objective-C
466 // void (*FunctionPointer)(void);
467 // void (&FunctionReference)(void);
468 // void (&&FunctionReference)(void);
469 // void (^ObjCBlock)(void);
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
);
477 FormatToken
*PossibleObjCForInToken
= nullptr;
478 while (CurrentToken
) {
479 const auto &Prev
= *CurrentToken
->Previous
;
480 if (Prev
.is(TT_PointerOrReference
) &&
481 Prev
.Previous
->isOneOf(tok::l_paren
, tok::coloncolon
)) {
482 ProbablyFunctionType
= true;
484 if (CurrentToken
->is(tok::comma
))
485 MightBeFunctionType
= false;
486 if (Prev
.is(TT_BinaryOperator
))
487 Contexts
.back().IsExpression
= true;
488 if (CurrentToken
->is(tok::r_paren
)) {
489 if (Prev
.is(TT_PointerOrReference
) && Prev
.Previous
== &OpeningParen
)
490 MightBeFunctionType
= true;
491 if (OpeningParen
.isNot(TT_CppCastLParen
) && MightBeFunctionType
&&
492 ProbablyFunctionType
&& CurrentToken
->Next
&&
493 (CurrentToken
->Next
->is(tok::l_paren
) ||
494 (CurrentToken
->Next
->is(tok::l_square
) &&
495 Line
.MustBeDeclaration
))) {
496 OpeningParen
.setType(OpeningParen
.Next
->is(tok::caret
)
498 : TT_FunctionTypeLParen
);
500 OpeningParen
.MatchingParen
= CurrentToken
;
501 CurrentToken
->MatchingParen
= &OpeningParen
;
503 if (CurrentToken
->Next
&& CurrentToken
->Next
->is(tok::l_brace
) &&
504 OpeningParen
.Previous
&& OpeningParen
.Previous
->is(tok::l_paren
)) {
505 // Detect the case where macros are used to generate lambdas or
506 // function bodies, e.g.:
507 // auto my_lambda = MACRO((Type *type, int i) { .. body .. });
508 for (FormatToken
*Tok
= &OpeningParen
; Tok
!= CurrentToken
;
510 if (Tok
->is(TT_BinaryOperator
) && Tok
->isPointerOrReference())
511 Tok
->setType(TT_PointerOrReference
);
515 if (StartsObjCMethodExpr
) {
516 CurrentToken
->setType(TT_ObjCMethodExpr
);
517 if (Contexts
.back().FirstObjCSelectorName
) {
518 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
519 Contexts
.back().LongestObjCSelectorName
;
523 if (OpeningParen
.is(TT_AttributeLParen
))
524 CurrentToken
->setType(TT_AttributeRParen
);
525 if (OpeningParen
.is(TT_TypeDeclarationParen
))
526 CurrentToken
->setType(TT_TypeDeclarationParen
);
527 if (OpeningParen
.Previous
&&
528 OpeningParen
.Previous
->is(TT_JavaAnnotation
)) {
529 CurrentToken
->setType(TT_JavaAnnotation
);
531 if (OpeningParen
.Previous
&&
532 OpeningParen
.Previous
->is(TT_LeadingJavaAnnotation
)) {
533 CurrentToken
->setType(TT_LeadingJavaAnnotation
);
535 if (OpeningParen
.Previous
&&
536 OpeningParen
.Previous
->is(TT_AttributeSquare
)) {
537 CurrentToken
->setType(TT_AttributeSquare
);
540 if (!HasMultipleLines
)
541 OpeningParen
.setPackingKind(PPK_Inconclusive
);
542 else if (HasMultipleParametersOnALine
)
543 OpeningParen
.setPackingKind(PPK_BinPacked
);
545 OpeningParen
.setPackingKind(PPK_OnePerLine
);
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
->isOneOf(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
);
589 // When we discover a 'new', we set CanBeExpression to 'false' in order to
590 // parse the type correctly. Reset that after a comma.
591 if (CurrentToken
->is(tok::comma
))
592 Contexts
.back().CanBeExpression
= true;
594 if (Style
.isTableGen()) {
595 if (CurrentToken
->is(tok::comma
)) {
596 if (Contexts
.back().IsTableGenCondOpe
)
597 CurrentToken
->setType(TT_TableGenCondOperatorComma
);
599 } else if (CurrentToken
->is(tok::colon
)) {
600 if (Contexts
.back().IsTableGenCondOpe
)
601 CurrentToken
->setType(TT_TableGenCondOperatorColon
);
604 // In TableGen there must be Values in parens.
605 if (!parseTableGenValue())
610 FormatToken
*Tok
= CurrentToken
;
613 updateParameterCount(&OpeningParen
, Tok
);
614 if (CurrentToken
&& CurrentToken
->HasUnescapedNewline
)
615 HasMultipleLines
= true;
620 bool isCSharpAttributeSpecifier(const FormatToken
&Tok
) {
621 if (!Style
.isCSharp())
624 // `identifier[i]` is not an attribute.
625 if (Tok
.Previous
&& Tok
.Previous
->is(tok::identifier
))
628 // Chains of [] in `identifier[i][j][k]` are not attributes.
629 if (Tok
.Previous
&& Tok
.Previous
->is(tok::r_square
)) {
630 auto *MatchingParen
= Tok
.Previous
->MatchingParen
;
631 if (!MatchingParen
|| MatchingParen
->is(TT_ArraySubscriptLSquare
))
635 const FormatToken
*AttrTok
= Tok
.Next
;
639 // Just an empty declaration e.g. string [].
640 if (AttrTok
->is(tok::r_square
))
643 // Move along the tokens inbetween the '[' and ']' e.g. [STAThread].
644 while (AttrTok
&& AttrTok
->isNot(tok::r_square
))
645 AttrTok
= AttrTok
->Next
;
650 // Allow an attribute to be the only content of a file.
651 AttrTok
= AttrTok
->Next
;
655 // Limit this to being an access modifier that follows.
656 if (AttrTok
->isAccessSpecifierKeyword() ||
657 AttrTok
->isOneOf(tok::comment
, tok::kw_class
, tok::kw_static
,
658 tok::l_square
, Keywords
.kw_internal
)) {
662 // incase its a [XXX] retval func(....
664 AttrTok
->Next
->startsSequence(tok::identifier
, tok::l_paren
)) {
675 // A '[' could be an index subscript (after an identifier or after
676 // ')' or ']'), it could be the start of an Objective-C method
677 // expression, it could the start of an Objective-C array literal,
678 // or it could be a C++ attribute specifier [[foo::bar]].
679 FormatToken
*Left
= CurrentToken
->Previous
;
680 Left
->ParentBracket
= Contexts
.back().ContextKind
;
681 FormatToken
*Parent
= Left
->getPreviousNonComment();
683 // Cases where '>' is followed by '['.
684 // In C++, this can happen either in array of templates (foo<int>[10])
685 // or when array is a nested template type (unique_ptr<type1<type2>[]>).
686 bool CppArrayTemplates
=
687 IsCpp
&& Parent
&& Parent
->is(TT_TemplateCloser
) &&
688 (Contexts
.back().CanBeExpression
|| Contexts
.back().IsExpression
||
689 Contexts
.back().ContextType
== Context::TemplateArgument
);
691 const bool IsInnerSquare
= Contexts
.back().InCpp11AttributeSpecifier
;
692 const bool IsCpp11AttributeSpecifier
=
693 isCppAttribute(IsCpp
, *Left
) || IsInnerSquare
;
695 // Treat C# Attributes [STAThread] much like C++ attributes [[...]].
696 bool IsCSharpAttributeSpecifier
=
697 isCSharpAttributeSpecifier(*Left
) ||
698 Contexts
.back().InCSharpAttributeSpecifier
;
700 bool InsideInlineASM
= Line
.startsWith(tok::kw_asm
);
701 bool IsCppStructuredBinding
= Left
->isCppStructuredBinding(IsCpp
);
702 bool StartsObjCMethodExpr
=
703 !IsCppStructuredBinding
&& !InsideInlineASM
&& !CppArrayTemplates
&&
704 IsCpp
&& !IsCpp11AttributeSpecifier
&& !IsCSharpAttributeSpecifier
&&
705 Contexts
.back().CanBeExpression
&& Left
->isNot(TT_LambdaLSquare
) &&
706 !CurrentToken
->isOneOf(tok::l_brace
, tok::r_square
) &&
708 Parent
->isOneOf(tok::colon
, tok::l_square
, tok::l_paren
,
709 tok::kw_return
, tok::kw_throw
) ||
710 Parent
->isUnaryOperator() ||
711 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
712 Parent
->isOneOf(TT_ObjCForIn
, TT_CastRParen
) ||
713 (getBinOpPrecedence(Parent
->Tok
.getKind(), true, true) >
715 bool ColonFound
= false;
717 unsigned BindingIncrease
= 1;
718 if (IsCppStructuredBinding
) {
719 Left
->setType(TT_StructuredBindingLSquare
);
720 } else if (Left
->is(TT_Unknown
)) {
721 if (StartsObjCMethodExpr
) {
722 Left
->setType(TT_ObjCMethodExpr
);
723 } else if (InsideInlineASM
) {
724 Left
->setType(TT_InlineASMSymbolicNameLSquare
);
725 } else if (IsCpp11AttributeSpecifier
) {
726 Left
->setType(TT_AttributeSquare
);
727 if (!IsInnerSquare
&& Left
->Previous
)
728 Left
->Previous
->EndsCppAttributeGroup
= false;
729 } else if (Style
.isJavaScript() && Parent
&&
730 Contexts
.back().ContextKind
== tok::l_brace
&&
731 Parent
->isOneOf(tok::l_brace
, tok::comma
)) {
732 Left
->setType(TT_JsComputedPropertyName
);
733 } else if (IsCpp
&& Contexts
.back().ContextKind
== tok::l_brace
&&
734 Parent
&& Parent
->isOneOf(tok::l_brace
, tok::comma
)) {
735 Left
->setType(TT_DesignatedInitializerLSquare
);
736 } else if (IsCSharpAttributeSpecifier
) {
737 Left
->setType(TT_AttributeSquare
);
738 } else if (CurrentToken
->is(tok::r_square
) && Parent
&&
739 Parent
->is(TT_TemplateCloser
)) {
740 Left
->setType(TT_ArraySubscriptLSquare
);
741 } else if (Style
.isProto()) {
742 // Square braces in LK_Proto can either be message field attributes:
744 // optional Aaa aaa = 1 [
752 // or text proto extensions (in options):
754 // option (Aaa.options) = {
755 // [type.type/type] {
760 // or repeated fields (in options):
762 // option (Aaa.options) = {
766 // In the first and the third case we want to spread the contents inside
767 // the square braces; in the second we want to keep them inline.
768 Left
->setType(TT_ArrayInitializerLSquare
);
769 if (!Left
->endsSequence(tok::l_square
, tok::numeric_constant
,
771 !Left
->endsSequence(tok::l_square
, tok::numeric_constant
,
773 !Left
->endsSequence(tok::l_square
, tok::colon
, TT_SelectorName
)) {
774 Left
->setType(TT_ProtoExtensionLSquare
);
775 BindingIncrease
= 10;
777 } else if (!CppArrayTemplates
&& Parent
&&
778 Parent
->isOneOf(TT_BinaryOperator
, TT_TemplateCloser
, tok::at
,
779 tok::comma
, tok::l_paren
, tok::l_square
,
780 tok::question
, tok::colon
, tok::kw_return
,
781 // Should only be relevant to JavaScript:
783 Left
->setType(TT_ArrayInitializerLSquare
);
785 BindingIncrease
= 10;
786 Left
->setType(TT_ArraySubscriptLSquare
);
790 ScopedContextCreator
ContextCreator(*this, tok::l_square
, BindingIncrease
);
791 Contexts
.back().IsExpression
= true;
792 if (Style
.isJavaScript() && Parent
&& Parent
->is(TT_JsTypeColon
))
793 Contexts
.back().IsExpression
= false;
795 Contexts
.back().ColonIsObjCMethodExpr
= StartsObjCMethodExpr
;
796 Contexts
.back().InCpp11AttributeSpecifier
= IsCpp11AttributeSpecifier
;
797 Contexts
.back().InCSharpAttributeSpecifier
= IsCSharpAttributeSpecifier
;
799 while (CurrentToken
) {
800 if (CurrentToken
->is(tok::r_square
)) {
801 if (IsCpp11AttributeSpecifier
) {
802 CurrentToken
->setType(TT_AttributeSquare
);
804 CurrentToken
->EndsCppAttributeGroup
= true;
806 if (IsCSharpAttributeSpecifier
) {
807 CurrentToken
->setType(TT_AttributeSquare
);
808 } else if (((CurrentToken
->Next
&&
809 CurrentToken
->Next
->is(tok::l_paren
)) ||
810 (CurrentToken
->Previous
&&
811 CurrentToken
->Previous
->Previous
== Left
)) &&
812 Left
->is(TT_ObjCMethodExpr
)) {
813 // An ObjC method call is rarely followed by an open parenthesis. It
814 // also can't be composed of just one token, unless it's a macro that
815 // will be expanded to more tokens.
816 // FIXME: Do we incorrectly label ":" with this?
817 StartsObjCMethodExpr
= false;
818 Left
->setType(TT_Unknown
);
820 if (StartsObjCMethodExpr
&& CurrentToken
->Previous
!= Left
) {
821 CurrentToken
->setType(TT_ObjCMethodExpr
);
822 // If we haven't seen a colon yet, make sure the last identifier
823 // before the r_square is tagged as a selector name component.
824 if (!ColonFound
&& CurrentToken
->Previous
&&
825 CurrentToken
->Previous
->is(TT_Unknown
) &&
826 canBeObjCSelectorComponent(*CurrentToken
->Previous
)) {
827 CurrentToken
->Previous
->setType(TT_SelectorName
);
829 // determineStarAmpUsage() thinks that '*' '[' is allocating an
830 // array of pointers, but if '[' starts a selector then '*' is a
832 if (Parent
&& Parent
->is(TT_PointerOrReference
))
833 Parent
->overwriteFixedType(TT_BinaryOperator
);
835 // An arrow after an ObjC method expression is not a lambda arrow.
836 if (CurrentToken
->is(TT_ObjCMethodExpr
) && CurrentToken
->Next
&&
837 CurrentToken
->Next
->is(TT_LambdaArrow
)) {
838 CurrentToken
->Next
->overwriteFixedType(TT_Unknown
);
840 Left
->MatchingParen
= CurrentToken
;
841 CurrentToken
->MatchingParen
= Left
;
842 // FirstObjCSelectorName is set when a colon is found. This does
843 // not work, however, when the method has no parameters.
844 // Here, we set FirstObjCSelectorName when the end of the method call is
845 // reached, in case it was not set already.
846 if (!Contexts
.back().FirstObjCSelectorName
) {
847 FormatToken
*Previous
= CurrentToken
->getPreviousNonComment();
848 if (Previous
&& Previous
->is(TT_SelectorName
)) {
849 Previous
->ObjCSelectorNameParts
= 1;
850 Contexts
.back().FirstObjCSelectorName
= Previous
;
853 Left
->ParameterCount
=
854 Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
856 if (Contexts
.back().FirstObjCSelectorName
) {
857 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
858 Contexts
.back().LongestObjCSelectorName
;
859 if (Left
->BlockParameterCount
> 1)
860 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
= 0;
862 if (Style
.isTableGen() && Left
->is(TT_TableGenListOpener
))
863 CurrentToken
->setType(TT_TableGenListCloser
);
867 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_brace
))
869 if (CurrentToken
->is(tok::colon
)) {
870 if (IsCpp11AttributeSpecifier
&&
871 CurrentToken
->endsSequence(tok::colon
, tok::identifier
,
873 // Remember that this is a [[using ns: foo]] C++ attribute, so we
874 // don't add a space before the colon (unlike other colons).
875 CurrentToken
->setType(TT_AttributeColon
);
876 } else if (!Style
.isVerilog() && !Line
.InPragmaDirective
&&
877 Left
->isOneOf(TT_ArraySubscriptLSquare
,
878 TT_DesignatedInitializerLSquare
)) {
879 Left
->setType(TT_ObjCMethodExpr
);
880 StartsObjCMethodExpr
= true;
881 Contexts
.back().ColonIsObjCMethodExpr
= true;
882 if (Parent
&& Parent
->is(tok::r_paren
)) {
883 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
884 Parent
->setType(TT_CastRParen
);
889 if (CurrentToken
->is(tok::comma
) && Left
->is(TT_ObjCMethodExpr
) &&
891 Left
->setType(TT_ArrayInitializerLSquare
);
893 FormatToken
*Tok
= CurrentToken
;
894 if (Style
.isTableGen()) {
895 if (CurrentToken
->isOneOf(tok::comma
, tok::minus
, tok::ellipsis
)) {
896 // '-' and '...' appears as a separator in slice.
899 // In TableGen there must be a list of Values in square brackets.
900 // It must be ValueList or SliceElements.
901 if (!parseTableGenValue())
904 updateParameterCount(Left
, Tok
);
909 updateParameterCount(Left
, Tok
);
914 void skipToNextNonComment() {
916 while (CurrentToken
&& CurrentToken
->is(tok::comment
))
920 // Simplified parser for TableGen Value. Returns true on success.
921 // It consists of SimpleValues, SimpleValues with Suffixes, and Value followed
922 // by '#', paste operator.
923 // There also exists the case the Value is parsed as NameValue.
924 // In this case, the Value ends if '{' is found.
925 bool parseTableGenValue(bool ParseNameMode
= false) {
928 while (CurrentToken
->is(tok::comment
))
930 if (!parseTableGenSimpleValue())
935 if (CurrentToken
->is(tok::hash
)) {
936 if (CurrentToken
->Next
&&
937 CurrentToken
->Next
->isOneOf(tok::colon
, tok::semi
, tok::l_brace
)) {
938 // Trailing paste operator.
939 // These are only the allowed cases in TGParser::ParseValue().
940 CurrentToken
->setType(TT_TableGenTrailingPasteOperator
);
944 FormatToken
*HashTok
= CurrentToken
;
945 skipToNextNonComment();
946 HashTok
->setType(TT_Unknown
);
947 if (!parseTableGenValue(ParseNameMode
))
950 // In name mode, '{' is regarded as the end of the value.
951 // See TGParser::ParseValue in TGParser.cpp
952 if (ParseNameMode
&& CurrentToken
->is(tok::l_brace
))
954 // These tokens indicates this is a value with suffixes.
955 if (CurrentToken
->isOneOf(tok::l_brace
, tok::l_square
, tok::period
)) {
956 CurrentToken
->setType(TT_TableGenValueSuffix
);
957 FormatToken
*Suffix
= CurrentToken
;
958 skipToNextNonComment();
959 if (Suffix
->is(tok::l_square
))
960 return parseSquare();
961 if (Suffix
->is(tok::l_brace
)) {
962 Scopes
.push_back(getScopeType(*Suffix
));
969 // TokVarName ::= "$" ualpha (ualpha | "0"..."9")*
970 // Appears as a part of DagArg.
971 // This does not change the current token on fail.
972 bool tryToParseTableGenTokVar() {
975 if (CurrentToken
->is(tok::identifier
) &&
976 CurrentToken
->TokenText
.front() == '$') {
977 skipToNextNonComment();
983 // DagArg ::= Value [":" TokVarName] | TokVarName
984 // Appears as a part of SimpleValue6.
985 bool parseTableGenDAGArg(bool AlignColon
= false) {
986 if (tryToParseTableGenTokVar())
988 if (parseTableGenValue()) {
989 if (CurrentToken
&& CurrentToken
->is(tok::colon
)) {
991 CurrentToken
->setType(TT_TableGenDAGArgListColonToAlign
);
993 CurrentToken
->setType(TT_TableGenDAGArgListColon
);
994 skipToNextNonComment();
995 return tryToParseTableGenTokVar();
1002 // Judge if the token is a operator ID to insert line break in DAGArg.
1003 // That is, TableGenBreakingDAGArgOperators is empty (by the definition of the
1004 // option) or the token is in the list.
1005 bool isTableGenDAGArgBreakingOperator(const FormatToken
&Tok
) {
1006 auto &Opes
= Style
.TableGenBreakingDAGArgOperators
;
1007 // If the list is empty, all operators are breaking operators.
1010 // Otherwise, the operator is limited to normal identifiers.
1011 if (Tok
.isNot(tok::identifier
) ||
1012 Tok
.isOneOf(TT_TableGenBangOperator
, TT_TableGenCondOperator
)) {
1015 // The case next is colon, it is not a operator of identifier.
1016 if (!Tok
.Next
|| Tok
.Next
->is(tok::colon
))
1018 return llvm::is_contained(Opes
, Tok
.TokenText
.str());
1021 // SimpleValue6 ::= "(" DagArg [DagArgList] ")"
1022 // This parses SimpleValue 6's inside part of "(" ")"
1023 bool parseTableGenDAGArgAndList(FormatToken
*Opener
) {
1024 FormatToken
*FirstTok
= CurrentToken
;
1025 if (!parseTableGenDAGArg())
1027 bool BreakInside
= false;
1028 if (Style
.TableGenBreakInsideDAGArg
!= FormatStyle::DAS_DontBreak
) {
1029 // Specialized detection for DAGArgOperator, that determines the way of
1030 // line break for this DAGArg elements.
1031 if (isTableGenDAGArgBreakingOperator(*FirstTok
)) {
1032 // Special case for identifier DAGArg operator.
1034 Opener
->setType(TT_TableGenDAGArgOpenerToBreak
);
1035 if (FirstTok
->isOneOf(TT_TableGenBangOperator
,
1036 TT_TableGenCondOperator
)) {
1037 // Special case for bang/cond operators. Set the whole operator as
1038 // the DAGArg operator. Always break after it.
1039 CurrentToken
->Previous
->setType(TT_TableGenDAGArgOperatorToBreak
);
1040 } else if (FirstTok
->is(tok::identifier
)) {
1041 if (Style
.TableGenBreakInsideDAGArg
== FormatStyle::DAS_BreakAll
)
1042 FirstTok
->setType(TT_TableGenDAGArgOperatorToBreak
);
1044 FirstTok
->setType(TT_TableGenDAGArgOperatorID
);
1048 // Parse the [DagArgList] part
1049 bool FirstDAGArgListElm
= true;
1050 while (CurrentToken
) {
1051 if (!FirstDAGArgListElm
&& CurrentToken
->is(tok::comma
)) {
1052 CurrentToken
->setType(BreakInside
? TT_TableGenDAGArgListCommaToBreak
1053 : TT_TableGenDAGArgListComma
);
1054 skipToNextNonComment();
1056 if (CurrentToken
&& CurrentToken
->is(tok::r_paren
)) {
1057 CurrentToken
->setType(TT_TableGenDAGArgCloser
);
1058 Opener
->MatchingParen
= CurrentToken
;
1059 CurrentToken
->MatchingParen
= Opener
;
1060 skipToNextNonComment();
1063 if (!parseTableGenDAGArg(
1065 Style
.AlignConsecutiveTableGenBreakingDAGArgColons
.Enabled
)) {
1068 FirstDAGArgListElm
= false;
1073 bool parseTableGenSimpleValue() {
1074 assert(Style
.isTableGen());
1077 FormatToken
*Tok
= CurrentToken
;
1078 skipToNextNonComment();
1079 // SimpleValue 1, 2, 3: Literals
1080 if (Tok
->isOneOf(tok::numeric_constant
, tok::string_literal
,
1081 TT_TableGenMultiLineString
, tok::kw_true
, tok::kw_false
,
1082 tok::question
, tok::kw_int
)) {
1085 // SimpleValue 4: ValueList, Type
1086 if (Tok
->is(tok::l_brace
)) {
1087 Scopes
.push_back(getScopeType(*Tok
));
1088 return parseBrace();
1090 // SimpleValue 5: List initializer
1091 if (Tok
->is(tok::l_square
)) {
1092 Tok
->setType(TT_TableGenListOpener
);
1095 if (Tok
->is(tok::less
)) {
1096 CurrentToken
->setType(TT_TemplateOpener
);
1097 return parseAngle();
1101 // SimpleValue 6: DAGArg [DAGArgList]
1102 // SimpleValue6 ::= "(" DagArg [DagArgList] ")"
1103 if (Tok
->is(tok::l_paren
)) {
1104 Tok
->setType(TT_TableGenDAGArgOpener
);
1105 return parseTableGenDAGArgAndList(Tok
);
1107 // SimpleValue 9: Bang operator
1108 if (Tok
->is(TT_TableGenBangOperator
)) {
1109 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
1110 CurrentToken
->setType(TT_TemplateOpener
);
1111 skipToNextNonComment();
1115 if (!CurrentToken
|| CurrentToken
->isNot(tok::l_paren
))
1117 skipToNextNonComment();
1118 // FIXME: Hack using inheritance to child context
1119 Contexts
.back().IsTableGenBangOpe
= true;
1120 bool Result
= parseParens();
1121 Contexts
.back().IsTableGenBangOpe
= false;
1124 // SimpleValue 9: Cond operator
1125 if (Tok
->is(TT_TableGenCondOperator
)) {
1127 skipToNextNonComment();
1128 if (!Tok
|| Tok
->isNot(tok::l_paren
))
1130 bool Result
= parseParens();
1133 // We have to check identifier at the last because the kind of bang/cond
1134 // operators are also identifier.
1135 // SimpleValue 7: Identifiers
1136 if (Tok
->is(tok::identifier
)) {
1137 // SimpleValue 8: Anonymous record
1138 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
1139 CurrentToken
->setType(TT_TemplateOpener
);
1140 skipToNextNonComment();
1141 return parseAngle();
1149 bool couldBeInStructArrayInitializer() const {
1150 if (Contexts
.size() < 2)
1152 // We want to back up no more then 2 context levels i.e.
1154 const auto End
= std::next(Contexts
.rbegin(), 2);
1155 auto Last
= Contexts
.rbegin();
1157 for (; Last
!= End
; ++Last
)
1158 if (Last
->ContextKind
== tok::l_brace
)
1160 return Depth
== 2 && Last
->ContextKind
!= tok::l_brace
;
1167 assert(CurrentToken
->Previous
);
1168 FormatToken
&OpeningBrace
= *CurrentToken
->Previous
;
1169 assert(OpeningBrace
.is(tok::l_brace
));
1170 OpeningBrace
.ParentBracket
= Contexts
.back().ContextKind
;
1172 if (Contexts
.back().CaretFound
)
1173 OpeningBrace
.overwriteFixedType(TT_ObjCBlockLBrace
);
1174 Contexts
.back().CaretFound
= false;
1176 ScopedContextCreator
ContextCreator(*this, tok::l_brace
, 1);
1177 Contexts
.back().ColonIsDictLiteral
= true;
1178 if (OpeningBrace
.is(BK_BracedInit
))
1179 Contexts
.back().IsExpression
= true;
1180 if (Style
.isJavaScript() && OpeningBrace
.Previous
&&
1181 OpeningBrace
.Previous
->is(TT_JsTypeColon
)) {
1182 Contexts
.back().IsExpression
= false;
1184 if (Style
.isVerilog() &&
1185 (!OpeningBrace
.getPreviousNonComment() ||
1186 OpeningBrace
.getPreviousNonComment()->isNot(Keywords
.kw_apostrophe
))) {
1187 Contexts
.back().VerilogMayBeConcatenation
= true;
1189 if (Style
.isTableGen())
1190 Contexts
.back().ColonIsDictLiteral
= false;
1192 unsigned CommaCount
= 0;
1193 while (CurrentToken
) {
1194 if (CurrentToken
->is(tok::r_brace
)) {
1195 assert(!Scopes
.empty());
1196 assert(Scopes
.back() == getScopeType(OpeningBrace
));
1198 assert(OpeningBrace
.Optional
== CurrentToken
->Optional
);
1199 OpeningBrace
.MatchingParen
= CurrentToken
;
1200 CurrentToken
->MatchingParen
= &OpeningBrace
;
1201 if (Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
) {
1202 if (OpeningBrace
.ParentBracket
== tok::l_brace
&&
1203 couldBeInStructArrayInitializer() && CommaCount
> 0) {
1204 Contexts
.back().ContextType
= Context::StructArrayInitializer
;
1210 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_square
))
1212 updateParameterCount(&OpeningBrace
, CurrentToken
);
1213 if (CurrentToken
->isOneOf(tok::colon
, tok::l_brace
, tok::less
)) {
1214 FormatToken
*Previous
= CurrentToken
->getPreviousNonComment();
1215 if (Previous
->is(TT_JsTypeOptionalQuestion
))
1216 Previous
= Previous
->getPreviousNonComment();
1217 if ((CurrentToken
->is(tok::colon
) && !Style
.isTableGen() &&
1218 (!Contexts
.back().ColonIsDictLiteral
|| !IsCpp
)) ||
1220 OpeningBrace
.setType(TT_DictLiteral
);
1221 if (Previous
->Tok
.getIdentifierInfo() ||
1222 Previous
->is(tok::string_literal
)) {
1223 Previous
->setType(TT_SelectorName
);
1226 if (CurrentToken
->is(tok::colon
) && OpeningBrace
.is(TT_Unknown
) &&
1227 !Style
.isTableGen()) {
1228 OpeningBrace
.setType(TT_DictLiteral
);
1229 } else if (Style
.isJavaScript()) {
1230 OpeningBrace
.overwriteFixedType(TT_DictLiteral
);
1233 if (CurrentToken
->is(tok::comma
)) {
1234 if (Style
.isJavaScript())
1235 OpeningBrace
.overwriteFixedType(TT_DictLiteral
);
1238 if (!consumeToken())
1244 void updateParameterCount(FormatToken
*Left
, FormatToken
*Current
) {
1245 // For ObjC methods, the number of parameters is calculated differently as
1246 // method declarations have a different structure (the parameters are not
1247 // inside a bracket scope).
1248 if (Current
->is(tok::l_brace
) && Current
->is(BK_Block
))
1249 ++Left
->BlockParameterCount
;
1250 if (Current
->is(tok::comma
)) {
1251 ++Left
->ParameterCount
;
1253 Left
->Role
.reset(new CommaSeparatedList(Style
));
1254 Left
->Role
->CommaFound(Current
);
1255 } else if (Left
->ParameterCount
== 0 && Current
->isNot(tok::comment
)) {
1256 Left
->ParameterCount
= 1;
1260 bool parseConditional() {
1261 while (CurrentToken
) {
1262 if (CurrentToken
->is(tok::colon
) && CurrentToken
->is(TT_Unknown
)) {
1263 CurrentToken
->setType(TT_ConditionalExpr
);
1267 if (!consumeToken())
1273 bool parseTemplateDeclaration() {
1274 if (!CurrentToken
|| CurrentToken
->isNot(tok::less
))
1277 CurrentToken
->setType(TT_TemplateOpener
);
1280 TemplateDeclarationDepth
++;
1281 const bool WellFormed
= parseAngle();
1282 TemplateDeclarationDepth
--;
1286 if (CurrentToken
&& TemplateDeclarationDepth
== 0)
1287 CurrentToken
->Previous
->ClosesTemplateDeclaration
= true;
1292 bool consumeToken() {
1294 const auto *Prev
= CurrentToken
->getPreviousNonComment();
1295 if (Prev
&& Prev
->is(tok::r_square
) && Prev
->is(TT_AttributeSquare
) &&
1296 CurrentToken
->isOneOf(tok::kw_if
, tok::kw_switch
, tok::kw_case
,
1297 tok::kw_default
, tok::kw_for
, tok::kw_while
) &&
1298 mustBreakAfterAttributes(*CurrentToken
, Style
)) {
1299 CurrentToken
->MustBreakBefore
= true;
1302 FormatToken
*Tok
= CurrentToken
;
1304 // In Verilog primitives' state tables, `:`, `?`, and `-` aren't normal
1306 if (Tok
->is(TT_VerilogTableItem
))
1308 // Multi-line string itself is a single annotated token.
1309 if (Tok
->is(TT_TableGenMultiLineString
))
1311 switch (bool IsIf
= false; Tok
->Tok
.getKind()) {
1314 if (!Tok
->Previous
&& Line
.MustBeDeclaration
)
1315 Tok
->setType(TT_ObjCMethodSpecifier
);
1320 // Goto labels and case labels are already identified in
1321 // UnwrappedLineParser.
1322 if (Tok
->isTypeFinalized())
1324 // Colons from ?: are handled in parseConditional().
1325 if (Style
.isJavaScript()) {
1326 if (Contexts
.back().ColonIsForRangeExpr
|| // colon in for loop
1327 (Contexts
.size() == 1 && // switch/case labels
1328 !Line
.First
->isOneOf(tok::kw_enum
, tok::kw_case
)) ||
1329 Contexts
.back().ContextKind
== tok::l_paren
|| // function params
1330 Contexts
.back().ContextKind
== tok::l_square
|| // array type
1331 (!Contexts
.back().IsExpression
&&
1332 Contexts
.back().ContextKind
== tok::l_brace
) || // object type
1333 (Contexts
.size() == 1 &&
1334 Line
.MustBeDeclaration
)) { // method/property declaration
1335 Contexts
.back().IsExpression
= false;
1336 Tok
->setType(TT_JsTypeColon
);
1339 } else if (Style
.isCSharp()) {
1340 if (Contexts
.back().InCSharpAttributeSpecifier
) {
1341 Tok
->setType(TT_AttributeColon
);
1344 if (Contexts
.back().ContextKind
== tok::l_paren
) {
1345 Tok
->setType(TT_CSharpNamedArgumentColon
);
1348 } else if (Style
.isVerilog() && Tok
->isNot(TT_BinaryOperator
)) {
1349 // The distribution weight operators are labeled
1350 // TT_BinaryOperator by the lexer.
1351 if (Keywords
.isVerilogEnd(*Tok
->Previous
) ||
1352 Keywords
.isVerilogBegin(*Tok
->Previous
)) {
1353 Tok
->setType(TT_VerilogBlockLabelColon
);
1354 } else if (Contexts
.back().ContextKind
== tok::l_square
) {
1355 Tok
->setType(TT_BitFieldColon
);
1356 } else if (Contexts
.back().ColonIsDictLiteral
) {
1357 Tok
->setType(TT_DictLiteral
);
1358 } else if (Contexts
.size() == 1) {
1359 // In Verilog a case label doesn't have the case keyword. We
1360 // assume a colon following an expression is a case label.
1361 // Colons from ?: are annotated in parseConditional().
1362 Tok
->setType(TT_CaseLabelColon
);
1363 if (Line
.Level
> 1 || (!Line
.InPPDirective
&& Line
.Level
> 0))
1368 if (Line
.First
->isOneOf(Keywords
.kw_module
, Keywords
.kw_import
) ||
1369 Line
.First
->startsSequence(tok::kw_export
, Keywords
.kw_module
) ||
1370 Line
.First
->startsSequence(tok::kw_export
, Keywords
.kw_import
)) {
1371 Tok
->setType(TT_ModulePartitionColon
);
1372 } else if (Line
.First
->is(tok::kw_asm
)) {
1373 Tok
->setType(TT_InlineASMColon
);
1374 } else if (Contexts
.back().ColonIsDictLiteral
|| Style
.isProto()) {
1375 Tok
->setType(TT_DictLiteral
);
1376 if (Style
.Language
== FormatStyle::LK_TextProto
) {
1377 if (FormatToken
*Previous
= Tok
->getPreviousNonComment())
1378 Previous
->setType(TT_SelectorName
);
1380 } else if (Contexts
.back().ColonIsObjCMethodExpr
||
1381 Line
.startsWith(TT_ObjCMethodSpecifier
)) {
1382 Tok
->setType(TT_ObjCMethodExpr
);
1383 const FormatToken
*BeforePrevious
= Tok
->Previous
->Previous
;
1384 // Ensure we tag all identifiers in method declarations as
1386 bool UnknownIdentifierInMethodDeclaration
=
1387 Line
.startsWith(TT_ObjCMethodSpecifier
) &&
1388 Tok
->Previous
->is(tok::identifier
) && Tok
->Previous
->is(TT_Unknown
);
1389 if (!BeforePrevious
||
1390 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
1391 !(BeforePrevious
->is(TT_CastRParen
) ||
1392 (BeforePrevious
->is(TT_ObjCMethodExpr
) &&
1393 BeforePrevious
->is(tok::colon
))) ||
1394 BeforePrevious
->is(tok::r_square
) ||
1395 Contexts
.back().LongestObjCSelectorName
== 0 ||
1396 UnknownIdentifierInMethodDeclaration
) {
1397 Tok
->Previous
->setType(TT_SelectorName
);
1398 if (!Contexts
.back().FirstObjCSelectorName
) {
1399 Contexts
.back().FirstObjCSelectorName
= Tok
->Previous
;
1400 } else if (Tok
->Previous
->ColumnWidth
>
1401 Contexts
.back().LongestObjCSelectorName
) {
1402 Contexts
.back().LongestObjCSelectorName
=
1403 Tok
->Previous
->ColumnWidth
;
1405 Tok
->Previous
->ParameterIndex
=
1406 Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
1407 ++Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
1409 } else if (Contexts
.back().ColonIsForRangeExpr
) {
1410 Tok
->setType(TT_RangeBasedForLoopColon
);
1411 for (auto *Prev
= Tok
->Previous
;
1412 Prev
&& !Prev
->isOneOf(tok::semi
, tok::l_paren
);
1413 Prev
= Prev
->Previous
) {
1414 if (Prev
->isPointerOrReference())
1415 Prev
->setFinalizedType(TT_PointerOrReference
);
1417 } else if (Contexts
.back().ContextType
== Context::C11GenericSelection
) {
1418 Tok
->setType(TT_GenericSelectionColon
);
1419 } else if (CurrentToken
&& CurrentToken
->is(tok::numeric_constant
)) {
1420 Tok
->setType(TT_BitFieldColon
);
1421 } else if (Contexts
.size() == 1 &&
1422 !Line
.First
->isOneOf(tok::kw_enum
, tok::kw_case
,
1424 FormatToken
*Prev
= Tok
->getPreviousNonComment();
1427 if (Prev
->isOneOf(tok::r_paren
, tok::kw_noexcept
) ||
1428 Prev
->ClosesRequiresClause
) {
1429 Tok
->setType(TT_CtorInitializerColon
);
1430 } else if (Prev
->is(tok::kw_try
)) {
1431 // Member initializer list within function try block.
1432 FormatToken
*PrevPrev
= Prev
->getPreviousNonComment();
1435 if (PrevPrev
&& PrevPrev
->isOneOf(tok::r_paren
, tok::kw_noexcept
))
1436 Tok
->setType(TT_CtorInitializerColon
);
1438 Tok
->setType(TT_InheritanceColon
);
1439 if (Prev
->isAccessSpecifierKeyword())
1440 Line
.Type
= LT_AccessModifier
;
1442 } else if (canBeObjCSelectorComponent(*Tok
->Previous
) && Tok
->Next
&&
1443 (Tok
->Next
->isOneOf(tok::r_paren
, tok::comma
) ||
1444 (canBeObjCSelectorComponent(*Tok
->Next
) && Tok
->Next
->Next
&&
1445 Tok
->Next
->Next
->is(tok::colon
)))) {
1446 // This handles a special macro in ObjC code where selectors including
1447 // the colon are passed as macro arguments.
1448 Tok
->setType(TT_ObjCMethodExpr
);
1453 // | and & in declarations/type expressions represent union and
1454 // intersection types, respectively.
1455 if (Style
.isJavaScript() && !Contexts
.back().IsExpression
)
1456 Tok
->setType(TT_JsTypeOperator
);
1459 if (Style
.isTableGen()) {
1460 // In TableGen it has the form 'if' <value> 'then'.
1461 if (!parseTableGenValue())
1463 if (CurrentToken
&& CurrentToken
->is(Keywords
.kw_then
))
1464 next(); // skip then
1468 CurrentToken
->isOneOf(tok::kw_constexpr
, tok::identifier
)) {
1474 if (CurrentToken
&& CurrentToken
->is(tok::l_paren
)) {
1476 if (!parseParens(IsIf
))
1481 if (Style
.isJavaScript()) {
1482 // x.for and {for: ...}
1483 if ((Tok
->Previous
&& Tok
->Previous
->is(tok::period
)) ||
1484 (Tok
->Next
&& Tok
->Next
->is(tok::colon
))) {
1487 // JS' for await ( ...
1488 if (CurrentToken
&& CurrentToken
->is(Keywords
.kw_await
))
1491 if (IsCpp
&& CurrentToken
&& CurrentToken
->is(tok::kw_co_await
))
1493 Contexts
.back().ColonIsForRangeExpr
= true;
1494 if (!CurrentToken
|| CurrentToken
->isNot(tok::l_paren
))
1501 // When faced with 'operator()()', the kw_operator handler incorrectly
1502 // marks the first l_paren as a OverloadedOperatorLParen. Here, we make
1503 // the first two parens OverloadedOperators and the second l_paren an
1504 // OverloadedOperatorLParen.
1505 if (Tok
->Previous
&& Tok
->Previous
->is(tok::r_paren
) &&
1506 Tok
->Previous
->MatchingParen
&&
1507 Tok
->Previous
->MatchingParen
->is(TT_OverloadedOperatorLParen
)) {
1508 Tok
->Previous
->setType(TT_OverloadedOperator
);
1509 Tok
->Previous
->MatchingParen
->setType(TT_OverloadedOperator
);
1510 Tok
->setType(TT_OverloadedOperatorLParen
);
1513 if (Style
.isVerilog()) {
1514 // Identify the parameter list and port list in a module instantiation.
1515 // This is still needed when we already have
1516 // UnwrappedLineParser::parseVerilogHierarchyHeader because that
1517 // function is only responsible for the definition, not the
1519 auto IsInstancePort
= [&]() {
1520 const FormatToken
*Prev
= Tok
->getPreviousNonComment();
1521 const FormatToken
*PrevPrev
;
1522 // In the following example all 4 left parentheses will be treated as
1523 // 'TT_VerilogInstancePortLParen'.
1525 // module_x instance_1(port_1); // Case A.
1526 // module_x #(parameter_1) // Case B.
1527 // instance_2(port_1), // Case C.
1528 // instance_3(port_1); // Case D.
1529 if (!Prev
|| !(PrevPrev
= Prev
->getPreviousNonComment()))
1532 if (Keywords
.isVerilogIdentifier(*Prev
) &&
1533 Keywords
.isVerilogIdentifier(*PrevPrev
)) {
1537 if (Prev
->is(Keywords
.kw_verilogHash
) &&
1538 Keywords
.isVerilogIdentifier(*PrevPrev
)) {
1542 if (Keywords
.isVerilogIdentifier(*Prev
) && PrevPrev
->is(tok::r_paren
))
1545 if (Keywords
.isVerilogIdentifier(*Prev
) && PrevPrev
->is(tok::comma
)) {
1546 const FormatToken
*PrevParen
= PrevPrev
->getPreviousNonComment();
1547 if (PrevParen
&& PrevParen
->is(tok::r_paren
) &&
1548 PrevParen
->MatchingParen
&&
1549 PrevParen
->MatchingParen
->is(TT_VerilogInstancePortLParen
)) {
1556 if (IsInstancePort())
1557 Tok
->setType(TT_VerilogInstancePortLParen
);
1562 if (Line
.MustBeDeclaration
&& Contexts
.size() == 1 &&
1563 !Contexts
.back().IsExpression
&& !Line
.startsWith(TT_ObjCProperty
) &&
1564 !Line
.startsWith(tok::l_paren
) &&
1565 !Tok
->isOneOf(TT_TypeDeclarationParen
, TT_RequiresExpressionLParen
)) {
1566 if (const auto *Previous
= Tok
->Previous
;
1568 (!Previous
->isAttribute() &&
1569 !Previous
->isOneOf(TT_RequiresClause
, TT_LeadingJavaAnnotation
))) {
1570 Line
.MightBeFunctionDecl
= true;
1571 Tok
->MightBeFunctionDeclParen
= true;
1576 if (Style
.isTableGen())
1577 Tok
->setType(TT_TableGenListOpener
);
1582 if (Style
.Language
== FormatStyle::LK_TextProto
) {
1583 FormatToken
*Previous
= Tok
->getPreviousNonComment();
1584 if (Previous
&& Previous
->isNot(TT_DictLiteral
))
1585 Previous
->setType(TT_SelectorName
);
1587 Scopes
.push_back(getScopeType(*Tok
));
1593 Tok
->setType(TT_TemplateOpener
);
1594 // In TT_Proto, we must distignuish between:
1596 // msg < item: data >
1597 // msg: < item: data >
1598 // In TT_TextProto, map<key, value> does not occur.
1599 if (Style
.Language
== FormatStyle::LK_TextProto
||
1600 (Style
.Language
== FormatStyle::LK_Proto
&& Tok
->Previous
&&
1601 Tok
->Previous
->isOneOf(TT_SelectorName
, TT_DictLiteral
))) {
1602 Tok
->setType(TT_DictLiteral
);
1603 FormatToken
*Previous
= Tok
->getPreviousNonComment();
1604 if (Previous
&& Previous
->isNot(TT_DictLiteral
))
1605 Previous
->setType(TT_SelectorName
);
1607 if (Style
.isTableGen())
1608 Tok
->setType(TT_TemplateOpener
);
1610 Tok
->setType(TT_BinaryOperator
);
1611 NonTemplateLess
.insert(Tok
);
1620 // Don't pop scope when encountering unbalanced r_brace.
1621 if (!Scopes
.empty())
1623 // Lines can start with '}'.
1628 if (Style
.Language
!= FormatStyle::LK_TextProto
&& Tok
->is(TT_Unknown
))
1629 Tok
->setType(TT_BinaryOperator
);
1630 if (Tok
->Previous
&& Tok
->Previous
->is(TT_TemplateCloser
))
1631 Tok
->SpacesRequiredBefore
= 1;
1633 case tok::kw_operator
:
1634 if (Style
.isProto())
1636 while (CurrentToken
&&
1637 !CurrentToken
->isOneOf(tok::l_paren
, tok::semi
, tok::r_paren
)) {
1638 if (CurrentToken
->isOneOf(tok::star
, tok::amp
))
1639 CurrentToken
->setType(TT_PointerOrReference
);
1640 auto Next
= CurrentToken
->getNextNonComment();
1643 if (Next
->is(tok::less
))
1649 auto Previous
= CurrentToken
->getPreviousNonComment();
1651 if (CurrentToken
->is(tok::comma
) && Previous
->isNot(tok::kw_operator
))
1653 if (Previous
->isOneOf(TT_BinaryOperator
, TT_UnaryOperator
, tok::comma
,
1654 tok::star
, tok::arrow
, tok::amp
, tok::ampamp
) ||
1655 // User defined literal.
1656 Previous
->TokenText
.starts_with("\"\"")) {
1657 Previous
->setType(TT_OverloadedOperator
);
1658 if (CurrentToken
->isOneOf(tok::less
, tok::greater
))
1662 if (CurrentToken
&& CurrentToken
->is(tok::l_paren
))
1663 CurrentToken
->setType(TT_OverloadedOperatorLParen
);
1664 if (CurrentToken
&& CurrentToken
->Previous
->is(TT_BinaryOperator
))
1665 CurrentToken
->Previous
->setType(TT_OverloadedOperator
);
1668 if (Style
.isJavaScript() && Tok
->Next
&&
1669 Tok
->Next
->isOneOf(tok::semi
, tok::comma
, tok::colon
, tok::r_paren
,
1670 tok::r_brace
, tok::r_square
)) {
1671 // Question marks before semicolons, colons, etc. indicate optional
1672 // types (fields, parameters), e.g.
1673 // function(x?: string, y?) {...}
1675 Tok
->setType(TT_JsTypeOptionalQuestion
);
1678 // Declarations cannot be conditional expressions, this can only be part
1679 // of a type declaration.
1680 if (Line
.MustBeDeclaration
&& !Contexts
.back().IsExpression
&&
1681 Style
.isJavaScript()) {
1684 if (Style
.isCSharp()) {
1685 // `Type?)`, `Type?>`, `Type? name;` and `Type? name =` can only be
1688 // `Type?)`, `Type?>`, `Type? name;`
1690 (Tok
->Next
->startsSequence(tok::question
, tok::r_paren
) ||
1691 Tok
->Next
->startsSequence(tok::question
, tok::greater
) ||
1692 Tok
->Next
->startsSequence(tok::question
, tok::identifier
,
1694 Tok
->setType(TT_CSharpNullable
);
1699 if (Tok
->Next
&& Tok
->Next
->is(tok::identifier
) && Tok
->Next
->Next
&&
1700 Tok
->Next
->Next
->is(tok::equal
)) {
1701 Tok
->setType(TT_CSharpNullable
);
1705 // Line.MustBeDeclaration will be true for `Type? name;`.
1707 // cond ? "A" : "B";
1709 // cond ? cond2 ? "A" : "B" : "C";
1710 if (!Contexts
.back().IsExpression
&& Line
.MustBeDeclaration
&&
1712 !Tok
->Next
->isOneOf(tok::identifier
, tok::string_literal
) ||
1714 !Tok
->Next
->Next
->isOneOf(tok::colon
, tok::question
))) {
1715 Tok
->setType(TT_CSharpNullable
);
1721 case tok::kw_template
:
1722 parseTemplateDeclaration();
1725 switch (Contexts
.back().ContextType
) {
1726 case Context::CtorInitializer
:
1727 Tok
->setType(TT_CtorInitializerComma
);
1729 case Context::InheritanceList
:
1730 Tok
->setType(TT_InheritanceComma
);
1732 case Context::VerilogInstancePortList
:
1733 Tok
->setType(TT_VerilogInstancePortComma
);
1736 if (Style
.isVerilog() && Contexts
.size() == 1 &&
1737 Line
.startsWith(Keywords
.kw_assign
)) {
1738 Tok
->setFinalizedType(TT_VerilogAssignComma
);
1739 } else if (Contexts
.back().FirstStartOfName
&&
1740 (Contexts
.size() == 1 || startsWithInitStatement(Line
))) {
1741 Contexts
.back().FirstStartOfName
->PartOfMultiVariableDeclStmt
= true;
1742 Line
.IsMultiVariableDeclStmt
= true;
1746 if (Contexts
.back().ContextType
== Context::ForEachMacro
)
1747 Contexts
.back().IsExpression
= true;
1749 case tok::kw_default
:
1750 // Unindent case labels.
1751 if (Style
.isVerilog() && Keywords
.isVerilogEndOfLabel(*Tok
) &&
1752 (Line
.Level
> 1 || (!Line
.InPPDirective
&& Line
.Level
> 0))) {
1756 case tok::identifier
:
1757 if (Tok
->isOneOf(Keywords
.kw___has_include
,
1758 Keywords
.kw___has_include_next
)) {
1761 if (Style
.isCSharp() && Tok
->is(Keywords
.kw_where
) && Tok
->Next
&&
1762 Tok
->Next
->isNot(tok::l_paren
)) {
1763 Tok
->setType(TT_CSharpGenericTypeConstraint
);
1764 parseCSharpGenericTypeConstraint();
1765 if (!Tok
->getPreviousNonComment())
1766 Line
.IsContinuation
= true;
1768 if (Style
.isTableGen()) {
1769 if (Tok
->is(Keywords
.kw_assert
)) {
1770 if (!parseTableGenValue())
1772 } else if (Tok
->isOneOf(Keywords
.kw_def
, Keywords
.kw_defm
) &&
1774 !Tok
->Next
->isOneOf(tok::colon
, tok::l_brace
))) {
1775 // The case NameValue appears.
1776 if (!parseTableGenValue(true))
1782 if (Tok
->isNot(TT_LambdaArrow
) && Tok
->Previous
&&
1783 Tok
->Previous
->is(tok::kw_noexcept
)) {
1784 Tok
->setType(TT_TrailingReturnArrow
);
1788 // In TableGen, there must be a value after "=";
1789 if (Style
.isTableGen() && !parseTableGenValue())
1798 void parseCSharpGenericTypeConstraint() {
1799 int OpenAngleBracketsCount
= 0;
1800 while (CurrentToken
) {
1801 if (CurrentToken
->is(tok::less
)) {
1802 // parseAngle is too greedy and will consume the whole line.
1803 CurrentToken
->setType(TT_TemplateOpener
);
1804 ++OpenAngleBracketsCount
;
1806 } else if (CurrentToken
->is(tok::greater
)) {
1807 CurrentToken
->setType(TT_TemplateCloser
);
1808 --OpenAngleBracketsCount
;
1810 } else if (CurrentToken
->is(tok::comma
) && OpenAngleBracketsCount
== 0) {
1811 // We allow line breaks after GenericTypeConstraintComma's
1812 // so do not flag commas in Generics as GenericTypeConstraintComma's.
1813 CurrentToken
->setType(TT_CSharpGenericTypeConstraintComma
);
1815 } else if (CurrentToken
->is(Keywords
.kw_where
)) {
1816 CurrentToken
->setType(TT_CSharpGenericTypeConstraint
);
1818 } else if (CurrentToken
->is(tok::colon
)) {
1819 CurrentToken
->setType(TT_CSharpGenericTypeConstraintColon
);
1827 void parseIncludeDirective() {
1828 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
1830 while (CurrentToken
) {
1831 // Mark tokens up to the trailing line comments as implicit string
1833 if (CurrentToken
->isNot(tok::comment
) &&
1834 !CurrentToken
->TokenText
.starts_with("//")) {
1835 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1842 void parseWarningOrError() {
1844 // We still want to format the whitespace left of the first token of the
1845 // warning or error.
1847 while (CurrentToken
) {
1848 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1853 void parsePragma() {
1854 next(); // Consume "pragma".
1856 CurrentToken
->isOneOf(Keywords
.kw_mark
, Keywords
.kw_option
,
1857 Keywords
.kw_region
)) {
1858 bool IsMarkOrRegion
=
1859 CurrentToken
->isOneOf(Keywords
.kw_mark
, Keywords
.kw_region
);
1861 next(); // Consume first token (so we fix leading whitespace).
1862 while (CurrentToken
) {
1863 if (IsMarkOrRegion
|| CurrentToken
->Previous
->is(TT_BinaryOperator
))
1864 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1870 void parseHasInclude() {
1871 if (!CurrentToken
|| CurrentToken
->isNot(tok::l_paren
))
1874 parseIncludeDirective();
1878 LineType
parsePreprocessorDirective() {
1879 bool IsFirstToken
= CurrentToken
->IsFirst
;
1880 LineType Type
= LT_PreprocessorDirective
;
1885 if (Style
.isJavaScript() && IsFirstToken
) {
1886 // JavaScript files can contain shebang lines of the form:
1887 // #!/usr/bin/env node
1888 // Treat these like C++ #include directives.
1889 while (CurrentToken
) {
1890 // Tokens cannot be comments here.
1891 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1894 return LT_ImportStatement
;
1897 if (CurrentToken
->is(tok::numeric_constant
)) {
1898 CurrentToken
->SpacesRequiredBefore
= 1;
1901 // Hashes in the middle of a line can lead to any strange token
1903 if (!CurrentToken
->Tok
.getIdentifierInfo())
1905 // In Verilog macro expansions start with a backtick just like preprocessor
1906 // directives. Thus we stop if the word is not a preprocessor directive.
1907 if (Style
.isVerilog() && !Keywords
.isVerilogPPDirective(*CurrentToken
))
1909 switch (CurrentToken
->Tok
.getIdentifierInfo()->getPPKeywordID()) {
1910 case tok::pp_include
:
1911 case tok::pp_include_next
:
1912 case tok::pp_import
:
1914 parseIncludeDirective();
1915 Type
= LT_ImportStatement
;
1918 case tok::pp_warning
:
1919 parseWarningOrError();
1921 case tok::pp_pragma
:
1926 Contexts
.back().IsExpression
= true;
1929 CurrentToken
->SpacesRequiredBefore
= true;
1935 while (CurrentToken
) {
1936 FormatToken
*Tok
= CurrentToken
;
1938 if (Tok
->is(tok::l_paren
)) {
1940 } else if (Tok
->isOneOf(Keywords
.kw___has_include
,
1941 Keywords
.kw___has_include_next
)) {
1949 LineType
parseLine() {
1952 NonTemplateLess
.clear();
1953 if (!Line
.InMacroBody
&& CurrentToken
->is(tok::hash
)) {
1954 // We were not yet allowed to use C++17 optional when this was being
1955 // written. So we used LT_Invalid to mark that the line is not a
1956 // preprocessor directive.
1957 auto Type
= parsePreprocessorDirective();
1958 if (Type
!= LT_Invalid
)
1962 // Directly allow to 'import <string-literal>' to support protocol buffer
1963 // definitions (github.com/google/protobuf) or missing "#" (either way we
1964 // should not break the line).
1965 IdentifierInfo
*Info
= CurrentToken
->Tok
.getIdentifierInfo();
1966 if ((Style
.Language
== FormatStyle::LK_Java
&&
1967 CurrentToken
->is(Keywords
.kw_package
)) ||
1968 (!Style
.isVerilog() && Info
&&
1969 Info
->getPPKeywordID() == tok::pp_import
&& CurrentToken
->Next
&&
1970 CurrentToken
->Next
->isOneOf(tok::string_literal
, tok::identifier
,
1973 parseIncludeDirective();
1974 return LT_ImportStatement
;
1977 // If this line starts and ends in '<' and '>', respectively, it is likely
1978 // part of "#define <a/b.h>".
1979 if (CurrentToken
->is(tok::less
) && Line
.Last
->is(tok::greater
)) {
1980 parseIncludeDirective();
1981 return LT_ImportStatement
;
1984 // In .proto files, top-level options and package statements are very
1985 // similar to import statements and should not be line-wrapped.
1986 if (Style
.Language
== FormatStyle::LK_Proto
&& Line
.Level
== 0 &&
1987 CurrentToken
->isOneOf(Keywords
.kw_option
, Keywords
.kw_package
)) {
1989 if (CurrentToken
&& CurrentToken
->is(tok::identifier
)) {
1990 while (CurrentToken
)
1992 return LT_ImportStatement
;
1996 bool KeywordVirtualFound
= false;
1997 bool ImportStatement
= false;
1999 // import {...} from '...';
2000 if (Style
.isJavaScript() && CurrentToken
->is(Keywords
.kw_import
))
2001 ImportStatement
= true;
2003 while (CurrentToken
) {
2004 if (CurrentToken
->is(tok::kw_virtual
))
2005 KeywordVirtualFound
= true;
2006 if (Style
.isJavaScript()) {
2007 // export {...} from '...';
2008 // An export followed by "from 'some string';" is a re-export from
2009 // another module identified by a URI and is treated as a
2010 // LT_ImportStatement (i.e. prevent wraps on it for long URIs).
2011 // Just "export {...};" or "export class ..." should not be treated as
2012 // an import in this sense.
2013 if (Line
.First
->is(tok::kw_export
) &&
2014 CurrentToken
->is(Keywords
.kw_from
) && CurrentToken
->Next
&&
2015 CurrentToken
->Next
->isStringLiteral()) {
2016 ImportStatement
= true;
2018 if (isClosureImportStatement(*CurrentToken
))
2019 ImportStatement
= true;
2021 if (!consumeToken())
2024 if (Line
.Type
== LT_AccessModifier
)
2025 return LT_AccessModifier
;
2026 if (KeywordVirtualFound
)
2027 return LT_VirtualFunctionDecl
;
2028 if (ImportStatement
)
2029 return LT_ImportStatement
;
2031 if (Line
.startsWith(TT_ObjCMethodSpecifier
)) {
2032 if (Contexts
.back().FirstObjCSelectorName
) {
2033 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
2034 Contexts
.back().LongestObjCSelectorName
;
2036 return LT_ObjCMethodDecl
;
2039 for (const auto &ctx
: Contexts
)
2040 if (ctx
.ContextType
== Context::StructArrayInitializer
)
2041 return LT_ArrayOfStructInitializer
;
2047 bool isClosureImportStatement(const FormatToken
&Tok
) {
2048 // FIXME: Closure-library specific stuff should not be hard-coded but be
2050 return Tok
.TokenText
== "goog" && Tok
.Next
&& Tok
.Next
->is(tok::period
) &&
2052 (Tok
.Next
->Next
->TokenText
== "module" ||
2053 Tok
.Next
->Next
->TokenText
== "provide" ||
2054 Tok
.Next
->Next
->TokenText
== "require" ||
2055 Tok
.Next
->Next
->TokenText
== "requireType" ||
2056 Tok
.Next
->Next
->TokenText
== "forwardDeclare") &&
2057 Tok
.Next
->Next
->Next
&& Tok
.Next
->Next
->Next
->is(tok::l_paren
);
2060 void resetTokenMetadata() {
2064 // Reset token type in case we have already looked at it and then
2065 // recovered from an error (e.g. failure to find the matching >).
2066 if (!CurrentToken
->isTypeFinalized() &&
2067 !CurrentToken
->isOneOf(
2068 TT_LambdaLSquare
, TT_LambdaLBrace
, TT_AttributeMacro
, TT_IfMacro
,
2069 TT_ForEachMacro
, TT_TypenameMacro
, TT_FunctionLBrace
,
2070 TT_ImplicitStringLiteral
, TT_InlineASMBrace
, TT_FatArrow
,
2071 TT_LambdaArrow
, TT_NamespaceMacro
, TT_OverloadedOperator
,
2072 TT_RegexLiteral
, TT_TemplateString
, TT_ObjCStringLiteral
,
2073 TT_UntouchableMacroFunc
, TT_StatementAttributeLikeMacro
,
2074 TT_FunctionLikeOrFreestandingMacro
, TT_ClassLBrace
, TT_EnumLBrace
,
2075 TT_RecordLBrace
, TT_StructLBrace
, TT_UnionLBrace
, TT_RequiresClause
,
2076 TT_RequiresClauseInARequiresExpression
, TT_RequiresExpression
,
2077 TT_RequiresExpressionLParen
, TT_RequiresExpressionLBrace
,
2078 TT_BracedListLBrace
)) {
2079 CurrentToken
->setType(TT_Unknown
);
2081 CurrentToken
->Role
.reset();
2082 CurrentToken
->MatchingParen
= nullptr;
2083 CurrentToken
->FakeLParens
.clear();
2084 CurrentToken
->FakeRParens
= 0;
2091 CurrentToken
->NestingLevel
= Contexts
.size() - 1;
2092 CurrentToken
->BindingStrength
= Contexts
.back().BindingStrength
;
2093 modifyContext(*CurrentToken
);
2094 determineTokenType(*CurrentToken
);
2095 CurrentToken
= CurrentToken
->Next
;
2097 resetTokenMetadata();
2100 /// A struct to hold information valid in a specific context, e.g.
2101 /// a pair of parenthesis.
2103 Context(tok::TokenKind ContextKind
, unsigned BindingStrength
,
2105 : ContextKind(ContextKind
), BindingStrength(BindingStrength
),
2106 IsExpression(IsExpression
) {}
2108 tok::TokenKind ContextKind
;
2109 unsigned BindingStrength
;
2111 unsigned LongestObjCSelectorName
= 0;
2112 bool ColonIsForRangeExpr
= false;
2113 bool ColonIsDictLiteral
= false;
2114 bool ColonIsObjCMethodExpr
= false;
2115 FormatToken
*FirstObjCSelectorName
= nullptr;
2116 FormatToken
*FirstStartOfName
= nullptr;
2117 bool CanBeExpression
= true;
2118 bool CaretFound
= false;
2119 bool InCpp11AttributeSpecifier
= false;
2120 bool InCSharpAttributeSpecifier
= false;
2121 bool VerilogAssignmentFound
= false;
2122 // Whether the braces may mean concatenation instead of structure or array
2124 bool VerilogMayBeConcatenation
= false;
2125 bool IsTableGenDAGArg
= false;
2126 bool IsTableGenBangOpe
= false;
2127 bool IsTableGenCondOpe
= false;
2130 // Like the part after `:` in a constructor.
2131 // Context(...) : IsExpression(IsExpression)
2133 // Like in the parentheses in a foreach.
2135 // Like the inheritance list in a class declaration.
2136 // class Input : public IO
2138 // Like in the braced list.
2140 StructArrayInitializer
,
2141 // Like in `static_cast<int>`.
2143 // C11 _Generic selection.
2144 C11GenericSelection
,
2145 // Like in the outer parentheses in `ffnand ff1(.q());`.
2146 VerilogInstancePortList
,
2147 } ContextType
= Unknown
;
2150 /// Puts a new \c Context onto the stack \c Contexts for the lifetime
2151 /// of each instance.
2152 struct ScopedContextCreator
{
2153 AnnotatingParser
&P
;
2155 ScopedContextCreator(AnnotatingParser
&P
, tok::TokenKind ContextKind
,
2158 P
.Contexts
.push_back(Context(ContextKind
,
2159 P
.Contexts
.back().BindingStrength
+ Increase
,
2160 P
.Contexts
.back().IsExpression
));
2163 ~ScopedContextCreator() {
2164 if (P
.Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
) {
2165 if (P
.Contexts
.back().ContextType
== Context::StructArrayInitializer
) {
2166 P
.Contexts
.pop_back();
2167 P
.Contexts
.back().ContextType
= Context::StructArrayInitializer
;
2171 P
.Contexts
.pop_back();
2175 void modifyContext(const FormatToken
&Current
) {
2176 auto AssignmentStartsExpression
= [&]() {
2177 if (Current
.getPrecedence() != prec::Assignment
)
2180 if (Line
.First
->isOneOf(tok::kw_using
, tok::kw_return
))
2182 if (Line
.First
->is(tok::kw_template
)) {
2183 assert(Current
.Previous
);
2184 if (Current
.Previous
->is(tok::kw_operator
)) {
2185 // `template ... operator=` cannot be an expression.
2189 // `template` keyword can start a variable template.
2190 const FormatToken
*Tok
= Line
.First
->getNextNonComment();
2191 assert(Tok
); // Current token is on the same line.
2192 if (Tok
->isNot(TT_TemplateOpener
)) {
2193 // Explicit template instantiations do not have `<>`.
2197 // This is the default value of a template parameter, determine if it's
2198 // type or non-type.
2199 if (Contexts
.back().ContextKind
== tok::less
) {
2200 assert(Current
.Previous
->Previous
);
2201 return !Current
.Previous
->Previous
->isOneOf(tok::kw_typename
,
2205 Tok
= Tok
->MatchingParen
;
2208 Tok
= Tok
->getNextNonComment();
2212 if (Tok
->isOneOf(tok::kw_class
, tok::kw_enum
, tok::kw_struct
,
2220 // Type aliases use `type X = ...;` in TypeScript and can be exported
2221 // using `export type ...`.
2222 if (Style
.isJavaScript() &&
2223 (Line
.startsWith(Keywords
.kw_type
, tok::identifier
) ||
2224 Line
.startsWith(tok::kw_export
, Keywords
.kw_type
,
2225 tok::identifier
))) {
2229 return !Current
.Previous
|| Current
.Previous
->isNot(tok::kw_operator
);
2232 if (AssignmentStartsExpression()) {
2233 Contexts
.back().IsExpression
= true;
2234 if (!Line
.startsWith(TT_UnaryOperator
)) {
2235 for (FormatToken
*Previous
= Current
.Previous
;
2236 Previous
&& Previous
->Previous
&&
2237 !Previous
->Previous
->isOneOf(tok::comma
, tok::semi
);
2238 Previous
= Previous
->Previous
) {
2239 if (Previous
->isOneOf(tok::r_square
, tok::r_paren
, tok::greater
)) {
2240 Previous
= Previous
->MatchingParen
;
2244 if (Previous
->opensScope())
2246 if (Previous
->isOneOf(TT_BinaryOperator
, TT_UnaryOperator
) &&
2247 Previous
->isPointerOrReference() && Previous
->Previous
&&
2248 Previous
->Previous
->isNot(tok::equal
)) {
2249 Previous
->setType(TT_PointerOrReference
);
2253 } else if (Current
.is(tok::lessless
) &&
2254 (!Current
.Previous
||
2255 Current
.Previous
->isNot(tok::kw_operator
))) {
2256 Contexts
.back().IsExpression
= true;
2257 } else if (Current
.isOneOf(tok::kw_return
, tok::kw_throw
)) {
2258 Contexts
.back().IsExpression
= true;
2259 } else if (Current
.is(TT_TrailingReturnArrow
)) {
2260 Contexts
.back().IsExpression
= false;
2261 } else if (Current
.isOneOf(TT_LambdaArrow
, Keywords
.kw_assert
)) {
2262 Contexts
.back().IsExpression
= Style
.Language
== FormatStyle::LK_Java
;
2263 } else if (Current
.Previous
&&
2264 Current
.Previous
->is(TT_CtorInitializerColon
)) {
2265 Contexts
.back().IsExpression
= true;
2266 Contexts
.back().ContextType
= Context::CtorInitializer
;
2267 } else if (Current
.Previous
&& Current
.Previous
->is(TT_InheritanceColon
)) {
2268 Contexts
.back().ContextType
= Context::InheritanceList
;
2269 } else if (Current
.isOneOf(tok::r_paren
, tok::greater
, tok::comma
)) {
2270 for (FormatToken
*Previous
= Current
.Previous
;
2271 Previous
&& Previous
->isOneOf(tok::star
, tok::amp
);
2272 Previous
= Previous
->Previous
) {
2273 Previous
->setType(TT_PointerOrReference
);
2275 if (Line
.MustBeDeclaration
&&
2276 Contexts
.front().ContextType
!= Context::CtorInitializer
) {
2277 Contexts
.back().IsExpression
= false;
2279 } else if (Current
.is(tok::kw_new
)) {
2280 Contexts
.back().CanBeExpression
= false;
2281 } else if (Current
.is(tok::semi
) ||
2282 (Current
.is(tok::exclaim
) && Current
.Previous
&&
2283 Current
.Previous
->isNot(tok::kw_operator
))) {
2284 // This should be the condition or increment in a for-loop.
2285 // But not operator !() (can't use TT_OverloadedOperator here as its not
2286 // been annotated yet).
2287 Contexts
.back().IsExpression
= true;
2291 static FormatToken
*untilMatchingParen(FormatToken
*Current
) {
2292 // Used when `MatchingParen` is not yet established.
2295 if (Current
->is(tok::l_paren
))
2297 if (Current
->is(tok::r_paren
))
2301 Current
= Current
->Next
;
2306 static bool isDeductionGuide(FormatToken
&Current
) {
2307 // Look for a deduction guide template<T> A(...) -> A<...>;
2308 if (Current
.Previous
&& Current
.Previous
->is(tok::r_paren
) &&
2309 Current
.startsSequence(tok::arrow
, tok::identifier
, tok::less
)) {
2310 // Find the TemplateCloser.
2311 FormatToken
*TemplateCloser
= Current
.Next
->Next
;
2312 int NestingLevel
= 0;
2313 while (TemplateCloser
) {
2314 // Skip over an expressions in parens A<(3 < 2)>;
2315 if (TemplateCloser
->is(tok::l_paren
)) {
2316 // No Matching Paren yet so skip to matching paren
2317 TemplateCloser
= untilMatchingParen(TemplateCloser
);
2318 if (!TemplateCloser
)
2321 if (TemplateCloser
->is(tok::less
))
2323 if (TemplateCloser
->is(tok::greater
))
2325 if (NestingLevel
< 1)
2327 TemplateCloser
= TemplateCloser
->Next
;
2329 // Assuming we have found the end of the template ensure its followed
2330 // with a semi-colon.
2331 if (TemplateCloser
&& TemplateCloser
->Next
&&
2332 TemplateCloser
->Next
->is(tok::semi
) &&
2333 Current
.Previous
->MatchingParen
) {
2334 // Determine if the identifier `A` prior to the A<..>; is the same as
2335 // prior to the A(..)
2336 FormatToken
*LeadingIdentifier
=
2337 Current
.Previous
->MatchingParen
->Previous
;
2339 return LeadingIdentifier
&&
2340 LeadingIdentifier
->TokenText
== Current
.Next
->TokenText
;
2346 void determineTokenType(FormatToken
&Current
) {
2347 if (Current
.isNot(TT_Unknown
)) {
2348 // The token type is already known.
2352 if ((Style
.isJavaScript() || Style
.isCSharp()) &&
2353 Current
.is(tok::exclaim
)) {
2354 if (Current
.Previous
) {
2356 Style
.isJavaScript()
2357 ? Keywords
.isJavaScriptIdentifier(
2358 *Current
.Previous
, /* AcceptIdentifierName= */ true)
2359 : Current
.Previous
->is(tok::identifier
);
2361 Current
.Previous
->isOneOf(
2362 tok::kw_default
, tok::kw_namespace
, tok::r_paren
, tok::r_square
,
2363 tok::r_brace
, tok::kw_false
, tok::kw_true
, Keywords
.kw_type
,
2364 Keywords
.kw_get
, Keywords
.kw_init
, Keywords
.kw_set
) ||
2365 Current
.Previous
->Tok
.isLiteral()) {
2366 Current
.setType(TT_NonNullAssertion
);
2371 Current
.Next
->isOneOf(TT_BinaryOperator
, Keywords
.kw_as
)) {
2372 Current
.setType(TT_NonNullAssertion
);
2377 // Line.MightBeFunctionDecl can only be true after the parentheses of a
2378 // function declaration have been found. In this case, 'Current' is a
2379 // trailing token of this declaration and thus cannot be a name.
2380 if ((Style
.isJavaScript() || Style
.Language
== FormatStyle::LK_Java
) &&
2381 Current
.is(Keywords
.kw_instanceof
)) {
2382 Current
.setType(TT_BinaryOperator
);
2383 } else if (isStartOfName(Current
) &&
2384 (!Line
.MightBeFunctionDecl
|| Current
.NestingLevel
!= 0)) {
2385 Contexts
.back().FirstStartOfName
= &Current
;
2386 Current
.setType(TT_StartOfName
);
2387 } else if (Current
.is(tok::semi
)) {
2388 // Reset FirstStartOfName after finding a semicolon so that a for loop
2389 // with multiple increment statements is not confused with a for loop
2390 // having multiple variable declarations.
2391 Contexts
.back().FirstStartOfName
= nullptr;
2392 } else if (Current
.isOneOf(tok::kw_auto
, tok::kw___auto_type
)) {
2394 } else if (Current
.is(tok::arrow
) &&
2395 Style
.Language
== FormatStyle::LK_Java
) {
2396 Current
.setType(TT_LambdaArrow
);
2397 } else if (Current
.is(tok::arrow
) && Style
.isVerilog()) {
2398 // The implication operator.
2399 Current
.setType(TT_BinaryOperator
);
2400 } else if (Current
.is(tok::arrow
) && AutoFound
&&
2401 Line
.MightBeFunctionDecl
&& Current
.NestingLevel
== 0 &&
2402 !Current
.Previous
->isOneOf(tok::kw_operator
, tok::identifier
)) {
2403 // not auto operator->() -> xxx;
2404 Current
.setType(TT_TrailingReturnArrow
);
2405 } else if (Current
.is(tok::arrow
) && Current
.Previous
&&
2406 Current
.Previous
->is(tok::r_brace
)) {
2407 // Concept implicit conversion constraint needs to be treated like
2408 // a trailing return type ... } -> <type>.
2409 Current
.setType(TT_TrailingReturnArrow
);
2410 } else if (isDeductionGuide(Current
)) {
2411 // Deduction guides trailing arrow " A(...) -> A<T>;".
2412 Current
.setType(TT_TrailingReturnArrow
);
2413 } else if (Current
.isPointerOrReference()) {
2414 Current
.setType(determineStarAmpUsage(
2416 Contexts
.back().CanBeExpression
&& Contexts
.back().IsExpression
,
2417 Contexts
.back().ContextType
== Context::TemplateArgument
));
2418 } else if (Current
.isOneOf(tok::minus
, tok::plus
, tok::caret
) ||
2419 (Style
.isVerilog() && Current
.is(tok::pipe
))) {
2420 Current
.setType(determinePlusMinusCaretUsage(Current
));
2421 if (Current
.is(TT_UnaryOperator
) && Current
.is(tok::caret
))
2422 Contexts
.back().CaretFound
= true;
2423 } else if (Current
.isOneOf(tok::minusminus
, tok::plusplus
)) {
2424 Current
.setType(determineIncrementUsage(Current
));
2425 } else if (Current
.isOneOf(tok::exclaim
, tok::tilde
)) {
2426 Current
.setType(TT_UnaryOperator
);
2427 } else if (Current
.is(tok::question
)) {
2428 if (Style
.isJavaScript() && Line
.MustBeDeclaration
&&
2429 !Contexts
.back().IsExpression
) {
2430 // In JavaScript, `interface X { foo?(): bar; }` is an optional method
2431 // on the interface, not a ternary expression.
2432 Current
.setType(TT_JsTypeOptionalQuestion
);
2433 } else if (Style
.isTableGen()) {
2434 // In TableGen, '?' is just an identifier like token.
2435 Current
.setType(TT_Unknown
);
2437 Current
.setType(TT_ConditionalExpr
);
2439 } else if (Current
.isBinaryOperator() &&
2440 (!Current
.Previous
|| Current
.Previous
->isNot(tok::l_square
)) &&
2441 (Current
.isNot(tok::greater
) &&
2442 Style
.Language
!= FormatStyle::LK_TextProto
)) {
2443 if (Style
.isVerilog()) {
2444 if (Current
.is(tok::lessequal
) && Contexts
.size() == 1 &&
2445 !Contexts
.back().VerilogAssignmentFound
) {
2446 // In Verilog `<=` is assignment if in its own statement. It is a
2447 // statement instead of an expression, that is it can not be chained.
2448 Current
.ForcedPrecedence
= prec::Assignment
;
2449 Current
.setFinalizedType(TT_BinaryOperator
);
2451 if (Current
.getPrecedence() == prec::Assignment
)
2452 Contexts
.back().VerilogAssignmentFound
= true;
2454 Current
.setType(TT_BinaryOperator
);
2455 } else if (Current
.is(tok::comment
)) {
2456 if (Current
.TokenText
.starts_with("/*")) {
2457 if (Current
.TokenText
.ends_with("*/")) {
2458 Current
.setType(TT_BlockComment
);
2460 // The lexer has for some reason determined a comment here. But we
2461 // cannot really handle it, if it isn't properly terminated.
2462 Current
.Tok
.setKind(tok::unknown
);
2465 Current
.setType(TT_LineComment
);
2467 } else if (Current
.is(tok::string_literal
)) {
2468 if (Style
.isVerilog() && Contexts
.back().VerilogMayBeConcatenation
&&
2469 Current
.getPreviousNonComment() &&
2470 Current
.getPreviousNonComment()->isOneOf(tok::comma
, tok::l_brace
) &&
2471 Current
.getNextNonComment() &&
2472 Current
.getNextNonComment()->isOneOf(tok::comma
, tok::r_brace
)) {
2473 Current
.setType(TT_StringInConcatenation
);
2475 } else if (Current
.is(tok::l_paren
)) {
2476 if (lParenStartsCppCast(Current
))
2477 Current
.setType(TT_CppCastLParen
);
2478 } else if (Current
.is(tok::r_paren
)) {
2479 if (rParenEndsCast(Current
))
2480 Current
.setType(TT_CastRParen
);
2481 if (Current
.MatchingParen
&& Current
.Next
&&
2482 !Current
.Next
->isBinaryOperator() &&
2483 !Current
.Next
->isOneOf(
2484 tok::semi
, tok::colon
, tok::l_brace
, tok::l_paren
, tok::comma
,
2485 tok::period
, tok::arrow
, tok::coloncolon
, tok::kw_noexcept
)) {
2486 if (FormatToken
*AfterParen
= Current
.MatchingParen
->Next
;
2487 AfterParen
&& AfterParen
->isNot(tok::caret
)) {
2488 // Make sure this isn't the return type of an Obj-C block declaration.
2489 if (FormatToken
*BeforeParen
= Current
.MatchingParen
->Previous
;
2490 BeforeParen
&& BeforeParen
->is(tok::identifier
) &&
2491 BeforeParen
->isNot(TT_TypenameMacro
) &&
2492 BeforeParen
->TokenText
== BeforeParen
->TokenText
.upper() &&
2493 (!BeforeParen
->Previous
||
2494 BeforeParen
->Previous
->ClosesTemplateDeclaration
||
2495 BeforeParen
->Previous
->ClosesRequiresClause
)) {
2496 Current
.setType(TT_FunctionAnnotationRParen
);
2500 } else if (Current
.is(tok::at
) && Current
.Next
&& !Style
.isJavaScript() &&
2501 Style
.Language
!= FormatStyle::LK_Java
) {
2502 // In Java & JavaScript, "@..." is a decorator or annotation. In ObjC, it
2503 // marks declarations and properties that need special formatting.
2504 switch (Current
.Next
->Tok
.getObjCKeywordID()) {
2505 case tok::objc_interface
:
2506 case tok::objc_implementation
:
2507 case tok::objc_protocol
:
2508 Current
.setType(TT_ObjCDecl
);
2510 case tok::objc_property
:
2511 Current
.setType(TT_ObjCProperty
);
2516 } else if (Current
.is(tok::period
)) {
2517 FormatToken
*PreviousNoComment
= Current
.getPreviousNonComment();
2518 if (PreviousNoComment
&&
2519 PreviousNoComment
->isOneOf(tok::comma
, tok::l_brace
)) {
2520 Current
.setType(TT_DesignatedInitializerPeriod
);
2521 } else if (Style
.Language
== FormatStyle::LK_Java
&& Current
.Previous
&&
2522 Current
.Previous
->isOneOf(TT_JavaAnnotation
,
2523 TT_LeadingJavaAnnotation
)) {
2524 Current
.setType(Current
.Previous
->getType());
2526 } else if (canBeObjCSelectorComponent(Current
) &&
2527 // FIXME(bug 36976): ObjC return types shouldn't use
2529 Current
.Previous
&& Current
.Previous
->is(TT_CastRParen
) &&
2530 Current
.Previous
->MatchingParen
&&
2531 Current
.Previous
->MatchingParen
->Previous
&&
2532 Current
.Previous
->MatchingParen
->Previous
->is(
2533 TT_ObjCMethodSpecifier
)) {
2534 // This is the first part of an Objective-C selector name. (If there's no
2535 // colon after this, this is the only place which annotates the identifier
2537 Current
.setType(TT_SelectorName
);
2538 } else if (Current
.isOneOf(tok::identifier
, tok::kw_const
, tok::kw_noexcept
,
2539 tok::kw_requires
) &&
2541 !Current
.Previous
->isOneOf(tok::equal
, tok::at
,
2542 TT_CtorInitializerComma
,
2543 TT_CtorInitializerColon
) &&
2544 Line
.MightBeFunctionDecl
&& Contexts
.size() == 1) {
2545 // Line.MightBeFunctionDecl can only be true after the parentheses of a
2546 // function declaration have been found.
2547 Current
.setType(TT_TrailingAnnotation
);
2548 } else if ((Style
.Language
== FormatStyle::LK_Java
||
2549 Style
.isJavaScript()) &&
2551 if (Current
.Previous
->is(tok::at
) &&
2552 Current
.isNot(Keywords
.kw_interface
)) {
2553 const FormatToken
&AtToken
= *Current
.Previous
;
2554 const FormatToken
*Previous
= AtToken
.getPreviousNonComment();
2555 if (!Previous
|| Previous
->is(TT_LeadingJavaAnnotation
))
2556 Current
.setType(TT_LeadingJavaAnnotation
);
2558 Current
.setType(TT_JavaAnnotation
);
2559 } else if (Current
.Previous
->is(tok::period
) &&
2560 Current
.Previous
->isOneOf(TT_JavaAnnotation
,
2561 TT_LeadingJavaAnnotation
)) {
2562 Current
.setType(Current
.Previous
->getType());
2567 /// Take a guess at whether \p Tok starts a name of a function or
2568 /// variable declaration.
2570 /// This is a heuristic based on whether \p Tok is an identifier following
2571 /// something that is likely a type.
2572 bool isStartOfName(const FormatToken
&Tok
) {
2573 // Handled in ExpressionParser for Verilog.
2574 if (Style
.isVerilog())
2577 if (Tok
.isNot(tok::identifier
) || !Tok
.Previous
)
2580 if (const auto *NextNonComment
= Tok
.getNextNonComment();
2581 (!NextNonComment
&& !Line
.InMacroBody
) ||
2583 (NextNonComment
->isPointerOrReference() ||
2584 NextNonComment
->is(tok::string_literal
) ||
2585 (Line
.InPragmaDirective
&& NextNonComment
->is(tok::identifier
))))) {
2589 if (Tok
.Previous
->isOneOf(TT_LeadingJavaAnnotation
, Keywords
.kw_instanceof
,
2593 if (Style
.isJavaScript() && Tok
.Previous
->is(Keywords
.kw_in
))
2596 // Skip "const" as it does not have an influence on whether this is a name.
2597 FormatToken
*PreviousNotConst
= Tok
.getPreviousNonComment();
2599 // For javascript const can be like "let" or "var"
2600 if (!Style
.isJavaScript())
2601 while (PreviousNotConst
&& PreviousNotConst
->is(tok::kw_const
))
2602 PreviousNotConst
= PreviousNotConst
->getPreviousNonComment();
2604 if (!PreviousNotConst
)
2607 if (PreviousNotConst
->ClosesRequiresClause
)
2610 if (Style
.isTableGen()) {
2611 // keywords such as let and def* defines names.
2612 if (Keywords
.isTableGenDefinition(*PreviousNotConst
))
2614 // Otherwise C++ style declarations is available only inside the brace.
2615 if (Contexts
.back().ContextKind
!= tok::l_brace
)
2619 bool IsPPKeyword
= PreviousNotConst
->is(tok::identifier
) &&
2620 PreviousNotConst
->Previous
&&
2621 PreviousNotConst
->Previous
->is(tok::hash
);
2623 if (PreviousNotConst
->is(TT_TemplateCloser
)) {
2624 return PreviousNotConst
&& PreviousNotConst
->MatchingParen
&&
2625 PreviousNotConst
->MatchingParen
->Previous
&&
2626 PreviousNotConst
->MatchingParen
->Previous
->isNot(tok::period
) &&
2627 PreviousNotConst
->MatchingParen
->Previous
->isNot(tok::kw_template
);
2630 if ((PreviousNotConst
->is(tok::r_paren
) &&
2631 PreviousNotConst
->is(TT_TypeDeclarationParen
)) ||
2632 PreviousNotConst
->is(TT_AttributeRParen
)) {
2636 // If is a preprocess keyword like #define.
2641 if (PreviousNotConst
->isOneOf(tok::identifier
, tok::kw_auto
) &&
2642 PreviousNotConst
->isNot(TT_StatementAttributeLikeMacro
)) {
2647 if (PreviousNotConst
->is(TT_PointerOrReference
))
2651 if (PreviousNotConst
->isTypeName(LangOpts
))
2655 if (Style
.Language
== FormatStyle::LK_Java
&&
2656 PreviousNotConst
->is(tok::r_square
)) {
2660 // const a = in JavaScript.
2661 return Style
.isJavaScript() && PreviousNotConst
->is(tok::kw_const
);
2664 /// Determine whether '(' is starting a C++ cast.
2665 bool lParenStartsCppCast(const FormatToken
&Tok
) {
2666 // C-style casts are only used in C++.
2670 FormatToken
*LeftOfParens
= Tok
.getPreviousNonComment();
2671 if (LeftOfParens
&& LeftOfParens
->is(TT_TemplateCloser
) &&
2672 LeftOfParens
->MatchingParen
) {
2673 auto *Prev
= LeftOfParens
->MatchingParen
->getPreviousNonComment();
2675 Prev
->isOneOf(tok::kw_const_cast
, tok::kw_dynamic_cast
,
2676 tok::kw_reinterpret_cast
, tok::kw_static_cast
)) {
2677 // FIXME: Maybe we should handle identifiers ending with "_cast",
2685 /// Determine whether ')' is ending a cast.
2686 bool rParenEndsCast(const FormatToken
&Tok
) {
2687 assert(Tok
.is(tok::r_paren
));
2689 if (!Tok
.MatchingParen
|| !Tok
.Previous
)
2692 // C-style casts are only used in C++, C# and Java.
2693 if (!IsCpp
&& !Style
.isCSharp() && Style
.Language
!= FormatStyle::LK_Java
)
2696 const auto *LParen
= Tok
.MatchingParen
;
2697 const auto *BeforeRParen
= Tok
.Previous
;
2698 const auto *AfterRParen
= Tok
.Next
;
2700 // Empty parens aren't casts and there are no casts at the end of the line.
2701 if (BeforeRParen
== LParen
|| !AfterRParen
)
2704 if (LParen
->is(TT_OverloadedOperatorLParen
))
2707 auto *LeftOfParens
= LParen
->getPreviousNonComment();
2709 // If there is a closing parenthesis left of the current
2710 // parentheses, look past it as these might be chained casts.
2711 if (LeftOfParens
->is(tok::r_paren
) &&
2712 LeftOfParens
->isNot(TT_CastRParen
)) {
2713 if (!LeftOfParens
->MatchingParen
||
2714 !LeftOfParens
->MatchingParen
->Previous
) {
2717 LeftOfParens
= LeftOfParens
->MatchingParen
->Previous
;
2720 if (LeftOfParens
->is(tok::r_square
)) {
2721 // delete[] (void *)ptr;
2722 auto MayBeArrayDelete
= [](FormatToken
*Tok
) -> FormatToken
* {
2723 if (Tok
->isNot(tok::r_square
))
2726 Tok
= Tok
->getPreviousNonComment();
2727 if (!Tok
|| Tok
->isNot(tok::l_square
))
2730 Tok
= Tok
->getPreviousNonComment();
2731 if (!Tok
|| Tok
->isNot(tok::kw_delete
))
2735 if (FormatToken
*MaybeDelete
= MayBeArrayDelete(LeftOfParens
))
2736 LeftOfParens
= MaybeDelete
;
2739 // The Condition directly below this one will see the operator arguments
2740 // as a (void *foo) cast.
2741 // void operator delete(void *foo) ATTRIB;
2742 if (LeftOfParens
->Tok
.getIdentifierInfo() && LeftOfParens
->Previous
&&
2743 LeftOfParens
->Previous
->is(tok::kw_operator
)) {
2747 // If there is an identifier (or with a few exceptions a keyword) right
2748 // before the parentheses, this is unlikely to be a cast.
2749 if (LeftOfParens
->Tok
.getIdentifierInfo() &&
2750 !LeftOfParens
->isOneOf(Keywords
.kw_in
, tok::kw_return
, tok::kw_case
,
2751 tok::kw_delete
, tok::kw_throw
)) {
2755 // Certain other tokens right before the parentheses are also signals that
2756 // this cannot be a cast.
2757 if (LeftOfParens
->isOneOf(tok::at
, tok::r_square
, TT_OverloadedOperator
,
2758 TT_TemplateCloser
, tok::ellipsis
)) {
2763 if (AfterRParen
->is(tok::question
) ||
2764 (AfterRParen
->is(tok::ampamp
) && !BeforeRParen
->isTypeName(LangOpts
))) {
2768 // `foreach((A a, B b) in someList)` should not be seen as a cast.
2769 if (AfterRParen
->is(Keywords
.kw_in
) && Style
.isCSharp())
2772 // Functions which end with decorations like volatile, noexcept are unlikely
2774 if (AfterRParen
->isOneOf(tok::kw_noexcept
, tok::kw_volatile
, tok::kw_const
,
2775 tok::kw_requires
, tok::kw_throw
, tok::arrow
,
2776 Keywords
.kw_override
, Keywords
.kw_final
) ||
2777 isCppAttribute(IsCpp
, *AfterRParen
)) {
2781 // As Java has no function types, a "(" after the ")" likely means that this
2783 if (Style
.Language
== FormatStyle::LK_Java
&& AfterRParen
->is(tok::l_paren
))
2786 // If a (non-string) literal follows, this is likely a cast.
2787 if (AfterRParen
->isOneOf(tok::kw_sizeof
, tok::kw_alignof
) ||
2788 (AfterRParen
->Tok
.isLiteral() &&
2789 AfterRParen
->isNot(tok::string_literal
))) {
2793 // Heuristically try to determine whether the parentheses contain a type.
2794 auto IsQualifiedPointerOrReference
= [](const FormatToken
*T
,
2795 const LangOptions
&LangOpts
) {
2796 // This is used to handle cases such as x = (foo *const)&y;
2797 assert(!T
->isTypeName(LangOpts
) && "Should have already been checked");
2798 // Strip trailing qualifiers such as const or volatile when checking
2799 // whether the parens could be a cast to a pointer/reference type.
2801 if (T
->is(TT_AttributeRParen
)) {
2802 // Handle `x = (foo *__attribute__((foo)))&v;`:
2803 assert(T
->is(tok::r_paren
));
2804 assert(T
->MatchingParen
);
2805 assert(T
->MatchingParen
->is(tok::l_paren
));
2806 assert(T
->MatchingParen
->is(TT_AttributeLParen
));
2807 if (const auto *Tok
= T
->MatchingParen
->Previous
;
2808 Tok
&& Tok
->isAttribute()) {
2812 } else if (T
->is(TT_AttributeSquare
)) {
2813 // Handle `x = (foo *[[clang::foo]])&v;`:
2814 if (T
->MatchingParen
&& T
->MatchingParen
->Previous
) {
2815 T
= T
->MatchingParen
->Previous
;
2818 } else if (T
->canBePointerOrReferenceQualifier()) {
2824 return T
&& T
->is(TT_PointerOrReference
);
2826 bool ParensAreType
=
2827 BeforeRParen
->isOneOf(TT_TemplateCloser
, TT_TypeDeclarationParen
) ||
2828 BeforeRParen
->isTypeName(LangOpts
) ||
2829 IsQualifiedPointerOrReference(BeforeRParen
, LangOpts
);
2830 bool ParensCouldEndDecl
=
2831 AfterRParen
->isOneOf(tok::equal
, tok::semi
, tok::l_brace
, tok::greater
);
2832 if (ParensAreType
&& !ParensCouldEndDecl
)
2835 // At this point, we heuristically assume that there are no casts at the
2836 // start of the line. We assume that we have found most cases where there
2837 // are by the logic above, e.g. "(void)x;".
2841 // Certain token types inside the parentheses mean that this can't be a
2843 for (const auto *Token
= LParen
->Next
; Token
!= &Tok
; Token
= Token
->Next
)
2844 if (Token
->is(TT_BinaryOperator
))
2847 // If the following token is an identifier or 'this', this is a cast. All
2848 // cases where this can be something else are handled above.
2849 if (AfterRParen
->isOneOf(tok::identifier
, tok::kw_this
))
2852 // Look for a cast `( x ) (`, where x may be a qualified identifier.
2853 if (AfterRParen
->is(tok::l_paren
)) {
2854 for (const auto *Prev
= BeforeRParen
; Prev
->is(tok::identifier
);) {
2855 Prev
= Prev
->Previous
;
2856 if (Prev
->is(tok::coloncolon
))
2857 Prev
= Prev
->Previous
;
2863 if (!AfterRParen
->Next
)
2866 if (AfterRParen
->is(tok::l_brace
) &&
2867 AfterRParen
->getBlockKind() == BK_BracedInit
) {
2871 // If the next token after the parenthesis is a unary operator, assume
2872 // that this is cast, unless there are unexpected tokens inside the
2874 const bool NextIsAmpOrStar
= AfterRParen
->isOneOf(tok::amp
, tok::star
);
2875 if (!(AfterRParen
->isUnaryOperator() || NextIsAmpOrStar
) ||
2876 AfterRParen
->is(tok::plus
) ||
2877 !AfterRParen
->Next
->isOneOf(tok::identifier
, tok::numeric_constant
)) {
2881 if (NextIsAmpOrStar
&&
2882 (AfterRParen
->Next
->is(tok::numeric_constant
) || Line
.InPPDirective
)) {
2886 if (Line
.InPPDirective
&& AfterRParen
->is(tok::minus
))
2889 const auto *Prev
= BeforeRParen
;
2891 // Look for a function pointer type, e.g. `(*)()`.
2892 if (Prev
->is(tok::r_paren
)) {
2893 if (Prev
->is(TT_CastRParen
))
2895 Prev
= Prev
->MatchingParen
;
2898 Prev
= Prev
->Previous
;
2899 if (!Prev
|| Prev
->isNot(tok::r_paren
))
2901 Prev
= Prev
->MatchingParen
;
2902 return Prev
&& Prev
->is(TT_FunctionTypeLParen
);
2905 // Search for unexpected tokens.
2906 for (Prev
= BeforeRParen
; Prev
!= LParen
; Prev
= Prev
->Previous
)
2907 if (!Prev
->isOneOf(tok::kw_const
, tok::identifier
, tok::coloncolon
))
2913 /// Returns true if the token is used as a unary operator.
2914 bool determineUnaryOperatorByUsage(const FormatToken
&Tok
) {
2915 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2919 // These keywords are deliberately not included here because they may
2920 // precede only one of unary star/amp and plus/minus but not both. They are
2921 // either included in determineStarAmpUsage or determinePlusMinusCaretUsage.
2923 // @ - It may be followed by a unary `-` in Objective-C literals. We don't
2924 // know how they can be followed by a star or amp.
2925 if (PrevToken
->isOneOf(
2926 TT_ConditionalExpr
, tok::l_paren
, tok::comma
, tok::colon
, tok::semi
,
2927 tok::equal
, tok::question
, tok::l_square
, tok::l_brace
,
2928 tok::kw_case
, tok::kw_co_await
, tok::kw_co_return
, tok::kw_co_yield
,
2929 tok::kw_delete
, tok::kw_return
, tok::kw_throw
)) {
2933 // We put sizeof here instead of only in determineStarAmpUsage. In the cases
2934 // where the unary `+` operator is overloaded, it is reasonable to write
2935 // things like `sizeof +x`. Like commit 446d6ec996c6c3.
2936 if (PrevToken
->is(tok::kw_sizeof
))
2939 // A sequence of leading unary operators.
2940 if (PrevToken
->isOneOf(TT_CastRParen
, TT_UnaryOperator
))
2943 // There can't be two consecutive binary operators.
2944 if (PrevToken
->is(TT_BinaryOperator
))
2950 /// Return the type of the given token assuming it is * or &.
2951 TokenType
determineStarAmpUsage(const FormatToken
&Tok
, bool IsExpression
,
2952 bool InTemplateArgument
) {
2953 if (Style
.isJavaScript())
2954 return TT_BinaryOperator
;
2956 // && in C# must be a binary operator.
2957 if (Style
.isCSharp() && Tok
.is(tok::ampamp
))
2958 return TT_BinaryOperator
;
2960 if (Style
.isVerilog()) {
2961 // In Verilog, `*` can only be a binary operator. `&` can be either unary
2962 // or binary. `*` also includes `*>` in module path declarations in
2963 // specify blocks because merged tokens take the type of the first one by
2965 if (Tok
.is(tok::star
))
2966 return TT_BinaryOperator
;
2967 return determineUnaryOperatorByUsage(Tok
) ? TT_UnaryOperator
2968 : TT_BinaryOperator
;
2971 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2973 return TT_UnaryOperator
;
2974 if (PrevToken
->is(TT_TypeName
))
2975 return TT_PointerOrReference
;
2976 if (PrevToken
->isOneOf(tok::kw_new
, tok::kw_delete
) && Tok
.is(tok::ampamp
))
2977 return TT_BinaryOperator
;
2979 const FormatToken
*NextToken
= Tok
.getNextNonComment();
2981 if (InTemplateArgument
&& NextToken
&& NextToken
->is(tok::kw_noexcept
))
2982 return TT_BinaryOperator
;
2985 NextToken
->isOneOf(tok::arrow
, tok::equal
, tok::comma
, tok::r_paren
,
2986 TT_RequiresClause
) ||
2987 (NextToken
->is(tok::kw_noexcept
) && !IsExpression
) ||
2988 NextToken
->canBePointerOrReferenceQualifier() ||
2989 (NextToken
->is(tok::l_brace
) && !NextToken
->getNextNonComment())) {
2990 return TT_PointerOrReference
;
2993 if (PrevToken
->is(tok::coloncolon
))
2994 return TT_PointerOrReference
;
2996 if (PrevToken
->is(tok::r_paren
) && PrevToken
->is(TT_TypeDeclarationParen
))
2997 return TT_PointerOrReference
;
2999 if (determineUnaryOperatorByUsage(Tok
))
3000 return TT_UnaryOperator
;
3002 if (NextToken
->is(tok::l_square
) && NextToken
->isNot(TT_LambdaLSquare
))
3003 return TT_PointerOrReference
;
3004 if (NextToken
->is(tok::kw_operator
) && !IsExpression
)
3005 return TT_PointerOrReference
;
3006 if (NextToken
->isOneOf(tok::comma
, tok::semi
))
3007 return TT_PointerOrReference
;
3009 // After right braces, star tokens are likely to be pointers to struct,
3012 // This by itself is not sufficient to distinguish from multiplication
3013 // following a brace-initialized expression, as in:
3014 // int i = int{42} * 2;
3015 // In the struct case, the part of the struct declaration until the `{` and
3016 // the `}` are put on separate unwrapped lines; in the brace-initialized
3017 // case, the matching `{` is on the same unwrapped line, so check for the
3018 // presence of the matching brace to distinguish between those.
3019 if (PrevToken
->is(tok::r_brace
) && Tok
.is(tok::star
) &&
3020 !PrevToken
->MatchingParen
) {
3021 return TT_PointerOrReference
;
3024 if (PrevToken
->endsSequence(tok::r_square
, tok::l_square
, tok::kw_delete
))
3025 return TT_UnaryOperator
;
3027 if (PrevToken
->Tok
.isLiteral() ||
3028 PrevToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::kw_true
,
3029 tok::kw_false
, tok::r_brace
)) {
3030 return TT_BinaryOperator
;
3033 const FormatToken
*NextNonParen
= NextToken
;
3034 while (NextNonParen
&& NextNonParen
->is(tok::l_paren
))
3035 NextNonParen
= NextNonParen
->getNextNonComment();
3036 if (NextNonParen
&& (NextNonParen
->Tok
.isLiteral() ||
3037 NextNonParen
->isOneOf(tok::kw_true
, tok::kw_false
) ||
3038 NextNonParen
->isUnaryOperator())) {
3039 return TT_BinaryOperator
;
3042 // If we know we're in a template argument, there are no named declarations.
3043 // Thus, having an identifier on the right-hand side indicates a binary
3045 if (InTemplateArgument
&& NextToken
->Tok
.isAnyIdentifier())
3046 return TT_BinaryOperator
;
3048 // "&&" followed by "(", "*", or "&" is quite unlikely to be two successive
3050 if (Tok
.is(tok::ampamp
) &&
3051 NextToken
->isOneOf(tok::l_paren
, tok::star
, tok::amp
)) {
3052 return TT_BinaryOperator
;
3055 // This catches some cases where evaluation order is used as control flow:
3057 if (NextToken
->Tok
.isAnyIdentifier()) {
3058 const FormatToken
*NextNextToken
= NextToken
->getNextNonComment();
3059 if (NextNextToken
&& NextNextToken
->is(tok::arrow
))
3060 return TT_BinaryOperator
;
3063 // It is very unlikely that we are going to find a pointer or reference type
3064 // definition on the RHS of an assignment.
3065 if (IsExpression
&& !Contexts
.back().CaretFound
)
3066 return TT_BinaryOperator
;
3068 // Opeartors at class scope are likely pointer or reference members.
3069 if (!Scopes
.empty() && Scopes
.back() == ST_Class
)
3070 return TT_PointerOrReference
;
3072 // Tokens that indicate member access or chained operator& use.
3073 auto IsChainedOperatorAmpOrMember
= [](const FormatToken
*token
) {
3074 return !token
|| token
->isOneOf(tok::amp
, tok::period
, tok::arrow
,
3075 tok::arrowstar
, tok::periodstar
);
3078 // It's more likely that & represents operator& than an uninitialized
3080 if (Tok
.is(tok::amp
) && PrevToken
&& PrevToken
->Tok
.isAnyIdentifier() &&
3081 IsChainedOperatorAmpOrMember(PrevToken
->getPreviousNonComment()) &&
3082 NextToken
&& NextToken
->Tok
.isAnyIdentifier()) {
3083 if (auto NextNext
= NextToken
->getNextNonComment();
3085 (IsChainedOperatorAmpOrMember(NextNext
) || NextNext
->is(tok::semi
))) {
3086 return TT_BinaryOperator
;
3090 return TT_PointerOrReference
;
3093 TokenType
determinePlusMinusCaretUsage(const FormatToken
&Tok
) {
3094 if (determineUnaryOperatorByUsage(Tok
))
3095 return TT_UnaryOperator
;
3097 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
3099 return TT_UnaryOperator
;
3101 if (PrevToken
->is(tok::at
))
3102 return TT_UnaryOperator
;
3104 // Fall back to marking the token as binary operator.
3105 return TT_BinaryOperator
;
3108 /// Determine whether ++/-- are pre- or post-increments/-decrements.
3109 TokenType
determineIncrementUsage(const FormatToken
&Tok
) {
3110 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
3111 if (!PrevToken
|| PrevToken
->is(TT_CastRParen
))
3112 return TT_UnaryOperator
;
3113 if (PrevToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::identifier
))
3114 return TT_TrailingUnaryOperator
;
3116 return TT_UnaryOperator
;
3119 SmallVector
<Context
, 8> Contexts
;
3121 const FormatStyle
&Style
;
3122 AnnotatedLine
&Line
;
3123 FormatToken
*CurrentToken
;
3126 LangOptions LangOpts
;
3127 const AdditionalKeywords
&Keywords
;
3129 SmallVector
<ScopeType
> &Scopes
;
3131 // Set of "<" tokens that do not open a template parameter list. If parseAngle
3132 // determines that a specific token can't be a template opener, it will make
3133 // same decision irrespective of the decisions for tokens leading up to it.
3134 // Store this information to prevent this from causing exponential runtime.
3135 llvm::SmallPtrSet
<FormatToken
*, 16> NonTemplateLess
;
3137 int TemplateDeclarationDepth
;
3140 static const int PrecedenceUnaryOperator
= prec::PointerToMember
+ 1;
3141 static const int PrecedenceArrowAndPeriod
= prec::PointerToMember
+ 2;
3143 /// Parses binary expressions by inserting fake parenthesis based on
3144 /// operator precedence.
3145 class ExpressionParser
{
3147 ExpressionParser(const FormatStyle
&Style
, const AdditionalKeywords
&Keywords
,
3148 AnnotatedLine
&Line
)
3149 : Style(Style
), Keywords(Keywords
), Line(Line
), Current(Line
.First
) {}
3151 /// Parse expressions with the given operator precedence.
3152 void parse(int Precedence
= 0) {
3153 // Skip 'return' and ObjC selector colons as they are not part of a binary
3155 while (Current
&& (Current
->is(tok::kw_return
) ||
3156 (Current
->is(tok::colon
) &&
3157 Current
->isOneOf(TT_ObjCMethodExpr
, TT_DictLiteral
)))) {
3161 if (!Current
|| Precedence
> PrecedenceArrowAndPeriod
)
3164 // Conditional expressions need to be parsed separately for proper nesting.
3165 if (Precedence
== prec::Conditional
) {
3166 parseConditionalExpr();
3170 // Parse unary operators, which all have a higher precedence than binary
3172 if (Precedence
== PrecedenceUnaryOperator
) {
3173 parseUnaryOperator();
3177 FormatToken
*Start
= Current
;
3178 FormatToken
*LatestOperator
= nullptr;
3179 unsigned OperatorIndex
= 0;
3180 // The first name of the current type in a port list.
3181 FormatToken
*VerilogFirstOfType
= nullptr;
3184 // In Verilog ports in a module header that don't have a type take the
3185 // type of the previous one. For example,
3186 // module a(output b,
3189 // In this case there need to be fake parentheses around b and c.
3190 if (Style
.isVerilog() && Precedence
== prec::Comma
) {
3191 VerilogFirstOfType
=
3192 verilogGroupDecl(VerilogFirstOfType
, LatestOperator
);
3195 // Consume operators with higher precedence.
3196 parse(Precedence
+ 1);
3198 int CurrentPrecedence
= getCurrentPrecedence();
3199 if (Style
.BreakBinaryOperations
== FormatStyle::BBO_OnePerLine
&&
3200 CurrentPrecedence
> prec::Conditional
&&
3201 CurrentPrecedence
< prec::PointerToMember
) {
3202 // When BreakBinaryOperations is set to BreakAll,
3203 // all operations will be on the same line or on individual lines.
3204 // Override precedence to avoid adding fake parenthesis which could
3205 // group operations of a different precedence level on the same line
3206 CurrentPrecedence
= prec::Additive
;
3209 if (Precedence
== CurrentPrecedence
&& Current
&&
3210 Current
->is(TT_SelectorName
)) {
3212 addFakeParenthesis(Start
, prec::Level(Precedence
));
3216 if ((Style
.isCSharp() || Style
.isJavaScript() ||
3217 Style
.Language
== FormatStyle::LK_Java
) &&
3218 Precedence
== prec::Additive
&& Current
) {
3219 // A string can be broken without parentheses around it when it is
3220 // already in a sequence of strings joined by `+` signs.
3221 FormatToken
*Prev
= Current
->getPreviousNonComment();
3222 if (Prev
&& Prev
->is(tok::string_literal
) &&
3223 (Prev
== Start
|| Prev
->endsSequence(tok::string_literal
, tok::plus
,
3224 TT_StringInConcatenation
))) {
3225 Prev
->setType(TT_StringInConcatenation
);
3229 // At the end of the line or when an operator with lower precedence is
3230 // found, insert fake parenthesis and return.
3232 (Current
->closesScope() &&
3233 (Current
->MatchingParen
|| Current
->is(TT_TemplateString
))) ||
3234 (CurrentPrecedence
!= -1 && CurrentPrecedence
< Precedence
) ||
3235 (CurrentPrecedence
== prec::Conditional
&&
3236 Precedence
== prec::Assignment
&& Current
->is(tok::colon
))) {
3240 // Consume scopes: (), [], <> and {}
3241 // In addition to that we handle require clauses as scope, so that the
3242 // constraints in that are correctly indented.
3243 if (Current
->opensScope() ||
3244 Current
->isOneOf(TT_RequiresClause
,
3245 TT_RequiresClauseInARequiresExpression
)) {
3246 // In fragment of a JavaScript template string can look like '}..${' and
3247 // thus close a scope and open a new one at the same time.
3248 while (Current
&& (!Current
->closesScope() || Current
->opensScope())) {
3255 if (CurrentPrecedence
== Precedence
) {
3257 LatestOperator
->NextOperator
= Current
;
3258 LatestOperator
= Current
;
3259 Current
->OperatorIndex
= OperatorIndex
;
3262 next(/*SkipPastLeadingComments=*/Precedence
> 0);
3266 // Group variables of the same type.
3267 if (Style
.isVerilog() && Precedence
== prec::Comma
&& VerilogFirstOfType
)
3268 addFakeParenthesis(VerilogFirstOfType
, prec::Comma
);
3270 if (LatestOperator
&& (Current
|| Precedence
> 0)) {
3271 // The requires clauses do not neccessarily end in a semicolon or a brace,
3272 // but just go over to struct/class or a function declaration, we need to
3273 // intervene so that the fake right paren is inserted correctly.
3276 Start
->Previous
->isOneOf(TT_RequiresClause
,
3277 TT_RequiresClauseInARequiresExpression
))
3279 auto Ret
= Current
? Current
: Line
.Last
;
3280 while (!Ret
->ClosesRequiresClause
&& Ret
->Previous
)
3281 Ret
= Ret
->Previous
;
3286 if (Precedence
== PrecedenceArrowAndPeriod
) {
3287 // Call expressions don't have a binary operator precedence.
3288 addFakeParenthesis(Start
, prec::Unknown
, End
);
3290 addFakeParenthesis(Start
, prec::Level(Precedence
), End
);
3296 /// Gets the precedence (+1) of the given token for binary operators
3297 /// and other tokens that we treat like binary operators.
3298 int getCurrentPrecedence() {
3300 const FormatToken
*NextNonComment
= Current
->getNextNonComment();
3301 if (Current
->is(TT_ConditionalExpr
))
3302 return prec::Conditional
;
3303 if (NextNonComment
&& Current
->is(TT_SelectorName
) &&
3304 (NextNonComment
->isOneOf(TT_DictLiteral
, TT_JsTypeColon
) ||
3305 (Style
.isProto() && NextNonComment
->is(tok::less
)))) {
3306 return prec::Assignment
;
3308 if (Current
->is(TT_JsComputedPropertyName
))
3309 return prec::Assignment
;
3310 if (Current
->is(TT_LambdaArrow
))
3312 if (Current
->is(TT_FatArrow
))
3313 return prec::Assignment
;
3314 if (Current
->isOneOf(tok::semi
, TT_InlineASMColon
, TT_SelectorName
) ||
3315 (Current
->is(tok::comment
) && NextNonComment
&&
3316 NextNonComment
->is(TT_SelectorName
))) {
3319 if (Current
->is(TT_RangeBasedForLoopColon
))
3321 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
3322 Current
->is(Keywords
.kw_instanceof
)) {
3323 return prec::Relational
;
3325 if (Style
.isJavaScript() &&
3326 Current
->isOneOf(Keywords
.kw_in
, Keywords
.kw_as
)) {
3327 return prec::Relational
;
3329 if (Current
->is(TT_BinaryOperator
) || Current
->is(tok::comma
))
3330 return Current
->getPrecedence();
3331 if (Current
->isOneOf(tok::period
, tok::arrow
) &&
3332 Current
->isNot(TT_TrailingReturnArrow
)) {
3333 return PrecedenceArrowAndPeriod
;
3335 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
3336 Current
->isOneOf(Keywords
.kw_extends
, Keywords
.kw_implements
,
3337 Keywords
.kw_throws
)) {
3340 // In Verilog case labels are not on separate lines straight out of
3341 // UnwrappedLineParser. The colon is not part of an expression.
3342 if (Style
.isVerilog() && Current
->is(tok::colon
))
3348 void addFakeParenthesis(FormatToken
*Start
, prec::Level Precedence
,
3349 FormatToken
*End
= nullptr) {
3350 // Do not assign fake parenthesis to tokens that are part of an
3351 // unexpanded macro call. The line within the macro call contains
3352 // the parenthesis and commas, and we will not find operators within
3354 if (Start
->MacroParent
)
3357 Start
->FakeLParens
.push_back(Precedence
);
3358 if (Precedence
> prec::Unknown
)
3359 Start
->StartsBinaryExpression
= true;
3360 if (!End
&& Current
)
3361 End
= Current
->getPreviousNonComment();
3364 if (Precedence
> prec::Unknown
)
3365 End
->EndsBinaryExpression
= true;
3369 /// Parse unary operator expressions and surround them with fake
3370 /// parentheses if appropriate.
3371 void parseUnaryOperator() {
3372 llvm::SmallVector
<FormatToken
*, 2> Tokens
;
3373 while (Current
&& Current
->is(TT_UnaryOperator
)) {
3374 Tokens
.push_back(Current
);
3377 parse(PrecedenceArrowAndPeriod
);
3378 for (FormatToken
*Token
: llvm::reverse(Tokens
)) {
3379 // The actual precedence doesn't matter.
3380 addFakeParenthesis(Token
, prec::Unknown
);
3384 void parseConditionalExpr() {
3385 while (Current
&& Current
->isTrailingComment())
3387 FormatToken
*Start
= Current
;
3388 parse(prec::LogicalOr
);
3389 if (!Current
|| Current
->isNot(tok::question
))
3392 parse(prec::Assignment
);
3393 if (!Current
|| Current
->isNot(TT_ConditionalExpr
))
3396 parse(prec::Assignment
);
3397 addFakeParenthesis(Start
, prec::Conditional
);
3400 void next(bool SkipPastLeadingComments
= true) {
3402 Current
= Current
->Next
;
3404 (Current
->NewlinesBefore
== 0 || SkipPastLeadingComments
) &&
3405 Current
->isTrailingComment()) {
3406 Current
= Current
->Next
;
3410 // Add fake parenthesis around declarations of the same type for example in a
3411 // module prototype. Return the first port / variable of the current type.
3412 FormatToken
*verilogGroupDecl(FormatToken
*FirstOfType
,
3413 FormatToken
*PreviousComma
) {
3417 FormatToken
*Start
= Current
;
3420 while (Start
->startsSequence(tok::l_paren
, tok::star
)) {
3421 if (!(Start
= Start
->MatchingParen
) ||
3422 !(Start
= Start
->getNextNonComment())) {
3427 FormatToken
*Tok
= Start
;
3429 if (Tok
->is(Keywords
.kw_assign
))
3430 Tok
= Tok
->getNextNonComment();
3432 // Skip any type qualifiers to find the first identifier. It may be either a
3433 // new type name or a variable name. There can be several type qualifiers
3434 // preceding a variable name, and we can not tell them apart by looking at
3435 // the word alone since a macro can be defined as either a type qualifier or
3436 // a variable name. Thus we use the last word before the dimensions instead
3437 // of the first word as the candidate for the variable or type name.
3438 FormatToken
*First
= nullptr;
3440 FormatToken
*Next
= Tok
->getNextNonComment();
3442 if (Tok
->is(tok::hash
)) {
3443 // Start of a macro expansion.
3447 Tok
= Tok
->getNextNonComment();
3448 } else if (Tok
->is(tok::hashhash
)) {
3449 // Concatenation. Skip.
3452 Tok
= Tok
->getNextNonComment();
3453 } else if (Keywords
.isVerilogQualifier(*Tok
) ||
3454 Keywords
.isVerilogIdentifier(*Tok
)) {
3457 // The name may have dots like `interface_foo.modport_foo`.
3458 while (Tok
&& Tok
->isOneOf(tok::period
, tok::coloncolon
) &&
3459 (Tok
= Tok
->getNextNonComment())) {
3460 if (Keywords
.isVerilogIdentifier(*Tok
))
3461 Tok
= Tok
->getNextNonComment();
3465 } else if (Tok
->is(tok::l_paren
)) {
3466 // Make sure the parenthesized list is a drive strength. Otherwise the
3467 // statement may be a module instantiation in which case we have already
3468 // found the instance name.
3470 Keywords
.kw_highz0
, Keywords
.kw_highz1
, Keywords
.kw_large
,
3471 Keywords
.kw_medium
, Keywords
.kw_pull0
, Keywords
.kw_pull1
,
3472 Keywords
.kw_small
, Keywords
.kw_strong0
, Keywords
.kw_strong1
,
3473 Keywords
.kw_supply0
, Keywords
.kw_supply1
, Keywords
.kw_weak0
,
3474 Keywords
.kw_weak1
)) {
3475 Tok
->setType(TT_VerilogStrength
);
3476 Tok
= Tok
->MatchingParen
;
3478 Tok
->setType(TT_VerilogStrength
);
3479 Tok
= Tok
->getNextNonComment();
3484 } else if (Tok
->is(Keywords
.kw_verilogHash
)) {
3486 if (Next
->is(tok::l_paren
))
3487 Next
= Next
->MatchingParen
;
3489 Tok
= Next
->getNextNonComment();
3495 // Find the second identifier. If it exists it will be the name.
3496 FormatToken
*Second
= nullptr;
3498 while (Tok
&& Tok
->is(tok::l_square
) && (Tok
= Tok
->MatchingParen
))
3499 Tok
= Tok
->getNextNonComment();
3500 if (Tok
&& (Tok
->is(tok::hash
) || Keywords
.isVerilogIdentifier(*Tok
)))
3503 // If the second identifier doesn't exist and there are qualifiers, the type
3505 FormatToken
*TypedName
= nullptr;
3508 if (First
&& First
->is(TT_Unknown
))
3509 First
->setType(TT_VerilogDimensionedTypeName
);
3510 } else if (First
!= Start
) {
3511 // If 'First' is null, then this isn't a declaration, 'TypedName' gets set
3512 // to null as intended.
3517 // This is a declaration with a new type.
3518 if (TypedName
->is(TT_Unknown
))
3519 TypedName
->setType(TT_StartOfName
);
3520 // Group variables of the previous type.
3521 if (FirstOfType
&& PreviousComma
) {
3522 PreviousComma
->setType(TT_VerilogTypeComma
);
3523 addFakeParenthesis(FirstOfType
, prec::Comma
, PreviousComma
->Previous
);
3526 FirstOfType
= TypedName
;
3528 // Don't let higher precedence handle the qualifiers. For example if we
3531 // We skip `parameter` here. This way the fake parentheses for the
3532 // assignment will be around `x = 0`.
3533 while (Current
&& Current
!= FirstOfType
) {
3534 if (Current
->opensScope()) {
3545 const FormatStyle
&Style
;
3546 const AdditionalKeywords
&Keywords
;
3547 const AnnotatedLine
&Line
;
3548 FormatToken
*Current
;
3551 } // end anonymous namespace
3553 void TokenAnnotator::setCommentLineLevels(
3554 SmallVectorImpl
<AnnotatedLine
*> &Lines
) const {
3555 const AnnotatedLine
*NextNonCommentLine
= nullptr;
3556 for (AnnotatedLine
*Line
: llvm::reverse(Lines
)) {
3557 assert(Line
->First
);
3559 // If the comment is currently aligned with the line immediately following
3560 // it, that's probably intentional and we should keep it.
3561 if (NextNonCommentLine
&& NextNonCommentLine
->First
->NewlinesBefore
< 2 &&
3562 Line
->isComment() && !isClangFormatOff(Line
->First
->TokenText
) &&
3563 NextNonCommentLine
->First
->OriginalColumn
==
3564 Line
->First
->OriginalColumn
) {
3565 const bool PPDirectiveOrImportStmt
=
3566 NextNonCommentLine
->Type
== LT_PreprocessorDirective
||
3567 NextNonCommentLine
->Type
== LT_ImportStatement
;
3568 if (PPDirectiveOrImportStmt
)
3569 Line
->Type
= LT_CommentAbovePPDirective
;
3570 // Align comments for preprocessor lines with the # in column 0 if
3571 // preprocessor lines are not indented. Otherwise, align with the next
3573 Line
->Level
= Style
.IndentPPDirectives
!= FormatStyle::PPDIS_BeforeHash
&&
3574 PPDirectiveOrImportStmt
3576 : NextNonCommentLine
->Level
;
3578 NextNonCommentLine
= Line
->First
->isNot(tok::r_brace
) ? Line
: nullptr;
3581 setCommentLineLevels(Line
->Children
);
3585 static unsigned maxNestingDepth(const AnnotatedLine
&Line
) {
3586 unsigned Result
= 0;
3587 for (const auto *Tok
= Line
.First
; Tok
; Tok
= Tok
->Next
)
3588 Result
= std::max(Result
, Tok
->NestingLevel
);
3592 // Returns the name of a function with no return type, e.g. a constructor or
3594 static FormatToken
*getFunctionName(const AnnotatedLine
&Line
,
3595 FormatToken
*&OpeningParen
) {
3596 for (FormatToken
*Tok
= Line
.getFirstNonComment(), *Name
= nullptr; Tok
;
3597 Tok
= Tok
->getNextNonComment()) {
3598 // Skip C++11 attributes both before and after the function name.
3599 if (Tok
->is(tok::l_square
) && Tok
->is(TT_AttributeSquare
)) {
3600 Tok
= Tok
->MatchingParen
;
3606 // Make sure the name is followed by a pair of parentheses.
3608 if (Tok
->is(tok::l_paren
) && Tok
->is(TT_Unknown
) && Tok
->MatchingParen
) {
3615 // Skip keywords that may precede the constructor/destructor name.
3616 if (Tok
->isOneOf(tok::kw_friend
, tok::kw_inline
, tok::kw_virtual
,
3617 tok::kw_constexpr
, tok::kw_consteval
, tok::kw_explicit
)) {
3621 // A qualified name may start from the global namespace.
3622 if (Tok
->is(tok::coloncolon
)) {
3628 // Skip to the unqualified part of the name.
3629 while (Tok
->startsSequence(tok::identifier
, tok::coloncolon
)) {
3631 Tok
= Tok
->Next
->Next
;
3636 // Skip the `~` if a destructor name.
3637 if (Tok
->is(tok::tilde
)) {
3643 // Make sure the name is not already annotated, e.g. as NamespaceMacro.
3644 if (Tok
->isNot(tok::identifier
) || Tok
->isNot(TT_Unknown
))
3653 // Checks if Tok is a constructor/destructor name qualified by its class name.
3654 static bool isCtorOrDtorName(const FormatToken
*Tok
) {
3655 assert(Tok
&& Tok
->is(tok::identifier
));
3656 const auto *Prev
= Tok
->Previous
;
3658 if (Prev
&& Prev
->is(tok::tilde
))
3659 Prev
= Prev
->Previous
;
3661 if (!Prev
|| !Prev
->endsSequence(tok::coloncolon
, tok::identifier
))
3664 assert(Prev
->Previous
);
3665 return Prev
->Previous
->TokenText
== Tok
->TokenText
;
3668 void TokenAnnotator::annotate(AnnotatedLine
&Line
) {
3669 if (!Line
.InMacroBody
)
3670 MacroBodyScopes
.clear();
3672 auto &ScopeStack
= Line
.InMacroBody
? MacroBodyScopes
: Scopes
;
3673 AnnotatingParser
Parser(Style
, Line
, Keywords
, ScopeStack
);
3674 Line
.Type
= Parser
.parseLine();
3676 if (!Line
.Children
.empty()) {
3677 ScopeStack
.push_back(ST_ChildBlock
);
3678 for (auto &Child
: Line
.Children
)
3680 // ScopeStack can become empty if Child has an unmatched `}`.
3681 if (!ScopeStack
.empty())
3682 ScopeStack
.pop_back();
3685 // With very deep nesting, ExpressionParser uses lots of stack and the
3686 // formatting algorithm is very slow. We're not going to do a good job here
3687 // anyway - it's probably generated code being formatted by mistake.
3688 // Just skip the whole line.
3689 if (maxNestingDepth(Line
) > 50)
3690 Line
.Type
= LT_Invalid
;
3692 if (Line
.Type
== LT_Invalid
)
3695 ExpressionParser
ExprParser(Style
, Keywords
, Line
);
3699 FormatToken
*OpeningParen
= nullptr;
3700 auto *Tok
= getFunctionName(Line
, OpeningParen
);
3701 if (Tok
&& ((!ScopeStack
.empty() && ScopeStack
.back() == ST_Class
) ||
3702 Line
.endsWith(TT_FunctionLBrace
) || isCtorOrDtorName(Tok
))) {
3703 Tok
->setFinalizedType(TT_CtorDtorDeclName
);
3704 assert(OpeningParen
);
3705 OpeningParen
->setFinalizedType(TT_FunctionDeclarationLParen
);
3709 if (Line
.startsWith(TT_ObjCMethodSpecifier
))
3710 Line
.Type
= LT_ObjCMethodDecl
;
3711 else if (Line
.startsWith(TT_ObjCDecl
))
3712 Line
.Type
= LT_ObjCDecl
;
3713 else if (Line
.startsWith(TT_ObjCProperty
))
3714 Line
.Type
= LT_ObjCProperty
;
3716 auto *First
= Line
.First
;
3717 First
->SpacesRequiredBefore
= 1;
3718 First
->CanBreakBefore
= First
->MustBreakBefore
;
3721 // This function heuristically determines whether 'Current' starts the name of a
3722 // function declaration.
3723 static bool isFunctionDeclarationName(const LangOptions
&LangOpts
,
3724 const FormatToken
&Current
,
3725 const AnnotatedLine
&Line
,
3726 FormatToken
*&ClosingParen
) {
3727 if (Current
.is(TT_FunctionDeclarationName
))
3730 if (!Current
.Tok
.getIdentifierInfo())
3733 const auto *Prev
= Current
.getPreviousNonComment();
3736 if (Prev
->is(tok::coloncolon
))
3737 Prev
= Prev
->Previous
;
3742 const auto &Previous
= *Prev
;
3744 if (const auto *PrevPrev
= Previous
.getPreviousNonComment();
3745 PrevPrev
&& PrevPrev
->is(TT_ObjCDecl
)) {
3749 auto skipOperatorName
=
3750 [&LangOpts
](const FormatToken
*Next
) -> const FormatToken
* {
3751 for (; Next
; Next
= Next
->Next
) {
3752 if (Next
->is(TT_OverloadedOperatorLParen
))
3754 if (Next
->is(TT_OverloadedOperator
))
3756 if (Next
->isOneOf(tok::kw_new
, tok::kw_delete
)) {
3757 // For 'new[]' and 'delete[]'.
3759 Next
->Next
->startsSequence(tok::l_square
, tok::r_square
)) {
3760 Next
= Next
->Next
->Next
;
3764 if (Next
->startsSequence(tok::l_square
, tok::r_square
)) {
3765 // For operator[]().
3769 if ((Next
->isTypeName(LangOpts
) || Next
->is(tok::identifier
)) &&
3770 Next
->Next
&& Next
->Next
->isPointerOrReference()) {
3771 // For operator void*(), operator char*(), operator Foo*().
3775 if (Next
->is(TT_TemplateOpener
) && Next
->MatchingParen
) {
3776 Next
= Next
->MatchingParen
;
3785 const auto *Next
= Current
.Next
;
3786 const bool IsCpp
= LangOpts
.CXXOperatorNames
;
3788 // Find parentheses of parameter list.
3789 if (Current
.is(tok::kw_operator
)) {
3790 if (Previous
.Tok
.getIdentifierInfo() &&
3791 !Previous
.isOneOf(tok::kw_return
, tok::kw_co_return
)) {
3794 if (Previous
.is(tok::r_paren
) && Previous
.is(TT_TypeDeclarationParen
)) {
3795 assert(Previous
.MatchingParen
);
3796 assert(Previous
.MatchingParen
->is(tok::l_paren
));
3797 assert(Previous
.MatchingParen
->is(TT_TypeDeclarationParen
));
3800 if (!Previous
.isPointerOrReference() && Previous
.isNot(TT_TemplateCloser
))
3802 Next
= skipOperatorName(Next
);
3804 if (Current
.isNot(TT_StartOfName
) || Current
.NestingLevel
!= 0)
3806 for (; Next
; Next
= Next
->Next
) {
3807 if (Next
->is(TT_TemplateOpener
) && Next
->MatchingParen
) {
3808 Next
= Next
->MatchingParen
;
3809 } else if (Next
->is(tok::coloncolon
)) {
3813 if (Next
->is(tok::kw_operator
)) {
3814 Next
= skipOperatorName(Next
->Next
);
3817 if (Next
->isNot(tok::identifier
))
3819 } else if (isCppAttribute(IsCpp
, *Next
)) {
3820 Next
= Next
->MatchingParen
;
3823 } else if (Next
->is(tok::l_paren
)) {
3831 // Check whether parameter list can belong to a function declaration.
3832 if (!Next
|| Next
->isNot(tok::l_paren
) || !Next
->MatchingParen
)
3834 ClosingParen
= Next
->MatchingParen
;
3835 assert(ClosingParen
->is(tok::r_paren
));
3836 // If the lines ends with "{", this is likely a function definition.
3837 if (Line
.Last
->is(tok::l_brace
))
3839 if (Next
->Next
== ClosingParen
)
3840 return true; // Empty parentheses.
3841 // If there is an &/&& after the r_paren, this is likely a function.
3842 if (ClosingParen
->Next
&& ClosingParen
->Next
->is(TT_PointerOrReference
))
3845 // Check for K&R C function definitions (and C++ function definitions with
3846 // unnamed parameters), e.g.:
3851 // bool g(size_t = 0, bool b = false)
3855 if (IsCpp
&& Next
->Next
&& Next
->Next
->is(tok::identifier
) &&
3856 !Line
.endsWith(tok::semi
)) {
3860 for (const FormatToken
*Tok
= Next
->Next
; Tok
&& Tok
!= ClosingParen
;
3862 if (Tok
->is(TT_TypeDeclarationParen
))
3864 if (Tok
->isOneOf(tok::l_paren
, TT_TemplateOpener
) && Tok
->MatchingParen
) {
3865 Tok
= Tok
->MatchingParen
;
3868 if (Tok
->is(tok::kw_const
) || Tok
->isTypeName(LangOpts
) ||
3869 Tok
->isOneOf(TT_PointerOrReference
, TT_StartOfName
, tok::ellipsis
)) {
3872 if (Tok
->isOneOf(tok::l_brace
, TT_ObjCMethodExpr
) || Tok
->Tok
.isLiteral())
3878 bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine
&Line
) const {
3879 assert(Line
.MightBeFunctionDecl
);
3881 if ((Style
.BreakAfterReturnType
== FormatStyle::RTBS_TopLevel
||
3882 Style
.BreakAfterReturnType
== FormatStyle::RTBS_TopLevelDefinitions
) &&
3887 switch (Style
.BreakAfterReturnType
) {
3888 case FormatStyle::RTBS_None
:
3889 case FormatStyle::RTBS_Automatic
:
3890 case FormatStyle::RTBS_ExceptShortType
:
3892 case FormatStyle::RTBS_All
:
3893 case FormatStyle::RTBS_TopLevel
:
3895 case FormatStyle::RTBS_AllDefinitions
:
3896 case FormatStyle::RTBS_TopLevelDefinitions
:
3897 return Line
.mightBeFunctionDefinition();
3903 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine
&Line
) const {
3904 for (AnnotatedLine
*ChildLine
: Line
.Children
)
3905 calculateFormattingInformation(*ChildLine
);
3907 auto *First
= Line
.First
;
3908 First
->TotalLength
= First
->IsMultiline
3910 : Line
.FirstStartColumn
+ First
->ColumnWidth
;
3911 bool AlignArrayOfStructures
=
3912 (Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
&&
3913 Line
.Type
== LT_ArrayOfStructInitializer
);
3914 if (AlignArrayOfStructures
)
3915 calculateArrayInitializerColumnList(Line
);
3917 const auto *FirstNonComment
= Line
.getFirstNonComment();
3918 bool SeenName
= false;
3919 bool LineIsFunctionDeclaration
= false;
3920 FormatToken
*AfterLastAttribute
= nullptr;
3921 FormatToken
*ClosingParen
= nullptr;
3923 for (auto *Tok
= FirstNonComment
? FirstNonComment
->Next
: nullptr; Tok
;
3925 if (Tok
->is(TT_StartOfName
))
3927 if (Tok
->Previous
->EndsCppAttributeGroup
)
3928 AfterLastAttribute
= Tok
;
3929 if (const bool IsCtorOrDtor
= Tok
->is(TT_CtorDtorDeclName
);
3931 isFunctionDeclarationName(LangOpts
, *Tok
, Line
, ClosingParen
)) {
3933 Tok
->setFinalizedType(TT_FunctionDeclarationName
);
3934 LineIsFunctionDeclaration
= true;
3937 auto *OpeningParen
= ClosingParen
->MatchingParen
;
3938 assert(OpeningParen
);
3939 if (OpeningParen
->is(TT_Unknown
))
3940 OpeningParen
->setType(TT_FunctionDeclarationLParen
);
3947 (LineIsFunctionDeclaration
||
3948 (FirstNonComment
&& FirstNonComment
->is(TT_CtorDtorDeclName
))) &&
3949 Line
.endsWith(tok::semi
, tok::r_brace
)) {
3950 auto *Tok
= Line
.Last
->Previous
;
3951 while (Tok
->isNot(tok::r_brace
))
3952 Tok
= Tok
->Previous
;
3953 if (auto *LBrace
= Tok
->MatchingParen
; LBrace
) {
3954 assert(LBrace
->is(tok::l_brace
));
3955 Tok
->setBlockKind(BK_Block
);
3956 LBrace
->setBlockKind(BK_Block
);
3957 LBrace
->setFinalizedType(TT_FunctionLBrace
);
3961 if (IsCpp
&& SeenName
&& AfterLastAttribute
&&
3962 mustBreakAfterAttributes(*AfterLastAttribute
, Style
)) {
3963 AfterLastAttribute
->MustBreakBefore
= true;
3964 if (LineIsFunctionDeclaration
)
3965 Line
.ReturnTypeWrapped
= true;
3969 if (!LineIsFunctionDeclaration
) {
3970 // Annotate */&/&& in `operator` function calls as binary operators.
3971 for (const auto *Tok
= FirstNonComment
; Tok
; Tok
= Tok
->Next
) {
3972 if (Tok
->isNot(tok::kw_operator
))
3976 } while (Tok
&& Tok
->isNot(TT_OverloadedOperatorLParen
));
3977 if (!Tok
|| !Tok
->MatchingParen
)
3979 const auto *LeftParen
= Tok
;
3980 for (Tok
= Tok
->Next
; Tok
&& Tok
!= LeftParen
->MatchingParen
;
3982 if (Tok
->isNot(tok::identifier
))
3984 auto *Next
= Tok
->Next
;
3985 const bool NextIsBinaryOperator
=
3986 Next
&& Next
->isPointerOrReference() && Next
->Next
&&
3987 Next
->Next
->is(tok::identifier
);
3988 if (!NextIsBinaryOperator
)
3990 Next
->setType(TT_BinaryOperator
);
3994 } else if (ClosingParen
) {
3995 for (auto *Tok
= ClosingParen
->Next
; Tok
; Tok
= Tok
->Next
) {
3996 if (Tok
->is(TT_CtorInitializerColon
))
3998 if (Tok
->is(tok::arrow
)) {
3999 Tok
->setType(TT_TrailingReturnArrow
);
4002 if (Tok
->isNot(TT_TrailingAnnotation
))
4004 const auto *Next
= Tok
->Next
;
4005 if (!Next
|| Next
->isNot(tok::l_paren
))
4007 Tok
= Next
->MatchingParen
;
4014 bool InFunctionDecl
= Line
.MightBeFunctionDecl
;
4015 for (auto *Current
= First
->Next
; Current
; Current
= Current
->Next
) {
4016 const FormatToken
*Prev
= Current
->Previous
;
4017 if (Current
->is(TT_LineComment
)) {
4018 if (Prev
->is(BK_BracedInit
) && Prev
->opensScope()) {
4019 Current
->SpacesRequiredBefore
=
4020 (Style
.Cpp11BracedListStyle
&& !Style
.SpacesInParensOptions
.Other
)
4023 } else if (Prev
->is(TT_VerilogMultiLineListLParen
)) {
4024 Current
->SpacesRequiredBefore
= 0;
4026 Current
->SpacesRequiredBefore
= Style
.SpacesBeforeTrailingComments
;
4029 // If we find a trailing comment, iterate backwards to determine whether
4030 // it seems to relate to a specific parameter. If so, break before that
4031 // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
4032 // to the previous line in:
4036 if (!Current
->HasUnescapedNewline
) {
4037 for (FormatToken
*Parameter
= Current
->Previous
; Parameter
;
4038 Parameter
= Parameter
->Previous
) {
4039 if (Parameter
->isOneOf(tok::comment
, tok::r_brace
))
4041 if (Parameter
->Previous
&& Parameter
->Previous
->is(tok::comma
)) {
4042 if (Parameter
->Previous
->isNot(TT_CtorInitializerComma
) &&
4043 Parameter
->HasUnescapedNewline
) {
4044 Parameter
->MustBreakBefore
= true;
4050 } else if (!Current
->Finalized
&& Current
->SpacesRequiredBefore
== 0 &&
4051 spaceRequiredBefore(Line
, *Current
)) {
4052 Current
->SpacesRequiredBefore
= 1;
4055 const auto &Children
= Prev
->Children
;
4056 if (!Children
.empty() && Children
.back()->Last
->is(TT_LineComment
)) {
4057 Current
->MustBreakBefore
= true;
4059 Current
->MustBreakBefore
=
4060 Current
->MustBreakBefore
|| mustBreakBefore(Line
, *Current
);
4061 if (!Current
->MustBreakBefore
&& InFunctionDecl
&&
4062 Current
->is(TT_FunctionDeclarationName
)) {
4063 Current
->MustBreakBefore
= mustBreakForReturnType(Line
);
4067 Current
->CanBreakBefore
=
4068 Current
->MustBreakBefore
|| canBreakBefore(Line
, *Current
);
4069 unsigned ChildSize
= 0;
4070 if (Prev
->Children
.size() == 1) {
4071 FormatToken
&LastOfChild
= *Prev
->Children
[0]->Last
;
4072 ChildSize
= LastOfChild
.isTrailingComment() ? Style
.ColumnLimit
4073 : LastOfChild
.TotalLength
+ 1;
4075 if (Current
->MustBreakBefore
|| Prev
->Children
.size() > 1 ||
4076 (Prev
->Children
.size() == 1 &&
4077 Prev
->Children
[0]->First
->MustBreakBefore
) ||
4078 Current
->IsMultiline
) {
4079 Current
->TotalLength
= Prev
->TotalLength
+ Style
.ColumnLimit
;
4081 Current
->TotalLength
= Prev
->TotalLength
+ Current
->ColumnWidth
+
4082 ChildSize
+ Current
->SpacesRequiredBefore
;
4085 if (Current
->is(TT_CtorInitializerColon
))
4086 InFunctionDecl
= false;
4088 // FIXME: Only calculate this if CanBreakBefore is true once static
4089 // initializers etc. are sorted out.
4090 // FIXME: Move magic numbers to a better place.
4092 // Reduce penalty for aligning ObjC method arguments using the colon
4093 // alignment as this is the canonical way (still prefer fitting everything
4094 // into one line if possible). Trying to fit a whole expression into one
4095 // line should not force other line breaks (e.g. when ObjC method
4096 // expression is a part of other expression).
4097 Current
->SplitPenalty
= splitPenalty(Line
, *Current
, InFunctionDecl
);
4098 if (Style
.Language
== FormatStyle::LK_ObjC
&&
4099 Current
->is(TT_SelectorName
) && Current
->ParameterIndex
> 0) {
4100 if (Current
->ParameterIndex
== 1)
4101 Current
->SplitPenalty
+= 5 * Current
->BindingStrength
;
4103 Current
->SplitPenalty
+= 20 * Current
->BindingStrength
;
4107 calculateUnbreakableTailLengths(Line
);
4108 unsigned IndentLevel
= Line
.Level
;
4109 for (auto *Current
= First
; Current
; Current
= Current
->Next
) {
4111 Current
->Role
->precomputeFormattingInfos(Current
);
4112 if (Current
->MatchingParen
&&
4113 Current
->MatchingParen
->opensBlockOrBlockTypeList(Style
) &&
4117 Current
->IndentLevel
= IndentLevel
;
4118 if (Current
->opensBlockOrBlockTypeList(Style
))
4122 LLVM_DEBUG({ printDebugInfo(Line
); });
4125 void TokenAnnotator::calculateUnbreakableTailLengths(
4126 AnnotatedLine
&Line
) const {
4127 unsigned UnbreakableTailLength
= 0;
4128 FormatToken
*Current
= Line
.Last
;
4130 Current
->UnbreakableTailLength
= UnbreakableTailLength
;
4131 if (Current
->CanBreakBefore
||
4132 Current
->isOneOf(tok::comment
, tok::string_literal
)) {
4133 UnbreakableTailLength
= 0;
4135 UnbreakableTailLength
+=
4136 Current
->ColumnWidth
+ Current
->SpacesRequiredBefore
;
4138 Current
= Current
->Previous
;
4142 void TokenAnnotator::calculateArrayInitializerColumnList(
4143 AnnotatedLine
&Line
) const {
4144 if (Line
.First
== Line
.Last
)
4146 auto *CurrentToken
= Line
.First
;
4147 CurrentToken
->ArrayInitializerLineStart
= true;
4149 while (CurrentToken
&& CurrentToken
!= Line
.Last
) {
4150 if (CurrentToken
->is(tok::l_brace
)) {
4151 CurrentToken
->IsArrayInitializer
= true;
4152 if (CurrentToken
->Next
)
4153 CurrentToken
->Next
->MustBreakBefore
= true;
4155 calculateInitializerColumnList(Line
, CurrentToken
->Next
, Depth
+ 1);
4157 CurrentToken
= CurrentToken
->Next
;
4162 FormatToken
*TokenAnnotator::calculateInitializerColumnList(
4163 AnnotatedLine
&Line
, FormatToken
*CurrentToken
, unsigned Depth
) const {
4164 while (CurrentToken
&& CurrentToken
!= Line
.Last
) {
4165 if (CurrentToken
->is(tok::l_brace
))
4167 else if (CurrentToken
->is(tok::r_brace
))
4169 if (Depth
== 2 && CurrentToken
->isOneOf(tok::l_brace
, tok::comma
)) {
4170 CurrentToken
= CurrentToken
->Next
;
4173 CurrentToken
->StartsColumn
= true;
4174 CurrentToken
= CurrentToken
->Previous
;
4176 CurrentToken
= CurrentToken
->Next
;
4178 return CurrentToken
;
4181 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine
&Line
,
4182 const FormatToken
&Tok
,
4183 bool InFunctionDecl
) const {
4184 const FormatToken
&Left
= *Tok
.Previous
;
4185 const FormatToken
&Right
= Tok
;
4187 if (Left
.is(tok::semi
))
4190 // Language specific handling.
4191 if (Style
.Language
== FormatStyle::LK_Java
) {
4192 if (Right
.isOneOf(Keywords
.kw_extends
, Keywords
.kw_throws
))
4194 if (Right
.is(Keywords
.kw_implements
))
4196 if (Left
.is(tok::comma
) && Left
.NestingLevel
== 0)
4198 } else if (Style
.isJavaScript()) {
4199 if (Right
.is(Keywords
.kw_function
) && Left
.isNot(tok::comma
))
4201 if (Left
.is(TT_JsTypeColon
))
4203 if ((Left
.is(TT_TemplateString
) && Left
.TokenText
.ends_with("${")) ||
4204 (Right
.is(TT_TemplateString
) && Right
.TokenText
.starts_with("}"))) {
4207 // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()".
4208 if (Left
.opensScope() && Right
.closesScope())
4210 } else if (Style
.Language
== FormatStyle::LK_Proto
) {
4211 if (Right
.is(tok::l_square
))
4213 if (Right
.is(tok::period
))
4217 if (Right
.is(tok::identifier
) && Right
.Next
&& Right
.Next
->is(TT_DictLiteral
))
4219 if (Right
.is(tok::l_square
)) {
4220 if (Left
.is(tok::r_square
))
4222 // Slightly prefer formatting local lambda definitions like functions.
4223 if (Right
.is(TT_LambdaLSquare
) && Left
.is(tok::equal
))
4225 if (!Right
.isOneOf(TT_ObjCMethodExpr
, TT_LambdaLSquare
,
4226 TT_ArrayInitializerLSquare
,
4227 TT_DesignatedInitializerLSquare
, TT_AttributeSquare
)) {
4232 if (Left
.is(tok::coloncolon
))
4233 return Style
.PenaltyBreakScopeResolution
;
4234 if (Right
.isOneOf(TT_StartOfName
, TT_FunctionDeclarationName
) ||
4235 Right
.is(tok::kw_operator
)) {
4236 if (Line
.startsWith(tok::kw_for
) && Right
.PartOfMultiVariableDeclStmt
)
4238 if (Left
.is(TT_StartOfName
))
4240 if (InFunctionDecl
&& Right
.NestingLevel
== 0)
4241 return Style
.PenaltyReturnTypeOnItsOwnLine
;
4244 if (Right
.is(TT_PointerOrReference
))
4246 if (Right
.is(TT_LambdaArrow
))
4248 if (Left
.is(tok::equal
) && Right
.is(tok::l_brace
))
4250 if (Left
.is(TT_CastRParen
))
4252 if (Left
.isOneOf(tok::kw_class
, tok::kw_struct
, tok::kw_union
))
4254 if (Left
.is(tok::comment
))
4257 if (Left
.isOneOf(TT_RangeBasedForLoopColon
, TT_InheritanceColon
,
4258 TT_CtorInitializerColon
)) {
4262 if (Right
.isMemberAccess()) {
4263 // Breaking before the "./->" of a chained call/member access is reasonably
4264 // cheap, as formatting those with one call per line is generally
4265 // desirable. In particular, it should be cheaper to break before the call
4266 // than it is to break inside a call's parameters, which could lead to weird
4267 // "hanging" indents. The exception is the very last "./->" to support this
4268 // frequent pattern:
4270 // aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc(
4273 // which might otherwise be blown up onto many lines. Here, clang-format
4274 // won't produce "hanging" indents anyway as there is no other trailing
4277 // Also apply higher penalty is not a call as that might lead to a wrapping
4281 // .aaaaaaaaa.bbbbbbbb(cccccccc);
4282 return !Right
.NextOperator
|| !Right
.NextOperator
->Previous
->closesScope()
4287 if (Right
.is(TT_TrailingAnnotation
) &&
4288 (!Right
.Next
|| Right
.Next
->isNot(tok::l_paren
))) {
4289 // Moving trailing annotations to the next line is fine for ObjC method
4291 if (Line
.startsWith(TT_ObjCMethodSpecifier
))
4293 // Generally, breaking before a trailing annotation is bad unless it is
4294 // function-like. It seems to be especially preferable to keep standard
4295 // annotations (i.e. "const", "final" and "override") on the same line.
4296 // Use a slightly higher penalty after ")" so that annotations like
4297 // "const override" are kept together.
4298 bool is_short_annotation
= Right
.TokenText
.size() < 10;
4299 return (Left
.is(tok::r_paren
) ? 100 : 120) + (is_short_annotation
? 50 : 0);
4302 // In for-loops, prefer breaking at ',' and ';'.
4303 if (Line
.startsWith(tok::kw_for
) && Left
.is(tok::equal
))
4306 // In Objective-C method expressions, prefer breaking before "param:" over
4307 // breaking after it.
4308 if (Right
.is(TT_SelectorName
))
4310 if (Left
.is(tok::colon
) && Left
.is(TT_ObjCMethodExpr
))
4311 return Line
.MightBeFunctionDecl
? 50 : 500;
4313 // In Objective-C type declarations, avoid breaking after the category's
4314 // open paren (we'll prefer breaking after the protocol list's opening
4315 // angle bracket, if present).
4316 if (Line
.Type
== LT_ObjCDecl
&& Left
.is(tok::l_paren
) && Left
.Previous
&&
4317 Left
.Previous
->isOneOf(tok::identifier
, tok::greater
)) {
4321 if (Left
.is(tok::l_paren
) && Style
.PenaltyBreakOpenParenthesis
!= 0)
4322 return Style
.PenaltyBreakOpenParenthesis
;
4323 if (Left
.is(tok::l_paren
) && InFunctionDecl
&&
4324 Style
.AlignAfterOpenBracket
!= FormatStyle::BAS_DontAlign
) {
4327 if (Left
.is(tok::l_paren
) && Left
.Previous
&&
4328 (Left
.Previous
->isOneOf(tok::kw_for
, tok::kw__Generic
) ||
4329 Left
.Previous
->isIf())) {
4332 if (Left
.is(tok::equal
) && InFunctionDecl
)
4334 if (Right
.is(tok::r_brace
))
4336 if (Left
.is(TT_TemplateOpener
))
4338 if (Left
.opensScope()) {
4339 // If we aren't aligning after opening parens/braces we can always break
4340 // here unless the style does not want us to place all arguments on the
4342 if (Style
.AlignAfterOpenBracket
== FormatStyle::BAS_DontAlign
&&
4343 (Left
.ParameterCount
<= 1 || Style
.AllowAllArgumentsOnNextLine
)) {
4346 if (Left
.is(tok::l_brace
) && !Style
.Cpp11BracedListStyle
)
4348 return Left
.ParameterCount
> 1 ? Style
.PenaltyBreakBeforeFirstCallParameter
4351 if (Left
.is(TT_JavaAnnotation
))
4354 if (Left
.is(TT_UnaryOperator
))
4356 if (Left
.isOneOf(tok::plus
, tok::comma
) && Left
.Previous
&&
4357 Left
.Previous
->isLabelString() &&
4358 (Left
.NextOperator
|| Left
.OperatorIndex
!= 0)) {
4361 if (Right
.is(tok::plus
) && Left
.isLabelString() &&
4362 (Right
.NextOperator
|| Right
.OperatorIndex
!= 0)) {
4365 if (Left
.is(tok::comma
))
4367 if (Right
.is(tok::lessless
) && Left
.isLabelString() &&
4368 (Right
.NextOperator
|| Right
.OperatorIndex
!= 1)) {
4371 if (Right
.is(tok::lessless
)) {
4372 // Breaking at a << is really cheap.
4373 if (Left
.isNot(tok::r_paren
) || Right
.OperatorIndex
> 0) {
4374 // Slightly prefer to break before the first one in log-like statements.
4379 if (Left
.ClosesTemplateDeclaration
)
4380 return Style
.PenaltyBreakTemplateDeclaration
;
4381 if (Left
.ClosesRequiresClause
)
4383 if (Left
.is(TT_ConditionalExpr
))
4384 return prec::Conditional
;
4385 prec::Level Level
= Left
.getPrecedence();
4386 if (Level
== prec::Unknown
)
4387 Level
= Right
.getPrecedence();
4388 if (Level
== prec::Assignment
)
4389 return Style
.PenaltyBreakAssignment
;
4390 if (Level
!= prec::Unknown
)
4396 bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken
&Right
) const {
4397 if (Style
.SpaceBeforeParens
== FormatStyle::SBPO_Always
)
4399 if (Right
.is(TT_OverloadedOperatorLParen
) &&
4400 Style
.SpaceBeforeParensOptions
.AfterOverloadedOperator
) {
4403 if (Style
.SpaceBeforeParensOptions
.BeforeNonEmptyParentheses
&&
4404 Right
.ParameterCount
> 0) {
4410 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine
&Line
,
4411 const FormatToken
&Left
,
4412 const FormatToken
&Right
) const {
4413 if (Left
.is(tok::kw_return
) &&
4414 !Right
.isOneOf(tok::semi
, tok::r_paren
, tok::hashhash
)) {
4417 if (Left
.is(tok::kw_throw
) && Right
.is(tok::l_paren
) && Right
.MatchingParen
&&
4418 Right
.MatchingParen
->is(TT_CastRParen
)) {
4421 if (Left
.is(Keywords
.kw_assert
) && Style
.Language
== FormatStyle::LK_Java
)
4423 if (Style
.ObjCSpaceAfterProperty
&& Line
.Type
== LT_ObjCProperty
&&
4424 Left
.Tok
.getObjCKeywordID() == tok::objc_property
) {
4427 if (Right
.is(tok::hashhash
))
4428 return Left
.is(tok::hash
);
4429 if (Left
.isOneOf(tok::hashhash
, tok::hash
))
4430 return Right
.is(tok::hash
);
4431 if (Left
.is(BK_Block
) && Right
.is(tok::r_brace
) &&
4432 Right
.MatchingParen
== &Left
&& Line
.Children
.empty()) {
4433 return Style
.SpaceInEmptyBlock
;
4435 if (Style
.SpacesInParens
== FormatStyle::SIPO_Custom
) {
4436 if ((Left
.is(tok::l_paren
) && Right
.is(tok::r_paren
)) ||
4437 (Left
.is(tok::l_brace
) && Left
.isNot(BK_Block
) &&
4438 Right
.is(tok::r_brace
) && Right
.isNot(BK_Block
))) {
4439 return Style
.SpacesInParensOptions
.InEmptyParentheses
;
4441 if (Style
.SpacesInParensOptions
.ExceptDoubleParentheses
&&
4442 Left
.is(tok::r_paren
) && Right
.is(tok::r_paren
)) {
4443 auto *InnerLParen
= Left
.MatchingParen
;
4444 if (InnerLParen
&& InnerLParen
->Previous
== Right
.MatchingParen
) {
4445 InnerLParen
->SpacesRequiredBefore
= 0;
4449 const FormatToken
*LeftParen
= nullptr;
4450 if (Left
.is(tok::l_paren
))
4452 else if (Right
.is(tok::r_paren
) && Right
.MatchingParen
)
4453 LeftParen
= Right
.MatchingParen
;
4454 if (LeftParen
&& (LeftParen
->is(TT_ConditionLParen
) ||
4455 (LeftParen
->Previous
&&
4456 isKeywordWithCondition(*LeftParen
->Previous
)))) {
4457 return Style
.SpacesInParensOptions
.InConditionalStatements
;
4461 // trailing return type 'auto': []() -> auto {}, auto foo() -> auto {}
4462 if (Left
.is(tok::kw_auto
) && Right
.isOneOf(TT_LambdaLBrace
, TT_FunctionLBrace
,
4463 // function return type 'auto'
4464 TT_FunctionTypeLParen
)) {
4469 if (Left
.is(tok::kw_auto
) && Right
.isOneOf(tok::l_paren
, tok::l_brace
))
4472 const auto *BeforeLeft
= Left
.Previous
;
4474 // operator co_await(x)
4475 if (Right
.is(tok::l_paren
) && Left
.is(tok::kw_co_await
) && BeforeLeft
&&
4476 BeforeLeft
->is(tok::kw_operator
)) {
4479 // co_await (x), co_yield (x), co_return (x)
4480 if (Left
.isOneOf(tok::kw_co_await
, tok::kw_co_yield
, tok::kw_co_return
) &&
4481 !Right
.isOneOf(tok::semi
, tok::r_paren
)) {
4485 if (Left
.is(tok::l_paren
) || Right
.is(tok::r_paren
)) {
4486 return (Right
.is(TT_CastRParen
) ||
4487 (Left
.MatchingParen
&& Left
.MatchingParen
->is(TT_CastRParen
)))
4488 ? Style
.SpacesInParensOptions
.InCStyleCasts
4489 : Style
.SpacesInParensOptions
.Other
;
4491 if (Right
.isOneOf(tok::semi
, tok::comma
))
4493 if (Right
.is(tok::less
) && Line
.Type
== LT_ObjCDecl
) {
4494 bool IsLightweightGeneric
= Right
.MatchingParen
&&
4495 Right
.MatchingParen
->Next
&&
4496 Right
.MatchingParen
->Next
->is(tok::colon
);
4497 return !IsLightweightGeneric
&& Style
.ObjCSpaceBeforeProtocolList
;
4499 if (Right
.is(tok::less
) && Left
.is(tok::kw_template
))
4500 return Style
.SpaceAfterTemplateKeyword
;
4501 if (Left
.isOneOf(tok::exclaim
, tok::tilde
))
4503 if (Left
.is(tok::at
) &&
4504 Right
.isOneOf(tok::identifier
, tok::string_literal
, tok::char_constant
,
4505 tok::numeric_constant
, tok::l_paren
, tok::l_brace
,
4506 tok::kw_true
, tok::kw_false
)) {
4509 if (Left
.is(tok::colon
))
4510 return Left
.isNot(TT_ObjCMethodExpr
);
4511 if (Left
.is(tok::coloncolon
))
4513 if (Left
.is(tok::less
) || Right
.isOneOf(tok::greater
, tok::less
)) {
4514 if (Style
.Language
== FormatStyle::LK_TextProto
||
4515 (Style
.Language
== FormatStyle::LK_Proto
&&
4516 (Left
.is(TT_DictLiteral
) || Right
.is(TT_DictLiteral
)))) {
4517 // Format empty list as `<>`.
4518 if (Left
.is(tok::less
) && Right
.is(tok::greater
))
4520 return !Style
.Cpp11BracedListStyle
;
4522 // Don't attempt to format operator<(), as it is handled later.
4523 if (Right
.isNot(TT_OverloadedOperatorLParen
))
4526 if (Right
.is(tok::ellipsis
)) {
4527 return Left
.Tok
.isLiteral() || (Left
.is(tok::identifier
) && BeforeLeft
&&
4528 BeforeLeft
->is(tok::kw_case
));
4530 if (Left
.is(tok::l_square
) && Right
.is(tok::amp
))
4531 return Style
.SpacesInSquareBrackets
;
4532 if (Right
.is(TT_PointerOrReference
)) {
4533 if (Left
.is(tok::r_paren
) && Line
.MightBeFunctionDecl
) {
4534 if (!Left
.MatchingParen
)
4536 FormatToken
*TokenBeforeMatchingParen
=
4537 Left
.MatchingParen
->getPreviousNonComment();
4538 if (!TokenBeforeMatchingParen
|| Left
.isNot(TT_TypeDeclarationParen
))
4541 // Add a space if the previous token is a pointer qualifier or the closing
4542 // parenthesis of __attribute__(()) expression and the style requires spaces
4543 // after pointer qualifiers.
4544 if ((Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_After
||
4545 Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
) &&
4546 (Left
.is(TT_AttributeRParen
) ||
4547 Left
.canBePointerOrReferenceQualifier())) {
4550 if (Left
.Tok
.isLiteral())
4552 // for (auto a = 0, b = 0; const auto & c : {1, 2, 3})
4553 if (Left
.isTypeOrIdentifier(LangOpts
) && Right
.Next
&& Right
.Next
->Next
&&
4554 Right
.Next
->Next
->is(TT_RangeBasedForLoopColon
)) {
4555 return getTokenPointerOrReferenceAlignment(Right
) !=
4556 FormatStyle::PAS_Left
;
4558 return !Left
.isOneOf(TT_PointerOrReference
, tok::l_paren
) &&
4559 (getTokenPointerOrReferenceAlignment(Right
) !=
4560 FormatStyle::PAS_Left
||
4561 (Line
.IsMultiVariableDeclStmt
&&
4562 (Left
.NestingLevel
== 0 ||
4563 (Left
.NestingLevel
== 1 && startsWithInitStatement(Line
)))));
4565 if (Right
.is(TT_FunctionTypeLParen
) && Left
.isNot(tok::l_paren
) &&
4566 (Left
.isNot(TT_PointerOrReference
) ||
4567 (getTokenPointerOrReferenceAlignment(Left
) != FormatStyle::PAS_Right
&&
4568 !Line
.IsMultiVariableDeclStmt
))) {
4571 if (Left
.is(TT_PointerOrReference
)) {
4572 // Add a space if the next token is a pointer qualifier and the style
4573 // requires spaces before pointer qualifiers.
4574 if ((Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Before
||
4575 Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
) &&
4576 Right
.canBePointerOrReferenceQualifier()) {
4580 if (Right
.Tok
.isLiteral())
4583 if (Right
.is(TT_BlockComment
))
4585 // foo() -> const Bar * override/final
4586 // S::foo() & noexcept/requires
4587 if (Right
.isOneOf(Keywords
.kw_override
, Keywords
.kw_final
, tok::kw_noexcept
,
4588 TT_RequiresClause
) &&
4589 Right
.isNot(TT_StartOfName
)) {
4593 if (Right
.is(tok::l_brace
) && Right
.is(BK_Block
))
4595 // for (auto a = 0, b = 0; const auto& c : {1, 2, 3})
4596 if (BeforeLeft
&& BeforeLeft
->isTypeOrIdentifier(LangOpts
) && Right
.Next
&&
4597 Right
.Next
->is(TT_RangeBasedForLoopColon
)) {
4598 return getTokenPointerOrReferenceAlignment(Left
) !=
4599 FormatStyle::PAS_Right
;
4601 if (Right
.isOneOf(TT_PointerOrReference
, TT_ArraySubscriptLSquare
,
4605 if (getTokenPointerOrReferenceAlignment(Left
) == FormatStyle::PAS_Right
)
4607 // FIXME: Setting IsMultiVariableDeclStmt for the whole line is error-prone,
4608 // because it does not take into account nested scopes like lambdas.
4609 // In multi-variable declaration statements, attach */& to the variable
4610 // independently of the style. However, avoid doing it if we are in a nested
4611 // scope, e.g. lambda. We still need to special-case statements with
4613 if (Line
.IsMultiVariableDeclStmt
&&
4614 (Left
.NestingLevel
== Line
.First
->NestingLevel
||
4615 ((Left
.NestingLevel
== Line
.First
->NestingLevel
+ 1) &&
4616 startsWithInitStatement(Line
)))) {
4621 if (BeforeLeft
->is(tok::coloncolon
)) {
4622 if (Left
.isNot(tok::star
))
4624 assert(Style
.PointerAlignment
!= FormatStyle::PAS_Right
);
4625 if (!Right
.startsSequence(tok::identifier
, tok::r_paren
))
4628 const auto *LParen
= Right
.Next
->MatchingParen
;
4629 return !LParen
|| LParen
->isNot(TT_FunctionTypeLParen
);
4631 return !BeforeLeft
->isOneOf(tok::l_paren
, tok::l_square
);
4633 // Ensure right pointer alignment with ellipsis e.g. int *...P
4634 if (Left
.is(tok::ellipsis
) && BeforeLeft
&&
4635 BeforeLeft
->isPointerOrReference()) {
4636 return Style
.PointerAlignment
!= FormatStyle::PAS_Right
;
4639 if (Right
.is(tok::star
) && Left
.is(tok::l_paren
))
4641 if (Left
.is(tok::star
) && Right
.isPointerOrReference())
4643 if (Right
.isPointerOrReference()) {
4644 const FormatToken
*Previous
= &Left
;
4645 while (Previous
&& Previous
->isNot(tok::kw_operator
)) {
4646 if (Previous
->is(tok::identifier
) || Previous
->isTypeName(LangOpts
)) {
4647 Previous
= Previous
->getPreviousNonComment();
4650 if (Previous
->is(TT_TemplateCloser
) && Previous
->MatchingParen
) {
4651 Previous
= Previous
->MatchingParen
->getPreviousNonComment();
4654 if (Previous
->is(tok::coloncolon
)) {
4655 Previous
= Previous
->getPreviousNonComment();
4660 // Space between the type and the * in:
4663 // operator void const*()
4664 // operator void volatile*()
4665 // operator /*comment*/ const char*()
4666 // operator volatile /*comment*/ char*()
4669 // operator std::Foo*()
4670 // operator C<T>::D<U>*()
4671 // dependent on PointerAlignment style.
4673 if (Previous
->endsSequence(tok::kw_operator
))
4674 return Style
.PointerAlignment
!= FormatStyle::PAS_Left
;
4675 if (Previous
->is(tok::kw_const
) || Previous
->is(tok::kw_volatile
)) {
4676 return (Style
.PointerAlignment
!= FormatStyle::PAS_Left
) ||
4677 (Style
.SpaceAroundPointerQualifiers
==
4678 FormatStyle::SAPQ_After
) ||
4679 (Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
);
4683 if (Style
.isCSharp() && Left
.is(Keywords
.kw_is
) && Right
.is(tok::l_square
))
4685 const auto SpaceRequiredForArrayInitializerLSquare
=
4686 [](const FormatToken
&LSquareTok
, const FormatStyle
&Style
) {
4687 return Style
.SpacesInContainerLiterals
||
4688 (Style
.isProto() && !Style
.Cpp11BracedListStyle
&&
4689 LSquareTok
.endsSequence(tok::l_square
, tok::colon
,
4692 if (Left
.is(tok::l_square
)) {
4693 return (Left
.is(TT_ArrayInitializerLSquare
) && Right
.isNot(tok::r_square
) &&
4694 SpaceRequiredForArrayInitializerLSquare(Left
, Style
)) ||
4695 (Left
.isOneOf(TT_ArraySubscriptLSquare
, TT_StructuredBindingLSquare
,
4696 TT_LambdaLSquare
) &&
4697 Style
.SpacesInSquareBrackets
&& Right
.isNot(tok::r_square
));
4699 if (Right
.is(tok::r_square
)) {
4700 return Right
.MatchingParen
&&
4701 ((Right
.MatchingParen
->is(TT_ArrayInitializerLSquare
) &&
4702 SpaceRequiredForArrayInitializerLSquare(*Right
.MatchingParen
,
4704 (Style
.SpacesInSquareBrackets
&&
4705 Right
.MatchingParen
->isOneOf(TT_ArraySubscriptLSquare
,
4706 TT_StructuredBindingLSquare
,
4707 TT_LambdaLSquare
)));
4709 if (Right
.is(tok::l_square
) &&
4710 !Right
.isOneOf(TT_ObjCMethodExpr
, TT_LambdaLSquare
,
4711 TT_DesignatedInitializerLSquare
,
4712 TT_StructuredBindingLSquare
, TT_AttributeSquare
) &&
4713 !Left
.isOneOf(tok::numeric_constant
, TT_DictLiteral
) &&
4714 !(Left
.isNot(tok::r_square
) && Style
.SpaceBeforeSquareBrackets
&&
4715 Right
.is(TT_ArraySubscriptLSquare
))) {
4718 if (Left
.is(tok::l_brace
) && Right
.is(tok::r_brace
))
4719 return !Left
.Children
.empty(); // No spaces in "{}".
4720 if ((Left
.is(tok::l_brace
) && Left
.isNot(BK_Block
)) ||
4721 (Right
.is(tok::r_brace
) && Right
.MatchingParen
&&
4722 Right
.MatchingParen
->isNot(BK_Block
))) {
4723 return !Style
.Cpp11BracedListStyle
|| Style
.SpacesInParensOptions
.Other
;
4725 if (Left
.is(TT_BlockComment
)) {
4726 // No whitespace in x(/*foo=*/1), except for JavaScript.
4727 return Style
.isJavaScript() || !Left
.TokenText
.ends_with("=*/");
4730 // Space between template and attribute.
4731 // e.g. template <typename T> [[nodiscard]] ...
4732 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_AttributeSquare
))
4734 // Space before parentheses common for all languages
4735 if (Right
.is(tok::l_paren
)) {
4736 if (Left
.is(TT_TemplateCloser
) && Right
.isNot(TT_FunctionTypeLParen
))
4737 return spaceRequiredBeforeParens(Right
);
4738 if (Left
.isOneOf(TT_RequiresClause
,
4739 TT_RequiresClauseInARequiresExpression
)) {
4740 return Style
.SpaceBeforeParensOptions
.AfterRequiresInClause
||
4741 spaceRequiredBeforeParens(Right
);
4743 if (Left
.is(TT_RequiresExpression
)) {
4744 return Style
.SpaceBeforeParensOptions
.AfterRequiresInExpression
||
4745 spaceRequiredBeforeParens(Right
);
4747 if (Left
.is(TT_AttributeRParen
) ||
4748 (Left
.is(tok::r_square
) && Left
.is(TT_AttributeSquare
))) {
4751 if (Left
.is(TT_ForEachMacro
)) {
4752 return Style
.SpaceBeforeParensOptions
.AfterForeachMacros
||
4753 spaceRequiredBeforeParens(Right
);
4755 if (Left
.is(TT_IfMacro
)) {
4756 return Style
.SpaceBeforeParensOptions
.AfterIfMacros
||
4757 spaceRequiredBeforeParens(Right
);
4759 if (Style
.SpaceBeforeParens
== FormatStyle::SBPO_Custom
&&
4760 Left
.isOneOf(tok::kw_new
, tok::kw_delete
) &&
4761 Right
.isNot(TT_OverloadedOperatorLParen
) &&
4762 !(Line
.MightBeFunctionDecl
&& Left
.is(TT_FunctionDeclarationName
))) {
4763 const auto *RParen
= Right
.MatchingParen
;
4764 return Style
.SpaceBeforeParensOptions
.AfterPlacementOperator
||
4765 (RParen
&& RParen
->is(TT_CastRParen
));
4767 if (Line
.Type
== LT_ObjCDecl
)
4769 if (Left
.is(tok::semi
))
4771 if (Left
.isOneOf(tok::pp_elif
, tok::kw_for
, tok::kw_while
, tok::kw_switch
,
4772 tok::kw_case
, TT_ForEachMacro
, TT_ObjCForIn
) ||
4773 Left
.isIf(Line
.Type
!= LT_PreprocessorDirective
) ||
4774 Right
.is(TT_ConditionLParen
)) {
4775 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
4776 spaceRequiredBeforeParens(Right
);
4779 // TODO add Operator overloading specific Options to
4780 // SpaceBeforeParensOptions
4781 if (Right
.is(TT_OverloadedOperatorLParen
))
4782 return spaceRequiredBeforeParens(Right
);
4783 // Function declaration or definition
4784 if (Line
.MightBeFunctionDecl
&& Right
.is(TT_FunctionDeclarationLParen
)) {
4785 if (spaceRequiredBeforeParens(Right
))
4787 const auto &Options
= Style
.SpaceBeforeParensOptions
;
4788 return Line
.mightBeFunctionDefinition()
4789 ? Options
.AfterFunctionDefinitionName
4790 : Options
.AfterFunctionDeclarationName
;
4793 if (Line
.Type
!= LT_PreprocessorDirective
&& Left
.is(tok::r_square
) &&
4794 Left
.MatchingParen
&& Left
.MatchingParen
->is(TT_LambdaLSquare
)) {
4795 return Style
.SpaceBeforeParensOptions
.AfterFunctionDefinitionName
||
4796 spaceRequiredBeforeParens(Right
);
4798 if (!BeforeLeft
|| !BeforeLeft
->isOneOf(tok::period
, tok::arrow
)) {
4799 if (Left
.isOneOf(tok::kw_try
, Keywords
.kw___except
, tok::kw_catch
)) {
4800 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
4801 spaceRequiredBeforeParens(Right
);
4803 if (Left
.isOneOf(tok::kw_new
, tok::kw_delete
)) {
4804 return ((!Line
.MightBeFunctionDecl
|| !BeforeLeft
) &&
4805 Style
.SpaceBeforeParens
!= FormatStyle::SBPO_Never
) ||
4806 spaceRequiredBeforeParens(Right
);
4809 if (Left
.is(tok::r_square
) && Left
.MatchingParen
&&
4810 Left
.MatchingParen
->Previous
&&
4811 Left
.MatchingParen
->Previous
->is(tok::kw_delete
)) {
4812 return (Style
.SpaceBeforeParens
!= FormatStyle::SBPO_Never
) ||
4813 spaceRequiredBeforeParens(Right
);
4816 // Handle builtins like identifiers.
4817 if (Line
.Type
!= LT_PreprocessorDirective
&&
4818 (Left
.Tok
.getIdentifierInfo() || Left
.is(tok::r_paren
))) {
4819 return spaceRequiredBeforeParens(Right
);
4823 if (Left
.is(tok::at
) && Right
.Tok
.getObjCKeywordID() != tok::objc_not_keyword
)
4825 if (Right
.is(TT_UnaryOperator
)) {
4826 return !Left
.isOneOf(tok::l_paren
, tok::l_square
, tok::at
) &&
4827 (Left
.isNot(tok::colon
) || Left
.isNot(TT_ObjCMethodExpr
));
4829 // No space between the variable name and the initializer list.
4831 // Verilog doesn't have such syntax, but it has word operators that are C++
4832 // identifiers like `a inside {b, c}`. So the rule is not applicable.
4833 if (!Style
.isVerilog() &&
4834 (Left
.isOneOf(tok::identifier
, tok::greater
, tok::r_square
,
4836 Left
.isTypeName(LangOpts
)) &&
4837 Right
.is(tok::l_brace
) && Right
.getNextNonComment() &&
4838 Right
.isNot(BK_Block
)) {
4841 if (Left
.is(tok::period
) || Right
.is(tok::period
))
4843 // u#str, U#str, L#str, u8#str
4844 // uR#str, UR#str, LR#str, u8R#str
4845 if (Right
.is(tok::hash
) && Left
.is(tok::identifier
) &&
4846 (Left
.TokenText
== "L" || Left
.TokenText
== "u" ||
4847 Left
.TokenText
== "U" || Left
.TokenText
== "u8" ||
4848 Left
.TokenText
== "LR" || Left
.TokenText
== "uR" ||
4849 Left
.TokenText
== "UR" || Left
.TokenText
== "u8R")) {
4852 if (Left
.is(TT_TemplateCloser
) && Left
.MatchingParen
&&
4853 Left
.MatchingParen
->Previous
&&
4854 (Left
.MatchingParen
->Previous
->is(tok::period
) ||
4855 Left
.MatchingParen
->Previous
->is(tok::coloncolon
))) {
4856 // Java call to generic function with explicit type:
4857 // A.<B<C<...>>>DoSomething();
4858 // A::<B<C<...>>>DoSomething(); // With a Java 8 method reference.
4861 if (Left
.is(TT_TemplateCloser
) && Right
.is(tok::l_square
))
4863 if (Left
.is(tok::l_brace
) && Left
.endsSequence(TT_DictLiteral
, tok::at
)) {
4864 // Objective-C dictionary literal -> no space after opening brace.
4867 if (Right
.is(tok::r_brace
) && Right
.MatchingParen
&&
4868 Right
.MatchingParen
->endsSequence(TT_DictLiteral
, tok::at
)) {
4869 // Objective-C dictionary literal -> no space before closing brace.
4872 if (Right
.is(TT_TrailingAnnotation
) && Right
.isOneOf(tok::amp
, tok::ampamp
) &&
4873 Left
.isOneOf(tok::kw_const
, tok::kw_volatile
) &&
4874 (!Right
.Next
|| Right
.Next
->is(tok::semi
))) {
4875 // Match const and volatile ref-qualifiers without any additional
4876 // qualifiers such as
4877 // void Fn() const &;
4878 return getTokenReferenceAlignment(Right
) != FormatStyle::PAS_Left
;
4884 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine
&Line
,
4885 const FormatToken
&Right
) const {
4886 const FormatToken
&Left
= *Right
.Previous
;
4888 // If the token is finalized don't touch it (as it could be in a
4889 // clang-format-off section).
4891 return Right
.hasWhitespaceBefore();
4893 const bool IsVerilog
= Style
.isVerilog();
4894 assert(!IsVerilog
|| !IsCpp
);
4896 // Never ever merge two words.
4897 if (Keywords
.isWordLike(Right
, IsVerilog
) &&
4898 Keywords
.isWordLike(Left
, IsVerilog
)) {
4902 // Leave a space between * and /* to avoid C4138 `comment end` found outside
4904 if (Left
.is(tok::star
) && Right
.is(tok::comment
))
4907 const auto *BeforeLeft
= Left
.Previous
;
4910 if (Left
.is(TT_OverloadedOperator
) &&
4911 Right
.isOneOf(TT_TemplateOpener
, TT_TemplateCloser
)) {
4914 // Space between UDL and dot: auto b = 4s .count();
4915 if (Right
.is(tok::period
) && Left
.is(tok::numeric_constant
))
4917 // Space between import <iostream>.
4919 if (Left
.is(Keywords
.kw_import
) && Right
.isOneOf(tok::less
, tok::ellipsis
))
4921 // Space between `module :` and `import :`.
4922 if (Left
.isOneOf(Keywords
.kw_module
, Keywords
.kw_import
) &&
4923 Right
.is(TT_ModulePartitionColon
)) {
4926 // No space between import foo:bar but keep a space between import :bar;
4927 if (Left
.is(tok::identifier
) && Right
.is(TT_ModulePartitionColon
))
4929 // No space between :bar;
4930 if (Left
.is(TT_ModulePartitionColon
) &&
4931 Right
.isOneOf(tok::identifier
, tok::kw_private
)) {
4934 if (Left
.is(tok::ellipsis
) && Right
.is(tok::identifier
) &&
4935 Line
.First
->is(Keywords
.kw_import
)) {
4938 // Space in __attribute__((attr)) ::type.
4939 if (Left
.isOneOf(TT_AttributeRParen
, TT_AttributeMacro
) &&
4940 Right
.is(tok::coloncolon
)) {
4944 if (Left
.is(tok::kw_operator
))
4945 return Right
.is(tok::coloncolon
);
4946 if (Right
.is(tok::l_brace
) && Right
.is(BK_BracedInit
) &&
4947 !Left
.opensScope() && Style
.SpaceBeforeCpp11BracedList
) {
4950 if (Left
.is(tok::less
) && Left
.is(TT_OverloadedOperator
) &&
4951 Right
.is(TT_TemplateOpener
)) {
4954 // C++ Core Guidelines suppression tag, e.g. `[[suppress(type.5)]]`.
4955 if (Left
.is(tok::identifier
) && Right
.is(tok::numeric_constant
))
4956 return Right
.TokenText
[0] != '.';
4957 // `Left` is a keyword (including C++ alternative operator) or identifier.
4958 if (Left
.Tok
.getIdentifierInfo() && Right
.Tok
.isLiteral())
4960 } else if (Style
.isProto()) {
4961 if (Right
.is(tok::period
) && !(BeforeLeft
&& BeforeLeft
->is(tok::period
)) &&
4962 Left
.isOneOf(Keywords
.kw_optional
, Keywords
.kw_required
,
4963 Keywords
.kw_repeated
, Keywords
.kw_extend
)) {
4966 if (Right
.is(tok::l_paren
) &&
4967 Left
.isOneOf(Keywords
.kw_returns
, Keywords
.kw_option
)) {
4970 if (Right
.isOneOf(tok::l_brace
, tok::less
) && Left
.is(TT_SelectorName
))
4972 // Slashes occur in text protocol extension syntax: [type/type] { ... }.
4973 if (Left
.is(tok::slash
) || Right
.is(tok::slash
))
4975 if (Left
.MatchingParen
&&
4976 Left
.MatchingParen
->is(TT_ProtoExtensionLSquare
) &&
4977 Right
.isOneOf(tok::l_brace
, tok::less
)) {
4978 return !Style
.Cpp11BracedListStyle
;
4980 // A percent is probably part of a formatting specification, such as %lld.
4981 if (Left
.is(tok::percent
))
4983 // Preserve the existence of a space before a percent for cases like 0x%04x
4985 if (Left
.is(tok::numeric_constant
) && Right
.is(tok::percent
))
4986 return Right
.hasWhitespaceBefore();
4987 } else if (Style
.isJson()) {
4988 if (Right
.is(tok::colon
) && Left
.is(tok::string_literal
))
4989 return Style
.SpaceBeforeJsonColon
;
4990 } else if (Style
.isCSharp()) {
4991 // Require spaces around '{' and before '}' unless they appear in
4992 // interpolated strings. Interpolated strings are merged into a single token
4993 // so cannot have spaces inserted by this function.
4995 // No space between 'this' and '['
4996 if (Left
.is(tok::kw_this
) && Right
.is(tok::l_square
))
4999 // No space between 'new' and '('
5000 if (Left
.is(tok::kw_new
) && Right
.is(tok::l_paren
))
5003 // Space before { (including space within '{ {').
5004 if (Right
.is(tok::l_brace
))
5007 // Spaces inside braces.
5008 if (Left
.is(tok::l_brace
) && Right
.isNot(tok::r_brace
))
5011 if (Left
.isNot(tok::l_brace
) && Right
.is(tok::r_brace
))
5014 // Spaces around '=>'.
5015 if (Left
.is(TT_FatArrow
) || Right
.is(TT_FatArrow
))
5018 // No spaces around attribute target colons
5019 if (Left
.is(TT_AttributeColon
) || Right
.is(TT_AttributeColon
))
5022 // space between type and variable e.g. Dictionary<string,string> foo;
5023 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_StartOfName
))
5026 // spaces inside square brackets.
5027 if (Left
.is(tok::l_square
) || Right
.is(tok::r_square
))
5028 return Style
.SpacesInSquareBrackets
;
5030 // No space before ? in nullable types.
5031 if (Right
.is(TT_CSharpNullable
))
5034 // No space before null forgiving '!'.
5035 if (Right
.is(TT_NonNullAssertion
))
5038 // No space between consecutive commas '[,,]'.
5039 if (Left
.is(tok::comma
) && Right
.is(tok::comma
))
5042 // space after var in `var (key, value)`
5043 if (Left
.is(Keywords
.kw_var
) && Right
.is(tok::l_paren
))
5046 // space between keywords and paren e.g. "using ("
5047 if (Right
.is(tok::l_paren
)) {
5048 if (Left
.isOneOf(tok::kw_using
, Keywords
.kw_async
, Keywords
.kw_when
,
5049 Keywords
.kw_lock
)) {
5050 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
5051 spaceRequiredBeforeParens(Right
);
5055 // space between method modifier and opening parenthesis of a tuple return
5057 if ((Left
.isAccessSpecifierKeyword() ||
5058 Left
.isOneOf(tok::kw_virtual
, tok::kw_extern
, tok::kw_static
,
5059 Keywords
.kw_internal
, Keywords
.kw_abstract
,
5060 Keywords
.kw_sealed
, Keywords
.kw_override
,
5061 Keywords
.kw_async
, Keywords
.kw_unsafe
)) &&
5062 Right
.is(tok::l_paren
)) {
5065 } else if (Style
.isJavaScript()) {
5066 if (Left
.is(TT_FatArrow
))
5069 if (Right
.is(tok::l_paren
) && Left
.is(Keywords
.kw_await
) && BeforeLeft
&&
5070 BeforeLeft
->is(tok::kw_for
)) {
5073 if (Left
.is(Keywords
.kw_async
) && Right
.is(tok::l_paren
) &&
5074 Right
.MatchingParen
) {
5075 const FormatToken
*Next
= Right
.MatchingParen
->getNextNonComment();
5076 // An async arrow function, for example: `x = async () => foo();`,
5077 // as opposed to calling a function called async: `x = async();`
5078 if (Next
&& Next
->is(TT_FatArrow
))
5081 if ((Left
.is(TT_TemplateString
) && Left
.TokenText
.ends_with("${")) ||
5082 (Right
.is(TT_TemplateString
) && Right
.TokenText
.starts_with("}"))) {
5085 // In tagged template literals ("html`bar baz`"), there is no space between
5086 // the tag identifier and the template string.
5087 if (Keywords
.isJavaScriptIdentifier(Left
,
5088 /* AcceptIdentifierName= */ false) &&
5089 Right
.is(TT_TemplateString
)) {
5092 if (Right
.is(tok::star
) &&
5093 Left
.isOneOf(Keywords
.kw_function
, Keywords
.kw_yield
)) {
5096 if (Right
.isOneOf(tok::l_brace
, tok::l_square
) &&
5097 Left
.isOneOf(Keywords
.kw_function
, Keywords
.kw_yield
,
5098 Keywords
.kw_extends
, Keywords
.kw_implements
)) {
5101 if (Right
.is(tok::l_paren
)) {
5102 // JS methods can use some keywords as names (e.g. `delete()`).
5103 if (Line
.MustBeDeclaration
&& Left
.Tok
.getIdentifierInfo())
5105 // Valid JS method names can include keywords, e.g. `foo.delete()` or
5106 // `bar.instanceof()`. Recognize call positions by preceding period.
5107 if (BeforeLeft
&& BeforeLeft
->is(tok::period
) &&
5108 Left
.Tok
.getIdentifierInfo()) {
5111 // Additional unary JavaScript operators that need a space after.
5112 if (Left
.isOneOf(tok::kw_throw
, Keywords
.kw_await
, Keywords
.kw_typeof
,
5117 // `foo as const;` casts into a const type.
5118 if (Left
.endsSequence(tok::kw_const
, Keywords
.kw_as
))
5120 if ((Left
.isOneOf(Keywords
.kw_let
, Keywords
.kw_var
, Keywords
.kw_in
,
5122 // "of" is only a keyword if it appears after another identifier
5123 // (e.g. as "const x of y" in a for loop), or after a destructuring
5124 // operation (const [x, y] of z, const {a, b} of c).
5125 (Left
.is(Keywords
.kw_of
) && BeforeLeft
&&
5126 (BeforeLeft
->is(tok::identifier
) ||
5127 BeforeLeft
->isOneOf(tok::r_square
, tok::r_brace
)))) &&
5128 (!BeforeLeft
|| BeforeLeft
->isNot(tok::period
))) {
5131 if (Left
.isOneOf(tok::kw_for
, Keywords
.kw_as
) && BeforeLeft
&&
5132 BeforeLeft
->is(tok::period
) && Right
.is(tok::l_paren
)) {
5135 if (Left
.is(Keywords
.kw_as
) &&
5136 Right
.isOneOf(tok::l_square
, tok::l_brace
, tok::l_paren
)) {
5139 if (Left
.is(tok::kw_default
) && BeforeLeft
&&
5140 BeforeLeft
->is(tok::kw_export
)) {
5143 if (Left
.is(Keywords
.kw_is
) && Right
.is(tok::l_brace
))
5145 if (Right
.isOneOf(TT_JsTypeColon
, TT_JsTypeOptionalQuestion
))
5147 if (Left
.is(TT_JsTypeOperator
) || Right
.is(TT_JsTypeOperator
))
5149 if ((Left
.is(tok::l_brace
) || Right
.is(tok::r_brace
)) &&
5150 Line
.First
->isOneOf(Keywords
.kw_import
, tok::kw_export
)) {
5153 if (Left
.is(tok::ellipsis
))
5155 if (Left
.is(TT_TemplateCloser
) &&
5156 !Right
.isOneOf(tok::equal
, tok::l_brace
, tok::comma
, tok::l_square
,
5157 Keywords
.kw_implements
, Keywords
.kw_extends
)) {
5158 // Type assertions ('<type>expr') are not followed by whitespace. Other
5159 // locations that should have whitespace following are identified by the
5160 // above set of follower tokens.
5163 if (Right
.is(TT_NonNullAssertion
))
5165 if (Left
.is(TT_NonNullAssertion
) &&
5166 Right
.isOneOf(Keywords
.kw_as
, Keywords
.kw_in
)) {
5167 return true; // "x! as string", "x! in y"
5169 } else if (Style
.Language
== FormatStyle::LK_Java
) {
5170 if (Left
.is(TT_CaseLabelArrow
) || Right
.is(TT_CaseLabelArrow
))
5172 if (Left
.is(tok::r_square
) && Right
.is(tok::l_brace
))
5174 // spaces inside square brackets.
5175 if (Left
.is(tok::l_square
) || Right
.is(tok::r_square
))
5176 return Style
.SpacesInSquareBrackets
;
5178 if (Left
.is(Keywords
.kw_synchronized
) && Right
.is(tok::l_paren
)) {
5179 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
5180 spaceRequiredBeforeParens(Right
);
5182 if ((Left
.isAccessSpecifierKeyword() ||
5183 Left
.isOneOf(tok::kw_static
, Keywords
.kw_final
, Keywords
.kw_abstract
,
5184 Keywords
.kw_native
)) &&
5185 Right
.is(TT_TemplateOpener
)) {
5188 } else if (IsVerilog
) {
5189 // An escaped identifier ends with whitespace.
5190 if (Left
.is(tok::identifier
) && Left
.TokenText
[0] == '\\')
5192 // Add space between things in a primitive's state table unless in a
5193 // transition like `(0?)`.
5194 if ((Left
.is(TT_VerilogTableItem
) &&
5195 !Right
.isOneOf(tok::r_paren
, tok::semi
)) ||
5196 (Right
.is(TT_VerilogTableItem
) && Left
.isNot(tok::l_paren
))) {
5197 const FormatToken
*Next
= Right
.getNextNonComment();
5198 return !(Next
&& Next
->is(tok::r_paren
));
5200 // Don't add space within a delay like `#0`.
5201 if (Left
.isNot(TT_BinaryOperator
) &&
5202 Left
.isOneOf(Keywords
.kw_verilogHash
, Keywords
.kw_verilogHashHash
)) {
5205 // Add space after a delay.
5206 if (Right
.isNot(tok::semi
) &&
5207 (Left
.endsSequence(tok::numeric_constant
, Keywords
.kw_verilogHash
) ||
5208 Left
.endsSequence(tok::numeric_constant
,
5209 Keywords
.kw_verilogHashHash
) ||
5210 (Left
.is(tok::r_paren
) && Left
.MatchingParen
&&
5211 Left
.MatchingParen
->endsSequence(tok::l_paren
, tok::at
)))) {
5214 // Don't add embedded spaces in a number literal like `16'h1?ax` or an array
5215 // literal like `'{}`.
5216 if (Left
.is(Keywords
.kw_apostrophe
) ||
5217 (Left
.is(TT_VerilogNumberBase
) && Right
.is(tok::numeric_constant
))) {
5220 // Add spaces around the implication operator `->`.
5221 if (Left
.is(tok::arrow
) || Right
.is(tok::arrow
))
5223 // Don't add spaces between two at signs. Like in a coverage event.
5224 // Don't add spaces between at and a sensitivity list like
5225 // `@(posedge clk)`.
5226 if (Left
.is(tok::at
) && Right
.isOneOf(tok::l_paren
, tok::star
, tok::at
))
5228 // Add space between the type name and dimension like `logic [1:0]`.
5229 if (Right
.is(tok::l_square
) &&
5230 Left
.isOneOf(TT_VerilogDimensionedTypeName
, Keywords
.kw_function
)) {
5233 // In a tagged union expression, there should be a space after the tag.
5234 if (Right
.isOneOf(tok::period
, Keywords
.kw_apostrophe
) &&
5235 Keywords
.isVerilogIdentifier(Left
) && Left
.getPreviousNonComment() &&
5236 Left
.getPreviousNonComment()->is(Keywords
.kw_tagged
)) {
5239 // Don't add spaces between a casting type and the quote or repetition count
5240 // and the brace. The case of tagged union expressions is handled by the
5242 if ((Right
.is(Keywords
.kw_apostrophe
) ||
5243 (Right
.is(BK_BracedInit
) && Right
.is(tok::l_brace
))) &&
5244 !(Left
.isOneOf(Keywords
.kw_assign
, Keywords
.kw_unique
) ||
5245 Keywords
.isVerilogWordOperator(Left
)) &&
5246 (Left
.isOneOf(tok::r_square
, tok::r_paren
, tok::r_brace
,
5247 tok::numeric_constant
) ||
5248 Keywords
.isWordLike(Left
))) {
5251 // Don't add spaces in imports like `import foo::*;`.
5252 if ((Right
.is(tok::star
) && Left
.is(tok::coloncolon
)) ||
5253 (Left
.is(tok::star
) && Right
.is(tok::semi
))) {
5256 // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
5257 if (Left
.endsSequence(tok::star
, tok::l_paren
) && Right
.is(tok::identifier
))
5259 // Add space before drive strength like in `wire (strong1, pull0)`.
5260 if (Right
.is(tok::l_paren
) && Right
.is(TT_VerilogStrength
))
5262 // Don't add space in a streaming concatenation like `{>>{j}}`.
5263 if ((Left
.is(tok::l_brace
) &&
5264 Right
.isOneOf(tok::lessless
, tok::greatergreater
)) ||
5265 (Left
.endsSequence(tok::lessless
, tok::l_brace
) ||
5266 Left
.endsSequence(tok::greatergreater
, tok::l_brace
))) {
5269 } else if (Style
.isTableGen()) {
5270 // Avoid to connect [ and {. [{ is start token of multiline string.
5271 if (Left
.is(tok::l_square
) && Right
.is(tok::l_brace
))
5273 if (Left
.is(tok::r_brace
) && Right
.is(tok::r_square
))
5275 // Do not insert around colon in DAGArg and cond operator.
5276 if (Right
.isOneOf(TT_TableGenDAGArgListColon
,
5277 TT_TableGenDAGArgListColonToAlign
) ||
5278 Left
.isOneOf(TT_TableGenDAGArgListColon
,
5279 TT_TableGenDAGArgListColonToAlign
)) {
5282 if (Right
.is(TT_TableGenCondOperatorColon
))
5284 if (Left
.isOneOf(TT_TableGenDAGArgOperatorID
,
5285 TT_TableGenDAGArgOperatorToBreak
) &&
5286 Right
.isNot(TT_TableGenDAGArgCloser
)) {
5289 // Do not insert bang operators and consequent openers.
5290 if (Right
.isOneOf(tok::l_paren
, tok::less
) &&
5291 Left
.isOneOf(TT_TableGenBangOperator
, TT_TableGenCondOperator
)) {
5294 // Trailing paste requires space before '{' or ':', the case in name values.
5295 // Not before ';', the case in normal values.
5296 if (Left
.is(TT_TableGenTrailingPasteOperator
) &&
5297 Right
.isOneOf(tok::l_brace
, tok::colon
)) {
5300 // Otherwise paste operator does not prefer space around.
5301 if (Left
.is(tok::hash
) || Right
.is(tok::hash
))
5303 // Sure not to connect after defining keywords.
5304 if (Keywords
.isTableGenDefinition(Left
))
5308 if (Left
.is(TT_ImplicitStringLiteral
))
5309 return Right
.hasWhitespaceBefore();
5310 if (Line
.Type
== LT_ObjCMethodDecl
) {
5311 if (Left
.is(TT_ObjCMethodSpecifier
))
5313 if (Left
.is(tok::r_paren
) && Left
.isNot(TT_AttributeRParen
) &&
5314 canBeObjCSelectorComponent(Right
)) {
5315 // Don't space between ')' and <id> or ')' and 'new'. 'new' is not a
5316 // keyword in Objective-C, and '+ (instancetype)new;' is a standard class
5317 // method declaration.
5321 if (Line
.Type
== LT_ObjCProperty
&&
5322 (Right
.is(tok::equal
) || Left
.is(tok::equal
))) {
5326 if (Right
.isOneOf(TT_TrailingReturnArrow
, TT_LambdaArrow
) ||
5327 Left
.isOneOf(TT_TrailingReturnArrow
, TT_LambdaArrow
)) {
5330 if (Left
.is(tok::comma
) && Right
.isNot(TT_OverloadedOperatorLParen
) &&
5331 // In an unexpanded macro call we only find the parentheses and commas
5332 // in a line; the commas and closing parenthesis do not require a space.
5333 (Left
.Children
.empty() || !Left
.MacroParent
)) {
5336 if (Right
.is(tok::comma
))
5338 if (Right
.is(TT_ObjCBlockLParen
))
5340 if (Right
.is(TT_CtorInitializerColon
))
5341 return Style
.SpaceBeforeCtorInitializerColon
;
5342 if (Right
.is(TT_InheritanceColon
) && !Style
.SpaceBeforeInheritanceColon
)
5344 if (Right
.is(TT_RangeBasedForLoopColon
) &&
5345 !Style
.SpaceBeforeRangeBasedForLoopColon
) {
5348 if (Left
.is(TT_BitFieldColon
)) {
5349 return Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Both
||
5350 Style
.BitFieldColonSpacing
== FormatStyle::BFCS_After
;
5352 if (Right
.is(tok::colon
)) {
5353 if (Right
.is(TT_CaseLabelColon
))
5354 return Style
.SpaceBeforeCaseColon
;
5355 if (Right
.is(TT_GotoLabelColon
))
5357 // `private:` and `public:`.
5358 if (!Right
.getNextNonComment())
5360 if (Right
.is(TT_ObjCMethodExpr
))
5362 if (Left
.is(tok::question
))
5364 if (Right
.is(TT_InlineASMColon
) && Left
.is(tok::coloncolon
))
5366 if (Right
.is(TT_DictLiteral
))
5367 return Style
.SpacesInContainerLiterals
;
5368 if (Right
.is(TT_AttributeColon
))
5370 if (Right
.is(TT_CSharpNamedArgumentColon
))
5372 if (Right
.is(TT_GenericSelectionColon
))
5374 if (Right
.is(TT_BitFieldColon
)) {
5375 return Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Both
||
5376 Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Before
;
5380 // Do not merge "- -" into "--".
5381 if ((Left
.isOneOf(tok::minus
, tok::minusminus
) &&
5382 Right
.isOneOf(tok::minus
, tok::minusminus
)) ||
5383 (Left
.isOneOf(tok::plus
, tok::plusplus
) &&
5384 Right
.isOneOf(tok::plus
, tok::plusplus
))) {
5387 if (Left
.is(TT_UnaryOperator
)) {
5388 // Lambda captures allow for a lone &, so "&]" needs to be properly
5390 if (Left
.is(tok::amp
) && Right
.is(tok::r_square
))
5391 return Style
.SpacesInSquareBrackets
;
5392 return Style
.SpaceAfterLogicalNot
&& Left
.is(tok::exclaim
);
5395 // If the next token is a binary operator or a selector name, we have
5396 // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.
5397 if (Left
.is(TT_CastRParen
)) {
5398 return Style
.SpaceAfterCStyleCast
||
5399 Right
.isOneOf(TT_BinaryOperator
, TT_SelectorName
);
5402 auto ShouldAddSpacesInAngles
= [this, &Right
]() {
5403 if (this->Style
.SpacesInAngles
== FormatStyle::SIAS_Always
)
5405 if (this->Style
.SpacesInAngles
== FormatStyle::SIAS_Leave
)
5406 return Right
.hasWhitespaceBefore();
5410 if (Left
.is(tok::greater
) && Right
.is(tok::greater
)) {
5411 if (Style
.Language
== FormatStyle::LK_TextProto
||
5412 (Style
.Language
== FormatStyle::LK_Proto
&& Left
.is(TT_DictLiteral
))) {
5413 return !Style
.Cpp11BracedListStyle
;
5415 return Right
.is(TT_TemplateCloser
) && Left
.is(TT_TemplateCloser
) &&
5416 ((Style
.Standard
< FormatStyle::LS_Cpp11
) ||
5417 ShouldAddSpacesInAngles());
5419 if (Right
.isOneOf(tok::arrow
, tok::arrowstar
, tok::periodstar
) ||
5420 Left
.isOneOf(tok::arrow
, tok::period
, tok::arrowstar
, tok::periodstar
) ||
5421 (Right
.is(tok::period
) && Right
.isNot(TT_DesignatedInitializerPeriod
))) {
5424 if (!Style
.SpaceBeforeAssignmentOperators
&& Left
.isNot(TT_TemplateCloser
) &&
5425 Right
.getPrecedence() == prec::Assignment
) {
5428 if (Style
.Language
== FormatStyle::LK_Java
&& Right
.is(tok::coloncolon
) &&
5429 (Left
.is(tok::identifier
) || Left
.is(tok::kw_this
))) {
5432 if (Right
.is(tok::coloncolon
) && Left
.is(tok::identifier
)) {
5433 // Generally don't remove existing spaces between an identifier and "::".
5434 // The identifier might actually be a macro name such as ALWAYS_INLINE. If
5435 // this turns out to be too lenient, add analysis of the identifier itself.
5436 return Right
.hasWhitespaceBefore();
5438 if (Right
.is(tok::coloncolon
) &&
5439 !Left
.isOneOf(tok::l_brace
, tok::comment
, tok::l_paren
)) {
5440 // Put a space between < and :: in vector< ::std::string >
5441 return (Left
.is(TT_TemplateOpener
) &&
5442 ((Style
.Standard
< FormatStyle::LS_Cpp11
) ||
5443 ShouldAddSpacesInAngles())) ||
5444 !(Left
.isOneOf(tok::l_paren
, tok::r_paren
, tok::l_square
,
5445 tok::kw___super
, TT_TemplateOpener
,
5446 TT_TemplateCloser
)) ||
5447 (Left
.is(tok::l_paren
) && Style
.SpacesInParensOptions
.Other
);
5449 if ((Left
.is(TT_TemplateOpener
)) != (Right
.is(TT_TemplateCloser
)))
5450 return ShouldAddSpacesInAngles();
5451 if (Left
.is(tok::r_paren
) && Right
.is(TT_PointerOrReference
) &&
5452 Right
.isOneOf(tok::amp
, tok::ampamp
)) {
5455 // Space before TT_StructuredBindingLSquare.
5456 if (Right
.is(TT_StructuredBindingLSquare
)) {
5457 return !Left
.isOneOf(tok::amp
, tok::ampamp
) ||
5458 getTokenReferenceAlignment(Left
) != FormatStyle::PAS_Right
;
5460 // Space before & or && following a TT_StructuredBindingLSquare.
5461 if (Right
.Next
&& Right
.Next
->is(TT_StructuredBindingLSquare
) &&
5462 Right
.isOneOf(tok::amp
, tok::ampamp
)) {
5463 return getTokenReferenceAlignment(Right
) != FormatStyle::PAS_Left
;
5465 if ((Right
.is(TT_BinaryOperator
) && Left
.isNot(tok::l_paren
)) ||
5466 (Left
.isOneOf(TT_BinaryOperator
, TT_ConditionalExpr
) &&
5467 Right
.isNot(tok::r_paren
))) {
5470 if (Right
.is(TT_TemplateOpener
) && Left
.is(tok::r_paren
) &&
5471 Left
.MatchingParen
&&
5472 Left
.MatchingParen
->is(TT_OverloadedOperatorLParen
)) {
5475 if (Right
.is(tok::less
) && Left
.isNot(tok::l_paren
) &&
5476 Line
.Type
== LT_ImportStatement
) {
5479 if (Right
.is(TT_TrailingUnaryOperator
))
5481 if (Left
.is(TT_RegexLiteral
))
5483 return spaceRequiredBetween(Line
, Left
, Right
);
5486 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
5487 static bool isAllmanBrace(const FormatToken
&Tok
) {
5488 return Tok
.is(tok::l_brace
) && Tok
.is(BK_Block
) &&
5489 !Tok
.isOneOf(TT_ObjCBlockLBrace
, TT_LambdaLBrace
, TT_DictLiteral
);
5492 // Returns 'true' if 'Tok' is a function argument.
5493 static bool IsFunctionArgument(const FormatToken
&Tok
) {
5494 return Tok
.MatchingParen
&& Tok
.MatchingParen
->Next
&&
5495 Tok
.MatchingParen
->Next
->isOneOf(tok::comma
, tok::r_paren
);
5499 isItAnEmptyLambdaAllowed(const FormatToken
&Tok
,
5500 FormatStyle::ShortLambdaStyle ShortLambdaOption
) {
5501 return Tok
.Children
.empty() && ShortLambdaOption
!= FormatStyle::SLS_None
;
5504 static bool isAllmanLambdaBrace(const FormatToken
&Tok
) {
5505 return Tok
.is(tok::l_brace
) && Tok
.is(BK_Block
) &&
5506 !Tok
.isOneOf(TT_ObjCBlockLBrace
, TT_DictLiteral
);
5509 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine
&Line
,
5510 const FormatToken
&Right
) const {
5511 const FormatToken
&Left
= *Right
.Previous
;
5512 if (Right
.NewlinesBefore
> 1 && Style
.MaxEmptyLinesToKeep
> 0 &&
5513 (!Style
.RemoveEmptyLinesInUnwrappedLines
|| &Right
== Line
.First
)) {
5517 if (Style
.BreakFunctionDefinitionParameters
&& Line
.MightBeFunctionDecl
&&
5518 Line
.mightBeFunctionDefinition() && Left
.MightBeFunctionDeclParen
&&
5519 Left
.ParameterCount
> 0) {
5523 // Ignores the first parameter as this will be handled separately by
5524 // BreakFunctionDefinitionParameters or AlignAfterOpenBracket.
5525 if (Style
.BinPackParameters
== FormatStyle::BPPS_AlwaysOnePerLine
&&
5526 Line
.MightBeFunctionDecl
&& !Left
.opensScope() &&
5527 startsNextParameter(Right
, Style
)) {
5531 const auto *BeforeLeft
= Left
.Previous
;
5532 const auto *AfterRight
= Right
.Next
;
5534 if (Style
.isCSharp()) {
5535 if (Left
.is(TT_FatArrow
) && Right
.is(tok::l_brace
) &&
5536 Style
.BraceWrapping
.AfterFunction
) {
5539 if (Right
.is(TT_CSharpNamedArgumentColon
) ||
5540 Left
.is(TT_CSharpNamedArgumentColon
)) {
5543 if (Right
.is(TT_CSharpGenericTypeConstraint
))
5545 if (AfterRight
&& AfterRight
->is(TT_FatArrow
) &&
5546 (Right
.is(tok::numeric_constant
) ||
5547 (Right
.is(tok::identifier
) && Right
.TokenText
== "_"))) {
5551 // Break after C# [...] and before public/protected/private/internal.
5552 if (Left
.is(TT_AttributeSquare
) && Left
.is(tok::r_square
) &&
5553 (Right
.isAccessSpecifier(/*ColonRequired=*/false) ||
5554 Right
.is(Keywords
.kw_internal
))) {
5557 // Break between ] and [ but only when there are really 2 attributes.
5558 if (Left
.is(TT_AttributeSquare
) && Right
.is(TT_AttributeSquare
) &&
5559 Left
.is(tok::r_square
) && Right
.is(tok::l_square
)) {
5562 } else if (Style
.isJavaScript()) {
5563 // FIXME: This might apply to other languages and token kinds.
5564 if (Right
.is(tok::string_literal
) && Left
.is(tok::plus
) && BeforeLeft
&&
5565 BeforeLeft
->is(tok::string_literal
)) {
5568 if (Left
.is(TT_DictLiteral
) && Left
.is(tok::l_brace
) && Line
.Level
== 0 &&
5569 BeforeLeft
&& BeforeLeft
->is(tok::equal
) &&
5570 Line
.First
->isOneOf(tok::identifier
, Keywords
.kw_import
, tok::kw_export
,
5572 // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match
5574 !Line
.First
->isOneOf(Keywords
.kw_var
, Keywords
.kw_let
)) {
5575 // Object literals on the top level of a file are treated as "enum-style".
5576 // Each key/value pair is put on a separate line, instead of bin-packing.
5579 if (Left
.is(tok::l_brace
) && Line
.Level
== 0 &&
5580 (Line
.startsWith(tok::kw_enum
) ||
5581 Line
.startsWith(tok::kw_const
, tok::kw_enum
) ||
5582 Line
.startsWith(tok::kw_export
, tok::kw_enum
) ||
5583 Line
.startsWith(tok::kw_export
, tok::kw_const
, tok::kw_enum
))) {
5584 // JavaScript top-level enum key/value pairs are put on separate lines
5585 // instead of bin-packing.
5588 if (Right
.is(tok::r_brace
) && Left
.is(tok::l_brace
) && BeforeLeft
&&
5589 BeforeLeft
->is(TT_FatArrow
)) {
5590 // JS arrow function (=> {...}).
5591 switch (Style
.AllowShortLambdasOnASingleLine
) {
5592 case FormatStyle::SLS_All
:
5594 case FormatStyle::SLS_None
:
5596 case FormatStyle::SLS_Empty
:
5597 return !Left
.Children
.empty();
5598 case FormatStyle::SLS_Inline
:
5599 // allow one-lining inline (e.g. in function call args) and empty arrow
5601 return (Left
.NestingLevel
== 0 && Line
.Level
== 0) &&
5602 !Left
.Children
.empty();
5604 llvm_unreachable("Unknown FormatStyle::ShortLambdaStyle enum");
5607 if (Right
.is(tok::r_brace
) && Left
.is(tok::l_brace
) &&
5608 !Left
.Children
.empty()) {
5609 // Support AllowShortFunctionsOnASingleLine for JavaScript.
5610 return Style
.AllowShortFunctionsOnASingleLine
== FormatStyle::SFS_None
||
5611 Style
.AllowShortFunctionsOnASingleLine
== FormatStyle::SFS_Empty
||
5612 (Left
.NestingLevel
== 0 && Line
.Level
== 0 &&
5613 Style
.AllowShortFunctionsOnASingleLine
&
5614 FormatStyle::SFS_InlineOnly
);
5616 } else if (Style
.Language
== FormatStyle::LK_Java
) {
5617 if (Right
.is(tok::plus
) && Left
.is(tok::string_literal
) && AfterRight
&&
5618 AfterRight
->is(tok::string_literal
)) {
5621 } else if (Style
.isVerilog()) {
5622 // Break between assignments.
5623 if (Left
.is(TT_VerilogAssignComma
))
5625 // Break between ports of different types.
5626 if (Left
.is(TT_VerilogTypeComma
))
5628 // Break between ports in a module instantiation and after the parameter
5630 if (Style
.VerilogBreakBetweenInstancePorts
&&
5631 (Left
.is(TT_VerilogInstancePortComma
) ||
5632 (Left
.is(tok::r_paren
) && Keywords
.isVerilogIdentifier(Right
) &&
5633 Left
.MatchingParen
&&
5634 Left
.MatchingParen
->is(TT_VerilogInstancePortLParen
)))) {
5637 // Break after labels. In Verilog labels don't have the 'case' keyword, so
5638 // it is hard to identify them in UnwrappedLineParser.
5639 if (!Keywords
.isVerilogBegin(Right
) && Keywords
.isVerilogEndOfLabel(Left
))
5641 } else if (Style
.BreakAdjacentStringLiterals
&&
5642 (IsCpp
|| Style
.isProto() ||
5643 Style
.Language
== FormatStyle::LK_TableGen
)) {
5644 if (Left
.isStringLiteral() && Right
.isStringLiteral())
5648 // Basic JSON newline processing.
5649 if (Style
.isJson()) {
5650 // Always break after a JSON record opener.
5653 if (Left
.is(TT_DictLiteral
) && Left
.is(tok::l_brace
))
5655 // Always break after a JSON array opener based on BreakArrays.
5656 if ((Left
.is(TT_ArrayInitializerLSquare
) && Left
.is(tok::l_square
) &&
5657 Right
.isNot(tok::r_square
)) ||
5658 Left
.is(tok::comma
)) {
5659 if (Right
.is(tok::l_brace
))
5661 // scan to the right if an we see an object or an array inside
5663 for (const auto *Tok
= &Right
; Tok
; Tok
= Tok
->Next
) {
5664 if (Tok
->isOneOf(tok::l_brace
, tok::l_square
))
5666 if (Tok
->isOneOf(tok::r_brace
, tok::r_square
))
5669 return Style
.BreakArrays
;
5671 } else if (Style
.isTableGen()) {
5672 // Break the comma in side cond operators.
5675 if (Left
.is(TT_TableGenCondOperatorComma
))
5677 if (Left
.is(TT_TableGenDAGArgOperatorToBreak
) &&
5678 Right
.isNot(TT_TableGenDAGArgCloser
)) {
5681 if (Left
.is(TT_TableGenDAGArgListCommaToBreak
))
5683 if (Right
.is(TT_TableGenDAGArgCloser
) && Right
.MatchingParen
&&
5684 Right
.MatchingParen
->is(TT_TableGenDAGArgOpenerToBreak
) &&
5685 &Left
!= Right
.MatchingParen
->Next
) {
5686 // Check to avoid empty DAGArg such as (ins).
5687 return Style
.TableGenBreakInsideDAGArg
== FormatStyle::DAS_BreakAll
;
5691 if (Line
.startsWith(tok::kw_asm
) && Right
.is(TT_InlineASMColon
) &&
5692 Style
.BreakBeforeInlineASMColon
== FormatStyle::BBIAS_Always
) {
5696 // If the last token before a '}', ']', or ')' is a comma or a trailing
5697 // comment, the intention is to insert a line break after it in order to make
5698 // shuffling around entries easier. Import statements, especially in
5699 // JavaScript, can be an exception to this rule.
5700 if (Style
.JavaScriptWrapImports
|| Line
.Type
!= LT_ImportStatement
) {
5701 const FormatToken
*BeforeClosingBrace
= nullptr;
5702 if ((Left
.isOneOf(tok::l_brace
, TT_ArrayInitializerLSquare
) ||
5703 (Style
.isJavaScript() && Left
.is(tok::l_paren
))) &&
5704 Left
.isNot(BK_Block
) && Left
.MatchingParen
) {
5705 BeforeClosingBrace
= Left
.MatchingParen
->Previous
;
5706 } else if (Right
.MatchingParen
&&
5707 (Right
.MatchingParen
->isOneOf(tok::l_brace
,
5708 TT_ArrayInitializerLSquare
) ||
5709 (Style
.isJavaScript() &&
5710 Right
.MatchingParen
->is(tok::l_paren
)))) {
5711 BeforeClosingBrace
= &Left
;
5713 if (BeforeClosingBrace
&& (BeforeClosingBrace
->is(tok::comma
) ||
5714 BeforeClosingBrace
->isTrailingComment())) {
5719 if (Right
.is(tok::comment
)) {
5720 return Left
.isNot(BK_BracedInit
) && Left
.isNot(TT_CtorInitializerColon
) &&
5721 (Right
.NewlinesBefore
> 0 && Right
.HasUnescapedNewline
);
5723 if (Left
.isTrailingComment())
5725 if (Left
.IsUnterminatedLiteral
)
5728 if (BeforeLeft
&& BeforeLeft
->is(tok::lessless
) &&
5729 Left
.is(tok::string_literal
) && Right
.is(tok::lessless
) && AfterRight
&&
5730 AfterRight
->is(tok::string_literal
)) {
5731 return Right
.NewlinesBefore
> 0;
5734 if (Right
.is(TT_RequiresClause
)) {
5735 switch (Style
.RequiresClausePosition
) {
5736 case FormatStyle::RCPS_OwnLine
:
5737 case FormatStyle::RCPS_OwnLineWithBrace
:
5738 case FormatStyle::RCPS_WithFollowing
:
5744 // Can break after template<> declaration
5745 if (Left
.ClosesTemplateDeclaration
&& Left
.MatchingParen
&&
5746 Left
.MatchingParen
->NestingLevel
== 0) {
5747 // Put concepts on the next line e.g.
5748 // template<typename T>
5750 if (Right
.is(tok::kw_concept
))
5751 return Style
.BreakBeforeConceptDeclarations
== FormatStyle::BBCDS_Always
;
5752 return Style
.BreakTemplateDeclarations
== FormatStyle::BTDS_Yes
||
5753 (Style
.BreakTemplateDeclarations
== FormatStyle::BTDS_Leave
&&
5754 Right
.NewlinesBefore
> 0);
5756 if (Left
.ClosesRequiresClause
) {
5757 switch (Style
.RequiresClausePosition
) {
5758 case FormatStyle::RCPS_OwnLine
:
5759 case FormatStyle::RCPS_WithPreceding
:
5760 return Right
.isNot(tok::semi
);
5761 case FormatStyle::RCPS_OwnLineWithBrace
:
5762 return !Right
.isOneOf(tok::semi
, tok::l_brace
);
5767 if (Style
.PackConstructorInitializers
== FormatStyle::PCIS_Never
) {
5768 if (Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeColon
&&
5769 (Left
.is(TT_CtorInitializerComma
) ||
5770 Right
.is(TT_CtorInitializerColon
))) {
5774 if (Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
&&
5775 Left
.isOneOf(TT_CtorInitializerColon
, TT_CtorInitializerComma
)) {
5779 if (Style
.PackConstructorInitializers
< FormatStyle::PCIS_CurrentLine
&&
5780 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
&&
5781 Right
.isOneOf(TT_CtorInitializerComma
, TT_CtorInitializerColon
)) {
5784 if (Style
.PackConstructorInitializers
== FormatStyle::PCIS_NextLineOnly
) {
5785 if ((Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeColon
||
5786 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
) &&
5787 Right
.is(TT_CtorInitializerColon
)) {
5791 if (Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
&&
5792 Left
.is(TT_CtorInitializerColon
)) {
5796 // Break only if we have multiple inheritance.
5797 if (Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
&&
5798 Right
.is(TT_InheritanceComma
)) {
5801 if (Style
.BreakInheritanceList
== FormatStyle::BILS_AfterComma
&&
5802 Left
.is(TT_InheritanceComma
)) {
5805 if (Right
.is(tok::string_literal
) && Right
.TokenText
.starts_with("R\"")) {
5806 // Multiline raw string literals are special wrt. line breaks. The author
5807 // has made a deliberate choice and might have aligned the contents of the
5808 // string literal accordingly. Thus, we try keep existing line breaks.
5809 return Right
.IsMultiline
&& Right
.NewlinesBefore
> 0;
5811 if ((Left
.is(tok::l_brace
) ||
5812 (Left
.is(tok::less
) && BeforeLeft
&& BeforeLeft
->is(tok::equal
))) &&
5813 Right
.NestingLevel
== 1 && Style
.Language
== FormatStyle::LK_Proto
) {
5814 // Don't put enums or option definitions onto single lines in protocol
5818 if (Right
.is(TT_InlineASMBrace
))
5819 return Right
.HasUnescapedNewline
;
5821 if (isAllmanBrace(Left
) || isAllmanBrace(Right
)) {
5822 auto *FirstNonComment
= Line
.getFirstNonComment();
5823 bool AccessSpecifier
=
5824 FirstNonComment
&& (FirstNonComment
->is(Keywords
.kw_internal
) ||
5825 FirstNonComment
->isAccessSpecifierKeyword());
5827 if (Style
.BraceWrapping
.AfterEnum
) {
5828 if (Line
.startsWith(tok::kw_enum
) ||
5829 Line
.startsWith(tok::kw_typedef
, tok::kw_enum
)) {
5832 // Ensure BraceWrapping for `public enum A {`.
5833 if (AccessSpecifier
&& FirstNonComment
->Next
&&
5834 FirstNonComment
->Next
->is(tok::kw_enum
)) {
5839 // Ensure BraceWrapping for `public interface A {`.
5840 if (Style
.BraceWrapping
.AfterClass
&&
5841 ((AccessSpecifier
&& FirstNonComment
->Next
&&
5842 FirstNonComment
->Next
->is(Keywords
.kw_interface
)) ||
5843 Line
.startsWith(Keywords
.kw_interface
))) {
5847 // Don't attempt to interpret struct return types as structs.
5848 if (Right
.isNot(TT_FunctionLBrace
)) {
5849 return (Line
.startsWith(tok::kw_class
) &&
5850 Style
.BraceWrapping
.AfterClass
) ||
5851 (Line
.startsWith(tok::kw_struct
) &&
5852 Style
.BraceWrapping
.AfterStruct
);
5856 if (Left
.is(TT_ObjCBlockLBrace
) &&
5857 Style
.AllowShortBlocksOnASingleLine
== FormatStyle::SBS_Never
) {
5861 // Ensure wrapping after __attribute__((XX)) and @interface etc.
5862 if (Left
.isOneOf(TT_AttributeRParen
, TT_AttributeMacro
) &&
5863 Right
.is(TT_ObjCDecl
)) {
5867 if (Left
.is(TT_LambdaLBrace
)) {
5868 if (IsFunctionArgument(Left
) &&
5869 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Inline
) {
5873 if (Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_None
||
5874 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Inline
||
5875 (!Left
.Children
.empty() &&
5876 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Empty
)) {
5881 if (Style
.BraceWrapping
.BeforeLambdaBody
&& Right
.is(TT_LambdaLBrace
) &&
5882 (Left
.isPointerOrReference() || Left
.is(TT_TemplateCloser
))) {
5886 // Put multiple Java annotation on a new line.
5887 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
5888 Left
.is(TT_LeadingJavaAnnotation
) &&
5889 Right
.isNot(TT_LeadingJavaAnnotation
) && Right
.isNot(tok::l_paren
) &&
5890 (Line
.Last
->is(tok::l_brace
) || Style
.BreakAfterJavaFieldAnnotations
)) {
5894 if (Right
.is(TT_ProtoExtensionLSquare
))
5897 // In text proto instances if a submessage contains at least 2 entries and at
5898 // least one of them is a submessage, like A { ... B { ... } ... },
5899 // put all of the entries of A on separate lines by forcing the selector of
5900 // the submessage B to be put on a newline.
5902 // Example: these can stay on one line:
5903 // a { scalar_1: 1 scalar_2: 2 }
5904 // a { b { key: value } }
5906 // and these entries need to be on a new line even if putting them all in one
5907 // line is under the column limit:
5913 // We enforce this by breaking before a submessage field that has previous
5914 // siblings, *and* breaking before a field that follows a submessage field.
5916 // Be careful to exclude the case [proto.ext] { ... } since the `]` is
5917 // the TT_SelectorName there, but we don't want to break inside the brackets.
5919 // Another edge case is @submessage { key: value }, which is a common
5920 // substitution placeholder. In this case we want to keep `@` and `submessage`
5923 // We ensure elsewhere that extensions are always on their own line.
5924 if (Style
.isProto() && Right
.is(TT_SelectorName
) &&
5925 Right
.isNot(tok::r_square
) && AfterRight
) {
5926 // Keep `@submessage` together in:
5927 // @submessage { key: value }
5928 if (Left
.is(tok::at
))
5930 // Look for the scope opener after selector in cases like:
5933 // selector: @base { ...
5934 const auto *LBrace
= AfterRight
;
5935 if (LBrace
&& LBrace
->is(tok::colon
)) {
5936 LBrace
= LBrace
->Next
;
5937 if (LBrace
&& LBrace
->is(tok::at
)) {
5938 LBrace
= LBrace
->Next
;
5940 LBrace
= LBrace
->Next
;
5944 // The scope opener is one of {, [, <:
5949 // In case of selector { ... }, the l_brace is TT_DictLiteral.
5950 // In case of an empty selector {}, the l_brace is not TT_DictLiteral,
5951 // so we check for immediately following r_brace.
5952 ((LBrace
->is(tok::l_brace
) &&
5953 (LBrace
->is(TT_DictLiteral
) ||
5954 (LBrace
->Next
&& LBrace
->Next
->is(tok::r_brace
)))) ||
5955 LBrace
->is(TT_ArrayInitializerLSquare
) || LBrace
->is(tok::less
))) {
5956 // If Left.ParameterCount is 0, then this submessage entry is not the
5957 // first in its parent submessage, and we want to break before this entry.
5958 // If Left.ParameterCount is greater than 0, then its parent submessage
5959 // might contain 1 or more entries and we want to break before this entry
5960 // if it contains at least 2 entries. We deal with this case later by
5961 // detecting and breaking before the next entry in the parent submessage.
5962 if (Left
.ParameterCount
== 0)
5964 // However, if this submessage is the first entry in its parent
5965 // submessage, Left.ParameterCount might be 1 in some cases.
5966 // We deal with this case later by detecting an entry
5967 // following a closing paren of this submessage.
5970 // If this is an entry immediately following a submessage, it will be
5971 // preceded by a closing paren of that submessage, like in:
5972 // left---. .---right
5974 // sub: { ... } key: value
5975 // If there was a comment between `}` an `key` above, then `key` would be
5976 // put on a new line anyways.
5977 if (Left
.isOneOf(tok::r_brace
, tok::greater
, tok::r_square
))
5984 bool TokenAnnotator::canBreakBefore(const AnnotatedLine
&Line
,
5985 const FormatToken
&Right
) const {
5986 const FormatToken
&Left
= *Right
.Previous
;
5987 // Language-specific stuff.
5988 if (Style
.isCSharp()) {
5989 if (Left
.isOneOf(TT_CSharpNamedArgumentColon
, TT_AttributeColon
) ||
5990 Right
.isOneOf(TT_CSharpNamedArgumentColon
, TT_AttributeColon
)) {
5993 // Only break after commas for generic type constraints.
5994 if (Line
.First
->is(TT_CSharpGenericTypeConstraint
))
5995 return Left
.is(TT_CSharpGenericTypeConstraintComma
);
5996 // Keep nullable operators attached to their identifiers.
5997 if (Right
.is(TT_CSharpNullable
))
5999 } else if (Style
.Language
== FormatStyle::LK_Java
) {
6000 if (Left
.isOneOf(Keywords
.kw_throws
, Keywords
.kw_extends
,
6001 Keywords
.kw_implements
)) {
6004 if (Right
.isOneOf(Keywords
.kw_throws
, Keywords
.kw_extends
,
6005 Keywords
.kw_implements
)) {
6008 } else if (Style
.isJavaScript()) {
6009 const FormatToken
*NonComment
= Right
.getPreviousNonComment();
6011 (NonComment
->isAccessSpecifierKeyword() ||
6012 NonComment
->isOneOf(
6013 tok::kw_return
, Keywords
.kw_yield
, tok::kw_continue
, tok::kw_break
,
6014 tok::kw_throw
, Keywords
.kw_interface
, Keywords
.kw_type
,
6015 tok::kw_static
, Keywords
.kw_readonly
, Keywords
.kw_override
,
6016 Keywords
.kw_abstract
, Keywords
.kw_get
, Keywords
.kw_set
,
6017 Keywords
.kw_async
, Keywords
.kw_await
))) {
6018 return false; // Otherwise automatic semicolon insertion would trigger.
6020 if (Right
.NestingLevel
== 0 &&
6021 (Left
.Tok
.getIdentifierInfo() ||
6022 Left
.isOneOf(tok::r_square
, tok::r_paren
)) &&
6023 Right
.isOneOf(tok::l_square
, tok::l_paren
)) {
6024 return false; // Otherwise automatic semicolon insertion would trigger.
6026 if (NonComment
&& NonComment
->is(tok::identifier
) &&
6027 NonComment
->TokenText
== "asserts") {
6030 if (Left
.is(TT_FatArrow
) && Right
.is(tok::l_brace
))
6032 if (Left
.is(TT_JsTypeColon
))
6034 // Don't wrap between ":" and "!" of a strict prop init ("field!: type;").
6035 if (Left
.is(tok::exclaim
) && Right
.is(tok::colon
))
6037 // Look for is type annotations like:
6038 // function f(): a is B { ... }
6039 // Do not break before is in these cases.
6040 if (Right
.is(Keywords
.kw_is
)) {
6041 const FormatToken
*Next
= Right
.getNextNonComment();
6042 // If `is` is followed by a colon, it's likely that it's a dict key, so
6043 // ignore it for this check.
6044 // For example this is common in Polymer:
6049 if (!Next
|| Next
->isNot(tok::colon
))
6052 if (Left
.is(Keywords
.kw_in
))
6053 return Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_None
;
6054 if (Right
.is(Keywords
.kw_in
))
6055 return Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_None
;
6056 if (Right
.is(Keywords
.kw_as
))
6057 return false; // must not break before as in 'x as type' casts
6058 if (Right
.isOneOf(Keywords
.kw_extends
, Keywords
.kw_infer
)) {
6059 // extends and infer can appear as keywords in conditional types:
6060 // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types
6061 // do not break before them, as the expressions are subject to ASI.
6064 if (Left
.is(Keywords
.kw_as
))
6066 if (Left
.is(TT_NonNullAssertion
))
6068 if (Left
.is(Keywords
.kw_declare
) &&
6069 Right
.isOneOf(Keywords
.kw_module
, tok::kw_namespace
,
6070 Keywords
.kw_function
, tok::kw_class
, tok::kw_enum
,
6071 Keywords
.kw_interface
, Keywords
.kw_type
, Keywords
.kw_var
,
6072 Keywords
.kw_let
, tok::kw_const
)) {
6073 // See grammar for 'declare' statements at:
6074 // https://github.com/Microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md#A.10
6077 if (Left
.isOneOf(Keywords
.kw_module
, tok::kw_namespace
) &&
6078 Right
.isOneOf(tok::identifier
, tok::string_literal
)) {
6079 return false; // must not break in "module foo { ...}"
6081 if (Right
.is(TT_TemplateString
) && Right
.closesScope())
6083 // Don't split tagged template literal so there is a break between the tag
6084 // identifier and template string.
6085 if (Left
.is(tok::identifier
) && Right
.is(TT_TemplateString
))
6087 if (Left
.is(TT_TemplateString
) && Left
.opensScope())
6089 } else if (Style
.isTableGen()) {
6090 // Avoid to break after "def", "class", "let" and so on.
6091 if (Keywords
.isTableGenDefinition(Left
))
6093 // Avoid to break after '(' in the cases that is in bang operators.
6094 if (Right
.is(tok::l_paren
)) {
6095 return !Left
.isOneOf(TT_TableGenBangOperator
, TT_TableGenCondOperator
,
6098 // Avoid to break between the value and its suffix part.
6099 if (Left
.is(TT_TableGenValueSuffix
))
6101 // Avoid to break around paste operator.
6102 if (Left
.is(tok::hash
) || Right
.is(tok::hash
))
6104 if (Left
.isOneOf(TT_TableGenBangOperator
, TT_TableGenCondOperator
))
6108 if (Left
.is(tok::at
))
6110 if (Left
.Tok
.getObjCKeywordID() == tok::objc_interface
)
6112 if (Left
.isOneOf(TT_JavaAnnotation
, TT_LeadingJavaAnnotation
))
6113 return Right
.isNot(tok::l_paren
);
6114 if (Right
.is(TT_PointerOrReference
)) {
6115 return Line
.IsMultiVariableDeclStmt
||
6116 (getTokenPointerOrReferenceAlignment(Right
) ==
6117 FormatStyle::PAS_Right
&&
6118 (!Right
.Next
|| Right
.Next
->isNot(TT_FunctionDeclarationName
)));
6120 if (Right
.isOneOf(TT_StartOfName
, TT_FunctionDeclarationName
) ||
6121 Right
.is(tok::kw_operator
)) {
6124 if (Left
.is(TT_PointerOrReference
))
6126 if (Right
.isTrailingComment()) {
6127 // We rely on MustBreakBefore being set correctly here as we should not
6128 // change the "binding" behavior of a comment.
6129 // The first comment in a braced lists is always interpreted as belonging to
6130 // the first list element. Otherwise, it should be placed outside of the
6132 return Left
.is(BK_BracedInit
) ||
6133 (Left
.is(TT_CtorInitializerColon
) && Right
.NewlinesBefore
> 0 &&
6134 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
);
6136 if (Left
.is(tok::question
) && Right
.is(tok::colon
))
6138 if (Right
.is(TT_ConditionalExpr
) || Right
.is(tok::question
))
6139 return Style
.BreakBeforeTernaryOperators
;
6140 if (Left
.is(TT_ConditionalExpr
) || Left
.is(tok::question
))
6141 return !Style
.BreakBeforeTernaryOperators
;
6142 if (Left
.is(TT_InheritanceColon
))
6143 return Style
.BreakInheritanceList
== FormatStyle::BILS_AfterColon
;
6144 if (Right
.is(TT_InheritanceColon
))
6145 return Style
.BreakInheritanceList
!= FormatStyle::BILS_AfterColon
;
6146 if (Right
.is(TT_ObjCMethodExpr
) && Right
.isNot(tok::r_square
) &&
6147 Left
.isNot(TT_SelectorName
)) {
6151 if (Right
.is(tok::colon
) &&
6152 !Right
.isOneOf(TT_CtorInitializerColon
, TT_InlineASMColon
)) {
6155 if (Left
.is(tok::colon
) && Left
.isOneOf(TT_DictLiteral
, TT_ObjCMethodExpr
)) {
6156 if (Style
.isProto()) {
6157 if (!Style
.AlwaysBreakBeforeMultilineStrings
&& Right
.isStringLiteral())
6159 // Prevent cases like:
6162 // { key: valueeeeeeeeeeee }
6164 // when the snippet does not fit into one line.
6168 // key: valueeeeeeeeeeee
6171 // instead, even if it is longer by one line.
6173 // Note that this allows the "{" to go over the column limit
6174 // when the column limit is just between ":" and "{", but that does
6175 // not happen too often and alternative formattings in this case are
6178 // The code covers the cases:
6180 // submessage: { ... }
6181 // submessage: < ... >
6182 // repeated: [ ... ]
6183 if (((Right
.is(tok::l_brace
) || Right
.is(tok::less
)) &&
6184 Right
.is(TT_DictLiteral
)) ||
6185 Right
.is(TT_ArrayInitializerLSquare
)) {
6191 if (Right
.is(tok::r_square
) && Right
.MatchingParen
&&
6192 Right
.MatchingParen
->is(TT_ProtoExtensionLSquare
)) {
6195 if (Right
.is(TT_SelectorName
) || (Right
.is(tok::identifier
) && Right
.Next
&&
6196 Right
.Next
->is(TT_ObjCMethodExpr
))) {
6197 return Left
.isNot(tok::period
); // FIXME: Properly parse ObjC calls.
6199 if (Left
.is(tok::r_paren
) && Line
.Type
== LT_ObjCProperty
)
6201 if (Right
.is(tok::kw_concept
))
6202 return Style
.BreakBeforeConceptDeclarations
!= FormatStyle::BBCDS_Never
;
6203 if (Right
.is(TT_RequiresClause
))
6205 if (Left
.ClosesTemplateDeclaration
) {
6206 return Style
.BreakTemplateDeclarations
!= FormatStyle::BTDS_Leave
||
6207 Right
.NewlinesBefore
> 0;
6209 if (Left
.is(TT_FunctionAnnotationRParen
))
6211 if (Left
.ClosesRequiresClause
)
6213 if (Right
.isOneOf(TT_RangeBasedForLoopColon
, TT_OverloadedOperatorLParen
,
6214 TT_OverloadedOperator
)) {
6217 if (Left
.is(TT_RangeBasedForLoopColon
))
6219 if (Right
.is(TT_RangeBasedForLoopColon
))
6221 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_TemplateOpener
))
6223 if ((Left
.is(tok::greater
) && Right
.is(tok::greater
)) ||
6224 (Left
.is(tok::less
) && Right
.is(tok::less
))) {
6227 if (Right
.is(TT_BinaryOperator
) &&
6228 Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_None
&&
6229 (Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_All
||
6230 Right
.getPrecedence() != prec::Assignment
)) {
6233 if (Left
.isOneOf(TT_TemplateCloser
, TT_UnaryOperator
) ||
6234 Left
.is(tok::kw_operator
)) {
6237 if (Left
.is(tok::equal
) && !Right
.isOneOf(tok::kw_default
, tok::kw_delete
) &&
6238 Line
.Type
== LT_VirtualFunctionDecl
&& Left
.NestingLevel
== 0) {
6241 if (Left
.is(tok::equal
) && Right
.is(tok::l_brace
) &&
6242 !Style
.Cpp11BracedListStyle
) {
6245 if (Left
.is(TT_AttributeLParen
) ||
6246 (Left
.is(tok::l_paren
) && Left
.is(TT_TypeDeclarationParen
))) {
6249 if (Left
.is(tok::l_paren
) && Left
.Previous
&&
6250 (Left
.Previous
->isOneOf(TT_BinaryOperator
, TT_CastRParen
))) {
6253 if (Right
.is(TT_ImplicitStringLiteral
))
6256 if (Right
.is(TT_TemplateCloser
))
6258 if (Right
.is(tok::r_square
) && Right
.MatchingParen
&&
6259 Right
.MatchingParen
->is(TT_LambdaLSquare
)) {
6263 // We only break before r_brace if there was a corresponding break before
6264 // the l_brace, which is tracked by BreakBeforeClosingBrace.
6265 if (Right
.is(tok::r_brace
)) {
6266 return Right
.MatchingParen
&& (Right
.MatchingParen
->is(BK_Block
) ||
6267 (Right
.isBlockIndentedInitRBrace(Style
)));
6270 // We only break before r_paren if we're in a block indented context.
6271 if (Right
.is(tok::r_paren
)) {
6272 if (Style
.AlignAfterOpenBracket
!= FormatStyle::BAS_BlockIndent
||
6273 !Right
.MatchingParen
) {
6276 auto Next
= Right
.Next
;
6277 if (Next
&& Next
->is(tok::r_paren
))
6279 if (Next
&& Next
->is(tok::l_paren
))
6281 const FormatToken
*Previous
= Right
.MatchingParen
->Previous
;
6282 return !(Previous
&& (Previous
->is(tok::kw_for
) || Previous
->isIf()));
6285 if (Left
.isOneOf(tok::r_paren
, TT_TrailingAnnotation
) &&
6286 Right
.is(TT_TrailingAnnotation
) &&
6287 Style
.AlignAfterOpenBracket
== FormatStyle::BAS_BlockIndent
) {
6291 // Allow breaking after a trailing annotation, e.g. after a method
6293 if (Left
.is(TT_TrailingAnnotation
)) {
6294 return !Right
.isOneOf(tok::l_brace
, tok::semi
, tok::equal
, tok::l_paren
,
6295 tok::less
, tok::coloncolon
);
6298 if (Right
.isAttribute())
6301 if (Right
.is(tok::l_square
) && Right
.is(TT_AttributeSquare
))
6302 return Left
.isNot(TT_AttributeSquare
);
6304 if (Left
.is(tok::identifier
) && Right
.is(tok::string_literal
))
6307 if (Right
.is(tok::identifier
) && Right
.Next
&& Right
.Next
->is(TT_DictLiteral
))
6310 if (Left
.is(TT_CtorInitializerColon
)) {
6311 return Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
&&
6312 (!Right
.isTrailingComment() || Right
.NewlinesBefore
> 0);
6314 if (Right
.is(TT_CtorInitializerColon
))
6315 return Style
.BreakConstructorInitializers
!= FormatStyle::BCIS_AfterColon
;
6316 if (Left
.is(TT_CtorInitializerComma
) &&
6317 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
) {
6320 if (Right
.is(TT_CtorInitializerComma
) &&
6321 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
) {
6324 if (Left
.is(TT_InheritanceComma
) &&
6325 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
) {
6328 if (Right
.is(TT_InheritanceComma
) &&
6329 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
) {
6332 if (Left
.is(TT_ArrayInitializerLSquare
))
6334 if (Right
.is(tok::kw_typename
) && Left
.isNot(tok::kw_const
))
6336 if ((Left
.isBinaryOperator() || Left
.is(TT_BinaryOperator
)) &&
6337 !Left
.isOneOf(tok::arrowstar
, tok::lessless
) &&
6338 Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_All
&&
6339 (Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_None
||
6340 Left
.getPrecedence() == prec::Assignment
)) {
6343 if ((Left
.is(TT_AttributeSquare
) && Right
.is(tok::l_square
)) ||
6344 (Left
.is(tok::r_square
) && Right
.is(TT_AttributeSquare
))) {
6348 auto ShortLambdaOption
= Style
.AllowShortLambdasOnASingleLine
;
6349 if (Style
.BraceWrapping
.BeforeLambdaBody
&& Right
.is(TT_LambdaLBrace
)) {
6350 if (isAllmanLambdaBrace(Left
))
6351 return !isItAnEmptyLambdaAllowed(Left
, ShortLambdaOption
);
6352 if (isAllmanLambdaBrace(Right
))
6353 return !isItAnEmptyLambdaAllowed(Right
, ShortLambdaOption
);
6356 if (Right
.is(tok::kw_noexcept
) && Right
.is(TT_TrailingAnnotation
)) {
6357 switch (Style
.AllowBreakBeforeNoexceptSpecifier
) {
6358 case FormatStyle::BBNSS_Never
:
6360 case FormatStyle::BBNSS_Always
:
6362 case FormatStyle::BBNSS_OnlyWithParen
:
6363 return Right
.Next
&& Right
.Next
->is(tok::l_paren
);
6367 return Left
.isOneOf(tok::comma
, tok::coloncolon
, tok::semi
, tok::l_brace
,
6368 tok::kw_class
, tok::kw_struct
, tok::comment
) ||
6369 Right
.isMemberAccess() ||
6370 Right
.isOneOf(TT_TrailingReturnArrow
, TT_LambdaArrow
, tok::lessless
,
6371 tok::colon
, tok::l_square
, tok::at
) ||
6372 (Left
.is(tok::r_paren
) &&
6373 Right
.isOneOf(tok::identifier
, tok::kw_const
)) ||
6374 (Left
.is(tok::l_paren
) && Right
.isNot(tok::r_paren
)) ||
6375 (Left
.is(TT_TemplateOpener
) && Right
.isNot(TT_TemplateCloser
));
6378 void TokenAnnotator::printDebugInfo(const AnnotatedLine
&Line
) const {
6379 llvm::errs() << "AnnotatedTokens(L=" << Line
.Level
<< ", P=" << Line
.PPLevel
6380 << ", T=" << Line
.Type
<< ", C=" << Line
.IsContinuation
6382 const FormatToken
*Tok
= Line
.First
;
6384 llvm::errs() << " M=" << Tok
->MustBreakBefore
6385 << " C=" << Tok
->CanBreakBefore
6386 << " T=" << getTokenTypeName(Tok
->getType())
6387 << " S=" << Tok
->SpacesRequiredBefore
6388 << " F=" << Tok
->Finalized
<< " B=" << Tok
->BlockParameterCount
6389 << " BK=" << Tok
->getBlockKind() << " P=" << Tok
->SplitPenalty
6390 << " Name=" << Tok
->Tok
.getName() << " L=" << Tok
->TotalLength
6391 << " PPK=" << Tok
->getPackingKind() << " FakeLParens=";
6392 for (prec::Level LParen
: Tok
->FakeLParens
)
6393 llvm::errs() << LParen
<< "/";
6394 llvm::errs() << " FakeRParens=" << Tok
->FakeRParens
;
6395 llvm::errs() << " II=" << Tok
->Tok
.getIdentifierInfo();
6396 llvm::errs() << " Text='" << Tok
->TokenText
<< "'\n";
6398 assert(Tok
== Line
.Last
);
6401 llvm::errs() << "----\n";
6404 FormatStyle::PointerAlignmentStyle
6405 TokenAnnotator::getTokenReferenceAlignment(const FormatToken
&Reference
) const {
6406 assert(Reference
.isOneOf(tok::amp
, tok::ampamp
));
6407 switch (Style
.ReferenceAlignment
) {
6408 case FormatStyle::RAS_Pointer
:
6409 return Style
.PointerAlignment
;
6410 case FormatStyle::RAS_Left
:
6411 return FormatStyle::PAS_Left
;
6412 case FormatStyle::RAS_Right
:
6413 return FormatStyle::PAS_Right
;
6414 case FormatStyle::RAS_Middle
:
6415 return FormatStyle::PAS_Middle
;
6417 assert(0); //"Unhandled value of ReferenceAlignment"
6418 return Style
.PointerAlignment
;
6421 FormatStyle::PointerAlignmentStyle
6422 TokenAnnotator::getTokenPointerOrReferenceAlignment(
6423 const FormatToken
&PointerOrReference
) const {
6424 if (PointerOrReference
.isOneOf(tok::amp
, tok::ampamp
)) {
6425 switch (Style
.ReferenceAlignment
) {
6426 case FormatStyle::RAS_Pointer
:
6427 return Style
.PointerAlignment
;
6428 case FormatStyle::RAS_Left
:
6429 return FormatStyle::PAS_Left
;
6430 case FormatStyle::RAS_Right
:
6431 return FormatStyle::PAS_Right
;
6432 case FormatStyle::RAS_Middle
:
6433 return FormatStyle::PAS_Middle
;
6436 assert(PointerOrReference
.is(tok::star
));
6437 return Style
.PointerAlignment
;
6440 } // namespace format
6441 } // namespace clang