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 static bool isLambdaParameterList(const FormatToken
*Left
) {
66 // Skip <...> if present.
67 if (Left
->Previous
&& Left
->Previous
->is(tok::greater
) &&
68 Left
->Previous
->MatchingParen
&&
69 Left
->Previous
->MatchingParen
->is(TT_TemplateOpener
)) {
70 Left
= Left
->Previous
->MatchingParen
;
74 return Left
->Previous
&& Left
->Previous
->is(tok::r_square
) &&
75 Left
->Previous
->MatchingParen
&&
76 Left
->Previous
->MatchingParen
->is(TT_LambdaLSquare
);
79 /// Returns \c true if the token is followed by a boolean condition, \c false
81 static bool isKeywordWithCondition(const FormatToken
&Tok
) {
82 return Tok
.isOneOf(tok::kw_if
, tok::kw_for
, tok::kw_while
, tok::kw_switch
,
83 tok::kw_constexpr
, tok::kw_catch
);
86 /// Returns \c true if the token starts a C++ attribute, \c false otherwise.
87 static bool isCppAttribute(bool IsCpp
, const FormatToken
&Tok
) {
88 if (!IsCpp
|| !Tok
.startsSequence(tok::l_square
, tok::l_square
))
90 // The first square bracket is part of an ObjC array literal
91 if (Tok
.Previous
&& Tok
.Previous
->is(tok::at
))
93 const FormatToken
*AttrTok
= Tok
.Next
->Next
;
96 // C++17 '[[using ns: foo, bar(baz, blech)]]'
97 // We assume nobody will name an ObjC variable 'using'.
98 if (AttrTok
->startsSequence(tok::kw_using
, tok::identifier
, tok::colon
))
100 if (AttrTok
->isNot(tok::identifier
))
102 while (AttrTok
&& !AttrTok
->startsSequence(tok::r_square
, tok::r_square
)) {
103 // ObjC message send. We assume nobody will use : in a C++11 attribute
104 // specifier parameter, although this is technically valid:
106 if (AttrTok
->is(tok::colon
) ||
107 AttrTok
->startsSequence(tok::identifier
, tok::identifier
) ||
108 AttrTok
->startsSequence(tok::r_paren
, tok::identifier
)) {
111 if (AttrTok
->is(tok::ellipsis
))
113 AttrTok
= AttrTok
->Next
;
115 return AttrTok
&& AttrTok
->startsSequence(tok::r_square
, tok::r_square
);
118 /// A parser that gathers additional information about tokens.
120 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
121 /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
122 /// into template parameter lists.
123 class AnnotatingParser
{
125 AnnotatingParser(const FormatStyle
&Style
, AnnotatedLine
&Line
,
126 const AdditionalKeywords
&Keywords
,
127 SmallVector
<ScopeType
> &Scopes
)
128 : Style(Style
), Line(Line
), CurrentToken(Line
.First
), AutoFound(false),
129 Keywords(Keywords
), Scopes(Scopes
) {
130 Contexts
.push_back(Context(tok::unknown
, 1, /*IsExpression=*/false));
131 resetTokenMetadata();
135 ScopeType
getScopeType(const FormatToken
&Token
) const {
136 switch (Token
.getType()) {
137 case TT_FunctionLBrace
:
138 case TT_LambdaLBrace
:
141 case TT_StructLBrace
:
150 if (!CurrentToken
|| !CurrentToken
->Previous
)
152 if (NonTemplateLess
.count(CurrentToken
->Previous
) > 0)
155 const FormatToken
&Previous
= *CurrentToken
->Previous
; // The '<'.
156 if (Previous
.Previous
) {
157 if (Previous
.Previous
->Tok
.isLiteral())
159 if (Previous
.Previous
->is(tok::r_brace
))
161 if (Previous
.Previous
->is(tok::r_paren
) && Contexts
.size() > 1 &&
162 (!Previous
.Previous
->MatchingParen
||
163 Previous
.Previous
->MatchingParen
->isNot(
164 TT_OverloadedOperatorLParen
))) {
167 if (Previous
.Previous
->is(tok::kw_operator
) &&
168 CurrentToken
->is(tok::l_paren
)) {
173 FormatToken
*Left
= CurrentToken
->Previous
;
174 Left
->ParentBracket
= Contexts
.back().ContextKind
;
175 ScopedContextCreator
ContextCreator(*this, tok::less
, 12);
177 // If this angle is in the context of an expression, we need to be more
178 // hesitant to detect it as opening template parameters.
179 bool InExprContext
= Contexts
.back().IsExpression
;
181 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 (Left
->Previous
&& Left
->Previous
->isNot(tok::kw_template
))
185 Contexts
.back().ContextType
= Context::TemplateArgument
;
187 if (Style
.Language
== FormatStyle::LK_Java
&&
188 CurrentToken
->is(tok::question
)) {
192 while (CurrentToken
) {
193 if (CurrentToken
->is(tok::greater
)) {
194 // Try to do a better job at looking for ">>" within the condition of
195 // a statement. Conservatively insert spaces between consecutive ">"
196 // tokens to prevent splitting right bitshift operators and potentially
197 // altering program semantics. This check is overly conservative and
198 // will prevent spaces from being inserted in select nested template
199 // parameter cases, but should not alter program semantics.
200 if (CurrentToken
->Next
&& CurrentToken
->Next
->is(tok::greater
) &&
201 Left
->ParentBracket
!= tok::less
&&
202 CurrentToken
->getStartOfNonWhitespace() ==
203 CurrentToken
->Next
->getStartOfNonWhitespace().getLocWithOffset(
207 Left
->MatchingParen
= CurrentToken
;
208 CurrentToken
->MatchingParen
= Left
;
209 // In TT_Proto, we must distignuish between:
211 // msg < item: data >
212 // msg: < item: data >
213 // In TT_TextProto, map<key, value> does not occur.
214 if (Style
.Language
== FormatStyle::LK_TextProto
||
215 (Style
.Language
== FormatStyle::LK_Proto
&& Left
->Previous
&&
216 Left
->Previous
->isOneOf(TT_SelectorName
, TT_DictLiteral
))) {
217 CurrentToken
->setType(TT_DictLiteral
);
219 CurrentToken
->setType(TT_TemplateCloser
);
220 CurrentToken
->Tok
.setLength(1);
222 if (CurrentToken
->Next
&& CurrentToken
->Next
->Tok
.isLiteral())
227 if (CurrentToken
->is(tok::question
) &&
228 Style
.Language
== FormatStyle::LK_Java
) {
232 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::r_brace
) ||
233 (CurrentToken
->isOneOf(tok::colon
, tok::question
) && InExprContext
&&
234 !Style
.isCSharp() && !Style
.isProto())) {
237 // If a && or || is found and interpreted as a binary operator, this set
238 // of angles is likely part of something like "a < b && c > d". If the
239 // angles are inside an expression, the ||/&& might also be a binary
240 // operator that was misinterpreted because we are parsing template
242 // FIXME: This is getting out of hand, write a decent parser.
243 if (CurrentToken
->Previous
->isOneOf(tok::pipepipe
, tok::ampamp
) &&
244 CurrentToken
->Previous
->is(TT_BinaryOperator
) &&
245 Contexts
[Contexts
.size() - 2].IsExpression
&&
246 !Line
.startsWith(tok::kw_template
)) {
249 updateParameterCount(Left
, CurrentToken
);
250 if (Style
.Language
== FormatStyle::LK_Proto
) {
251 if (FormatToken
*Previous
= CurrentToken
->getPreviousNonComment()) {
252 if (CurrentToken
->is(tok::colon
) ||
253 (CurrentToken
->isOneOf(tok::l_brace
, tok::less
) &&
254 Previous
->isNot(tok::colon
))) {
255 Previous
->setType(TT_SelectorName
);
265 bool parseUntouchableParens() {
266 while (CurrentToken
) {
267 CurrentToken
->Finalized
= true;
268 switch (CurrentToken
->Tok
.getKind()) {
271 if (!parseUntouchableParens())
286 bool parseParens(bool LookForDecls
= false) {
289 assert(CurrentToken
->Previous
&& "Unknown previous token");
290 FormatToken
&OpeningParen
= *CurrentToken
->Previous
;
291 assert(OpeningParen
.is(tok::l_paren
));
292 FormatToken
*PrevNonComment
= OpeningParen
.getPreviousNonComment();
293 OpeningParen
.ParentBracket
= Contexts
.back().ContextKind
;
294 ScopedContextCreator
ContextCreator(*this, tok::l_paren
, 1);
296 // FIXME: This is a bit of a hack. Do better.
297 Contexts
.back().ColonIsForRangeExpr
=
298 Contexts
.size() == 2 && Contexts
[0].ColonIsForRangeExpr
;
300 if (OpeningParen
.Previous
&&
301 OpeningParen
.Previous
->is(TT_UntouchableMacroFunc
)) {
302 OpeningParen
.Finalized
= true;
303 return parseUntouchableParens();
306 bool StartsObjCMethodExpr
= false;
307 if (!Style
.isVerilog()) {
308 if (FormatToken
*MaybeSel
= OpeningParen
.Previous
) {
309 // @selector( starts a selector.
310 if (MaybeSel
->isObjCAtKeyword(tok::objc_selector
) &&
311 MaybeSel
->Previous
&& MaybeSel
->Previous
->is(tok::at
)) {
312 StartsObjCMethodExpr
= true;
317 if (OpeningParen
.is(TT_OverloadedOperatorLParen
)) {
318 // Find the previous kw_operator token.
319 FormatToken
*Prev
= &OpeningParen
;
320 while (Prev
->isNot(tok::kw_operator
)) {
321 Prev
= Prev
->Previous
;
322 assert(Prev
&& "Expect a kw_operator prior to the OperatorLParen!");
325 // If faced with "a.operator*(argument)" or "a->operator*(argument)",
326 // i.e. the operator is called as a member function,
327 // then the argument must be an expression.
328 bool OperatorCalledAsMemberFunction
=
329 Prev
->Previous
&& Prev
->Previous
->isOneOf(tok::period
, tok::arrow
);
330 Contexts
.back().IsExpression
= OperatorCalledAsMemberFunction
;
331 } else if (OpeningParen
.is(TT_VerilogInstancePortLParen
)) {
332 Contexts
.back().IsExpression
= true;
333 Contexts
.back().ContextType
= Context::VerilogInstancePortList
;
334 } else if (Style
.isJavaScript() &&
335 (Line
.startsWith(Keywords
.kw_type
, tok::identifier
) ||
336 Line
.startsWith(tok::kw_export
, Keywords
.kw_type
,
339 // export type X = (...);
340 Contexts
.back().IsExpression
= false;
341 } else if (OpeningParen
.Previous
&&
342 (OpeningParen
.Previous
->isOneOf(
343 tok::kw_static_assert
, tok::kw_noexcept
, tok::kw_explicit
,
344 tok::kw_while
, tok::l_paren
, tok::comma
,
345 TT_BinaryOperator
) ||
346 OpeningParen
.Previous
->isIf())) {
347 // static_assert, if and while usually contain expressions.
348 Contexts
.back().IsExpression
= true;
349 } else if (Style
.isJavaScript() && OpeningParen
.Previous
&&
350 (OpeningParen
.Previous
->is(Keywords
.kw_function
) ||
351 (OpeningParen
.Previous
->endsSequence(tok::identifier
,
352 Keywords
.kw_function
)))) {
353 // function(...) or function f(...)
354 Contexts
.back().IsExpression
= false;
355 } else if (Style
.isJavaScript() && OpeningParen
.Previous
&&
356 OpeningParen
.Previous
->is(TT_JsTypeColon
)) {
357 // let x: (SomeType);
358 Contexts
.back().IsExpression
= false;
359 } else if (isLambdaParameterList(&OpeningParen
)) {
360 // This is a parameter list of a lambda expression.
361 Contexts
.back().IsExpression
= false;
362 } else if (OpeningParen
.is(TT_RequiresExpressionLParen
)) {
363 Contexts
.back().IsExpression
= false;
364 } else if (OpeningParen
.Previous
&&
365 OpeningParen
.Previous
->is(tok::kw__Generic
)) {
366 Contexts
.back().ContextType
= Context::C11GenericSelection
;
367 Contexts
.back().IsExpression
= true;
368 } else if (Line
.InPPDirective
&&
369 (!OpeningParen
.Previous
||
370 OpeningParen
.Previous
->isNot(tok::identifier
))) {
371 Contexts
.back().IsExpression
= true;
372 } else if (Contexts
[Contexts
.size() - 2].CaretFound
) {
373 // This is the parameter list of an ObjC block.
374 Contexts
.back().IsExpression
= false;
375 } else if (OpeningParen
.Previous
&&
376 OpeningParen
.Previous
->is(TT_ForEachMacro
)) {
377 // The first argument to a foreach macro is a declaration.
378 Contexts
.back().ContextType
= Context::ForEachMacro
;
379 Contexts
.back().IsExpression
= false;
380 } else if (OpeningParen
.Previous
&& OpeningParen
.Previous
->MatchingParen
&&
381 OpeningParen
.Previous
->MatchingParen
->isOneOf(
382 TT_ObjCBlockLParen
, TT_FunctionTypeLParen
)) {
383 Contexts
.back().IsExpression
= false;
384 } else if (!Line
.MustBeDeclaration
&& !Line
.InPPDirective
) {
386 OpeningParen
.Previous
&&
387 OpeningParen
.Previous
->isOneOf(tok::kw_for
, tok::kw_catch
);
388 Contexts
.back().IsExpression
= !IsForOrCatch
;
391 // Infer the role of the l_paren based on the previous token if we haven't
393 if (PrevNonComment
&& OpeningParen
.is(TT_Unknown
)) {
394 if (PrevNonComment
->isAttribute()) {
395 OpeningParen
.setType(TT_AttributeLParen
);
396 } else if (PrevNonComment
->isOneOf(TT_TypenameMacro
, tok::kw_decltype
,
398 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,
399 #include "clang/Basic/TransformTypeTraits.def"
401 OpeningParen
.setType(TT_TypeDeclarationParen
);
402 // decltype() and typeof() usually contain expressions.
403 if (PrevNonComment
->isOneOf(tok::kw_decltype
, tok::kw_typeof
))
404 Contexts
.back().IsExpression
= true;
408 if (StartsObjCMethodExpr
) {
409 Contexts
.back().ColonIsObjCMethodExpr
= true;
410 OpeningParen
.setType(TT_ObjCMethodExpr
);
413 // MightBeFunctionType and ProbablyFunctionType are used for
414 // function pointer and reference types as well as Objective-C
417 // void (*FunctionPointer)(void);
418 // void (&FunctionReference)(void);
419 // void (&&FunctionReference)(void);
420 // void (^ObjCBlock)(void);
421 bool MightBeFunctionType
= !Contexts
[Contexts
.size() - 2].IsExpression
;
422 bool ProbablyFunctionType
=
423 CurrentToken
->isPointerOrReference() || CurrentToken
->is(tok::caret
);
424 bool HasMultipleLines
= false;
425 bool HasMultipleParametersOnALine
= false;
426 bool MightBeObjCForRangeLoop
=
427 OpeningParen
.Previous
&& OpeningParen
.Previous
->is(tok::kw_for
);
428 FormatToken
*PossibleObjCForInToken
= nullptr;
429 while (CurrentToken
) {
430 // LookForDecls is set when "if (" has been seen. Check for
431 // 'identifier' '*' 'identifier' followed by not '=' -- this
432 // '*' has to be a binary operator but determineStarAmpUsage() will
433 // categorize it as an unary operator, so set the right type here.
434 if (LookForDecls
&& CurrentToken
->Next
) {
435 FormatToken
*Prev
= CurrentToken
->getPreviousNonComment();
437 FormatToken
*PrevPrev
= Prev
->getPreviousNonComment();
438 FormatToken
*Next
= CurrentToken
->Next
;
439 if (PrevPrev
&& PrevPrev
->is(tok::identifier
) &&
440 PrevPrev
->isNot(TT_TypeName
) && Prev
->isPointerOrReference() &&
441 CurrentToken
->is(tok::identifier
) && Next
->isNot(tok::equal
)) {
442 Prev
->setType(TT_BinaryOperator
);
443 LookForDecls
= false;
448 if (CurrentToken
->Previous
->is(TT_PointerOrReference
) &&
449 CurrentToken
->Previous
->Previous
->isOneOf(tok::l_paren
,
451 ProbablyFunctionType
= true;
453 if (CurrentToken
->is(tok::comma
))
454 MightBeFunctionType
= false;
455 if (CurrentToken
->Previous
->is(TT_BinaryOperator
))
456 Contexts
.back().IsExpression
= true;
457 if (CurrentToken
->is(tok::r_paren
)) {
458 if (OpeningParen
.isNot(TT_CppCastLParen
) && MightBeFunctionType
&&
459 ProbablyFunctionType
&& CurrentToken
->Next
&&
460 (CurrentToken
->Next
->is(tok::l_paren
) ||
461 (CurrentToken
->Next
->is(tok::l_square
) &&
462 Line
.MustBeDeclaration
))) {
463 OpeningParen
.setType(OpeningParen
.Next
->is(tok::caret
)
465 : TT_FunctionTypeLParen
);
467 OpeningParen
.MatchingParen
= CurrentToken
;
468 CurrentToken
->MatchingParen
= &OpeningParen
;
470 if (CurrentToken
->Next
&& CurrentToken
->Next
->is(tok::l_brace
) &&
471 OpeningParen
.Previous
&& OpeningParen
.Previous
->is(tok::l_paren
)) {
472 // Detect the case where macros are used to generate lambdas or
473 // function bodies, e.g.:
474 // auto my_lambda = MACRO((Type *type, int i) { .. body .. });
475 for (FormatToken
*Tok
= &OpeningParen
; Tok
!= CurrentToken
;
477 if (Tok
->is(TT_BinaryOperator
) && Tok
->isPointerOrReference())
478 Tok
->setType(TT_PointerOrReference
);
482 if (StartsObjCMethodExpr
) {
483 CurrentToken
->setType(TT_ObjCMethodExpr
);
484 if (Contexts
.back().FirstObjCSelectorName
) {
485 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
486 Contexts
.back().LongestObjCSelectorName
;
490 if (OpeningParen
.is(TT_AttributeLParen
))
491 CurrentToken
->setType(TT_AttributeRParen
);
492 if (OpeningParen
.is(TT_TypeDeclarationParen
))
493 CurrentToken
->setType(TT_TypeDeclarationParen
);
494 if (OpeningParen
.Previous
&&
495 OpeningParen
.Previous
->is(TT_JavaAnnotation
)) {
496 CurrentToken
->setType(TT_JavaAnnotation
);
498 if (OpeningParen
.Previous
&&
499 OpeningParen
.Previous
->is(TT_LeadingJavaAnnotation
)) {
500 CurrentToken
->setType(TT_LeadingJavaAnnotation
);
502 if (OpeningParen
.Previous
&&
503 OpeningParen
.Previous
->is(TT_AttributeSquare
)) {
504 CurrentToken
->setType(TT_AttributeSquare
);
507 if (!HasMultipleLines
)
508 OpeningParen
.setPackingKind(PPK_Inconclusive
);
509 else if (HasMultipleParametersOnALine
)
510 OpeningParen
.setPackingKind(PPK_BinPacked
);
512 OpeningParen
.setPackingKind(PPK_OnePerLine
);
517 if (CurrentToken
->isOneOf(tok::r_square
, tok::r_brace
))
520 if (CurrentToken
->is(tok::l_brace
) && OpeningParen
.is(TT_ObjCBlockLParen
))
521 OpeningParen
.setType(TT_Unknown
);
522 if (CurrentToken
->is(tok::comma
) && CurrentToken
->Next
&&
523 !CurrentToken
->Next
->HasUnescapedNewline
&&
524 !CurrentToken
->Next
->isTrailingComment()) {
525 HasMultipleParametersOnALine
= true;
527 bool ProbablyFunctionTypeLParen
=
528 (CurrentToken
->is(tok::l_paren
) && CurrentToken
->Next
&&
529 CurrentToken
->Next
->isOneOf(tok::star
, tok::amp
, tok::caret
));
530 if ((CurrentToken
->Previous
->isOneOf(tok::kw_const
, tok::kw_auto
) ||
531 CurrentToken
->Previous
->isSimpleTypeSpecifier()) &&
532 !(CurrentToken
->is(tok::l_brace
) ||
533 (CurrentToken
->is(tok::l_paren
) && !ProbablyFunctionTypeLParen
))) {
534 Contexts
.back().IsExpression
= false;
536 if (CurrentToken
->isOneOf(tok::semi
, tok::colon
)) {
537 MightBeObjCForRangeLoop
= false;
538 if (PossibleObjCForInToken
) {
539 PossibleObjCForInToken
->setType(TT_Unknown
);
540 PossibleObjCForInToken
= nullptr;
543 if (MightBeObjCForRangeLoop
&& CurrentToken
->is(Keywords
.kw_in
)) {
544 PossibleObjCForInToken
= CurrentToken
;
545 PossibleObjCForInToken
->setType(TT_ObjCForIn
);
547 // When we discover a 'new', we set CanBeExpression to 'false' in order to
548 // parse the type correctly. Reset that after a comma.
549 if (CurrentToken
->is(tok::comma
))
550 Contexts
.back().CanBeExpression
= true;
552 FormatToken
*Tok
= CurrentToken
;
555 updateParameterCount(&OpeningParen
, Tok
);
556 if (CurrentToken
&& CurrentToken
->HasUnescapedNewline
)
557 HasMultipleLines
= true;
562 bool isCSharpAttributeSpecifier(const FormatToken
&Tok
) {
563 if (!Style
.isCSharp())
566 // `identifier[i]` is not an attribute.
567 if (Tok
.Previous
&& Tok
.Previous
->is(tok::identifier
))
570 // Chains of [] in `identifier[i][j][k]` are not attributes.
571 if (Tok
.Previous
&& Tok
.Previous
->is(tok::r_square
)) {
572 auto *MatchingParen
= Tok
.Previous
->MatchingParen
;
573 if (!MatchingParen
|| MatchingParen
->is(TT_ArraySubscriptLSquare
))
577 const FormatToken
*AttrTok
= Tok
.Next
;
581 // Just an empty declaration e.g. string [].
582 if (AttrTok
->is(tok::r_square
))
585 // Move along the tokens inbetween the '[' and ']' e.g. [STAThread].
586 while (AttrTok
&& AttrTok
->isNot(tok::r_square
))
587 AttrTok
= AttrTok
->Next
;
592 // Allow an attribute to be the only content of a file.
593 AttrTok
= AttrTok
->Next
;
597 // Limit this to being an access modifier that follows.
598 if (AttrTok
->isOneOf(tok::kw_public
, tok::kw_private
, tok::kw_protected
,
599 tok::comment
, tok::kw_class
, tok::kw_static
,
600 tok::l_square
, Keywords
.kw_internal
)) {
604 // incase its a [XXX] retval func(....
606 AttrTok
->Next
->startsSequence(tok::identifier
, tok::l_paren
)) {
617 // A '[' could be an index subscript (after an identifier or after
618 // ')' or ']'), it could be the start of an Objective-C method
619 // expression, it could the start of an Objective-C array literal,
620 // or it could be a C++ attribute specifier [[foo::bar]].
621 FormatToken
*Left
= CurrentToken
->Previous
;
622 Left
->ParentBracket
= Contexts
.back().ContextKind
;
623 FormatToken
*Parent
= Left
->getPreviousNonComment();
625 // Cases where '>' is followed by '['.
626 // In C++, this can happen either in array of templates (foo<int>[10])
627 // or when array is a nested template type (unique_ptr<type1<type2>[]>).
628 bool CppArrayTemplates
=
629 Style
.isCpp() && Parent
&& Parent
->is(TT_TemplateCloser
) &&
630 (Contexts
.back().CanBeExpression
|| Contexts
.back().IsExpression
||
631 Contexts
.back().ContextType
== Context::TemplateArgument
);
633 const bool IsInnerSquare
= Contexts
.back().InCpp11AttributeSpecifier
;
634 const bool IsCpp11AttributeSpecifier
=
635 isCppAttribute(Style
.isCpp(), *Left
) || IsInnerSquare
;
637 // Treat C# Attributes [STAThread] much like C++ attributes [[...]].
638 bool IsCSharpAttributeSpecifier
=
639 isCSharpAttributeSpecifier(*Left
) ||
640 Contexts
.back().InCSharpAttributeSpecifier
;
642 bool InsideInlineASM
= Line
.startsWith(tok::kw_asm
);
643 bool IsCppStructuredBinding
= Left
->isCppStructuredBinding(Style
);
644 bool StartsObjCMethodExpr
=
645 !IsCppStructuredBinding
&& !InsideInlineASM
&& !CppArrayTemplates
&&
646 Style
.isCpp() && !IsCpp11AttributeSpecifier
&&
647 !IsCSharpAttributeSpecifier
&& Contexts
.back().CanBeExpression
&&
648 Left
->isNot(TT_LambdaLSquare
) &&
649 !CurrentToken
->isOneOf(tok::l_brace
, tok::r_square
) &&
651 Parent
->isOneOf(tok::colon
, tok::l_square
, tok::l_paren
,
652 tok::kw_return
, tok::kw_throw
) ||
653 Parent
->isUnaryOperator() ||
654 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
655 Parent
->isOneOf(TT_ObjCForIn
, TT_CastRParen
) ||
656 (getBinOpPrecedence(Parent
->Tok
.getKind(), true, true) >
658 bool ColonFound
= false;
660 unsigned BindingIncrease
= 1;
661 if (IsCppStructuredBinding
) {
662 Left
->setType(TT_StructuredBindingLSquare
);
663 } else if (Left
->is(TT_Unknown
)) {
664 if (StartsObjCMethodExpr
) {
665 Left
->setType(TT_ObjCMethodExpr
);
666 } else if (InsideInlineASM
) {
667 Left
->setType(TT_InlineASMSymbolicNameLSquare
);
668 } else if (IsCpp11AttributeSpecifier
) {
669 Left
->setType(TT_AttributeSquare
);
670 if (!IsInnerSquare
&& Left
->Previous
)
671 Left
->Previous
->EndsCppAttributeGroup
= false;
672 } else if (Style
.isJavaScript() && Parent
&&
673 Contexts
.back().ContextKind
== tok::l_brace
&&
674 Parent
->isOneOf(tok::l_brace
, tok::comma
)) {
675 Left
->setType(TT_JsComputedPropertyName
);
676 } else if (Style
.isCpp() && Contexts
.back().ContextKind
== tok::l_brace
&&
677 Parent
&& Parent
->isOneOf(tok::l_brace
, tok::comma
)) {
678 Left
->setType(TT_DesignatedInitializerLSquare
);
679 } else if (IsCSharpAttributeSpecifier
) {
680 Left
->setType(TT_AttributeSquare
);
681 } else if (CurrentToken
->is(tok::r_square
) && Parent
&&
682 Parent
->is(TT_TemplateCloser
)) {
683 Left
->setType(TT_ArraySubscriptLSquare
);
684 } else if (Style
.isProto()) {
685 // Square braces in LK_Proto can either be message field attributes:
687 // optional Aaa aaa = 1 [
695 // or text proto extensions (in options):
697 // option (Aaa.options) = {
698 // [type.type/type] {
703 // or repeated fields (in options):
705 // option (Aaa.options) = {
709 // In the first and the third case we want to spread the contents inside
710 // the square braces; in the second we want to keep them inline.
711 Left
->setType(TT_ArrayInitializerLSquare
);
712 if (!Left
->endsSequence(tok::l_square
, tok::numeric_constant
,
714 !Left
->endsSequence(tok::l_square
, tok::numeric_constant
,
716 !Left
->endsSequence(tok::l_square
, tok::colon
, TT_SelectorName
)) {
717 Left
->setType(TT_ProtoExtensionLSquare
);
718 BindingIncrease
= 10;
720 } else if (!CppArrayTemplates
&& Parent
&&
721 Parent
->isOneOf(TT_BinaryOperator
, TT_TemplateCloser
, tok::at
,
722 tok::comma
, tok::l_paren
, tok::l_square
,
723 tok::question
, tok::colon
, tok::kw_return
,
724 // Should only be relevant to JavaScript:
726 Left
->setType(TT_ArrayInitializerLSquare
);
728 BindingIncrease
= 10;
729 Left
->setType(TT_ArraySubscriptLSquare
);
733 ScopedContextCreator
ContextCreator(*this, tok::l_square
, BindingIncrease
);
734 Contexts
.back().IsExpression
= true;
735 if (Style
.isJavaScript() && Parent
&& Parent
->is(TT_JsTypeColon
))
736 Contexts
.back().IsExpression
= false;
738 Contexts
.back().ColonIsObjCMethodExpr
= StartsObjCMethodExpr
;
739 Contexts
.back().InCpp11AttributeSpecifier
= IsCpp11AttributeSpecifier
;
740 Contexts
.back().InCSharpAttributeSpecifier
= IsCSharpAttributeSpecifier
;
742 while (CurrentToken
) {
743 if (CurrentToken
->is(tok::r_square
)) {
744 if (IsCpp11AttributeSpecifier
) {
745 CurrentToken
->setType(TT_AttributeSquare
);
747 CurrentToken
->EndsCppAttributeGroup
= true;
749 if (IsCSharpAttributeSpecifier
) {
750 CurrentToken
->setType(TT_AttributeSquare
);
751 } else if (((CurrentToken
->Next
&&
752 CurrentToken
->Next
->is(tok::l_paren
)) ||
753 (CurrentToken
->Previous
&&
754 CurrentToken
->Previous
->Previous
== Left
)) &&
755 Left
->is(TT_ObjCMethodExpr
)) {
756 // An ObjC method call is rarely followed by an open parenthesis. It
757 // also can't be composed of just one token, unless it's a macro that
758 // will be expanded to more tokens.
759 // FIXME: Do we incorrectly label ":" with this?
760 StartsObjCMethodExpr
= false;
761 Left
->setType(TT_Unknown
);
763 if (StartsObjCMethodExpr
&& CurrentToken
->Previous
!= Left
) {
764 CurrentToken
->setType(TT_ObjCMethodExpr
);
765 // If we haven't seen a colon yet, make sure the last identifier
766 // before the r_square is tagged as a selector name component.
767 if (!ColonFound
&& CurrentToken
->Previous
&&
768 CurrentToken
->Previous
->is(TT_Unknown
) &&
769 canBeObjCSelectorComponent(*CurrentToken
->Previous
)) {
770 CurrentToken
->Previous
->setType(TT_SelectorName
);
772 // determineStarAmpUsage() thinks that '*' '[' is allocating an
773 // array of pointers, but if '[' starts a selector then '*' is a
775 if (Parent
&& Parent
->is(TT_PointerOrReference
))
776 Parent
->overwriteFixedType(TT_BinaryOperator
);
778 // An arrow after an ObjC method expression is not a lambda arrow.
779 if (CurrentToken
->getType() == TT_ObjCMethodExpr
&&
780 CurrentToken
->Next
&&
781 CurrentToken
->Next
->is(TT_TrailingReturnArrow
)) {
782 CurrentToken
->Next
->overwriteFixedType(TT_Unknown
);
784 Left
->MatchingParen
= CurrentToken
;
785 CurrentToken
->MatchingParen
= Left
;
786 // FirstObjCSelectorName is set when a colon is found. This does
787 // not work, however, when the method has no parameters.
788 // Here, we set FirstObjCSelectorName when the end of the method call is
789 // reached, in case it was not set already.
790 if (!Contexts
.back().FirstObjCSelectorName
) {
791 FormatToken
*Previous
= CurrentToken
->getPreviousNonComment();
792 if (Previous
&& Previous
->is(TT_SelectorName
)) {
793 Previous
->ObjCSelectorNameParts
= 1;
794 Contexts
.back().FirstObjCSelectorName
= Previous
;
797 Left
->ParameterCount
=
798 Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
800 if (Contexts
.back().FirstObjCSelectorName
) {
801 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
802 Contexts
.back().LongestObjCSelectorName
;
803 if (Left
->BlockParameterCount
> 1)
804 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
= 0;
809 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_brace
))
811 if (CurrentToken
->is(tok::colon
)) {
812 if (IsCpp11AttributeSpecifier
&&
813 CurrentToken
->endsSequence(tok::colon
, tok::identifier
,
815 // Remember that this is a [[using ns: foo]] C++ attribute, so we
816 // don't add a space before the colon (unlike other colons).
817 CurrentToken
->setType(TT_AttributeColon
);
818 } else if (!Style
.isVerilog() && !Line
.InPragmaDirective
&&
819 Left
->isOneOf(TT_ArraySubscriptLSquare
,
820 TT_DesignatedInitializerLSquare
)) {
821 Left
->setType(TT_ObjCMethodExpr
);
822 StartsObjCMethodExpr
= true;
823 Contexts
.back().ColonIsObjCMethodExpr
= true;
824 if (Parent
&& Parent
->is(tok::r_paren
)) {
825 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
826 Parent
->setType(TT_CastRParen
);
831 if (CurrentToken
->is(tok::comma
) && Left
->is(TT_ObjCMethodExpr
) &&
833 Left
->setType(TT_ArrayInitializerLSquare
);
835 FormatToken
*Tok
= CurrentToken
;
838 updateParameterCount(Left
, Tok
);
843 bool couldBeInStructArrayInitializer() const {
844 if (Contexts
.size() < 2)
846 // We want to back up no more then 2 context levels i.e.
848 const auto End
= std::next(Contexts
.rbegin(), 2);
849 auto Last
= Contexts
.rbegin();
851 for (; Last
!= End
; ++Last
)
852 if (Last
->ContextKind
== tok::l_brace
)
854 return Depth
== 2 && Last
->ContextKind
!= tok::l_brace
;
861 assert(CurrentToken
->Previous
);
862 FormatToken
&OpeningBrace
= *CurrentToken
->Previous
;
863 assert(OpeningBrace
.is(tok::l_brace
));
864 OpeningBrace
.ParentBracket
= Contexts
.back().ContextKind
;
866 if (Contexts
.back().CaretFound
)
867 OpeningBrace
.overwriteFixedType(TT_ObjCBlockLBrace
);
868 Contexts
.back().CaretFound
= false;
870 ScopedContextCreator
ContextCreator(*this, tok::l_brace
, 1);
871 Contexts
.back().ColonIsDictLiteral
= true;
872 if (OpeningBrace
.is(BK_BracedInit
))
873 Contexts
.back().IsExpression
= true;
874 if (Style
.isJavaScript() && OpeningBrace
.Previous
&&
875 OpeningBrace
.Previous
->is(TT_JsTypeColon
)) {
876 Contexts
.back().IsExpression
= false;
878 if (Style
.isVerilog() &&
879 (!OpeningBrace
.getPreviousNonComment() ||
880 OpeningBrace
.getPreviousNonComment()->isNot(Keywords
.kw_apostrophe
))) {
881 Contexts
.back().VerilogMayBeConcatenation
= true;
884 unsigned CommaCount
= 0;
885 while (CurrentToken
) {
886 if (CurrentToken
->is(tok::r_brace
)) {
887 assert(!Scopes
.empty());
888 assert(Scopes
.back() == getScopeType(OpeningBrace
));
890 assert(OpeningBrace
.Optional
== CurrentToken
->Optional
);
891 OpeningBrace
.MatchingParen
= CurrentToken
;
892 CurrentToken
->MatchingParen
= &OpeningBrace
;
893 if (Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
) {
894 if (OpeningBrace
.ParentBracket
== tok::l_brace
&&
895 couldBeInStructArrayInitializer() && CommaCount
> 0) {
896 Contexts
.back().ContextType
= Context::StructArrayInitializer
;
902 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_square
))
904 updateParameterCount(&OpeningBrace
, CurrentToken
);
905 if (CurrentToken
->isOneOf(tok::colon
, tok::l_brace
, tok::less
)) {
906 FormatToken
*Previous
= CurrentToken
->getPreviousNonComment();
907 if (Previous
->is(TT_JsTypeOptionalQuestion
))
908 Previous
= Previous
->getPreviousNonComment();
909 if ((CurrentToken
->is(tok::colon
) &&
910 (!Contexts
.back().ColonIsDictLiteral
|| !Style
.isCpp())) ||
912 OpeningBrace
.setType(TT_DictLiteral
);
913 if (Previous
->Tok
.getIdentifierInfo() ||
914 Previous
->is(tok::string_literal
)) {
915 Previous
->setType(TT_SelectorName
);
918 if (CurrentToken
->is(tok::colon
) && OpeningBrace
.is(TT_Unknown
))
919 OpeningBrace
.setType(TT_DictLiteral
);
920 else if (Style
.isJavaScript())
921 OpeningBrace
.overwriteFixedType(TT_DictLiteral
);
923 if (CurrentToken
->is(tok::comma
)) {
924 if (Style
.isJavaScript())
925 OpeningBrace
.overwriteFixedType(TT_DictLiteral
);
934 void updateParameterCount(FormatToken
*Left
, FormatToken
*Current
) {
935 // For ObjC methods, the number of parameters is calculated differently as
936 // method declarations have a different structure (the parameters are not
937 // inside a bracket scope).
938 if (Current
->is(tok::l_brace
) && Current
->is(BK_Block
))
939 ++Left
->BlockParameterCount
;
940 if (Current
->is(tok::comma
)) {
941 ++Left
->ParameterCount
;
943 Left
->Role
.reset(new CommaSeparatedList(Style
));
944 Left
->Role
->CommaFound(Current
);
945 } else if (Left
->ParameterCount
== 0 && Current
->isNot(tok::comment
)) {
946 Left
->ParameterCount
= 1;
950 bool parseConditional() {
951 while (CurrentToken
) {
952 if (CurrentToken
->is(tok::colon
)) {
953 CurrentToken
->setType(TT_ConditionalExpr
);
963 bool parseTemplateDeclaration() {
964 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
965 CurrentToken
->setType(TT_TemplateOpener
);
970 CurrentToken
->Previous
->ClosesTemplateDeclaration
= true;
976 bool consumeToken() {
978 const auto *Prev
= CurrentToken
->getPreviousNonComment();
979 if (Prev
&& Prev
->is(tok::r_square
) && Prev
->is(TT_AttributeSquare
) &&
980 CurrentToken
->isOneOf(tok::kw_if
, tok::kw_switch
, tok::kw_case
,
981 tok::kw_default
, tok::kw_for
, tok::kw_while
) &&
982 mustBreakAfterAttributes(*CurrentToken
, Style
)) {
983 CurrentToken
->MustBreakBefore
= true;
986 FormatToken
*Tok
= CurrentToken
;
988 // In Verilog primitives' state tables, `:`, `?`, and `-` aren't normal
990 if (Tok
->is(TT_VerilogTableItem
))
992 switch (Tok
->Tok
.getKind()) {
995 if (!Tok
->Previous
&& Line
.MustBeDeclaration
)
996 Tok
->setType(TT_ObjCMethodSpecifier
);
1001 // Goto labels and case labels are already identified in
1002 // UnwrappedLineParser.
1003 if (Tok
->isTypeFinalized())
1005 // Colons from ?: are handled in parseConditional().
1006 if (Style
.isJavaScript()) {
1007 if (Contexts
.back().ColonIsForRangeExpr
|| // colon in for loop
1008 (Contexts
.size() == 1 && // switch/case labels
1009 !Line
.First
->isOneOf(tok::kw_enum
, tok::kw_case
)) ||
1010 Contexts
.back().ContextKind
== tok::l_paren
|| // function params
1011 Contexts
.back().ContextKind
== tok::l_square
|| // array type
1012 (!Contexts
.back().IsExpression
&&
1013 Contexts
.back().ContextKind
== tok::l_brace
) || // object type
1014 (Contexts
.size() == 1 &&
1015 Line
.MustBeDeclaration
)) { // method/property declaration
1016 Contexts
.back().IsExpression
= false;
1017 Tok
->setType(TT_JsTypeColon
);
1020 } else if (Style
.isCSharp()) {
1021 if (Contexts
.back().InCSharpAttributeSpecifier
) {
1022 Tok
->setType(TT_AttributeColon
);
1025 if (Contexts
.back().ContextKind
== tok::l_paren
) {
1026 Tok
->setType(TT_CSharpNamedArgumentColon
);
1029 } else if (Style
.isVerilog() && Tok
->isNot(TT_BinaryOperator
)) {
1030 // The distribution weight operators are labeled
1031 // TT_BinaryOperator by the lexer.
1032 if (Keywords
.isVerilogEnd(*Tok
->Previous
) ||
1033 Keywords
.isVerilogBegin(*Tok
->Previous
)) {
1034 Tok
->setType(TT_VerilogBlockLabelColon
);
1035 } else if (Contexts
.back().ContextKind
== tok::l_square
) {
1036 Tok
->setType(TT_BitFieldColon
);
1037 } else if (Contexts
.back().ColonIsDictLiteral
) {
1038 Tok
->setType(TT_DictLiteral
);
1039 } else if (Contexts
.size() == 1) {
1040 // In Verilog a case label doesn't have the case keyword. We
1041 // assume a colon following an expression is a case label.
1042 // Colons from ?: are annotated in parseConditional().
1043 Tok
->setType(TT_CaseLabelColon
);
1044 if (Line
.Level
> 1 || (!Line
.InPPDirective
&& Line
.Level
> 0))
1049 if (Line
.First
->isOneOf(Keywords
.kw_module
, Keywords
.kw_import
) ||
1050 Line
.First
->startsSequence(tok::kw_export
, Keywords
.kw_module
) ||
1051 Line
.First
->startsSequence(tok::kw_export
, Keywords
.kw_import
)) {
1052 Tok
->setType(TT_ModulePartitionColon
);
1053 } else if (Contexts
.back().ColonIsDictLiteral
|| Style
.isProto()) {
1054 Tok
->setType(TT_DictLiteral
);
1055 if (Style
.Language
== FormatStyle::LK_TextProto
) {
1056 if (FormatToken
*Previous
= Tok
->getPreviousNonComment())
1057 Previous
->setType(TT_SelectorName
);
1059 } else if (Contexts
.back().ColonIsObjCMethodExpr
||
1060 Line
.startsWith(TT_ObjCMethodSpecifier
)) {
1061 Tok
->setType(TT_ObjCMethodExpr
);
1062 const FormatToken
*BeforePrevious
= Tok
->Previous
->Previous
;
1063 // Ensure we tag all identifiers in method declarations as
1065 bool UnknownIdentifierInMethodDeclaration
=
1066 Line
.startsWith(TT_ObjCMethodSpecifier
) &&
1067 Tok
->Previous
->is(tok::identifier
) && Tok
->Previous
->is(TT_Unknown
);
1068 if (!BeforePrevious
||
1069 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
1070 !(BeforePrevious
->is(TT_CastRParen
) ||
1071 (BeforePrevious
->is(TT_ObjCMethodExpr
) &&
1072 BeforePrevious
->is(tok::colon
))) ||
1073 BeforePrevious
->is(tok::r_square
) ||
1074 Contexts
.back().LongestObjCSelectorName
== 0 ||
1075 UnknownIdentifierInMethodDeclaration
) {
1076 Tok
->Previous
->setType(TT_SelectorName
);
1077 if (!Contexts
.back().FirstObjCSelectorName
) {
1078 Contexts
.back().FirstObjCSelectorName
= Tok
->Previous
;
1079 } else if (Tok
->Previous
->ColumnWidth
>
1080 Contexts
.back().LongestObjCSelectorName
) {
1081 Contexts
.back().LongestObjCSelectorName
=
1082 Tok
->Previous
->ColumnWidth
;
1084 Tok
->Previous
->ParameterIndex
=
1085 Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
1086 ++Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
1088 } else if (Contexts
.back().ColonIsForRangeExpr
) {
1089 Tok
->setType(TT_RangeBasedForLoopColon
);
1090 } else if (Contexts
.back().ContextType
== Context::C11GenericSelection
) {
1091 Tok
->setType(TT_GenericSelectionColon
);
1092 } else if (CurrentToken
&& CurrentToken
->is(tok::numeric_constant
)) {
1093 Tok
->setType(TT_BitFieldColon
);
1094 } else if (Contexts
.size() == 1 &&
1095 !Line
.First
->isOneOf(tok::kw_enum
, tok::kw_case
,
1097 FormatToken
*Prev
= Tok
->getPreviousNonComment();
1100 if (Prev
->isOneOf(tok::r_paren
, tok::kw_noexcept
) ||
1101 Prev
->ClosesRequiresClause
) {
1102 Tok
->setType(TT_CtorInitializerColon
);
1103 } else if (Prev
->is(tok::kw_try
)) {
1104 // Member initializer list within function try block.
1105 FormatToken
*PrevPrev
= Prev
->getPreviousNonComment();
1108 if (PrevPrev
&& PrevPrev
->isOneOf(tok::r_paren
, tok::kw_noexcept
))
1109 Tok
->setType(TT_CtorInitializerColon
);
1111 Tok
->setType(TT_InheritanceColon
);
1113 } else if (canBeObjCSelectorComponent(*Tok
->Previous
) && Tok
->Next
&&
1114 (Tok
->Next
->isOneOf(tok::r_paren
, tok::comma
) ||
1115 (canBeObjCSelectorComponent(*Tok
->Next
) && Tok
->Next
->Next
&&
1116 Tok
->Next
->Next
->is(tok::colon
)))) {
1117 // This handles a special macro in ObjC code where selectors including
1118 // the colon are passed as macro arguments.
1119 Tok
->setType(TT_ObjCMethodExpr
);
1120 } else if (Contexts
.back().ContextKind
== tok::l_paren
&&
1121 !Line
.InPragmaDirective
) {
1122 Tok
->setType(TT_InlineASMColon
);
1127 // | and & in declarations/type expressions represent union and
1128 // intersection types, respectively.
1129 if (Style
.isJavaScript() && !Contexts
.back().IsExpression
)
1130 Tok
->setType(TT_JsTypeOperator
);
1134 CurrentToken
->isOneOf(tok::kw_constexpr
, tok::identifier
)) {
1139 if (CurrentToken
&& CurrentToken
->is(tok::l_paren
)) {
1141 if (!parseParens(/*LookForDecls=*/true))
1146 if (Style
.isJavaScript()) {
1147 // x.for and {for: ...}
1148 if ((Tok
->Previous
&& Tok
->Previous
->is(tok::period
)) ||
1149 (Tok
->Next
&& Tok
->Next
->is(tok::colon
))) {
1152 // JS' for await ( ...
1153 if (CurrentToken
&& CurrentToken
->is(Keywords
.kw_await
))
1156 if (Style
.isCpp() && CurrentToken
&& CurrentToken
->is(tok::kw_co_await
))
1158 Contexts
.back().ColonIsForRangeExpr
= true;
1159 if (!CurrentToken
|| CurrentToken
->isNot(tok::l_paren
))
1166 // When faced with 'operator()()', the kw_operator handler incorrectly
1167 // marks the first l_paren as a OverloadedOperatorLParen. Here, we make
1168 // the first two parens OverloadedOperators and the second l_paren an
1169 // OverloadedOperatorLParen.
1170 if (Tok
->Previous
&& Tok
->Previous
->is(tok::r_paren
) &&
1171 Tok
->Previous
->MatchingParen
&&
1172 Tok
->Previous
->MatchingParen
->is(TT_OverloadedOperatorLParen
)) {
1173 Tok
->Previous
->setType(TT_OverloadedOperator
);
1174 Tok
->Previous
->MatchingParen
->setType(TT_OverloadedOperator
);
1175 Tok
->setType(TT_OverloadedOperatorLParen
);
1178 if (Style
.isVerilog()) {
1179 // Identify the parameter list and port list in a module instantiation.
1180 // This is still needed when we already have
1181 // UnwrappedLineParser::parseVerilogHierarchyHeader because that
1182 // function is only responsible for the definition, not the
1184 auto IsInstancePort
= [&]() {
1185 const FormatToken
*Prev
= Tok
->getPreviousNonComment();
1186 const FormatToken
*PrevPrev
;
1187 // In the following example all 4 left parentheses will be treated as
1188 // 'TT_VerilogInstancePortLParen'.
1190 // module_x instance_1(port_1); // Case A.
1191 // module_x #(parameter_1) // Case B.
1192 // instance_2(port_1), // Case C.
1193 // instance_3(port_1); // Case D.
1194 if (!Prev
|| !(PrevPrev
= Prev
->getPreviousNonComment()))
1197 if (Keywords
.isVerilogIdentifier(*Prev
) &&
1198 Keywords
.isVerilogIdentifier(*PrevPrev
)) {
1202 if (Prev
->is(Keywords
.kw_verilogHash
) &&
1203 Keywords
.isVerilogIdentifier(*PrevPrev
)) {
1207 if (Keywords
.isVerilogIdentifier(*Prev
) && PrevPrev
->is(tok::r_paren
))
1210 if (Keywords
.isVerilogIdentifier(*Prev
) && PrevPrev
->is(tok::comma
)) {
1211 const FormatToken
*PrevParen
= PrevPrev
->getPreviousNonComment();
1212 if (PrevParen
->is(tok::r_paren
) && PrevParen
->MatchingParen
&&
1213 PrevParen
->MatchingParen
->is(TT_VerilogInstancePortLParen
)) {
1220 if (IsInstancePort())
1221 Tok
->setFinalizedType(TT_VerilogInstancePortLParen
);
1226 if (Line
.MustBeDeclaration
&& Contexts
.size() == 1 &&
1227 !Contexts
.back().IsExpression
&& !Line
.startsWith(TT_ObjCProperty
) &&
1228 !Tok
->isOneOf(TT_TypeDeclarationParen
, TT_RequiresExpressionLParen
)) {
1229 if (const auto *Previous
= Tok
->Previous
;
1231 (!Previous
->isAttribute() &&
1232 !Previous
->isOneOf(TT_RequiresClause
, TT_LeadingJavaAnnotation
))) {
1233 Line
.MightBeFunctionDecl
= true;
1242 if (Style
.Language
== FormatStyle::LK_TextProto
) {
1243 FormatToken
*Previous
= Tok
->getPreviousNonComment();
1244 if (Previous
&& Previous
->getType() != TT_DictLiteral
)
1245 Previous
->setType(TT_SelectorName
);
1247 Scopes
.push_back(getScopeType(*Tok
));
1253 Tok
->setType(TT_TemplateOpener
);
1254 // In TT_Proto, we must distignuish between:
1256 // msg < item: data >
1257 // msg: < item: data >
1258 // In TT_TextProto, map<key, value> does not occur.
1259 if (Style
.Language
== FormatStyle::LK_TextProto
||
1260 (Style
.Language
== FormatStyle::LK_Proto
&& Tok
->Previous
&&
1261 Tok
->Previous
->isOneOf(TT_SelectorName
, TT_DictLiteral
))) {
1262 Tok
->setType(TT_DictLiteral
);
1263 FormatToken
*Previous
= Tok
->getPreviousNonComment();
1264 if (Previous
&& Previous
->getType() != TT_DictLiteral
)
1265 Previous
->setType(TT_SelectorName
);
1268 Tok
->setType(TT_BinaryOperator
);
1269 NonTemplateLess
.insert(Tok
);
1278 // Don't pop scope when encountering unbalanced r_brace.
1279 if (!Scopes
.empty())
1281 // Lines can start with '}'.
1286 if (Style
.Language
!= FormatStyle::LK_TextProto
)
1287 Tok
->setType(TT_BinaryOperator
);
1288 if (Tok
->Previous
&& Tok
->Previous
->is(TT_TemplateCloser
))
1289 Tok
->SpacesRequiredBefore
= 1;
1291 case tok::kw_operator
:
1292 if (Style
.isProto())
1294 while (CurrentToken
&&
1295 !CurrentToken
->isOneOf(tok::l_paren
, tok::semi
, tok::r_paren
)) {
1296 if (CurrentToken
->isOneOf(tok::star
, tok::amp
))
1297 CurrentToken
->setType(TT_PointerOrReference
);
1298 auto Next
= CurrentToken
->getNextNonComment();
1301 if (Next
->is(tok::less
))
1307 auto Previous
= CurrentToken
->getPreviousNonComment();
1309 if (CurrentToken
->is(tok::comma
) && Previous
->isNot(tok::kw_operator
))
1311 if (Previous
->isOneOf(TT_BinaryOperator
, TT_UnaryOperator
, tok::comma
,
1312 tok::star
, tok::arrow
, tok::amp
, tok::ampamp
) ||
1313 // User defined literal.
1314 Previous
->TokenText
.starts_with("\"\"")) {
1315 Previous
->setType(TT_OverloadedOperator
);
1316 if (CurrentToken
->isOneOf(tok::less
, tok::greater
))
1320 if (CurrentToken
&& CurrentToken
->is(tok::l_paren
))
1321 CurrentToken
->setType(TT_OverloadedOperatorLParen
);
1322 if (CurrentToken
&& CurrentToken
->Previous
->is(TT_BinaryOperator
))
1323 CurrentToken
->Previous
->setType(TT_OverloadedOperator
);
1326 if (Style
.isJavaScript() && Tok
->Next
&&
1327 Tok
->Next
->isOneOf(tok::semi
, tok::comma
, tok::colon
, tok::r_paren
,
1328 tok::r_brace
, tok::r_square
)) {
1329 // Question marks before semicolons, colons, etc. indicate optional
1330 // types (fields, parameters), e.g.
1331 // function(x?: string, y?) {...}
1333 Tok
->setType(TT_JsTypeOptionalQuestion
);
1336 // Declarations cannot be conditional expressions, this can only be part
1337 // of a type declaration.
1338 if (Line
.MustBeDeclaration
&& !Contexts
.back().IsExpression
&&
1339 Style
.isJavaScript()) {
1342 if (Style
.isCSharp()) {
1343 // `Type?)`, `Type?>`, `Type? name;` and `Type? name =` can only be
1346 // `Type?)`, `Type?>`, `Type? name;`
1348 (Tok
->Next
->startsSequence(tok::question
, tok::r_paren
) ||
1349 Tok
->Next
->startsSequence(tok::question
, tok::greater
) ||
1350 Tok
->Next
->startsSequence(tok::question
, tok::identifier
,
1352 Tok
->setType(TT_CSharpNullable
);
1357 if (Tok
->Next
&& Tok
->Next
->is(tok::identifier
) && Tok
->Next
->Next
&&
1358 Tok
->Next
->Next
->is(tok::equal
)) {
1359 Tok
->setType(TT_CSharpNullable
);
1363 // Line.MustBeDeclaration will be true for `Type? name;`.
1365 // cond ? "A" : "B";
1367 // cond ? cond2 ? "A" : "B" : "C";
1368 if (!Contexts
.back().IsExpression
&& Line
.MustBeDeclaration
&&
1370 !Tok
->Next
->isOneOf(tok::identifier
, tok::string_literal
) ||
1372 !Tok
->Next
->Next
->isOneOf(tok::colon
, tok::question
))) {
1373 Tok
->setType(TT_CSharpNullable
);
1379 case tok::kw_template
:
1380 parseTemplateDeclaration();
1383 switch (Contexts
.back().ContextType
) {
1384 case Context::CtorInitializer
:
1385 Tok
->setType(TT_CtorInitializerComma
);
1387 case Context::InheritanceList
:
1388 Tok
->setType(TT_InheritanceComma
);
1390 case Context::VerilogInstancePortList
:
1391 Tok
->setFinalizedType(TT_VerilogInstancePortComma
);
1394 if (Style
.isVerilog() && Contexts
.size() == 1 &&
1395 Line
.startsWith(Keywords
.kw_assign
)) {
1396 Tok
->setFinalizedType(TT_VerilogAssignComma
);
1397 } else if (Contexts
.back().FirstStartOfName
&&
1398 (Contexts
.size() == 1 || startsWithInitStatement(Line
))) {
1399 Contexts
.back().FirstStartOfName
->PartOfMultiVariableDeclStmt
= true;
1400 Line
.IsMultiVariableDeclStmt
= true;
1404 if (Contexts
.back().ContextType
== Context::ForEachMacro
)
1405 Contexts
.back().IsExpression
= true;
1407 case tok::kw_default
:
1408 // Unindent case labels.
1409 if (Style
.isVerilog() && Keywords
.isVerilogEndOfLabel(*Tok
) &&
1410 (Line
.Level
> 1 || (!Line
.InPPDirective
&& Line
.Level
> 0))) {
1414 case tok::identifier
:
1415 if (Tok
->isOneOf(Keywords
.kw___has_include
,
1416 Keywords
.kw___has_include_next
)) {
1419 if (Style
.isCSharp() && Tok
->is(Keywords
.kw_where
) && Tok
->Next
&&
1420 Tok
->Next
->isNot(tok::l_paren
)) {
1421 Tok
->setType(TT_CSharpGenericTypeConstraint
);
1422 parseCSharpGenericTypeConstraint();
1423 if (!Tok
->getPreviousNonComment())
1424 Line
.IsContinuation
= true;
1428 if (Tok
->Previous
&& Tok
->Previous
->is(tok::kw_noexcept
))
1429 Tok
->setType(TT_TrailingReturnArrow
);
1437 void parseCSharpGenericTypeConstraint() {
1438 int OpenAngleBracketsCount
= 0;
1439 while (CurrentToken
) {
1440 if (CurrentToken
->is(tok::less
)) {
1441 // parseAngle is too greedy and will consume the whole line.
1442 CurrentToken
->setType(TT_TemplateOpener
);
1443 ++OpenAngleBracketsCount
;
1445 } else if (CurrentToken
->is(tok::greater
)) {
1446 CurrentToken
->setType(TT_TemplateCloser
);
1447 --OpenAngleBracketsCount
;
1449 } else if (CurrentToken
->is(tok::comma
) && OpenAngleBracketsCount
== 0) {
1450 // We allow line breaks after GenericTypeConstraintComma's
1451 // so do not flag commas in Generics as GenericTypeConstraintComma's.
1452 CurrentToken
->setType(TT_CSharpGenericTypeConstraintComma
);
1454 } else if (CurrentToken
->is(Keywords
.kw_where
)) {
1455 CurrentToken
->setType(TT_CSharpGenericTypeConstraint
);
1457 } else if (CurrentToken
->is(tok::colon
)) {
1458 CurrentToken
->setType(TT_CSharpGenericTypeConstraintColon
);
1466 void parseIncludeDirective() {
1467 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
1469 while (CurrentToken
) {
1470 // Mark tokens up to the trailing line comments as implicit string
1472 if (CurrentToken
->isNot(tok::comment
) &&
1473 !CurrentToken
->TokenText
.starts_with("//")) {
1474 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1481 void parseWarningOrError() {
1483 // We still want to format the whitespace left of the first token of the
1484 // warning or error.
1486 while (CurrentToken
) {
1487 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1492 void parsePragma() {
1493 next(); // Consume "pragma".
1495 CurrentToken
->isOneOf(Keywords
.kw_mark
, Keywords
.kw_option
,
1496 Keywords
.kw_region
)) {
1497 bool IsMarkOrRegion
=
1498 CurrentToken
->isOneOf(Keywords
.kw_mark
, Keywords
.kw_region
);
1500 next(); // Consume first token (so we fix leading whitespace).
1501 while (CurrentToken
) {
1502 if (IsMarkOrRegion
|| CurrentToken
->Previous
->is(TT_BinaryOperator
))
1503 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1509 void parseHasInclude() {
1510 if (!CurrentToken
|| CurrentToken
->isNot(tok::l_paren
))
1513 parseIncludeDirective();
1517 LineType
parsePreprocessorDirective() {
1518 bool IsFirstToken
= CurrentToken
->IsFirst
;
1519 LineType Type
= LT_PreprocessorDirective
;
1524 if (Style
.isJavaScript() && IsFirstToken
) {
1525 // JavaScript files can contain shebang lines of the form:
1526 // #!/usr/bin/env node
1527 // Treat these like C++ #include directives.
1528 while (CurrentToken
) {
1529 // Tokens cannot be comments here.
1530 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1533 return LT_ImportStatement
;
1536 if (CurrentToken
->is(tok::numeric_constant
)) {
1537 CurrentToken
->SpacesRequiredBefore
= 1;
1540 // Hashes in the middle of a line can lead to any strange token
1542 if (!CurrentToken
->Tok
.getIdentifierInfo())
1544 // In Verilog macro expansions start with a backtick just like preprocessor
1545 // directives. Thus we stop if the word is not a preprocessor directive.
1546 if (Style
.isVerilog() && !Keywords
.isVerilogPPDirective(*CurrentToken
))
1548 switch (CurrentToken
->Tok
.getIdentifierInfo()->getPPKeywordID()) {
1549 case tok::pp_include
:
1550 case tok::pp_include_next
:
1551 case tok::pp_import
:
1553 parseIncludeDirective();
1554 Type
= LT_ImportStatement
;
1557 case tok::pp_warning
:
1558 parseWarningOrError();
1560 case tok::pp_pragma
:
1565 Contexts
.back().IsExpression
= true;
1572 while (CurrentToken
) {
1573 FormatToken
*Tok
= CurrentToken
;
1575 if (Tok
->is(tok::l_paren
)) {
1577 } else if (Tok
->isOneOf(Keywords
.kw___has_include
,
1578 Keywords
.kw___has_include_next
)) {
1586 LineType
parseLine() {
1589 NonTemplateLess
.clear();
1590 if (!Line
.InMacroBody
&& CurrentToken
->is(tok::hash
)) {
1591 // We were not yet allowed to use C++17 optional when this was being
1592 // written. So we used LT_Invalid to mark that the line is not a
1593 // preprocessor directive.
1594 auto Type
= parsePreprocessorDirective();
1595 if (Type
!= LT_Invalid
)
1599 // Directly allow to 'import <string-literal>' to support protocol buffer
1600 // definitions (github.com/google/protobuf) or missing "#" (either way we
1601 // should not break the line).
1602 IdentifierInfo
*Info
= CurrentToken
->Tok
.getIdentifierInfo();
1603 if ((Style
.Language
== FormatStyle::LK_Java
&&
1604 CurrentToken
->is(Keywords
.kw_package
)) ||
1605 (!Style
.isVerilog() && Info
&&
1606 Info
->getPPKeywordID() == tok::pp_import
&& CurrentToken
->Next
&&
1607 CurrentToken
->Next
->isOneOf(tok::string_literal
, tok::identifier
,
1610 parseIncludeDirective();
1611 return LT_ImportStatement
;
1614 // If this line starts and ends in '<' and '>', respectively, it is likely
1615 // part of "#define <a/b.h>".
1616 if (CurrentToken
->is(tok::less
) && Line
.Last
->is(tok::greater
)) {
1617 parseIncludeDirective();
1618 return LT_ImportStatement
;
1621 // In .proto files, top-level options and package statements are very
1622 // similar to import statements and should not be line-wrapped.
1623 if (Style
.Language
== FormatStyle::LK_Proto
&& Line
.Level
== 0 &&
1624 CurrentToken
->isOneOf(Keywords
.kw_option
, Keywords
.kw_package
)) {
1626 if (CurrentToken
&& CurrentToken
->is(tok::identifier
)) {
1627 while (CurrentToken
)
1629 return LT_ImportStatement
;
1633 bool KeywordVirtualFound
= false;
1634 bool ImportStatement
= false;
1636 // import {...} from '...';
1637 if (Style
.isJavaScript() && CurrentToken
->is(Keywords
.kw_import
))
1638 ImportStatement
= true;
1640 while (CurrentToken
) {
1641 if (CurrentToken
->is(tok::kw_virtual
))
1642 KeywordVirtualFound
= true;
1643 if (Style
.isJavaScript()) {
1644 // export {...} from '...';
1645 // An export followed by "from 'some string';" is a re-export from
1646 // another module identified by a URI and is treated as a
1647 // LT_ImportStatement (i.e. prevent wraps on it for long URIs).
1648 // Just "export {...};" or "export class ..." should not be treated as
1649 // an import in this sense.
1650 if (Line
.First
->is(tok::kw_export
) &&
1651 CurrentToken
->is(Keywords
.kw_from
) && CurrentToken
->Next
&&
1652 CurrentToken
->Next
->isStringLiteral()) {
1653 ImportStatement
= true;
1655 if (isClosureImportStatement(*CurrentToken
))
1656 ImportStatement
= true;
1658 if (!consumeToken())
1661 if (KeywordVirtualFound
)
1662 return LT_VirtualFunctionDecl
;
1663 if (ImportStatement
)
1664 return LT_ImportStatement
;
1666 if (Line
.startsWith(TT_ObjCMethodSpecifier
)) {
1667 if (Contexts
.back().FirstObjCSelectorName
) {
1668 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
1669 Contexts
.back().LongestObjCSelectorName
;
1671 return LT_ObjCMethodDecl
;
1674 for (const auto &ctx
: Contexts
)
1675 if (ctx
.ContextType
== Context::StructArrayInitializer
)
1676 return LT_ArrayOfStructInitializer
;
1682 bool isClosureImportStatement(const FormatToken
&Tok
) {
1683 // FIXME: Closure-library specific stuff should not be hard-coded but be
1685 return Tok
.TokenText
== "goog" && Tok
.Next
&& Tok
.Next
->is(tok::period
) &&
1687 (Tok
.Next
->Next
->TokenText
== "module" ||
1688 Tok
.Next
->Next
->TokenText
== "provide" ||
1689 Tok
.Next
->Next
->TokenText
== "require" ||
1690 Tok
.Next
->Next
->TokenText
== "requireType" ||
1691 Tok
.Next
->Next
->TokenText
== "forwardDeclare") &&
1692 Tok
.Next
->Next
->Next
&& Tok
.Next
->Next
->Next
->is(tok::l_paren
);
1695 void resetTokenMetadata() {
1699 // Reset token type in case we have already looked at it and then
1700 // recovered from an error (e.g. failure to find the matching >).
1701 if (!CurrentToken
->isTypeFinalized() &&
1702 !CurrentToken
->isOneOf(
1703 TT_LambdaLSquare
, TT_LambdaLBrace
, TT_AttributeMacro
, TT_IfMacro
,
1704 TT_ForEachMacro
, TT_TypenameMacro
, TT_FunctionLBrace
,
1705 TT_ImplicitStringLiteral
, TT_InlineASMBrace
, TT_FatArrow
,
1706 TT_NamespaceMacro
, TT_OverloadedOperator
, TT_RegexLiteral
,
1707 TT_TemplateString
, TT_ObjCStringLiteral
, TT_UntouchableMacroFunc
,
1708 TT_StatementAttributeLikeMacro
, TT_FunctionLikeOrFreestandingMacro
,
1709 TT_ClassLBrace
, TT_EnumLBrace
, TT_RecordLBrace
, TT_StructLBrace
,
1710 TT_UnionLBrace
, TT_RequiresClause
,
1711 TT_RequiresClauseInARequiresExpression
, TT_RequiresExpression
,
1712 TT_RequiresExpressionLParen
, TT_RequiresExpressionLBrace
,
1713 TT_BracedListLBrace
)) {
1714 CurrentToken
->setType(TT_Unknown
);
1716 CurrentToken
->Role
.reset();
1717 CurrentToken
->MatchingParen
= nullptr;
1718 CurrentToken
->FakeLParens
.clear();
1719 CurrentToken
->FakeRParens
= 0;
1726 CurrentToken
->NestingLevel
= Contexts
.size() - 1;
1727 CurrentToken
->BindingStrength
= Contexts
.back().BindingStrength
;
1728 modifyContext(*CurrentToken
);
1729 determineTokenType(*CurrentToken
);
1730 CurrentToken
= CurrentToken
->Next
;
1732 resetTokenMetadata();
1735 /// A struct to hold information valid in a specific context, e.g.
1736 /// a pair of parenthesis.
1738 Context(tok::TokenKind ContextKind
, unsigned BindingStrength
,
1740 : ContextKind(ContextKind
), BindingStrength(BindingStrength
),
1741 IsExpression(IsExpression
) {}
1743 tok::TokenKind ContextKind
;
1744 unsigned BindingStrength
;
1746 unsigned LongestObjCSelectorName
= 0;
1747 bool ColonIsForRangeExpr
= false;
1748 bool ColonIsDictLiteral
= false;
1749 bool ColonIsObjCMethodExpr
= false;
1750 FormatToken
*FirstObjCSelectorName
= nullptr;
1751 FormatToken
*FirstStartOfName
= nullptr;
1752 bool CanBeExpression
= true;
1753 bool CaretFound
= false;
1754 bool InCpp11AttributeSpecifier
= false;
1755 bool InCSharpAttributeSpecifier
= false;
1756 bool VerilogAssignmentFound
= false;
1757 // Whether the braces may mean concatenation instead of structure or array
1759 bool VerilogMayBeConcatenation
= false;
1762 // Like the part after `:` in a constructor.
1763 // Context(...) : IsExpression(IsExpression)
1765 // Like in the parentheses in a foreach.
1767 // Like the inheritance list in a class declaration.
1768 // class Input : public IO
1770 // Like in the braced list.
1772 StructArrayInitializer
,
1773 // Like in `static_cast<int>`.
1775 // C11 _Generic selection.
1776 C11GenericSelection
,
1777 // Like in the outer parentheses in `ffnand ff1(.q());`.
1778 VerilogInstancePortList
,
1779 } ContextType
= Unknown
;
1782 /// Puts a new \c Context onto the stack \c Contexts for the lifetime
1783 /// of each instance.
1784 struct ScopedContextCreator
{
1785 AnnotatingParser
&P
;
1787 ScopedContextCreator(AnnotatingParser
&P
, tok::TokenKind ContextKind
,
1790 P
.Contexts
.push_back(Context(ContextKind
,
1791 P
.Contexts
.back().BindingStrength
+ Increase
,
1792 P
.Contexts
.back().IsExpression
));
1795 ~ScopedContextCreator() {
1796 if (P
.Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
) {
1797 if (P
.Contexts
.back().ContextType
== Context::StructArrayInitializer
) {
1798 P
.Contexts
.pop_back();
1799 P
.Contexts
.back().ContextType
= Context::StructArrayInitializer
;
1803 P
.Contexts
.pop_back();
1807 void modifyContext(const FormatToken
&Current
) {
1808 auto AssignmentStartsExpression
= [&]() {
1809 if (Current
.getPrecedence() != prec::Assignment
)
1812 if (Line
.First
->isOneOf(tok::kw_using
, tok::kw_return
))
1814 if (Line
.First
->is(tok::kw_template
)) {
1815 assert(Current
.Previous
);
1816 if (Current
.Previous
->is(tok::kw_operator
)) {
1817 // `template ... operator=` cannot be an expression.
1821 // `template` keyword can start a variable template.
1822 const FormatToken
*Tok
= Line
.First
->getNextNonComment();
1823 assert(Tok
); // Current token is on the same line.
1824 if (Tok
->isNot(TT_TemplateOpener
)) {
1825 // Explicit template instantiations do not have `<>`.
1829 // This is the default value of a template parameter, determine if it's
1830 // type or non-type.
1831 if (Contexts
.back().ContextKind
== tok::less
) {
1832 assert(Current
.Previous
->Previous
);
1833 return !Current
.Previous
->Previous
->isOneOf(tok::kw_typename
,
1837 Tok
= Tok
->MatchingParen
;
1840 Tok
= Tok
->getNextNonComment();
1844 if (Tok
->isOneOf(tok::kw_class
, tok::kw_enum
, tok::kw_struct
,
1852 // Type aliases use `type X = ...;` in TypeScript and can be exported
1853 // using `export type ...`.
1854 if (Style
.isJavaScript() &&
1855 (Line
.startsWith(Keywords
.kw_type
, tok::identifier
) ||
1856 Line
.startsWith(tok::kw_export
, Keywords
.kw_type
,
1857 tok::identifier
))) {
1861 return !Current
.Previous
|| Current
.Previous
->isNot(tok::kw_operator
);
1864 if (AssignmentStartsExpression()) {
1865 Contexts
.back().IsExpression
= true;
1866 if (!Line
.startsWith(TT_UnaryOperator
)) {
1867 for (FormatToken
*Previous
= Current
.Previous
;
1868 Previous
&& Previous
->Previous
&&
1869 !Previous
->Previous
->isOneOf(tok::comma
, tok::semi
);
1870 Previous
= Previous
->Previous
) {
1871 if (Previous
->isOneOf(tok::r_square
, tok::r_paren
, tok::greater
)) {
1872 Previous
= Previous
->MatchingParen
;
1876 if (Previous
->opensScope())
1878 if (Previous
->isOneOf(TT_BinaryOperator
, TT_UnaryOperator
) &&
1879 Previous
->isPointerOrReference() && Previous
->Previous
&&
1880 Previous
->Previous
->isNot(tok::equal
)) {
1881 Previous
->setType(TT_PointerOrReference
);
1885 } else if (Current
.is(tok::lessless
) &&
1886 (!Current
.Previous
||
1887 Current
.Previous
->isNot(tok::kw_operator
))) {
1888 Contexts
.back().IsExpression
= true;
1889 } else if (Current
.isOneOf(tok::kw_return
, tok::kw_throw
)) {
1890 Contexts
.back().IsExpression
= true;
1891 } else if (Current
.is(TT_TrailingReturnArrow
)) {
1892 Contexts
.back().IsExpression
= false;
1893 } else if (Current
.is(Keywords
.kw_assert
)) {
1894 Contexts
.back().IsExpression
= Style
.Language
== FormatStyle::LK_Java
;
1895 } else if (Current
.Previous
&&
1896 Current
.Previous
->is(TT_CtorInitializerColon
)) {
1897 Contexts
.back().IsExpression
= true;
1898 Contexts
.back().ContextType
= Context::CtorInitializer
;
1899 } else if (Current
.Previous
&& Current
.Previous
->is(TT_InheritanceColon
)) {
1900 Contexts
.back().ContextType
= Context::InheritanceList
;
1901 } else if (Current
.isOneOf(tok::r_paren
, tok::greater
, tok::comma
)) {
1902 for (FormatToken
*Previous
= Current
.Previous
;
1903 Previous
&& Previous
->isOneOf(tok::star
, tok::amp
);
1904 Previous
= Previous
->Previous
) {
1905 Previous
->setType(TT_PointerOrReference
);
1907 if (Line
.MustBeDeclaration
&&
1908 Contexts
.front().ContextType
!= Context::CtorInitializer
) {
1909 Contexts
.back().IsExpression
= false;
1911 } else if (Current
.is(tok::kw_new
)) {
1912 Contexts
.back().CanBeExpression
= false;
1913 } else if (Current
.is(tok::semi
) ||
1914 (Current
.is(tok::exclaim
) && Current
.Previous
&&
1915 Current
.Previous
->isNot(tok::kw_operator
))) {
1916 // This should be the condition or increment in a for-loop.
1917 // But not operator !() (can't use TT_OverloadedOperator here as its not
1918 // been annotated yet).
1919 Contexts
.back().IsExpression
= true;
1923 static FormatToken
*untilMatchingParen(FormatToken
*Current
) {
1924 // Used when `MatchingParen` is not yet established.
1927 if (Current
->is(tok::l_paren
))
1929 if (Current
->is(tok::r_paren
))
1933 Current
= Current
->Next
;
1938 static bool isDeductionGuide(FormatToken
&Current
) {
1939 // Look for a deduction guide template<T> A(...) -> A<...>;
1940 if (Current
.Previous
&& Current
.Previous
->is(tok::r_paren
) &&
1941 Current
.startsSequence(tok::arrow
, tok::identifier
, tok::less
)) {
1942 // Find the TemplateCloser.
1943 FormatToken
*TemplateCloser
= Current
.Next
->Next
;
1944 int NestingLevel
= 0;
1945 while (TemplateCloser
) {
1946 // Skip over an expressions in parens A<(3 < 2)>;
1947 if (TemplateCloser
->is(tok::l_paren
)) {
1948 // No Matching Paren yet so skip to matching paren
1949 TemplateCloser
= untilMatchingParen(TemplateCloser
);
1950 if (!TemplateCloser
)
1953 if (TemplateCloser
->is(tok::less
))
1955 if (TemplateCloser
->is(tok::greater
))
1957 if (NestingLevel
< 1)
1959 TemplateCloser
= TemplateCloser
->Next
;
1961 // Assuming we have found the end of the template ensure its followed
1962 // with a semi-colon.
1963 if (TemplateCloser
&& TemplateCloser
->Next
&&
1964 TemplateCloser
->Next
->is(tok::semi
) &&
1965 Current
.Previous
->MatchingParen
) {
1966 // Determine if the identifier `A` prior to the A<..>; is the same as
1967 // prior to the A(..)
1968 FormatToken
*LeadingIdentifier
=
1969 Current
.Previous
->MatchingParen
->Previous
;
1971 return LeadingIdentifier
&&
1972 LeadingIdentifier
->TokenText
== Current
.Next
->TokenText
;
1978 void determineTokenType(FormatToken
&Current
) {
1979 if (Current
.isNot(TT_Unknown
)) {
1980 // The token type is already known.
1984 if ((Style
.isJavaScript() || Style
.isCSharp()) &&
1985 Current
.is(tok::exclaim
)) {
1986 if (Current
.Previous
) {
1988 Style
.isJavaScript()
1989 ? Keywords
.IsJavaScriptIdentifier(
1990 *Current
.Previous
, /* AcceptIdentifierName= */ true)
1991 : Current
.Previous
->is(tok::identifier
);
1993 Current
.Previous
->isOneOf(
1994 tok::kw_default
, tok::kw_namespace
, tok::r_paren
, tok::r_square
,
1995 tok::r_brace
, tok::kw_false
, tok::kw_true
, Keywords
.kw_type
,
1996 Keywords
.kw_get
, Keywords
.kw_init
, Keywords
.kw_set
) ||
1997 Current
.Previous
->Tok
.isLiteral()) {
1998 Current
.setType(TT_NonNullAssertion
);
2003 Current
.Next
->isOneOf(TT_BinaryOperator
, Keywords
.kw_as
)) {
2004 Current
.setType(TT_NonNullAssertion
);
2009 // Line.MightBeFunctionDecl can only be true after the parentheses of a
2010 // function declaration have been found. In this case, 'Current' is a
2011 // trailing token of this declaration and thus cannot be a name.
2012 if (Current
.is(Keywords
.kw_instanceof
)) {
2013 Current
.setType(TT_BinaryOperator
);
2014 } else if (isStartOfName(Current
) &&
2015 (!Line
.MightBeFunctionDecl
|| Current
.NestingLevel
!= 0)) {
2016 Contexts
.back().FirstStartOfName
= &Current
;
2017 Current
.setType(TT_StartOfName
);
2018 } else if (Current
.is(tok::semi
)) {
2019 // Reset FirstStartOfName after finding a semicolon so that a for loop
2020 // with multiple increment statements is not confused with a for loop
2021 // having multiple variable declarations.
2022 Contexts
.back().FirstStartOfName
= nullptr;
2023 } else if (Current
.isOneOf(tok::kw_auto
, tok::kw___auto_type
)) {
2025 } else if (Current
.is(tok::arrow
) &&
2026 Style
.Language
== FormatStyle::LK_Java
) {
2027 Current
.setType(TT_TrailingReturnArrow
);
2028 } else if (Current
.is(tok::arrow
) && Style
.isVerilog()) {
2029 // The implication operator.
2030 Current
.setType(TT_BinaryOperator
);
2031 } else if (Current
.is(tok::arrow
) && AutoFound
&&
2032 Line
.MightBeFunctionDecl
&& Current
.NestingLevel
== 0 &&
2033 !Current
.Previous
->isOneOf(tok::kw_operator
, tok::identifier
)) {
2034 // not auto operator->() -> xxx;
2035 Current
.setType(TT_TrailingReturnArrow
);
2036 } else if (Current
.is(tok::arrow
) && Current
.Previous
&&
2037 Current
.Previous
->is(tok::r_brace
)) {
2038 // Concept implicit conversion constraint needs to be treated like
2039 // a trailing return type ... } -> <type>.
2040 Current
.setType(TT_TrailingReturnArrow
);
2041 } else if (isDeductionGuide(Current
)) {
2042 // Deduction guides trailing arrow " A(...) -> A<T>;".
2043 Current
.setType(TT_TrailingReturnArrow
);
2044 } else if (Current
.isPointerOrReference()) {
2045 Current
.setType(determineStarAmpUsage(
2047 Contexts
.back().CanBeExpression
&& Contexts
.back().IsExpression
,
2048 Contexts
.back().ContextType
== Context::TemplateArgument
));
2049 } else if (Current
.isOneOf(tok::minus
, tok::plus
, tok::caret
) ||
2050 (Style
.isVerilog() && Current
.is(tok::pipe
))) {
2051 Current
.setType(determinePlusMinusCaretUsage(Current
));
2052 if (Current
.is(TT_UnaryOperator
) && Current
.is(tok::caret
))
2053 Contexts
.back().CaretFound
= true;
2054 } else if (Current
.isOneOf(tok::minusminus
, tok::plusplus
)) {
2055 Current
.setType(determineIncrementUsage(Current
));
2056 } else if (Current
.isOneOf(tok::exclaim
, tok::tilde
)) {
2057 Current
.setType(TT_UnaryOperator
);
2058 } else if (Current
.is(tok::question
)) {
2059 if (Style
.isJavaScript() && Line
.MustBeDeclaration
&&
2060 !Contexts
.back().IsExpression
) {
2061 // In JavaScript, `interface X { foo?(): bar; }` is an optional method
2062 // on the interface, not a ternary expression.
2063 Current
.setType(TT_JsTypeOptionalQuestion
);
2065 Current
.setType(TT_ConditionalExpr
);
2067 } else if (Current
.isBinaryOperator() &&
2068 (!Current
.Previous
|| Current
.Previous
->isNot(tok::l_square
)) &&
2069 (Current
.isNot(tok::greater
) &&
2070 Style
.Language
!= FormatStyle::LK_TextProto
)) {
2071 if (Style
.isVerilog()) {
2072 if (Current
.is(tok::lessequal
) && Contexts
.size() == 1 &&
2073 !Contexts
.back().VerilogAssignmentFound
) {
2074 // In Verilog `<=` is assignment if in its own statement. It is a
2075 // statement instead of an expression, that is it can not be chained.
2076 Current
.ForcedPrecedence
= prec::Assignment
;
2077 Current
.setFinalizedType(TT_BinaryOperator
);
2079 if (Current
.getPrecedence() == prec::Assignment
)
2080 Contexts
.back().VerilogAssignmentFound
= true;
2082 Current
.setType(TT_BinaryOperator
);
2083 } else if (Current
.is(tok::comment
)) {
2084 if (Current
.TokenText
.starts_with("/*")) {
2085 if (Current
.TokenText
.ends_with("*/")) {
2086 Current
.setType(TT_BlockComment
);
2088 // The lexer has for some reason determined a comment here. But we
2089 // cannot really handle it, if it isn't properly terminated.
2090 Current
.Tok
.setKind(tok::unknown
);
2093 Current
.setType(TT_LineComment
);
2095 } else if (Current
.is(tok::string_literal
)) {
2096 if (Style
.isVerilog() && Contexts
.back().VerilogMayBeConcatenation
&&
2097 Current
.getPreviousNonComment() &&
2098 Current
.getPreviousNonComment()->isOneOf(tok::comma
, tok::l_brace
) &&
2099 Current
.getNextNonComment() &&
2100 Current
.getNextNonComment()->isOneOf(tok::comma
, tok::r_brace
)) {
2101 Current
.setType(TT_StringInConcatenation
);
2103 } else if (Current
.is(tok::l_paren
)) {
2104 if (lParenStartsCppCast(Current
))
2105 Current
.setType(TT_CppCastLParen
);
2106 } else if (Current
.is(tok::r_paren
)) {
2107 if (rParenEndsCast(Current
))
2108 Current
.setType(TT_CastRParen
);
2109 if (Current
.MatchingParen
&& Current
.Next
&&
2110 !Current
.Next
->isBinaryOperator() &&
2111 !Current
.Next
->isOneOf(tok::semi
, tok::colon
, tok::l_brace
,
2112 tok::comma
, tok::period
, tok::arrow
,
2113 tok::coloncolon
, tok::kw_noexcept
)) {
2114 if (FormatToken
*AfterParen
= Current
.MatchingParen
->Next
;
2115 AfterParen
&& AfterParen
->isNot(tok::caret
)) {
2116 // Make sure this isn't the return type of an Obj-C block declaration.
2117 if (FormatToken
*BeforeParen
= Current
.MatchingParen
->Previous
;
2118 BeforeParen
&& BeforeParen
->is(tok::identifier
) &&
2119 BeforeParen
->isNot(TT_TypenameMacro
) &&
2120 BeforeParen
->TokenText
== BeforeParen
->TokenText
.upper() &&
2121 (!BeforeParen
->Previous
||
2122 BeforeParen
->Previous
->ClosesTemplateDeclaration
||
2123 BeforeParen
->Previous
->ClosesRequiresClause
)) {
2124 Current
.setType(TT_FunctionAnnotationRParen
);
2128 } else if (Current
.is(tok::at
) && Current
.Next
&& !Style
.isJavaScript() &&
2129 Style
.Language
!= FormatStyle::LK_Java
) {
2130 // In Java & JavaScript, "@..." is a decorator or annotation. In ObjC, it
2131 // marks declarations and properties that need special formatting.
2132 switch (Current
.Next
->Tok
.getObjCKeywordID()) {
2133 case tok::objc_interface
:
2134 case tok::objc_implementation
:
2135 case tok::objc_protocol
:
2136 Current
.setType(TT_ObjCDecl
);
2138 case tok::objc_property
:
2139 Current
.setType(TT_ObjCProperty
);
2144 } else if (Current
.is(tok::period
)) {
2145 FormatToken
*PreviousNoComment
= Current
.getPreviousNonComment();
2146 if (PreviousNoComment
&&
2147 PreviousNoComment
->isOneOf(tok::comma
, tok::l_brace
)) {
2148 Current
.setType(TT_DesignatedInitializerPeriod
);
2149 } else if (Style
.Language
== FormatStyle::LK_Java
&& Current
.Previous
&&
2150 Current
.Previous
->isOneOf(TT_JavaAnnotation
,
2151 TT_LeadingJavaAnnotation
)) {
2152 Current
.setType(Current
.Previous
->getType());
2154 } else if (canBeObjCSelectorComponent(Current
) &&
2155 // FIXME(bug 36976): ObjC return types shouldn't use
2157 Current
.Previous
&& Current
.Previous
->is(TT_CastRParen
) &&
2158 Current
.Previous
->MatchingParen
&&
2159 Current
.Previous
->MatchingParen
->Previous
&&
2160 Current
.Previous
->MatchingParen
->Previous
->is(
2161 TT_ObjCMethodSpecifier
)) {
2162 // This is the first part of an Objective-C selector name. (If there's no
2163 // colon after this, this is the only place which annotates the identifier
2165 Current
.setType(TT_SelectorName
);
2166 } else if (Current
.isOneOf(tok::identifier
, tok::kw_const
, tok::kw_noexcept
,
2167 tok::kw_requires
) &&
2169 !Current
.Previous
->isOneOf(tok::equal
, tok::at
,
2170 TT_CtorInitializerComma
,
2171 TT_CtorInitializerColon
) &&
2172 Line
.MightBeFunctionDecl
&& Contexts
.size() == 1) {
2173 // Line.MightBeFunctionDecl can only be true after the parentheses of a
2174 // function declaration have been found.
2175 Current
.setType(TT_TrailingAnnotation
);
2176 } else if ((Style
.Language
== FormatStyle::LK_Java
||
2177 Style
.isJavaScript()) &&
2179 if (Current
.Previous
->is(tok::at
) &&
2180 Current
.isNot(Keywords
.kw_interface
)) {
2181 const FormatToken
&AtToken
= *Current
.Previous
;
2182 const FormatToken
*Previous
= AtToken
.getPreviousNonComment();
2183 if (!Previous
|| Previous
->is(TT_LeadingJavaAnnotation
))
2184 Current
.setType(TT_LeadingJavaAnnotation
);
2186 Current
.setType(TT_JavaAnnotation
);
2187 } else if (Current
.Previous
->is(tok::period
) &&
2188 Current
.Previous
->isOneOf(TT_JavaAnnotation
,
2189 TT_LeadingJavaAnnotation
)) {
2190 Current
.setType(Current
.Previous
->getType());
2195 /// Take a guess at whether \p Tok starts a name of a function or
2196 /// variable declaration.
2198 /// This is a heuristic based on whether \p Tok is an identifier following
2199 /// something that is likely a type.
2200 bool isStartOfName(const FormatToken
&Tok
) {
2201 // Handled in ExpressionParser for Verilog.
2202 if (Style
.isVerilog())
2205 if (Tok
.isNot(tok::identifier
) || !Tok
.Previous
)
2208 if (const auto *NextNonComment
= Tok
.getNextNonComment();
2209 (!NextNonComment
&& !Line
.InMacroBody
) ||
2211 (NextNonComment
->isPointerOrReference() ||
2212 NextNonComment
->isOneOf(tok::identifier
, tok::string_literal
)))) {
2216 if (Tok
.Previous
->isOneOf(TT_LeadingJavaAnnotation
, Keywords
.kw_instanceof
,
2220 if (Style
.isJavaScript() && Tok
.Previous
->is(Keywords
.kw_in
))
2223 // Skip "const" as it does not have an influence on whether this is a name.
2224 FormatToken
*PreviousNotConst
= Tok
.getPreviousNonComment();
2226 // For javascript const can be like "let" or "var"
2227 if (!Style
.isJavaScript())
2228 while (PreviousNotConst
&& PreviousNotConst
->is(tok::kw_const
))
2229 PreviousNotConst
= PreviousNotConst
->getPreviousNonComment();
2231 if (!PreviousNotConst
)
2234 if (PreviousNotConst
->ClosesRequiresClause
)
2237 bool IsPPKeyword
= PreviousNotConst
->is(tok::identifier
) &&
2238 PreviousNotConst
->Previous
&&
2239 PreviousNotConst
->Previous
->is(tok::hash
);
2241 if (PreviousNotConst
->is(TT_TemplateCloser
)) {
2242 return PreviousNotConst
&& PreviousNotConst
->MatchingParen
&&
2243 PreviousNotConst
->MatchingParen
->Previous
&&
2244 PreviousNotConst
->MatchingParen
->Previous
->isNot(tok::period
) &&
2245 PreviousNotConst
->MatchingParen
->Previous
->isNot(tok::kw_template
);
2248 if ((PreviousNotConst
->is(tok::r_paren
) &&
2249 PreviousNotConst
->is(TT_TypeDeclarationParen
)) ||
2250 PreviousNotConst
->is(TT_AttributeRParen
)) {
2254 // If is a preprocess keyword like #define.
2259 if (PreviousNotConst
->isOneOf(tok::identifier
, tok::kw_auto
))
2263 if (PreviousNotConst
->is(TT_PointerOrReference
))
2267 if (PreviousNotConst
->isSimpleTypeSpecifier())
2271 if (Style
.Language
== FormatStyle::LK_Java
&&
2272 PreviousNotConst
->is(tok::r_square
)) {
2276 // const a = in JavaScript.
2277 return Style
.isJavaScript() && PreviousNotConst
->is(tok::kw_const
);
2280 /// Determine whether '(' is starting a C++ cast.
2281 bool lParenStartsCppCast(const FormatToken
&Tok
) {
2282 // C-style casts are only used in C++.
2286 FormatToken
*LeftOfParens
= Tok
.getPreviousNonComment();
2287 if (LeftOfParens
&& LeftOfParens
->is(TT_TemplateCloser
) &&
2288 LeftOfParens
->MatchingParen
) {
2289 auto *Prev
= LeftOfParens
->MatchingParen
->getPreviousNonComment();
2291 Prev
->isOneOf(tok::kw_const_cast
, tok::kw_dynamic_cast
,
2292 tok::kw_reinterpret_cast
, tok::kw_static_cast
)) {
2293 // FIXME: Maybe we should handle identifiers ending with "_cast",
2301 /// Determine whether ')' is ending a cast.
2302 bool rParenEndsCast(const FormatToken
&Tok
) {
2303 // C-style casts are only used in C++, C# and Java.
2304 if (!Style
.isCSharp() && !Style
.isCpp() &&
2305 Style
.Language
!= FormatStyle::LK_Java
) {
2309 // Empty parens aren't casts and there are no casts at the end of the line.
2310 if (Tok
.Previous
== Tok
.MatchingParen
|| !Tok
.Next
|| !Tok
.MatchingParen
)
2313 if (Tok
.MatchingParen
->is(TT_OverloadedOperatorLParen
))
2316 FormatToken
*LeftOfParens
= Tok
.MatchingParen
->getPreviousNonComment();
2318 // If there is a closing parenthesis left of the current
2319 // parentheses, look past it as these might be chained casts.
2320 if (LeftOfParens
->is(tok::r_paren
) &&
2321 LeftOfParens
->isNot(TT_CastRParen
)) {
2322 if (!LeftOfParens
->MatchingParen
||
2323 !LeftOfParens
->MatchingParen
->Previous
) {
2326 LeftOfParens
= LeftOfParens
->MatchingParen
->Previous
;
2329 if (LeftOfParens
->is(tok::r_square
)) {
2330 // delete[] (void *)ptr;
2331 auto MayBeArrayDelete
= [](FormatToken
*Tok
) -> FormatToken
* {
2332 if (Tok
->isNot(tok::r_square
))
2335 Tok
= Tok
->getPreviousNonComment();
2336 if (!Tok
|| Tok
->isNot(tok::l_square
))
2339 Tok
= Tok
->getPreviousNonComment();
2340 if (!Tok
|| Tok
->isNot(tok::kw_delete
))
2344 if (FormatToken
*MaybeDelete
= MayBeArrayDelete(LeftOfParens
))
2345 LeftOfParens
= MaybeDelete
;
2348 // The Condition directly below this one will see the operator arguments
2349 // as a (void *foo) cast.
2350 // void operator delete(void *foo) ATTRIB;
2351 if (LeftOfParens
->Tok
.getIdentifierInfo() && LeftOfParens
->Previous
&&
2352 LeftOfParens
->Previous
->is(tok::kw_operator
)) {
2356 // If there is an identifier (or with a few exceptions a keyword) right
2357 // before the parentheses, this is unlikely to be a cast.
2358 if (LeftOfParens
->Tok
.getIdentifierInfo() &&
2359 !LeftOfParens
->isOneOf(Keywords
.kw_in
, tok::kw_return
, tok::kw_case
,
2360 tok::kw_delete
, tok::kw_throw
)) {
2364 // Certain other tokens right before the parentheses are also signals that
2365 // this cannot be a cast.
2366 if (LeftOfParens
->isOneOf(tok::at
, tok::r_square
, TT_OverloadedOperator
,
2367 TT_TemplateCloser
, tok::ellipsis
)) {
2372 if (Tok
.Next
->is(tok::question
))
2375 // `foreach((A a, B b) in someList)` should not be seen as a cast.
2376 if (Tok
.Next
->is(Keywords
.kw_in
) && Style
.isCSharp())
2379 // Functions which end with decorations like volatile, noexcept are unlikely
2381 if (Tok
.Next
->isOneOf(tok::kw_noexcept
, tok::kw_volatile
, tok::kw_const
,
2382 tok::kw_requires
, tok::kw_throw
, tok::arrow
,
2383 Keywords
.kw_override
, Keywords
.kw_final
) ||
2384 isCppAttribute(Style
.isCpp(), *Tok
.Next
)) {
2388 // As Java has no function types, a "(" after the ")" likely means that this
2390 if (Style
.Language
== FormatStyle::LK_Java
&& Tok
.Next
->is(tok::l_paren
))
2393 // If a (non-string) literal follows, this is likely a cast.
2394 if (Tok
.Next
->isOneOf(tok::kw_sizeof
, tok::kw_alignof
) ||
2395 (Tok
.Next
->Tok
.isLiteral() && Tok
.Next
->isNot(tok::string_literal
))) {
2399 // Heuristically try to determine whether the parentheses contain a type.
2400 auto IsQualifiedPointerOrReference
= [](FormatToken
*T
) {
2401 // This is used to handle cases such as x = (foo *const)&y;
2402 assert(!T
->isSimpleTypeSpecifier() && "Should have already been checked");
2403 // Strip trailing qualifiers such as const or volatile when checking
2404 // whether the parens could be a cast to a pointer/reference type.
2406 if (T
->is(TT_AttributeRParen
)) {
2407 // Handle `x = (foo *__attribute__((foo)))&v;`:
2408 assert(T
->is(tok::r_paren
));
2409 assert(T
->MatchingParen
);
2410 assert(T
->MatchingParen
->is(tok::l_paren
));
2411 assert(T
->MatchingParen
->is(TT_AttributeLParen
));
2412 if (const auto *Tok
= T
->MatchingParen
->Previous
;
2413 Tok
&& Tok
->isAttribute()) {
2417 } else if (T
->is(TT_AttributeSquare
)) {
2418 // Handle `x = (foo *[[clang::foo]])&v;`:
2419 if (T
->MatchingParen
&& T
->MatchingParen
->Previous
) {
2420 T
= T
->MatchingParen
->Previous
;
2423 } else if (T
->canBePointerOrReferenceQualifier()) {
2429 return T
&& T
->is(TT_PointerOrReference
);
2431 bool ParensAreType
=
2433 Tok
.Previous
->isOneOf(TT_TemplateCloser
, TT_TypeDeclarationParen
) ||
2434 Tok
.Previous
->isSimpleTypeSpecifier() ||
2435 IsQualifiedPointerOrReference(Tok
.Previous
);
2436 bool ParensCouldEndDecl
=
2437 Tok
.Next
->isOneOf(tok::equal
, tok::semi
, tok::l_brace
, tok::greater
);
2438 if (ParensAreType
&& !ParensCouldEndDecl
)
2441 // At this point, we heuristically assume that there are no casts at the
2442 // start of the line. We assume that we have found most cases where there
2443 // are by the logic above, e.g. "(void)x;".
2447 // Certain token types inside the parentheses mean that this can't be a
2449 for (const FormatToken
*Token
= Tok
.MatchingParen
->Next
; Token
!= &Tok
;
2450 Token
= Token
->Next
) {
2451 if (Token
->is(TT_BinaryOperator
))
2455 // If the following token is an identifier or 'this', this is a cast. All
2456 // cases where this can be something else are handled above.
2457 if (Tok
.Next
->isOneOf(tok::identifier
, tok::kw_this
))
2460 // Look for a cast `( x ) (`.
2461 if (Tok
.Next
->is(tok::l_paren
) && Tok
.Previous
&& Tok
.Previous
->Previous
) {
2462 if (Tok
.Previous
->is(tok::identifier
) &&
2463 Tok
.Previous
->Previous
->is(tok::l_paren
)) {
2468 if (!Tok
.Next
->Next
)
2471 // If the next token after the parenthesis is a unary operator, assume
2472 // that this is cast, unless there are unexpected tokens inside the
2474 const bool NextIsAmpOrStar
= Tok
.Next
->isOneOf(tok::amp
, tok::star
);
2475 if (!(Tok
.Next
->isUnaryOperator() || NextIsAmpOrStar
) ||
2476 Tok
.Next
->is(tok::plus
) ||
2477 !Tok
.Next
->Next
->isOneOf(tok::identifier
, tok::numeric_constant
)) {
2480 if (NextIsAmpOrStar
&&
2481 (Tok
.Next
->Next
->is(tok::numeric_constant
) || Line
.InPPDirective
)) {
2484 // Search for unexpected tokens.
2485 for (FormatToken
*Prev
= Tok
.Previous
; Prev
!= Tok
.MatchingParen
;
2486 Prev
= Prev
->Previous
) {
2487 if (!Prev
->isOneOf(tok::kw_const
, tok::identifier
, tok::coloncolon
))
2493 /// Returns true if the token is used as a unary operator.
2494 bool determineUnaryOperatorByUsage(const FormatToken
&Tok
) {
2495 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2499 // These keywords are deliberately not included here because they may
2500 // precede only one of unary star/amp and plus/minus but not both. They are
2501 // either included in determineStarAmpUsage or determinePlusMinusCaretUsage.
2503 // @ - It may be followed by a unary `-` in Objective-C literals. We don't
2504 // know how they can be followed by a star or amp.
2505 if (PrevToken
->isOneOf(
2506 TT_ConditionalExpr
, tok::l_paren
, tok::comma
, tok::colon
, tok::semi
,
2507 tok::equal
, tok::question
, tok::l_square
, tok::l_brace
,
2508 tok::kw_case
, tok::kw_co_await
, tok::kw_co_return
, tok::kw_co_yield
,
2509 tok::kw_delete
, tok::kw_return
, tok::kw_throw
)) {
2513 // We put sizeof here instead of only in determineStarAmpUsage. In the cases
2514 // where the unary `+` operator is overloaded, it is reasonable to write
2515 // things like `sizeof +x`. Like commit 446d6ec996c6c3.
2516 if (PrevToken
->is(tok::kw_sizeof
))
2519 // A sequence of leading unary operators.
2520 if (PrevToken
->isOneOf(TT_CastRParen
, TT_UnaryOperator
))
2523 // There can't be two consecutive binary operators.
2524 if (PrevToken
->is(TT_BinaryOperator
))
2530 /// Return the type of the given token assuming it is * or &.
2531 TokenType
determineStarAmpUsage(const FormatToken
&Tok
, bool IsExpression
,
2532 bool InTemplateArgument
) {
2533 if (Style
.isJavaScript())
2534 return TT_BinaryOperator
;
2536 // && in C# must be a binary operator.
2537 if (Style
.isCSharp() && Tok
.is(tok::ampamp
))
2538 return TT_BinaryOperator
;
2540 if (Style
.isVerilog()) {
2541 // In Verilog, `*` can only be a binary operator. `&` can be either unary
2542 // or binary. `*` also includes `*>` in module path declarations in
2543 // specify blocks because merged tokens take the type of the first one by
2545 if (Tok
.is(tok::star
))
2546 return TT_BinaryOperator
;
2547 return determineUnaryOperatorByUsage(Tok
) ? TT_UnaryOperator
2548 : TT_BinaryOperator
;
2551 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2553 return TT_UnaryOperator
;
2554 if (PrevToken
->is(TT_TypeName
))
2555 return TT_PointerOrReference
;
2557 const FormatToken
*NextToken
= Tok
.getNextNonComment();
2559 if (InTemplateArgument
&& NextToken
&& NextToken
->is(tok::kw_noexcept
))
2560 return TT_BinaryOperator
;
2563 NextToken
->isOneOf(tok::arrow
, tok::equal
, tok::comma
, tok::r_paren
,
2564 TT_RequiresClause
) ||
2565 (NextToken
->is(tok::kw_noexcept
) && !IsExpression
) ||
2566 NextToken
->canBePointerOrReferenceQualifier() ||
2567 (NextToken
->is(tok::l_brace
) && !NextToken
->getNextNonComment())) {
2568 return TT_PointerOrReference
;
2571 if (PrevToken
->is(tok::coloncolon
))
2572 return TT_PointerOrReference
;
2574 if (PrevToken
->is(tok::r_paren
) && PrevToken
->is(TT_TypeDeclarationParen
))
2575 return TT_PointerOrReference
;
2577 if (determineUnaryOperatorByUsage(Tok
))
2578 return TT_UnaryOperator
;
2580 if (NextToken
->is(tok::l_square
) && NextToken
->isNot(TT_LambdaLSquare
))
2581 return TT_PointerOrReference
;
2582 if (NextToken
->is(tok::kw_operator
) && !IsExpression
)
2583 return TT_PointerOrReference
;
2584 if (NextToken
->isOneOf(tok::comma
, tok::semi
))
2585 return TT_PointerOrReference
;
2587 // After right braces, star tokens are likely to be pointers to struct,
2590 // This by itself is not sufficient to distinguish from multiplication
2591 // following a brace-initialized expression, as in:
2592 // int i = int{42} * 2;
2593 // In the struct case, the part of the struct declaration until the `{` and
2594 // the `}` are put on separate unwrapped lines; in the brace-initialized
2595 // case, the matching `{` is on the same unwrapped line, so check for the
2596 // presence of the matching brace to distinguish between those.
2597 if (PrevToken
->is(tok::r_brace
) && Tok
.is(tok::star
) &&
2598 !PrevToken
->MatchingParen
) {
2599 return TT_PointerOrReference
;
2602 if (PrevToken
->endsSequence(tok::r_square
, tok::l_square
, tok::kw_delete
))
2603 return TT_UnaryOperator
;
2605 if (PrevToken
->Tok
.isLiteral() ||
2606 PrevToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::kw_true
,
2607 tok::kw_false
, tok::r_brace
)) {
2608 return TT_BinaryOperator
;
2611 const FormatToken
*NextNonParen
= NextToken
;
2612 while (NextNonParen
&& NextNonParen
->is(tok::l_paren
))
2613 NextNonParen
= NextNonParen
->getNextNonComment();
2614 if (NextNonParen
&& (NextNonParen
->Tok
.isLiteral() ||
2615 NextNonParen
->isOneOf(tok::kw_true
, tok::kw_false
) ||
2616 NextNonParen
->isUnaryOperator())) {
2617 return TT_BinaryOperator
;
2620 // If we know we're in a template argument, there are no named declarations.
2621 // Thus, having an identifier on the right-hand side indicates a binary
2623 if (InTemplateArgument
&& NextToken
->Tok
.isAnyIdentifier())
2624 return TT_BinaryOperator
;
2626 // "&&" followed by "(", "*", or "&" is quite unlikely to be two successive
2628 if (Tok
.is(tok::ampamp
) &&
2629 NextToken
->isOneOf(tok::l_paren
, tok::star
, tok::amp
)) {
2630 return TT_BinaryOperator
;
2633 // This catches some cases where evaluation order is used as control flow:
2635 if (NextToken
->Tok
.isAnyIdentifier()) {
2636 const FormatToken
*NextNextToken
= NextToken
->getNextNonComment();
2637 if (NextNextToken
&& NextNextToken
->is(tok::arrow
))
2638 return TT_BinaryOperator
;
2641 // It is very unlikely that we are going to find a pointer or reference type
2642 // definition on the RHS of an assignment.
2643 if (IsExpression
&& !Contexts
.back().CaretFound
)
2644 return TT_BinaryOperator
;
2646 // Opeartors at class scope are likely pointer or reference members.
2647 if (!Scopes
.empty() && Scopes
.back() == ST_Class
)
2648 return TT_PointerOrReference
;
2650 // Tokens that indicate member access or chained operator& use.
2651 auto IsChainedOperatorAmpOrMember
= [](const FormatToken
*token
) {
2652 return !token
|| token
->isOneOf(tok::amp
, tok::period
, tok::arrow
,
2653 tok::arrowstar
, tok::periodstar
);
2656 // It's more likely that & represents operator& than an uninitialized
2658 if (Tok
.is(tok::amp
) && PrevToken
&& PrevToken
->Tok
.isAnyIdentifier() &&
2659 IsChainedOperatorAmpOrMember(PrevToken
->getPreviousNonComment()) &&
2660 NextToken
&& NextToken
->Tok
.isAnyIdentifier()) {
2661 if (auto NextNext
= NextToken
->getNextNonComment();
2663 (IsChainedOperatorAmpOrMember(NextNext
) || NextNext
->is(tok::semi
))) {
2664 return TT_BinaryOperator
;
2668 return TT_PointerOrReference
;
2671 TokenType
determinePlusMinusCaretUsage(const FormatToken
&Tok
) {
2672 if (determineUnaryOperatorByUsage(Tok
))
2673 return TT_UnaryOperator
;
2675 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2677 return TT_UnaryOperator
;
2679 if (PrevToken
->is(tok::at
))
2680 return TT_UnaryOperator
;
2682 // Fall back to marking the token as binary operator.
2683 return TT_BinaryOperator
;
2686 /// Determine whether ++/-- are pre- or post-increments/-decrements.
2687 TokenType
determineIncrementUsage(const FormatToken
&Tok
) {
2688 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2689 if (!PrevToken
|| PrevToken
->is(TT_CastRParen
))
2690 return TT_UnaryOperator
;
2691 if (PrevToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::identifier
))
2692 return TT_TrailingUnaryOperator
;
2694 return TT_UnaryOperator
;
2697 SmallVector
<Context
, 8> Contexts
;
2699 const FormatStyle
&Style
;
2700 AnnotatedLine
&Line
;
2701 FormatToken
*CurrentToken
;
2703 const AdditionalKeywords
&Keywords
;
2705 SmallVector
<ScopeType
> &Scopes
;
2707 // Set of "<" tokens that do not open a template parameter list. If parseAngle
2708 // determines that a specific token can't be a template opener, it will make
2709 // same decision irrespective of the decisions for tokens leading up to it.
2710 // Store this information to prevent this from causing exponential runtime.
2711 llvm::SmallPtrSet
<FormatToken
*, 16> NonTemplateLess
;
2714 static const int PrecedenceUnaryOperator
= prec::PointerToMember
+ 1;
2715 static const int PrecedenceArrowAndPeriod
= prec::PointerToMember
+ 2;
2717 /// Parses binary expressions by inserting fake parenthesis based on
2718 /// operator precedence.
2719 class ExpressionParser
{
2721 ExpressionParser(const FormatStyle
&Style
, const AdditionalKeywords
&Keywords
,
2722 AnnotatedLine
&Line
)
2723 : Style(Style
), Keywords(Keywords
), Line(Line
), Current(Line
.First
) {}
2725 /// Parse expressions with the given operator precedence.
2726 void parse(int Precedence
= 0) {
2727 // Skip 'return' and ObjC selector colons as they are not part of a binary
2729 while (Current
&& (Current
->is(tok::kw_return
) ||
2730 (Current
->is(tok::colon
) &&
2731 Current
->isOneOf(TT_ObjCMethodExpr
, TT_DictLiteral
)))) {
2735 if (!Current
|| Precedence
> PrecedenceArrowAndPeriod
)
2738 // Conditional expressions need to be parsed separately for proper nesting.
2739 if (Precedence
== prec::Conditional
) {
2740 parseConditionalExpr();
2744 // Parse unary operators, which all have a higher precedence than binary
2746 if (Precedence
== PrecedenceUnaryOperator
) {
2747 parseUnaryOperator();
2751 FormatToken
*Start
= Current
;
2752 FormatToken
*LatestOperator
= nullptr;
2753 unsigned OperatorIndex
= 0;
2754 // The first name of the current type in a port list.
2755 FormatToken
*VerilogFirstOfType
= nullptr;
2758 // In Verilog ports in a module header that don't have a type take the
2759 // type of the previous one. For example,
2760 // module a(output b,
2763 // In this case there need to be fake parentheses around b and c.
2764 if (Style
.isVerilog() && Precedence
== prec::Comma
) {
2765 VerilogFirstOfType
=
2766 verilogGroupDecl(VerilogFirstOfType
, LatestOperator
);
2769 // Consume operators with higher precedence.
2770 parse(Precedence
+ 1);
2772 // Do not assign fake parenthesis to tokens that are part of an
2773 // unexpanded macro call. The line within the macro call contains
2774 // the parenthesis and commas, and we will not find operators within
2776 if (Current
&& Current
->MacroParent
)
2779 int CurrentPrecedence
= getCurrentPrecedence();
2781 if (Precedence
== CurrentPrecedence
&& Current
&&
2782 Current
->is(TT_SelectorName
)) {
2784 addFakeParenthesis(Start
, prec::Level(Precedence
));
2788 if ((Style
.isCSharp() || Style
.isJavaScript() ||
2789 Style
.Language
== FormatStyle::LK_Java
) &&
2790 Precedence
== prec::Additive
&& Current
) {
2791 // A string can be broken without parentheses around it when it is
2792 // already in a sequence of strings joined by `+` signs.
2793 FormatToken
*Prev
= Current
->getPreviousNonComment();
2794 if (Prev
&& Prev
->is(tok::string_literal
) &&
2795 (Prev
== Start
|| Prev
->endsSequence(tok::string_literal
, tok::plus
,
2796 TT_StringInConcatenation
))) {
2797 Prev
->setType(TT_StringInConcatenation
);
2801 // At the end of the line or when an operator with lower precedence is
2802 // found, insert fake parenthesis and return.
2804 (Current
->closesScope() &&
2805 (Current
->MatchingParen
|| Current
->is(TT_TemplateString
))) ||
2806 (CurrentPrecedence
!= -1 && CurrentPrecedence
< Precedence
) ||
2807 (CurrentPrecedence
== prec::Conditional
&&
2808 Precedence
== prec::Assignment
&& Current
->is(tok::colon
))) {
2812 // Consume scopes: (), [], <> and {}
2813 // In addition to that we handle require clauses as scope, so that the
2814 // constraints in that are correctly indented.
2815 if (Current
->opensScope() ||
2816 Current
->isOneOf(TT_RequiresClause
,
2817 TT_RequiresClauseInARequiresExpression
)) {
2818 // In fragment of a JavaScript template string can look like '}..${' and
2819 // thus close a scope and open a new one at the same time.
2820 while (Current
&& (!Current
->closesScope() || Current
->opensScope())) {
2827 if (CurrentPrecedence
== Precedence
) {
2829 LatestOperator
->NextOperator
= Current
;
2830 LatestOperator
= Current
;
2831 Current
->OperatorIndex
= OperatorIndex
;
2834 next(/*SkipPastLeadingComments=*/Precedence
> 0);
2838 // Group variables of the same type.
2839 if (Style
.isVerilog() && Precedence
== prec::Comma
&& VerilogFirstOfType
)
2840 addFakeParenthesis(VerilogFirstOfType
, prec::Comma
);
2842 if (LatestOperator
&& (Current
|| Precedence
> 0)) {
2843 // The requires clauses do not neccessarily end in a semicolon or a brace,
2844 // but just go over to struct/class or a function declaration, we need to
2845 // intervene so that the fake right paren is inserted correctly.
2848 Start
->Previous
->isOneOf(TT_RequiresClause
,
2849 TT_RequiresClauseInARequiresExpression
))
2851 auto Ret
= Current
? Current
: Line
.Last
;
2852 while (!Ret
->ClosesRequiresClause
&& Ret
->Previous
)
2853 Ret
= Ret
->Previous
;
2858 if (Precedence
== PrecedenceArrowAndPeriod
) {
2859 // Call expressions don't have a binary operator precedence.
2860 addFakeParenthesis(Start
, prec::Unknown
, End
);
2862 addFakeParenthesis(Start
, prec::Level(Precedence
), End
);
2868 /// Gets the precedence (+1) of the given token for binary operators
2869 /// and other tokens that we treat like binary operators.
2870 int getCurrentPrecedence() {
2872 const FormatToken
*NextNonComment
= Current
->getNextNonComment();
2873 if (Current
->is(TT_ConditionalExpr
))
2874 return prec::Conditional
;
2875 if (NextNonComment
&& Current
->is(TT_SelectorName
) &&
2876 (NextNonComment
->isOneOf(TT_DictLiteral
, TT_JsTypeColon
) ||
2877 (Style
.isProto() && NextNonComment
->is(tok::less
)))) {
2878 return prec::Assignment
;
2880 if (Current
->is(TT_JsComputedPropertyName
))
2881 return prec::Assignment
;
2882 if (Current
->is(TT_TrailingReturnArrow
))
2884 if (Current
->is(TT_FatArrow
))
2885 return prec::Assignment
;
2886 if (Current
->isOneOf(tok::semi
, TT_InlineASMColon
, TT_SelectorName
) ||
2887 (Current
->is(tok::comment
) && NextNonComment
&&
2888 NextNonComment
->is(TT_SelectorName
))) {
2891 if (Current
->is(TT_RangeBasedForLoopColon
))
2893 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
2894 Current
->is(Keywords
.kw_instanceof
)) {
2895 return prec::Relational
;
2897 if (Style
.isJavaScript() &&
2898 Current
->isOneOf(Keywords
.kw_in
, Keywords
.kw_as
)) {
2899 return prec::Relational
;
2901 if (Current
->is(TT_BinaryOperator
) || Current
->is(tok::comma
))
2902 return Current
->getPrecedence();
2903 if (Current
->isOneOf(tok::period
, tok::arrow
) &&
2904 Current
->isNot(TT_TrailingReturnArrow
)) {
2905 return PrecedenceArrowAndPeriod
;
2907 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
2908 Current
->isOneOf(Keywords
.kw_extends
, Keywords
.kw_implements
,
2909 Keywords
.kw_throws
)) {
2912 // In Verilog case labels are not on separate lines straight out of
2913 // UnwrappedLineParser. The colon is not part of an expression.
2914 if (Style
.isVerilog() && Current
->is(tok::colon
))
2920 void addFakeParenthesis(FormatToken
*Start
, prec::Level Precedence
,
2921 FormatToken
*End
= nullptr) {
2922 Start
->FakeLParens
.push_back(Precedence
);
2923 if (Precedence
> prec::Unknown
)
2924 Start
->StartsBinaryExpression
= true;
2925 if (!End
&& Current
)
2926 End
= Current
->getPreviousNonComment();
2929 if (Precedence
> prec::Unknown
)
2930 End
->EndsBinaryExpression
= true;
2934 /// Parse unary operator expressions and surround them with fake
2935 /// parentheses if appropriate.
2936 void parseUnaryOperator() {
2937 llvm::SmallVector
<FormatToken
*, 2> Tokens
;
2938 while (Current
&& Current
->is(TT_UnaryOperator
)) {
2939 Tokens
.push_back(Current
);
2942 parse(PrecedenceArrowAndPeriod
);
2943 for (FormatToken
*Token
: llvm::reverse(Tokens
)) {
2944 // The actual precedence doesn't matter.
2945 addFakeParenthesis(Token
, prec::Unknown
);
2949 void parseConditionalExpr() {
2950 while (Current
&& Current
->isTrailingComment())
2952 FormatToken
*Start
= Current
;
2953 parse(prec::LogicalOr
);
2954 if (!Current
|| Current
->isNot(tok::question
))
2957 parse(prec::Assignment
);
2958 if (!Current
|| Current
->isNot(TT_ConditionalExpr
))
2961 parse(prec::Assignment
);
2962 addFakeParenthesis(Start
, prec::Conditional
);
2965 void next(bool SkipPastLeadingComments
= true) {
2967 Current
= Current
->Next
;
2969 (Current
->NewlinesBefore
== 0 || SkipPastLeadingComments
) &&
2970 Current
->isTrailingComment()) {
2971 Current
= Current
->Next
;
2975 // Add fake parenthesis around declarations of the same type for example in a
2976 // module prototype. Return the first port / variable of the current type.
2977 FormatToken
*verilogGroupDecl(FormatToken
*FirstOfType
,
2978 FormatToken
*PreviousComma
) {
2982 FormatToken
*Start
= Current
;
2985 while (Start
->startsSequence(tok::l_paren
, tok::star
)) {
2986 if (!(Start
= Start
->MatchingParen
) ||
2987 !(Start
= Start
->getNextNonComment())) {
2992 FormatToken
*Tok
= Start
;
2994 if (Tok
->is(Keywords
.kw_assign
))
2995 Tok
= Tok
->getNextNonComment();
2997 // Skip any type qualifiers to find the first identifier. It may be either a
2998 // new type name or a variable name. There can be several type qualifiers
2999 // preceding a variable name, and we can not tell them apart by looking at
3000 // the word alone since a macro can be defined as either a type qualifier or
3001 // a variable name. Thus we use the last word before the dimensions instead
3002 // of the first word as the candidate for the variable or type name.
3003 FormatToken
*First
= nullptr;
3005 FormatToken
*Next
= Tok
->getNextNonComment();
3007 if (Tok
->is(tok::hash
)) {
3008 // Start of a macro expansion.
3012 Tok
= Tok
->getNextNonComment();
3013 } else if (Tok
->is(tok::hashhash
)) {
3014 // Concatenation. Skip.
3017 Tok
= Tok
->getNextNonComment();
3018 } else if (Keywords
.isVerilogQualifier(*Tok
) ||
3019 Keywords
.isVerilogIdentifier(*Tok
)) {
3022 // The name may have dots like `interface_foo.modport_foo`.
3023 while (Tok
&& Tok
->isOneOf(tok::period
, tok::coloncolon
) &&
3024 (Tok
= Tok
->getNextNonComment())) {
3025 if (Keywords
.isVerilogIdentifier(*Tok
))
3026 Tok
= Tok
->getNextNonComment();
3030 } else if (Tok
->is(tok::l_paren
)) {
3031 // Make sure the parenthesized list is a drive strength. Otherwise the
3032 // statement may be a module instantiation in which case we have already
3033 // found the instance name.
3035 Keywords
.kw_highz0
, Keywords
.kw_highz1
, Keywords
.kw_large
,
3036 Keywords
.kw_medium
, Keywords
.kw_pull0
, Keywords
.kw_pull1
,
3037 Keywords
.kw_small
, Keywords
.kw_strong0
, Keywords
.kw_strong1
,
3038 Keywords
.kw_supply0
, Keywords
.kw_supply1
, Keywords
.kw_weak0
,
3039 Keywords
.kw_weak1
)) {
3040 Tok
->setType(TT_VerilogStrength
);
3041 Tok
= Tok
->MatchingParen
;
3043 Tok
->setType(TT_VerilogStrength
);
3044 Tok
= Tok
->getNextNonComment();
3049 } else if (Tok
->is(tok::hash
)) {
3050 if (Next
->is(tok::l_paren
))
3051 Next
= Next
->MatchingParen
;
3053 Tok
= Next
->getNextNonComment();
3059 // Find the second identifier. If it exists it will be the name.
3060 FormatToken
*Second
= nullptr;
3062 while (Tok
&& Tok
->is(tok::l_square
) && (Tok
= Tok
->MatchingParen
))
3063 Tok
= Tok
->getNextNonComment();
3064 if (Tok
&& (Tok
->is(tok::hash
) || Keywords
.isVerilogIdentifier(*Tok
)))
3067 // If the second identifier doesn't exist and there are qualifiers, the type
3069 FormatToken
*TypedName
= nullptr;
3072 if (First
&& First
->is(TT_Unknown
))
3073 First
->setType(TT_VerilogDimensionedTypeName
);
3074 } else if (First
!= Start
) {
3075 // If 'First' is null, then this isn't a declaration, 'TypedName' gets set
3076 // to null as intended.
3081 // This is a declaration with a new type.
3082 if (TypedName
->is(TT_Unknown
))
3083 TypedName
->setType(TT_StartOfName
);
3084 // Group variables of the previous type.
3085 if (FirstOfType
&& PreviousComma
) {
3086 PreviousComma
->setType(TT_VerilogTypeComma
);
3087 addFakeParenthesis(FirstOfType
, prec::Comma
, PreviousComma
->Previous
);
3090 FirstOfType
= TypedName
;
3092 // Don't let higher precedence handle the qualifiers. For example if we
3095 // We skip `parameter` here. This way the fake parentheses for the
3096 // assignment will be around `x = 0`.
3097 while (Current
&& Current
!= FirstOfType
) {
3098 if (Current
->opensScope()) {
3109 const FormatStyle
&Style
;
3110 const AdditionalKeywords
&Keywords
;
3111 const AnnotatedLine
&Line
;
3112 FormatToken
*Current
;
3115 } // end anonymous namespace
3117 void TokenAnnotator::setCommentLineLevels(
3118 SmallVectorImpl
<AnnotatedLine
*> &Lines
) const {
3119 const AnnotatedLine
*NextNonCommentLine
= nullptr;
3120 for (AnnotatedLine
*Line
: llvm::reverse(Lines
)) {
3121 assert(Line
->First
);
3123 // If the comment is currently aligned with the line immediately following
3124 // it, that's probably intentional and we should keep it.
3125 if (NextNonCommentLine
&& NextNonCommentLine
->First
->NewlinesBefore
< 2 &&
3126 Line
->isComment() && !isClangFormatOff(Line
->First
->TokenText
) &&
3127 NextNonCommentLine
->First
->OriginalColumn
==
3128 Line
->First
->OriginalColumn
) {
3129 const bool PPDirectiveOrImportStmt
=
3130 NextNonCommentLine
->Type
== LT_PreprocessorDirective
||
3131 NextNonCommentLine
->Type
== LT_ImportStatement
;
3132 if (PPDirectiveOrImportStmt
)
3133 Line
->Type
= LT_CommentAbovePPDirective
;
3134 // Align comments for preprocessor lines with the # in column 0 if
3135 // preprocessor lines are not indented. Otherwise, align with the next
3137 Line
->Level
= Style
.IndentPPDirectives
!= FormatStyle::PPDIS_BeforeHash
&&
3138 PPDirectiveOrImportStmt
3140 : NextNonCommentLine
->Level
;
3142 NextNonCommentLine
= Line
->First
->isNot(tok::r_brace
) ? Line
: nullptr;
3145 setCommentLineLevels(Line
->Children
);
3149 static unsigned maxNestingDepth(const AnnotatedLine
&Line
) {
3150 unsigned Result
= 0;
3151 for (const auto *Tok
= Line
.First
; Tok
; Tok
= Tok
->Next
)
3152 Result
= std::max(Result
, Tok
->NestingLevel
);
3156 // Returns the name of a function with no return type, e.g. a constructor or
3158 static FormatToken
*getFunctionName(const AnnotatedLine
&Line
) {
3159 for (FormatToken
*Tok
= Line
.getFirstNonComment(), *Name
= nullptr; Tok
;
3160 Tok
= Tok
->getNextNonComment()) {
3161 // Skip C++11 attributes both before and after the function name.
3162 if (Tok
->is(tok::l_square
) && Tok
->is(TT_AttributeSquare
)) {
3163 Tok
= Tok
->MatchingParen
;
3169 // Make sure the name is followed by a pair of parentheses.
3171 return Tok
->is(tok::l_paren
) && Tok
->isNot(TT_FunctionTypeLParen
) &&
3177 // Skip keywords that may precede the constructor/destructor name.
3178 if (Tok
->isOneOf(tok::kw_friend
, tok::kw_inline
, tok::kw_virtual
,
3179 tok::kw_constexpr
, tok::kw_consteval
, tok::kw_explicit
)) {
3183 // A qualified name may start from the global namespace.
3184 if (Tok
->is(tok::coloncolon
)) {
3190 // Skip to the unqualified part of the name.
3191 while (Tok
->startsSequence(tok::identifier
, tok::coloncolon
)) {
3193 Tok
= Tok
->Next
->Next
;
3198 // Skip the `~` if a destructor name.
3199 if (Tok
->is(tok::tilde
)) {
3205 // Make sure the name is not already annotated, e.g. as NamespaceMacro.
3206 if (Tok
->isNot(tok::identifier
) || Tok
->isNot(TT_Unknown
))
3215 // Checks if Tok is a constructor/destructor name qualified by its class name.
3216 static bool isCtorOrDtorName(const FormatToken
*Tok
) {
3217 assert(Tok
&& Tok
->is(tok::identifier
));
3218 const auto *Prev
= Tok
->Previous
;
3220 if (Prev
&& Prev
->is(tok::tilde
))
3221 Prev
= Prev
->Previous
;
3223 if (!Prev
|| !Prev
->endsSequence(tok::coloncolon
, tok::identifier
))
3226 assert(Prev
->Previous
);
3227 return Prev
->Previous
->TokenText
== Tok
->TokenText
;
3230 void TokenAnnotator::annotate(AnnotatedLine
&Line
) {
3231 AnnotatingParser
Parser(Style
, Line
, Keywords
, Scopes
);
3232 Line
.Type
= Parser
.parseLine();
3234 for (auto &Child
: Line
.Children
)
3237 // With very deep nesting, ExpressionParser uses lots of stack and the
3238 // formatting algorithm is very slow. We're not going to do a good job here
3239 // anyway - it's probably generated code being formatted by mistake.
3240 // Just skip the whole line.
3241 if (maxNestingDepth(Line
) > 50)
3242 Line
.Type
= LT_Invalid
;
3244 if (Line
.Type
== LT_Invalid
)
3247 ExpressionParser
ExprParser(Style
, Keywords
, Line
);
3250 if (Style
.isCpp()) {
3251 auto *Tok
= getFunctionName(Line
);
3252 if (Tok
&& ((!Scopes
.empty() && Scopes
.back() == ST_Class
) ||
3253 Line
.endsWith(TT_FunctionLBrace
) || isCtorOrDtorName(Tok
))) {
3254 Tok
->setFinalizedType(TT_CtorDtorDeclName
);
3258 if (Line
.startsWith(TT_ObjCMethodSpecifier
))
3259 Line
.Type
= LT_ObjCMethodDecl
;
3260 else if (Line
.startsWith(TT_ObjCDecl
))
3261 Line
.Type
= LT_ObjCDecl
;
3262 else if (Line
.startsWith(TT_ObjCProperty
))
3263 Line
.Type
= LT_ObjCProperty
;
3265 auto *First
= Line
.First
;
3266 First
->SpacesRequiredBefore
= 1;
3267 First
->CanBreakBefore
= First
->MustBreakBefore
;
3269 if (First
->is(tok::eof
) && First
->NewlinesBefore
== 0 &&
3270 Style
.InsertNewlineAtEOF
) {
3271 First
->NewlinesBefore
= 1;
3275 // This function heuristically determines whether 'Current' starts the name of a
3276 // function declaration.
3277 static bool isFunctionDeclarationName(bool IsCpp
, const FormatToken
&Current
,
3278 const AnnotatedLine
&Line
,
3279 FormatToken
*&ClosingParen
) {
3280 assert(Current
.Previous
);
3282 if (Current
.is(TT_FunctionDeclarationName
))
3285 if (!Current
.Tok
.getIdentifierInfo())
3288 auto skipOperatorName
= [](const FormatToken
*Next
) -> const FormatToken
* {
3289 for (; Next
; Next
= Next
->Next
) {
3290 if (Next
->is(TT_OverloadedOperatorLParen
))
3292 if (Next
->is(TT_OverloadedOperator
))
3294 if (Next
->isOneOf(tok::kw_new
, tok::kw_delete
)) {
3295 // For 'new[]' and 'delete[]'.
3297 Next
->Next
->startsSequence(tok::l_square
, tok::r_square
)) {
3298 Next
= Next
->Next
->Next
;
3302 if (Next
->startsSequence(tok::l_square
, tok::r_square
)) {
3303 // For operator[]().
3307 if ((Next
->isSimpleTypeSpecifier() || Next
->is(tok::identifier
)) &&
3308 Next
->Next
&& Next
->Next
->isPointerOrReference()) {
3309 // For operator void*(), operator char*(), operator Foo*().
3313 if (Next
->is(TT_TemplateOpener
) && Next
->MatchingParen
) {
3314 Next
= Next
->MatchingParen
;
3323 // Find parentheses of parameter list.
3324 const FormatToken
*Next
= Current
.Next
;
3325 if (Current
.is(tok::kw_operator
)) {
3326 const auto *Previous
= Current
.Previous
;
3327 if (Previous
->Tok
.getIdentifierInfo() &&
3328 !Previous
->isOneOf(tok::kw_return
, tok::kw_co_return
)) {
3331 if (Previous
->is(tok::r_paren
) && Previous
->is(TT_TypeDeclarationParen
)) {
3332 assert(Previous
->MatchingParen
);
3333 assert(Previous
->MatchingParen
->is(tok::l_paren
));
3334 assert(Previous
->MatchingParen
->is(TT_TypeDeclarationParen
));
3337 if (!Previous
->isPointerOrReference() && Previous
->isNot(TT_TemplateCloser
))
3339 Next
= skipOperatorName(Next
);
3341 if (Current
.isNot(TT_StartOfName
) || Current
.NestingLevel
!= 0)
3343 for (; Next
; Next
= Next
->Next
) {
3344 if (Next
->is(TT_TemplateOpener
) && Next
->MatchingParen
) {
3345 Next
= Next
->MatchingParen
;
3346 } else if (Next
->is(tok::coloncolon
)) {
3350 if (Next
->is(tok::kw_operator
)) {
3351 Next
= skipOperatorName(Next
->Next
);
3354 if (Next
->isNot(tok::identifier
))
3356 } else if (isCppAttribute(IsCpp
, *Next
)) {
3357 Next
= Next
->MatchingParen
;
3360 } else if (Next
->is(tok::l_paren
)) {
3368 // Check whether parameter list can belong to a function declaration.
3369 if (!Next
|| Next
->isNot(tok::l_paren
) || !Next
->MatchingParen
)
3371 ClosingParen
= Next
->MatchingParen
;
3372 assert(ClosingParen
->is(tok::r_paren
));
3373 // If the lines ends with "{", this is likely a function definition.
3374 if (Line
.Last
->is(tok::l_brace
))
3376 if (Next
->Next
== ClosingParen
)
3377 return true; // Empty parentheses.
3378 // If there is an &/&& after the r_paren, this is likely a function.
3379 if (ClosingParen
->Next
&& ClosingParen
->Next
->is(TT_PointerOrReference
))
3382 // Check for K&R C function definitions (and C++ function definitions with
3383 // unnamed parameters), e.g.:
3388 // bool g(size_t = 0, bool b = false)
3392 if (IsCpp
&& Next
->Next
&& Next
->Next
->is(tok::identifier
) &&
3393 !Line
.endsWith(tok::semi
)) {
3397 for (const FormatToken
*Tok
= Next
->Next
; Tok
&& Tok
!= ClosingParen
;
3399 if (Tok
->is(TT_TypeDeclarationParen
))
3401 if (Tok
->isOneOf(tok::l_paren
, TT_TemplateOpener
) && Tok
->MatchingParen
) {
3402 Tok
= Tok
->MatchingParen
;
3405 if (Tok
->is(tok::kw_const
) || Tok
->isSimpleTypeSpecifier() ||
3406 Tok
->isOneOf(TT_PointerOrReference
, TT_StartOfName
, tok::ellipsis
)) {
3409 if (Tok
->isOneOf(tok::l_brace
, TT_ObjCMethodExpr
) || Tok
->Tok
.isLiteral())
3415 bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine
&Line
) const {
3416 assert(Line
.MightBeFunctionDecl
);
3418 if ((Style
.AlwaysBreakAfterReturnType
== FormatStyle::RTBS_TopLevel
||
3419 Style
.AlwaysBreakAfterReturnType
==
3420 FormatStyle::RTBS_TopLevelDefinitions
) &&
3425 switch (Style
.AlwaysBreakAfterReturnType
) {
3426 case FormatStyle::RTBS_None
:
3428 case FormatStyle::RTBS_All
:
3429 case FormatStyle::RTBS_TopLevel
:
3431 case FormatStyle::RTBS_AllDefinitions
:
3432 case FormatStyle::RTBS_TopLevelDefinitions
:
3433 return Line
.mightBeFunctionDefinition();
3439 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine
&Line
) const {
3440 for (AnnotatedLine
*ChildLine
: Line
.Children
)
3441 calculateFormattingInformation(*ChildLine
);
3443 Line
.First
->TotalLength
=
3444 Line
.First
->IsMultiline
? Style
.ColumnLimit
3445 : Line
.FirstStartColumn
+ Line
.First
->ColumnWidth
;
3446 FormatToken
*Current
= Line
.First
->Next
;
3447 bool InFunctionDecl
= Line
.MightBeFunctionDecl
;
3448 bool AlignArrayOfStructures
=
3449 (Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
&&
3450 Line
.Type
== LT_ArrayOfStructInitializer
);
3451 if (AlignArrayOfStructures
)
3452 calculateArrayInitializerColumnList(Line
);
3454 const bool IsCpp
= Style
.isCpp();
3455 bool SeenName
= false;
3456 bool LineIsFunctionDeclaration
= false;
3457 FormatToken
*ClosingParen
= nullptr;
3458 FormatToken
*AfterLastAttribute
= nullptr;
3460 for (auto *Tok
= Current
; Tok
; Tok
= Tok
->Next
) {
3461 if (Tok
->is(TT_StartOfName
))
3463 if (Tok
->Previous
->EndsCppAttributeGroup
)
3464 AfterLastAttribute
= Tok
;
3465 if (const bool IsCtorOrDtor
= Tok
->is(TT_CtorDtorDeclName
);
3467 isFunctionDeclarationName(Style
.isCpp(), *Tok
, Line
, ClosingParen
)) {
3468 if (!IsCtorOrDtor
) {
3469 LineIsFunctionDeclaration
= true;
3470 Tok
->setFinalizedType(TT_FunctionDeclarationName
);
3477 if (IsCpp
&& LineIsFunctionDeclaration
&&
3478 Line
.endsWith(tok::semi
, tok::r_brace
)) {
3479 auto *Tok
= Line
.Last
->Previous
;
3480 while (Tok
->isNot(tok::r_brace
))
3481 Tok
= Tok
->Previous
;
3482 if (auto *LBrace
= Tok
->MatchingParen
; LBrace
) {
3483 assert(LBrace
->is(tok::l_brace
));
3484 Tok
->setBlockKind(BK_Block
);
3485 LBrace
->setBlockKind(BK_Block
);
3486 LBrace
->setFinalizedType(TT_FunctionLBrace
);
3490 if (IsCpp
&& SeenName
&& AfterLastAttribute
&&
3491 mustBreakAfterAttributes(*AfterLastAttribute
, Style
)) {
3492 AfterLastAttribute
->MustBreakBefore
= true;
3493 if (LineIsFunctionDeclaration
)
3494 Line
.ReturnTypeWrapped
= true;
3498 if (!LineIsFunctionDeclaration
) {
3499 // Annotate */&/&& in `operator` function calls as binary operators.
3500 for (const auto *Tok
= Line
.First
; Tok
; Tok
= Tok
->Next
) {
3501 if (Tok
->isNot(tok::kw_operator
))
3505 } while (Tok
&& Tok
->isNot(TT_OverloadedOperatorLParen
));
3508 const auto *LeftParen
= Tok
;
3509 for (Tok
= Tok
->Next
; Tok
&& Tok
!= LeftParen
->MatchingParen
;
3511 if (Tok
->isNot(tok::identifier
))
3513 auto *Next
= Tok
->Next
;
3514 const bool NextIsBinaryOperator
=
3515 Next
&& Next
->isPointerOrReference() && Next
->Next
&&
3516 Next
->Next
->is(tok::identifier
);
3517 if (!NextIsBinaryOperator
)
3519 Next
->setType(TT_BinaryOperator
);
3523 } else if (ClosingParen
) {
3524 for (auto *Tok
= ClosingParen
->Next
; Tok
; Tok
= Tok
->Next
) {
3525 if (Tok
->is(tok::arrow
)) {
3526 Tok
->setType(TT_TrailingReturnArrow
);
3529 if (Tok
->isNot(TT_TrailingAnnotation
))
3531 const auto *Next
= Tok
->Next
;
3532 if (!Next
|| Next
->isNot(tok::l_paren
))
3534 Tok
= Next
->MatchingParen
;
3542 const FormatToken
*Prev
= Current
->Previous
;
3543 if (Current
->is(TT_LineComment
)) {
3544 if (Prev
->is(BK_BracedInit
) && Prev
->opensScope()) {
3545 Current
->SpacesRequiredBefore
=
3546 (Style
.Cpp11BracedListStyle
&& !Style
.SpacesInParensOptions
.Other
)
3549 } else if (Prev
->is(TT_VerilogMultiLineListLParen
)) {
3550 Current
->SpacesRequiredBefore
= 0;
3552 Current
->SpacesRequiredBefore
= Style
.SpacesBeforeTrailingComments
;
3555 // If we find a trailing comment, iterate backwards to determine whether
3556 // it seems to relate to a specific parameter. If so, break before that
3557 // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
3558 // to the previous line in:
3562 if (!Current
->HasUnescapedNewline
) {
3563 for (FormatToken
*Parameter
= Current
->Previous
; Parameter
;
3564 Parameter
= Parameter
->Previous
) {
3565 if (Parameter
->isOneOf(tok::comment
, tok::r_brace
))
3567 if (Parameter
->Previous
&& Parameter
->Previous
->is(tok::comma
)) {
3568 if (Parameter
->Previous
->isNot(TT_CtorInitializerComma
) &&
3569 Parameter
->HasUnescapedNewline
) {
3570 Parameter
->MustBreakBefore
= true;
3576 } else if (!Current
->Finalized
&& Current
->SpacesRequiredBefore
== 0 &&
3577 spaceRequiredBefore(Line
, *Current
)) {
3578 Current
->SpacesRequiredBefore
= 1;
3581 const auto &Children
= Prev
->Children
;
3582 if (!Children
.empty() && Children
.back()->Last
->is(TT_LineComment
)) {
3583 Current
->MustBreakBefore
= true;
3585 Current
->MustBreakBefore
=
3586 Current
->MustBreakBefore
|| mustBreakBefore(Line
, *Current
);
3587 if (!Current
->MustBreakBefore
&& InFunctionDecl
&&
3588 Current
->is(TT_FunctionDeclarationName
)) {
3589 Current
->MustBreakBefore
= mustBreakForReturnType(Line
);
3593 Current
->CanBreakBefore
=
3594 Current
->MustBreakBefore
|| canBreakBefore(Line
, *Current
);
3595 unsigned ChildSize
= 0;
3596 if (Prev
->Children
.size() == 1) {
3597 FormatToken
&LastOfChild
= *Prev
->Children
[0]->Last
;
3598 ChildSize
= LastOfChild
.isTrailingComment() ? Style
.ColumnLimit
3599 : LastOfChild
.TotalLength
+ 1;
3601 if (Current
->MustBreakBefore
|| Prev
->Children
.size() > 1 ||
3602 (Prev
->Children
.size() == 1 &&
3603 Prev
->Children
[0]->First
->MustBreakBefore
) ||
3604 Current
->IsMultiline
) {
3605 Current
->TotalLength
= Prev
->TotalLength
+ Style
.ColumnLimit
;
3607 Current
->TotalLength
= Prev
->TotalLength
+ Current
->ColumnWidth
+
3608 ChildSize
+ Current
->SpacesRequiredBefore
;
3611 if (Current
->is(TT_CtorInitializerColon
))
3612 InFunctionDecl
= false;
3614 // FIXME: Only calculate this if CanBreakBefore is true once static
3615 // initializers etc. are sorted out.
3616 // FIXME: Move magic numbers to a better place.
3618 // Reduce penalty for aligning ObjC method arguments using the colon
3619 // alignment as this is the canonical way (still prefer fitting everything
3620 // into one line if possible). Trying to fit a whole expression into one
3621 // line should not force other line breaks (e.g. when ObjC method
3622 // expression is a part of other expression).
3623 Current
->SplitPenalty
= splitPenalty(Line
, *Current
, InFunctionDecl
);
3624 if (Style
.Language
== FormatStyle::LK_ObjC
&&
3625 Current
->is(TT_SelectorName
) && Current
->ParameterIndex
> 0) {
3626 if (Current
->ParameterIndex
== 1)
3627 Current
->SplitPenalty
+= 5 * Current
->BindingStrength
;
3629 Current
->SplitPenalty
+= 20 * Current
->BindingStrength
;
3632 Current
= Current
->Next
;
3635 calculateUnbreakableTailLengths(Line
);
3636 unsigned IndentLevel
= Line
.Level
;
3637 for (Current
= Line
.First
; Current
; Current
= Current
->Next
) {
3639 Current
->Role
->precomputeFormattingInfos(Current
);
3640 if (Current
->MatchingParen
&&
3641 Current
->MatchingParen
->opensBlockOrBlockTypeList(Style
) &&
3645 Current
->IndentLevel
= IndentLevel
;
3646 if (Current
->opensBlockOrBlockTypeList(Style
))
3650 LLVM_DEBUG({ printDebugInfo(Line
); });
3653 void TokenAnnotator::calculateUnbreakableTailLengths(
3654 AnnotatedLine
&Line
) const {
3655 unsigned UnbreakableTailLength
= 0;
3656 FormatToken
*Current
= Line
.Last
;
3658 Current
->UnbreakableTailLength
= UnbreakableTailLength
;
3659 if (Current
->CanBreakBefore
||
3660 Current
->isOneOf(tok::comment
, tok::string_literal
)) {
3661 UnbreakableTailLength
= 0;
3663 UnbreakableTailLength
+=
3664 Current
->ColumnWidth
+ Current
->SpacesRequiredBefore
;
3666 Current
= Current
->Previous
;
3670 void TokenAnnotator::calculateArrayInitializerColumnList(
3671 AnnotatedLine
&Line
) const {
3672 if (Line
.First
== Line
.Last
)
3674 auto *CurrentToken
= Line
.First
;
3675 CurrentToken
->ArrayInitializerLineStart
= true;
3677 while (CurrentToken
&& CurrentToken
!= Line
.Last
) {
3678 if (CurrentToken
->is(tok::l_brace
)) {
3679 CurrentToken
->IsArrayInitializer
= true;
3680 if (CurrentToken
->Next
)
3681 CurrentToken
->Next
->MustBreakBefore
= true;
3683 calculateInitializerColumnList(Line
, CurrentToken
->Next
, Depth
+ 1);
3685 CurrentToken
= CurrentToken
->Next
;
3690 FormatToken
*TokenAnnotator::calculateInitializerColumnList(
3691 AnnotatedLine
&Line
, FormatToken
*CurrentToken
, unsigned Depth
) const {
3692 while (CurrentToken
&& CurrentToken
!= Line
.Last
) {
3693 if (CurrentToken
->is(tok::l_brace
))
3695 else if (CurrentToken
->is(tok::r_brace
))
3697 if (Depth
== 2 && CurrentToken
->isOneOf(tok::l_brace
, tok::comma
)) {
3698 CurrentToken
= CurrentToken
->Next
;
3701 CurrentToken
->StartsColumn
= true;
3702 CurrentToken
= CurrentToken
->Previous
;
3704 CurrentToken
= CurrentToken
->Next
;
3706 return CurrentToken
;
3709 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine
&Line
,
3710 const FormatToken
&Tok
,
3711 bool InFunctionDecl
) const {
3712 const FormatToken
&Left
= *Tok
.Previous
;
3713 const FormatToken
&Right
= Tok
;
3715 if (Left
.is(tok::semi
))
3718 // Language specific handling.
3719 if (Style
.Language
== FormatStyle::LK_Java
) {
3720 if (Right
.isOneOf(Keywords
.kw_extends
, Keywords
.kw_throws
))
3722 if (Right
.is(Keywords
.kw_implements
))
3724 if (Left
.is(tok::comma
) && Left
.NestingLevel
== 0)
3726 } else if (Style
.isJavaScript()) {
3727 if (Right
.is(Keywords
.kw_function
) && Left
.isNot(tok::comma
))
3729 if (Left
.is(TT_JsTypeColon
))
3731 if ((Left
.is(TT_TemplateString
) && Left
.TokenText
.ends_with("${")) ||
3732 (Right
.is(TT_TemplateString
) && Right
.TokenText
.starts_with("}"))) {
3735 // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()".
3736 if (Left
.opensScope() && Right
.closesScope())
3738 } else if (Style
.Language
== FormatStyle::LK_Proto
) {
3739 if (Right
.is(tok::l_square
))
3741 if (Right
.is(tok::period
))
3745 if (Right
.is(tok::identifier
) && Right
.Next
&& Right
.Next
->is(TT_DictLiteral
))
3747 if (Right
.is(tok::l_square
)) {
3748 if (Left
.is(tok::r_square
))
3750 // Slightly prefer formatting local lambda definitions like functions.
3751 if (Right
.is(TT_LambdaLSquare
) && Left
.is(tok::equal
))
3753 if (!Right
.isOneOf(TT_ObjCMethodExpr
, TT_LambdaLSquare
,
3754 TT_ArrayInitializerLSquare
,
3755 TT_DesignatedInitializerLSquare
, TT_AttributeSquare
)) {
3760 if (Left
.is(tok::coloncolon
))
3762 if (Right
.isOneOf(TT_StartOfName
, TT_FunctionDeclarationName
) ||
3763 Right
.is(tok::kw_operator
)) {
3764 if (Line
.startsWith(tok::kw_for
) && Right
.PartOfMultiVariableDeclStmt
)
3766 if (Left
.is(TT_StartOfName
))
3768 if (InFunctionDecl
&& Right
.NestingLevel
== 0)
3769 return Style
.PenaltyReturnTypeOnItsOwnLine
;
3772 if (Right
.is(TT_PointerOrReference
))
3774 if (Right
.is(TT_TrailingReturnArrow
))
3776 if (Left
.is(tok::equal
) && Right
.is(tok::l_brace
))
3778 if (Left
.is(TT_CastRParen
))
3780 if (Left
.isOneOf(tok::kw_class
, tok::kw_struct
, tok::kw_union
))
3782 if (Left
.is(tok::comment
))
3785 if (Left
.isOneOf(TT_RangeBasedForLoopColon
, TT_InheritanceColon
,
3786 TT_CtorInitializerColon
)) {
3790 if (Right
.isMemberAccess()) {
3791 // Breaking before the "./->" of a chained call/member access is reasonably
3792 // cheap, as formatting those with one call per line is generally
3793 // desirable. In particular, it should be cheaper to break before the call
3794 // than it is to break inside a call's parameters, which could lead to weird
3795 // "hanging" indents. The exception is the very last "./->" to support this
3796 // frequent pattern:
3798 // aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc(
3801 // which might otherwise be blown up onto many lines. Here, clang-format
3802 // won't produce "hanging" indents anyway as there is no other trailing
3805 // Also apply higher penalty is not a call as that might lead to a wrapping
3809 // .aaaaaaaaa.bbbbbbbb(cccccccc);
3810 return !Right
.NextOperator
|| !Right
.NextOperator
->Previous
->closesScope()
3815 if (Right
.is(TT_TrailingAnnotation
) &&
3816 (!Right
.Next
|| Right
.Next
->isNot(tok::l_paren
))) {
3817 // Moving trailing annotations to the next line is fine for ObjC method
3819 if (Line
.startsWith(TT_ObjCMethodSpecifier
))
3821 // Generally, breaking before a trailing annotation is bad unless it is
3822 // function-like. It seems to be especially preferable to keep standard
3823 // annotations (i.e. "const", "final" and "override") on the same line.
3824 // Use a slightly higher penalty after ")" so that annotations like
3825 // "const override" are kept together.
3826 bool is_short_annotation
= Right
.TokenText
.size() < 10;
3827 return (Left
.is(tok::r_paren
) ? 100 : 120) + (is_short_annotation
? 50 : 0);
3830 // In for-loops, prefer breaking at ',' and ';'.
3831 if (Line
.startsWith(tok::kw_for
) && Left
.is(tok::equal
))
3834 // In Objective-C method expressions, prefer breaking before "param:" over
3835 // breaking after it.
3836 if (Right
.is(TT_SelectorName
))
3838 if (Left
.is(tok::colon
) && Left
.is(TT_ObjCMethodExpr
))
3839 return Line
.MightBeFunctionDecl
? 50 : 500;
3841 // In Objective-C type declarations, avoid breaking after the category's
3842 // open paren (we'll prefer breaking after the protocol list's opening
3843 // angle bracket, if present).
3844 if (Line
.Type
== LT_ObjCDecl
&& Left
.is(tok::l_paren
) && Left
.Previous
&&
3845 Left
.Previous
->isOneOf(tok::identifier
, tok::greater
)) {
3849 if (Left
.is(tok::l_paren
) && Style
.PenaltyBreakOpenParenthesis
!= 0)
3850 return Style
.PenaltyBreakOpenParenthesis
;
3851 if (Left
.is(tok::l_paren
) && InFunctionDecl
&&
3852 Style
.AlignAfterOpenBracket
!= FormatStyle::BAS_DontAlign
) {
3855 if (Left
.is(tok::l_paren
) && Left
.Previous
&&
3856 (Left
.Previous
->isOneOf(tok::kw_for
, tok::kw__Generic
) ||
3857 Left
.Previous
->isIf())) {
3860 if (Left
.is(tok::equal
) && InFunctionDecl
)
3862 if (Right
.is(tok::r_brace
))
3864 if (Left
.is(TT_TemplateOpener
))
3866 if (Left
.opensScope()) {
3867 // If we aren't aligning after opening parens/braces we can always break
3868 // here unless the style does not want us to place all arguments on the
3870 if (Style
.AlignAfterOpenBracket
== FormatStyle::BAS_DontAlign
&&
3871 (Left
.ParameterCount
<= 1 || Style
.AllowAllArgumentsOnNextLine
)) {
3874 if (Left
.is(tok::l_brace
) && !Style
.Cpp11BracedListStyle
)
3876 return Left
.ParameterCount
> 1 ? Style
.PenaltyBreakBeforeFirstCallParameter
3879 if (Left
.is(TT_JavaAnnotation
))
3882 if (Left
.is(TT_UnaryOperator
))
3884 if (Left
.isOneOf(tok::plus
, tok::comma
) && Left
.Previous
&&
3885 Left
.Previous
->isLabelString() &&
3886 (Left
.NextOperator
|| Left
.OperatorIndex
!= 0)) {
3889 if (Right
.is(tok::plus
) && Left
.isLabelString() &&
3890 (Right
.NextOperator
|| Right
.OperatorIndex
!= 0)) {
3893 if (Left
.is(tok::comma
))
3895 if (Right
.is(tok::lessless
) && Left
.isLabelString() &&
3896 (Right
.NextOperator
|| Right
.OperatorIndex
!= 1)) {
3899 if (Right
.is(tok::lessless
)) {
3900 // Breaking at a << is really cheap.
3901 if (Left
.isNot(tok::r_paren
) || Right
.OperatorIndex
> 0) {
3902 // Slightly prefer to break before the first one in log-like statements.
3907 if (Left
.ClosesTemplateDeclaration
)
3908 return Style
.PenaltyBreakTemplateDeclaration
;
3909 if (Left
.ClosesRequiresClause
)
3911 if (Left
.is(TT_ConditionalExpr
))
3912 return prec::Conditional
;
3913 prec::Level Level
= Left
.getPrecedence();
3914 if (Level
== prec::Unknown
)
3915 Level
= Right
.getPrecedence();
3916 if (Level
== prec::Assignment
)
3917 return Style
.PenaltyBreakAssignment
;
3918 if (Level
!= prec::Unknown
)
3924 bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken
&Right
) const {
3925 if (Style
.SpaceBeforeParens
== FormatStyle::SBPO_Always
)
3927 if (Right
.is(TT_OverloadedOperatorLParen
) &&
3928 Style
.SpaceBeforeParensOptions
.AfterOverloadedOperator
) {
3931 if (Style
.SpaceBeforeParensOptions
.BeforeNonEmptyParentheses
&&
3932 Right
.ParameterCount
> 0) {
3938 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine
&Line
,
3939 const FormatToken
&Left
,
3940 const FormatToken
&Right
) const {
3941 if (Left
.is(tok::kw_return
) &&
3942 !Right
.isOneOf(tok::semi
, tok::r_paren
, tok::hashhash
)) {
3945 if (Left
.is(tok::kw_throw
) && Right
.is(tok::l_paren
) && Right
.MatchingParen
&&
3946 Right
.MatchingParen
->is(TT_CastRParen
)) {
3949 if (Left
.is(Keywords
.kw_assert
) && Style
.Language
== FormatStyle::LK_Java
)
3951 if (Style
.ObjCSpaceAfterProperty
&& Line
.Type
== LT_ObjCProperty
&&
3952 Left
.Tok
.getObjCKeywordID() == tok::objc_property
) {
3955 if (Right
.is(tok::hashhash
))
3956 return Left
.is(tok::hash
);
3957 if (Left
.isOneOf(tok::hashhash
, tok::hash
))
3958 return Right
.is(tok::hash
);
3959 if ((Left
.is(tok::l_paren
) && Right
.is(tok::r_paren
)) ||
3960 (Left
.is(tok::l_brace
) && Left
.isNot(BK_Block
) &&
3961 Right
.is(tok::r_brace
) && Right
.isNot(BK_Block
))) {
3962 return Style
.SpacesInParensOptions
.InEmptyParentheses
;
3964 if (Style
.SpacesInParensOptions
.InConditionalStatements
) {
3965 const FormatToken
*LeftParen
= nullptr;
3966 if (Left
.is(tok::l_paren
))
3968 else if (Right
.is(tok::r_paren
) && Right
.MatchingParen
)
3969 LeftParen
= Right
.MatchingParen
;
3971 if (LeftParen
->is(TT_ConditionLParen
))
3973 if (LeftParen
->Previous
&& isKeywordWithCondition(*LeftParen
->Previous
))
3978 // trailing return type 'auto': []() -> auto {}, auto foo() -> auto {}
3979 if (Left
.is(tok::kw_auto
) && Right
.isOneOf(TT_LambdaLBrace
, TT_FunctionLBrace
,
3980 // function return type 'auto'
3981 TT_FunctionTypeLParen
)) {
3986 if (Left
.is(tok::kw_auto
) && Right
.isOneOf(tok::l_paren
, tok::l_brace
))
3989 // operator co_await(x)
3990 if (Right
.is(tok::l_paren
) && Left
.is(tok::kw_co_await
) && Left
.Previous
&&
3991 Left
.Previous
->is(tok::kw_operator
)) {
3994 // co_await (x), co_yield (x), co_return (x)
3995 if (Left
.isOneOf(tok::kw_co_await
, tok::kw_co_yield
, tok::kw_co_return
) &&
3996 !Right
.isOneOf(tok::semi
, tok::r_paren
)) {
4000 if (Left
.is(tok::l_paren
) || Right
.is(tok::r_paren
)) {
4001 return (Right
.is(TT_CastRParen
) ||
4002 (Left
.MatchingParen
&& Left
.MatchingParen
->is(TT_CastRParen
)))
4003 ? Style
.SpacesInParensOptions
.InCStyleCasts
4004 : Style
.SpacesInParensOptions
.Other
;
4006 if (Right
.isOneOf(tok::semi
, tok::comma
))
4008 if (Right
.is(tok::less
) && Line
.Type
== LT_ObjCDecl
) {
4009 bool IsLightweightGeneric
= Right
.MatchingParen
&&
4010 Right
.MatchingParen
->Next
&&
4011 Right
.MatchingParen
->Next
->is(tok::colon
);
4012 return !IsLightweightGeneric
&& Style
.ObjCSpaceBeforeProtocolList
;
4014 if (Right
.is(tok::less
) && Left
.is(tok::kw_template
))
4015 return Style
.SpaceAfterTemplateKeyword
;
4016 if (Left
.isOneOf(tok::exclaim
, tok::tilde
))
4018 if (Left
.is(tok::at
) &&
4019 Right
.isOneOf(tok::identifier
, tok::string_literal
, tok::char_constant
,
4020 tok::numeric_constant
, tok::l_paren
, tok::l_brace
,
4021 tok::kw_true
, tok::kw_false
)) {
4024 if (Left
.is(tok::colon
))
4025 return Left
.isNot(TT_ObjCMethodExpr
);
4026 if (Left
.is(tok::coloncolon
))
4028 if (Left
.is(tok::less
) || Right
.isOneOf(tok::greater
, tok::less
)) {
4029 if (Style
.Language
== FormatStyle::LK_TextProto
||
4030 (Style
.Language
== FormatStyle::LK_Proto
&&
4031 (Left
.is(TT_DictLiteral
) || Right
.is(TT_DictLiteral
)))) {
4032 // Format empty list as `<>`.
4033 if (Left
.is(tok::less
) && Right
.is(tok::greater
))
4035 return !Style
.Cpp11BracedListStyle
;
4037 // Don't attempt to format operator<(), as it is handled later.
4038 if (Right
.isNot(TT_OverloadedOperatorLParen
))
4041 if (Right
.is(tok::ellipsis
)) {
4042 return Left
.Tok
.isLiteral() || (Left
.is(tok::identifier
) && Left
.Previous
&&
4043 Left
.Previous
->is(tok::kw_case
));
4045 if (Left
.is(tok::l_square
) && Right
.is(tok::amp
))
4046 return Style
.SpacesInSquareBrackets
;
4047 if (Right
.is(TT_PointerOrReference
)) {
4048 if (Left
.is(tok::r_paren
) && Line
.MightBeFunctionDecl
) {
4049 if (!Left
.MatchingParen
)
4051 FormatToken
*TokenBeforeMatchingParen
=
4052 Left
.MatchingParen
->getPreviousNonComment();
4053 if (!TokenBeforeMatchingParen
|| Left
.isNot(TT_TypeDeclarationParen
))
4056 // Add a space if the previous token is a pointer qualifier or the closing
4057 // parenthesis of __attribute__(()) expression and the style requires spaces
4058 // after pointer qualifiers.
4059 if ((Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_After
||
4060 Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
) &&
4061 (Left
.is(TT_AttributeRParen
) ||
4062 Left
.canBePointerOrReferenceQualifier())) {
4065 if (Left
.Tok
.isLiteral())
4067 // for (auto a = 0, b = 0; const auto & c : {1, 2, 3})
4068 if (Left
.isTypeOrIdentifier() && Right
.Next
&& Right
.Next
->Next
&&
4069 Right
.Next
->Next
->is(TT_RangeBasedForLoopColon
)) {
4070 return getTokenPointerOrReferenceAlignment(Right
) !=
4071 FormatStyle::PAS_Left
;
4073 return !Left
.isOneOf(TT_PointerOrReference
, tok::l_paren
) &&
4074 (getTokenPointerOrReferenceAlignment(Right
) !=
4075 FormatStyle::PAS_Left
||
4076 (Line
.IsMultiVariableDeclStmt
&&
4077 (Left
.NestingLevel
== 0 ||
4078 (Left
.NestingLevel
== 1 && startsWithInitStatement(Line
)))));
4080 if (Right
.is(TT_FunctionTypeLParen
) && Left
.isNot(tok::l_paren
) &&
4081 (Left
.isNot(TT_PointerOrReference
) ||
4082 (getTokenPointerOrReferenceAlignment(Left
) != FormatStyle::PAS_Right
&&
4083 !Line
.IsMultiVariableDeclStmt
))) {
4086 if (Left
.is(TT_PointerOrReference
)) {
4087 // Add a space if the next token is a pointer qualifier and the style
4088 // requires spaces before pointer qualifiers.
4089 if ((Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Before
||
4090 Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
) &&
4091 Right
.canBePointerOrReferenceQualifier()) {
4095 if (Right
.Tok
.isLiteral())
4098 if (Right
.is(TT_BlockComment
))
4100 // foo() -> const Bar * override/final
4101 // S::foo() & noexcept/requires
4102 if (Right
.isOneOf(Keywords
.kw_override
, Keywords
.kw_final
, tok::kw_noexcept
,
4103 TT_RequiresClause
) &&
4104 Right
.isNot(TT_StartOfName
)) {
4108 if (Right
.is(tok::l_brace
) && Right
.is(BK_Block
))
4110 // for (auto a = 0, b = 0; const auto& c : {1, 2, 3})
4111 if (Left
.Previous
&& Left
.Previous
->isTypeOrIdentifier() && Right
.Next
&&
4112 Right
.Next
->is(TT_RangeBasedForLoopColon
)) {
4113 return getTokenPointerOrReferenceAlignment(Left
) !=
4114 FormatStyle::PAS_Right
;
4116 if (Right
.isOneOf(TT_PointerOrReference
, TT_ArraySubscriptLSquare
,
4120 if (getTokenPointerOrReferenceAlignment(Left
) == FormatStyle::PAS_Right
)
4122 // FIXME: Setting IsMultiVariableDeclStmt for the whole line is error-prone,
4123 // because it does not take into account nested scopes like lambdas.
4124 // In multi-variable declaration statements, attach */& to the variable
4125 // independently of the style. However, avoid doing it if we are in a nested
4126 // scope, e.g. lambda. We still need to special-case statements with
4128 if (Line
.IsMultiVariableDeclStmt
&&
4129 (Left
.NestingLevel
== Line
.First
->NestingLevel
||
4130 ((Left
.NestingLevel
== Line
.First
->NestingLevel
+ 1) &&
4131 startsWithInitStatement(Line
)))) {
4134 return Left
.Previous
&& !Left
.Previous
->isOneOf(
4135 tok::l_paren
, tok::coloncolon
, tok::l_square
);
4137 // Ensure right pointer alignment with ellipsis e.g. int *...P
4138 if (Left
.is(tok::ellipsis
) && Left
.Previous
&&
4139 Left
.Previous
->isPointerOrReference()) {
4140 return Style
.PointerAlignment
!= FormatStyle::PAS_Right
;
4143 if (Right
.is(tok::star
) && Left
.is(tok::l_paren
))
4145 if (Left
.is(tok::star
) && Right
.isPointerOrReference())
4147 if (Right
.isPointerOrReference()) {
4148 const FormatToken
*Previous
= &Left
;
4149 while (Previous
&& Previous
->isNot(tok::kw_operator
)) {
4150 if (Previous
->is(tok::identifier
) || Previous
->isSimpleTypeSpecifier()) {
4151 Previous
= Previous
->getPreviousNonComment();
4154 if (Previous
->is(TT_TemplateCloser
) && Previous
->MatchingParen
) {
4155 Previous
= Previous
->MatchingParen
->getPreviousNonComment();
4158 if (Previous
->is(tok::coloncolon
)) {
4159 Previous
= Previous
->getPreviousNonComment();
4164 // Space between the type and the * in:
4167 // operator void const*()
4168 // operator void volatile*()
4169 // operator /*comment*/ const char*()
4170 // operator volatile /*comment*/ char*()
4173 // operator std::Foo*()
4174 // operator C<T>::D<U>*()
4175 // dependent on PointerAlignment style.
4177 if (Previous
->endsSequence(tok::kw_operator
))
4178 return Style
.PointerAlignment
!= FormatStyle::PAS_Left
;
4179 if (Previous
->is(tok::kw_const
) || Previous
->is(tok::kw_volatile
)) {
4180 return (Style
.PointerAlignment
!= FormatStyle::PAS_Left
) ||
4181 (Style
.SpaceAroundPointerQualifiers
==
4182 FormatStyle::SAPQ_After
) ||
4183 (Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
);
4187 if (Style
.isCSharp() && Left
.is(Keywords
.kw_is
) && Right
.is(tok::l_square
))
4189 const auto SpaceRequiredForArrayInitializerLSquare
=
4190 [](const FormatToken
&LSquareTok
, const FormatStyle
&Style
) {
4191 return Style
.SpacesInContainerLiterals
||
4192 (Style
.isProto() && !Style
.Cpp11BracedListStyle
&&
4193 LSquareTok
.endsSequence(tok::l_square
, tok::colon
,
4196 if (Left
.is(tok::l_square
)) {
4197 return (Left
.is(TT_ArrayInitializerLSquare
) && Right
.isNot(tok::r_square
) &&
4198 SpaceRequiredForArrayInitializerLSquare(Left
, Style
)) ||
4199 (Left
.isOneOf(TT_ArraySubscriptLSquare
, TT_StructuredBindingLSquare
,
4200 TT_LambdaLSquare
) &&
4201 Style
.SpacesInSquareBrackets
&& Right
.isNot(tok::r_square
));
4203 if (Right
.is(tok::r_square
)) {
4204 return Right
.MatchingParen
&&
4205 ((Right
.MatchingParen
->is(TT_ArrayInitializerLSquare
) &&
4206 SpaceRequiredForArrayInitializerLSquare(*Right
.MatchingParen
,
4208 (Style
.SpacesInSquareBrackets
&&
4209 Right
.MatchingParen
->isOneOf(TT_ArraySubscriptLSquare
,
4210 TT_StructuredBindingLSquare
,
4211 TT_LambdaLSquare
)));
4213 if (Right
.is(tok::l_square
) &&
4214 !Right
.isOneOf(TT_ObjCMethodExpr
, TT_LambdaLSquare
,
4215 TT_DesignatedInitializerLSquare
,
4216 TT_StructuredBindingLSquare
, TT_AttributeSquare
) &&
4217 !Left
.isOneOf(tok::numeric_constant
, TT_DictLiteral
) &&
4218 !(Left
.isNot(tok::r_square
) && Style
.SpaceBeforeSquareBrackets
&&
4219 Right
.is(TT_ArraySubscriptLSquare
))) {
4222 if (Left
.is(tok::l_brace
) && Right
.is(tok::r_brace
))
4223 return !Left
.Children
.empty(); // No spaces in "{}".
4224 if ((Left
.is(tok::l_brace
) && Left
.isNot(BK_Block
)) ||
4225 (Right
.is(tok::r_brace
) && Right
.MatchingParen
&&
4226 Right
.MatchingParen
->isNot(BK_Block
))) {
4227 return !Style
.Cpp11BracedListStyle
|| Style
.SpacesInParensOptions
.Other
;
4229 if (Left
.is(TT_BlockComment
)) {
4230 // No whitespace in x(/*foo=*/1), except for JavaScript.
4231 return Style
.isJavaScript() || !Left
.TokenText
.ends_with("=*/");
4234 // Space between template and attribute.
4235 // e.g. template <typename T> [[nodiscard]] ...
4236 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_AttributeSquare
))
4238 // Space before parentheses common for all languages
4239 if (Right
.is(tok::l_paren
)) {
4240 if (Left
.is(TT_TemplateCloser
) && Right
.isNot(TT_FunctionTypeLParen
))
4241 return spaceRequiredBeforeParens(Right
);
4242 if (Left
.isOneOf(TT_RequiresClause
,
4243 TT_RequiresClauseInARequiresExpression
)) {
4244 return Style
.SpaceBeforeParensOptions
.AfterRequiresInClause
||
4245 spaceRequiredBeforeParens(Right
);
4247 if (Left
.is(TT_RequiresExpression
)) {
4248 return Style
.SpaceBeforeParensOptions
.AfterRequiresInExpression
||
4249 spaceRequiredBeforeParens(Right
);
4251 if (Left
.is(TT_AttributeRParen
) ||
4252 (Left
.is(tok::r_square
) && Left
.is(TT_AttributeSquare
))) {
4255 if (Left
.is(TT_ForEachMacro
)) {
4256 return Style
.SpaceBeforeParensOptions
.AfterForeachMacros
||
4257 spaceRequiredBeforeParens(Right
);
4259 if (Left
.is(TT_IfMacro
)) {
4260 return Style
.SpaceBeforeParensOptions
.AfterIfMacros
||
4261 spaceRequiredBeforeParens(Right
);
4263 if (Style
.SpaceBeforeParens
== FormatStyle::SBPO_Custom
&&
4264 Left
.isOneOf(tok::kw_new
, tok::kw_delete
) &&
4265 Right
.isNot(TT_OverloadedOperatorLParen
) &&
4266 !(Line
.MightBeFunctionDecl
&& Left
.is(TT_FunctionDeclarationName
))) {
4267 if (Style
.SpaceBeforeParensOptions
.AfterPlacementOperator
==
4268 FormatStyle::SpaceBeforeParensCustom::APO_Always
||
4269 (Style
.SpaceBeforeParensOptions
.AfterPlacementOperator
==
4270 FormatStyle::SpaceBeforeParensCustom::APO_Leave
&&
4271 Right
.hasWhitespaceBefore())) {
4276 if (Line
.Type
== LT_ObjCDecl
)
4278 if (Left
.is(tok::semi
))
4280 if (Left
.isOneOf(tok::pp_elif
, tok::kw_for
, tok::kw_while
, tok::kw_switch
,
4281 tok::kw_case
, TT_ForEachMacro
, TT_ObjCForIn
) ||
4282 Left
.isIf(Line
.Type
!= LT_PreprocessorDirective
) ||
4283 Right
.is(TT_ConditionLParen
)) {
4284 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
4285 spaceRequiredBeforeParens(Right
);
4288 // TODO add Operator overloading specific Options to
4289 // SpaceBeforeParensOptions
4290 if (Right
.is(TT_OverloadedOperatorLParen
))
4291 return spaceRequiredBeforeParens(Right
);
4292 // Function declaration or definition
4293 if (Line
.MightBeFunctionDecl
&& (Left
.is(TT_FunctionDeclarationName
))) {
4294 if (Line
.mightBeFunctionDefinition()) {
4295 return Style
.SpaceBeforeParensOptions
.AfterFunctionDefinitionName
||
4296 spaceRequiredBeforeParens(Right
);
4298 return Style
.SpaceBeforeParensOptions
.AfterFunctionDeclarationName
||
4299 spaceRequiredBeforeParens(Right
);
4303 if (Line
.Type
!= LT_PreprocessorDirective
&& Left
.is(tok::r_square
) &&
4304 Left
.MatchingParen
&& Left
.MatchingParen
->is(TT_LambdaLSquare
)) {
4305 return Style
.SpaceBeforeParensOptions
.AfterFunctionDefinitionName
||
4306 spaceRequiredBeforeParens(Right
);
4308 if (!Left
.Previous
|| Left
.Previous
->isNot(tok::period
)) {
4309 if (Left
.isOneOf(tok::kw_try
, Keywords
.kw___except
, tok::kw_catch
)) {
4310 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
4311 spaceRequiredBeforeParens(Right
);
4313 if (Left
.isOneOf(tok::kw_new
, tok::kw_delete
)) {
4314 return ((!Line
.MightBeFunctionDecl
|| !Left
.Previous
) &&
4315 Style
.SpaceBeforeParens
!= FormatStyle::SBPO_Never
) ||
4316 spaceRequiredBeforeParens(Right
);
4319 if (Left
.is(tok::r_square
) && Left
.MatchingParen
&&
4320 Left
.MatchingParen
->Previous
&&
4321 Left
.MatchingParen
->Previous
->is(tok::kw_delete
)) {
4322 return (Style
.SpaceBeforeParens
!= FormatStyle::SBPO_Never
) ||
4323 spaceRequiredBeforeParens(Right
);
4326 // Handle builtins like identifiers.
4327 if (Line
.Type
!= LT_PreprocessorDirective
&&
4328 (Left
.Tok
.getIdentifierInfo() || Left
.is(tok::r_paren
))) {
4329 return spaceRequiredBeforeParens(Right
);
4333 if (Left
.is(tok::at
) && Right
.Tok
.getObjCKeywordID() != tok::objc_not_keyword
)
4335 if (Right
.is(TT_UnaryOperator
)) {
4336 return !Left
.isOneOf(tok::l_paren
, tok::l_square
, tok::at
) &&
4337 (Left
.isNot(tok::colon
) || Left
.isNot(TT_ObjCMethodExpr
));
4339 // No space between the variable name and the initializer list.
4341 // Verilog doesn't have such syntax, but it has word operators that are C++
4342 // identifiers like `a inside {b, c}`. So the rule is not applicable.
4343 if (!Style
.isVerilog() &&
4344 (Left
.isOneOf(tok::identifier
, tok::greater
, tok::r_square
,
4346 Left
.isSimpleTypeSpecifier()) &&
4347 Right
.is(tok::l_brace
) && Right
.getNextNonComment() &&
4348 Right
.isNot(BK_Block
)) {
4351 if (Left
.is(tok::period
) || Right
.is(tok::period
))
4353 // u#str, U#str, L#str, u8#str
4354 // uR#str, UR#str, LR#str, u8R#str
4355 if (Right
.is(tok::hash
) && Left
.is(tok::identifier
) &&
4356 (Left
.TokenText
== "L" || Left
.TokenText
== "u" ||
4357 Left
.TokenText
== "U" || Left
.TokenText
== "u8" ||
4358 Left
.TokenText
== "LR" || Left
.TokenText
== "uR" ||
4359 Left
.TokenText
== "UR" || Left
.TokenText
== "u8R")) {
4362 if (Left
.is(TT_TemplateCloser
) && Left
.MatchingParen
&&
4363 Left
.MatchingParen
->Previous
&&
4364 (Left
.MatchingParen
->Previous
->is(tok::period
) ||
4365 Left
.MatchingParen
->Previous
->is(tok::coloncolon
))) {
4366 // Java call to generic function with explicit type:
4367 // A.<B<C<...>>>DoSomething();
4368 // A::<B<C<...>>>DoSomething(); // With a Java 8 method reference.
4371 if (Left
.is(TT_TemplateCloser
) && Right
.is(tok::l_square
))
4373 if (Left
.is(tok::l_brace
) && Left
.endsSequence(TT_DictLiteral
, tok::at
)) {
4374 // Objective-C dictionary literal -> no space after opening brace.
4377 if (Right
.is(tok::r_brace
) && Right
.MatchingParen
&&
4378 Right
.MatchingParen
->endsSequence(TT_DictLiteral
, tok::at
)) {
4379 // Objective-C dictionary literal -> no space before closing brace.
4382 if (Right
.getType() == TT_TrailingAnnotation
&&
4383 Right
.isOneOf(tok::amp
, tok::ampamp
) &&
4384 Left
.isOneOf(tok::kw_const
, tok::kw_volatile
) &&
4385 (!Right
.Next
|| Right
.Next
->is(tok::semi
))) {
4386 // Match const and volatile ref-qualifiers without any additional
4387 // qualifiers such as
4388 // void Fn() const &;
4389 return getTokenReferenceAlignment(Right
) != FormatStyle::PAS_Left
;
4395 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine
&Line
,
4396 const FormatToken
&Right
) const {
4397 const FormatToken
&Left
= *Right
.Previous
;
4399 // If the token is finalized don't touch it (as it could be in a
4400 // clang-format-off section).
4402 return Right
.hasWhitespaceBefore();
4404 // Never ever merge two words.
4405 if (Keywords
.isWordLike(Right
) && Keywords
.isWordLike(Left
))
4408 // Leave a space between * and /* to avoid C4138 `comment end` found outside
4410 if (Left
.is(tok::star
) && Right
.is(tok::comment
))
4413 if (Style
.isCpp()) {
4414 if (Left
.is(TT_OverloadedOperator
) &&
4415 Right
.isOneOf(TT_TemplateOpener
, TT_TemplateCloser
)) {
4418 // Space between UDL and dot: auto b = 4s .count();
4419 if (Right
.is(tok::period
) && Left
.is(tok::numeric_constant
))
4421 // Space between import <iostream>.
4423 if (Left
.is(Keywords
.kw_import
) && Right
.isOneOf(tok::less
, tok::ellipsis
))
4425 // Space between `module :` and `import :`.
4426 if (Left
.isOneOf(Keywords
.kw_module
, Keywords
.kw_import
) &&
4427 Right
.is(TT_ModulePartitionColon
)) {
4430 // No space between import foo:bar but keep a space between import :bar;
4431 if (Left
.is(tok::identifier
) && Right
.is(TT_ModulePartitionColon
))
4433 // No space between :bar;
4434 if (Left
.is(TT_ModulePartitionColon
) &&
4435 Right
.isOneOf(tok::identifier
, tok::kw_private
)) {
4438 if (Left
.is(tok::ellipsis
) && Right
.is(tok::identifier
) &&
4439 Line
.First
->is(Keywords
.kw_import
)) {
4442 // Space in __attribute__((attr)) ::type.
4443 if (Left
.isOneOf(TT_AttributeRParen
, TT_AttributeMacro
) &&
4444 Right
.is(tok::coloncolon
)) {
4448 if (Left
.is(tok::kw_operator
))
4449 return Right
.is(tok::coloncolon
);
4450 if (Right
.is(tok::l_brace
) && Right
.is(BK_BracedInit
) &&
4451 !Left
.opensScope() && Style
.SpaceBeforeCpp11BracedList
) {
4454 if (Left
.is(tok::less
) && Left
.is(TT_OverloadedOperator
) &&
4455 Right
.is(TT_TemplateOpener
)) {
4458 } else if (Style
.isProto()) {
4459 if (Right
.is(tok::period
) &&
4460 Left
.isOneOf(Keywords
.kw_optional
, Keywords
.kw_required
,
4461 Keywords
.kw_repeated
, Keywords
.kw_extend
)) {
4464 if (Right
.is(tok::l_paren
) &&
4465 Left
.isOneOf(Keywords
.kw_returns
, Keywords
.kw_option
)) {
4468 if (Right
.isOneOf(tok::l_brace
, tok::less
) && Left
.is(TT_SelectorName
))
4470 // Slashes occur in text protocol extension syntax: [type/type] { ... }.
4471 if (Left
.is(tok::slash
) || Right
.is(tok::slash
))
4473 if (Left
.MatchingParen
&&
4474 Left
.MatchingParen
->is(TT_ProtoExtensionLSquare
) &&
4475 Right
.isOneOf(tok::l_brace
, tok::less
)) {
4476 return !Style
.Cpp11BracedListStyle
;
4478 // A percent is probably part of a formatting specification, such as %lld.
4479 if (Left
.is(tok::percent
))
4481 // Preserve the existence of a space before a percent for cases like 0x%04x
4483 if (Left
.is(tok::numeric_constant
) && Right
.is(tok::percent
))
4484 return Right
.hasWhitespaceBefore();
4485 } else if (Style
.isJson()) {
4486 if (Right
.is(tok::colon
) && Left
.is(tok::string_literal
))
4487 return Style
.SpaceBeforeJsonColon
;
4488 } else if (Style
.isCSharp()) {
4489 // Require spaces around '{' and before '}' unless they appear in
4490 // interpolated strings. Interpolated strings are merged into a single token
4491 // so cannot have spaces inserted by this function.
4493 // No space between 'this' and '['
4494 if (Left
.is(tok::kw_this
) && Right
.is(tok::l_square
))
4497 // No space between 'new' and '('
4498 if (Left
.is(tok::kw_new
) && Right
.is(tok::l_paren
))
4501 // Space before { (including space within '{ {').
4502 if (Right
.is(tok::l_brace
))
4505 // Spaces inside braces.
4506 if (Left
.is(tok::l_brace
) && Right
.isNot(tok::r_brace
))
4509 if (Left
.isNot(tok::l_brace
) && Right
.is(tok::r_brace
))
4512 // Spaces around '=>'.
4513 if (Left
.is(TT_FatArrow
) || Right
.is(TT_FatArrow
))
4516 // No spaces around attribute target colons
4517 if (Left
.is(TT_AttributeColon
) || Right
.is(TT_AttributeColon
))
4520 // space between type and variable e.g. Dictionary<string,string> foo;
4521 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_StartOfName
))
4524 // spaces inside square brackets.
4525 if (Left
.is(tok::l_square
) || Right
.is(tok::r_square
))
4526 return Style
.SpacesInSquareBrackets
;
4528 // No space before ? in nullable types.
4529 if (Right
.is(TT_CSharpNullable
))
4532 // No space before null forgiving '!'.
4533 if (Right
.is(TT_NonNullAssertion
))
4536 // No space between consecutive commas '[,,]'.
4537 if (Left
.is(tok::comma
) && Right
.is(tok::comma
))
4540 // space after var in `var (key, value)`
4541 if (Left
.is(Keywords
.kw_var
) && Right
.is(tok::l_paren
))
4544 // space between keywords and paren e.g. "using ("
4545 if (Right
.is(tok::l_paren
)) {
4546 if (Left
.isOneOf(tok::kw_using
, Keywords
.kw_async
, Keywords
.kw_when
,
4547 Keywords
.kw_lock
)) {
4548 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
4549 spaceRequiredBeforeParens(Right
);
4553 // space between method modifier and opening parenthesis of a tuple return
4555 if (Left
.isOneOf(tok::kw_public
, tok::kw_private
, tok::kw_protected
,
4556 tok::kw_virtual
, tok::kw_extern
, tok::kw_static
,
4557 Keywords
.kw_internal
, Keywords
.kw_abstract
,
4558 Keywords
.kw_sealed
, Keywords
.kw_override
,
4559 Keywords
.kw_async
, Keywords
.kw_unsafe
) &&
4560 Right
.is(tok::l_paren
)) {
4563 } else if (Style
.isJavaScript()) {
4564 if (Left
.is(TT_FatArrow
))
4567 if (Right
.is(tok::l_paren
) && Left
.is(Keywords
.kw_await
) && Left
.Previous
&&
4568 Left
.Previous
->is(tok::kw_for
)) {
4571 if (Left
.is(Keywords
.kw_async
) && Right
.is(tok::l_paren
) &&
4572 Right
.MatchingParen
) {
4573 const FormatToken
*Next
= Right
.MatchingParen
->getNextNonComment();
4574 // An async arrow function, for example: `x = async () => foo();`,
4575 // as opposed to calling a function called async: `x = async();`
4576 if (Next
&& Next
->is(TT_FatArrow
))
4579 if ((Left
.is(TT_TemplateString
) && Left
.TokenText
.ends_with("${")) ||
4580 (Right
.is(TT_TemplateString
) && Right
.TokenText
.starts_with("}"))) {
4583 // In tagged template literals ("html`bar baz`"), there is no space between
4584 // the tag identifier and the template string.
4585 if (Keywords
.IsJavaScriptIdentifier(Left
,
4586 /* AcceptIdentifierName= */ false) &&
4587 Right
.is(TT_TemplateString
)) {
4590 if (Right
.is(tok::star
) &&
4591 Left
.isOneOf(Keywords
.kw_function
, Keywords
.kw_yield
)) {
4594 if (Right
.isOneOf(tok::l_brace
, tok::l_square
) &&
4595 Left
.isOneOf(Keywords
.kw_function
, Keywords
.kw_yield
,
4596 Keywords
.kw_extends
, Keywords
.kw_implements
)) {
4599 if (Right
.is(tok::l_paren
)) {
4600 // JS methods can use some keywords as names (e.g. `delete()`).
4601 if (Line
.MustBeDeclaration
&& Left
.Tok
.getIdentifierInfo())
4603 // Valid JS method names can include keywords, e.g. `foo.delete()` or
4604 // `bar.instanceof()`. Recognize call positions by preceding period.
4605 if (Left
.Previous
&& Left
.Previous
->is(tok::period
) &&
4606 Left
.Tok
.getIdentifierInfo()) {
4609 // Additional unary JavaScript operators that need a space after.
4610 if (Left
.isOneOf(tok::kw_throw
, Keywords
.kw_await
, Keywords
.kw_typeof
,
4615 // `foo as const;` casts into a const type.
4616 if (Left
.endsSequence(tok::kw_const
, Keywords
.kw_as
))
4618 if ((Left
.isOneOf(Keywords
.kw_let
, Keywords
.kw_var
, Keywords
.kw_in
,
4620 // "of" is only a keyword if it appears after another identifier
4621 // (e.g. as "const x of y" in a for loop), or after a destructuring
4622 // operation (const [x, y] of z, const {a, b} of c).
4623 (Left
.is(Keywords
.kw_of
) && Left
.Previous
&&
4624 (Left
.Previous
->is(tok::identifier
) ||
4625 Left
.Previous
->isOneOf(tok::r_square
, tok::r_brace
)))) &&
4626 (!Left
.Previous
|| Left
.Previous
->isNot(tok::period
))) {
4629 if (Left
.isOneOf(tok::kw_for
, Keywords
.kw_as
) && Left
.Previous
&&
4630 Left
.Previous
->is(tok::period
) && Right
.is(tok::l_paren
)) {
4633 if (Left
.is(Keywords
.kw_as
) &&
4634 Right
.isOneOf(tok::l_square
, tok::l_brace
, tok::l_paren
)) {
4637 if (Left
.is(tok::kw_default
) && Left
.Previous
&&
4638 Left
.Previous
->is(tok::kw_export
)) {
4641 if (Left
.is(Keywords
.kw_is
) && Right
.is(tok::l_brace
))
4643 if (Right
.isOneOf(TT_JsTypeColon
, TT_JsTypeOptionalQuestion
))
4645 if (Left
.is(TT_JsTypeOperator
) || Right
.is(TT_JsTypeOperator
))
4647 if ((Left
.is(tok::l_brace
) || Right
.is(tok::r_brace
)) &&
4648 Line
.First
->isOneOf(Keywords
.kw_import
, tok::kw_export
)) {
4651 if (Left
.is(tok::ellipsis
))
4653 if (Left
.is(TT_TemplateCloser
) &&
4654 !Right
.isOneOf(tok::equal
, tok::l_brace
, tok::comma
, tok::l_square
,
4655 Keywords
.kw_implements
, Keywords
.kw_extends
)) {
4656 // Type assertions ('<type>expr') are not followed by whitespace. Other
4657 // locations that should have whitespace following are identified by the
4658 // above set of follower tokens.
4661 if (Right
.is(TT_NonNullAssertion
))
4663 if (Left
.is(TT_NonNullAssertion
) &&
4664 Right
.isOneOf(Keywords
.kw_as
, Keywords
.kw_in
)) {
4665 return true; // "x! as string", "x! in y"
4667 } else if (Style
.Language
== FormatStyle::LK_Java
) {
4668 if (Left
.is(tok::r_square
) && Right
.is(tok::l_brace
))
4670 if (Left
.is(Keywords
.kw_synchronized
) && Right
.is(tok::l_paren
)) {
4671 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
4672 spaceRequiredBeforeParens(Right
);
4674 if ((Left
.isOneOf(tok::kw_static
, tok::kw_public
, tok::kw_private
,
4675 tok::kw_protected
) ||
4676 Left
.isOneOf(Keywords
.kw_final
, Keywords
.kw_abstract
,
4677 Keywords
.kw_native
)) &&
4678 Right
.is(TT_TemplateOpener
)) {
4681 } else if (Style
.isVerilog()) {
4682 // An escaped identifier ends with whitespace.
4683 if (Style
.isVerilog() && Left
.is(tok::identifier
) &&
4684 Left
.TokenText
[0] == '\\') {
4687 // Add space between things in a primitive's state table unless in a
4688 // transition like `(0?)`.
4689 if ((Left
.is(TT_VerilogTableItem
) &&
4690 !Right
.isOneOf(tok::r_paren
, tok::semi
)) ||
4691 (Right
.is(TT_VerilogTableItem
) && Left
.isNot(tok::l_paren
))) {
4692 const FormatToken
*Next
= Right
.getNextNonComment();
4693 return !(Next
&& Next
->is(tok::r_paren
));
4695 // Don't add space within a delay like `#0`.
4696 if (Left
.isNot(TT_BinaryOperator
) &&
4697 Left
.isOneOf(Keywords
.kw_verilogHash
, Keywords
.kw_verilogHashHash
)) {
4700 // Add space after a delay.
4701 if (Right
.isNot(tok::semi
) &&
4702 (Left
.endsSequence(tok::numeric_constant
, Keywords
.kw_verilogHash
) ||
4703 Left
.endsSequence(tok::numeric_constant
,
4704 Keywords
.kw_verilogHashHash
) ||
4705 (Left
.is(tok::r_paren
) && Left
.MatchingParen
&&
4706 Left
.MatchingParen
->endsSequence(tok::l_paren
, tok::at
)))) {
4709 // Don't add embedded spaces in a number literal like `16'h1?ax` or an array
4710 // literal like `'{}`.
4711 if (Left
.is(Keywords
.kw_apostrophe
) ||
4712 (Left
.is(TT_VerilogNumberBase
) && Right
.is(tok::numeric_constant
))) {
4715 // Add spaces around the implication operator `->`.
4716 if (Left
.is(tok::arrow
) || Right
.is(tok::arrow
))
4718 // Don't add spaces between two at signs. Like in a coverage event.
4719 // Don't add spaces between at and a sensitivity list like
4720 // `@(posedge clk)`.
4721 if (Left
.is(tok::at
) && Right
.isOneOf(tok::l_paren
, tok::star
, tok::at
))
4723 // Add space between the type name and dimension like `logic [1:0]`.
4724 if (Right
.is(tok::l_square
) &&
4725 Left
.isOneOf(TT_VerilogDimensionedTypeName
, Keywords
.kw_function
)) {
4728 // In a tagged union expression, there should be a space after the tag.
4729 if (Right
.isOneOf(tok::period
, Keywords
.kw_apostrophe
) &&
4730 Keywords
.isVerilogIdentifier(Left
) && Left
.getPreviousNonComment() &&
4731 Left
.getPreviousNonComment()->is(Keywords
.kw_tagged
)) {
4734 // Don't add spaces between a casting type and the quote or repetition count
4735 // and the brace. The case of tagged union expressions is handled by the
4737 if ((Right
.is(Keywords
.kw_apostrophe
) ||
4738 (Right
.is(BK_BracedInit
) && Right
.is(tok::l_brace
))) &&
4739 !(Left
.isOneOf(Keywords
.kw_assign
, Keywords
.kw_unique
) ||
4740 Keywords
.isVerilogWordOperator(Left
)) &&
4741 (Left
.isOneOf(tok::r_square
, tok::r_paren
, tok::r_brace
,
4742 tok::numeric_constant
) ||
4743 Keywords
.isWordLike(Left
))) {
4746 // Don't add spaces in imports like `import foo::*;`.
4747 if ((Right
.is(tok::star
) && Left
.is(tok::coloncolon
)) ||
4748 (Left
.is(tok::star
) && Right
.is(tok::semi
))) {
4751 // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
4752 if (Left
.endsSequence(tok::star
, tok::l_paren
) && Right
.is(tok::identifier
))
4754 // Add space before drive strength like in `wire (strong1, pull0)`.
4755 if (Right
.is(tok::l_paren
) && Right
.is(TT_VerilogStrength
))
4757 // Don't add space in a streaming concatenation like `{>>{j}}`.
4758 if ((Left
.is(tok::l_brace
) &&
4759 Right
.isOneOf(tok::lessless
, tok::greatergreater
)) ||
4760 (Left
.endsSequence(tok::lessless
, tok::l_brace
) ||
4761 Left
.endsSequence(tok::greatergreater
, tok::l_brace
))) {
4765 if (Left
.is(TT_ImplicitStringLiteral
))
4766 return Right
.hasWhitespaceBefore();
4767 if (Line
.Type
== LT_ObjCMethodDecl
) {
4768 if (Left
.is(TT_ObjCMethodSpecifier
))
4770 if (Left
.is(tok::r_paren
) && Left
.isNot(TT_AttributeRParen
) &&
4771 canBeObjCSelectorComponent(Right
)) {
4772 // Don't space between ')' and <id> or ')' and 'new'. 'new' is not a
4773 // keyword in Objective-C, and '+ (instancetype)new;' is a standard class
4774 // method declaration.
4778 if (Line
.Type
== LT_ObjCProperty
&&
4779 (Right
.is(tok::equal
) || Left
.is(tok::equal
))) {
4783 if (Right
.is(TT_TrailingReturnArrow
) || Left
.is(TT_TrailingReturnArrow
))
4786 if (Left
.is(tok::comma
) && Right
.isNot(TT_OverloadedOperatorLParen
) &&
4787 // In an unexpanded macro call we only find the parentheses and commas
4788 // in a line; the commas and closing parenthesis do not require a space.
4789 (Left
.Children
.empty() || !Left
.MacroParent
)) {
4792 if (Right
.is(tok::comma
))
4794 if (Right
.is(TT_ObjCBlockLParen
))
4796 if (Right
.is(TT_CtorInitializerColon
))
4797 return Style
.SpaceBeforeCtorInitializerColon
;
4798 if (Right
.is(TT_InheritanceColon
) && !Style
.SpaceBeforeInheritanceColon
)
4800 if (Right
.is(TT_RangeBasedForLoopColon
) &&
4801 !Style
.SpaceBeforeRangeBasedForLoopColon
) {
4804 if (Left
.is(TT_BitFieldColon
)) {
4805 return Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Both
||
4806 Style
.BitFieldColonSpacing
== FormatStyle::BFCS_After
;
4808 if (Right
.is(tok::colon
)) {
4809 if (Right
.is(TT_CaseLabelColon
))
4810 return Style
.SpaceBeforeCaseColon
;
4811 if (Right
.is(TT_GotoLabelColon
))
4813 // `private:` and `public:`.
4814 if (!Right
.getNextNonComment())
4816 if (Right
.is(TT_ObjCMethodExpr
))
4818 if (Left
.is(tok::question
))
4820 if (Right
.is(TT_InlineASMColon
) && Left
.is(tok::coloncolon
))
4822 if (Right
.is(TT_DictLiteral
))
4823 return Style
.SpacesInContainerLiterals
;
4824 if (Right
.is(TT_AttributeColon
))
4826 if (Right
.is(TT_CSharpNamedArgumentColon
))
4828 if (Right
.is(TT_GenericSelectionColon
))
4830 if (Right
.is(TT_BitFieldColon
)) {
4831 return Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Both
||
4832 Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Before
;
4836 // Do not merge "- -" into "--".
4837 if ((Left
.isOneOf(tok::minus
, tok::minusminus
) &&
4838 Right
.isOneOf(tok::minus
, tok::minusminus
)) ||
4839 (Left
.isOneOf(tok::plus
, tok::plusplus
) &&
4840 Right
.isOneOf(tok::plus
, tok::plusplus
))) {
4843 if (Left
.is(TT_UnaryOperator
)) {
4844 if (Right
.isNot(tok::l_paren
)) {
4845 // The alternative operators for ~ and ! are "compl" and "not".
4846 // If they are used instead, we do not want to combine them with
4847 // the token to the right, unless that is a left paren.
4848 if (Left
.is(tok::exclaim
) && Left
.TokenText
== "not")
4850 if (Left
.is(tok::tilde
) && Left
.TokenText
== "compl")
4852 // Lambda captures allow for a lone &, so "&]" needs to be properly
4854 if (Left
.is(tok::amp
) && Right
.is(tok::r_square
))
4855 return Style
.SpacesInSquareBrackets
;
4857 return (Style
.SpaceAfterLogicalNot
&& Left
.is(tok::exclaim
)) ||
4858 Right
.is(TT_BinaryOperator
);
4861 // If the next token is a binary operator or a selector name, we have
4862 // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.
4863 if (Left
.is(TT_CastRParen
)) {
4864 return Style
.SpaceAfterCStyleCast
||
4865 Right
.isOneOf(TT_BinaryOperator
, TT_SelectorName
);
4868 auto ShouldAddSpacesInAngles
= [this, &Right
]() {
4869 if (this->Style
.SpacesInAngles
== FormatStyle::SIAS_Always
)
4871 if (this->Style
.SpacesInAngles
== FormatStyle::SIAS_Leave
)
4872 return Right
.hasWhitespaceBefore();
4876 if (Left
.is(tok::greater
) && Right
.is(tok::greater
)) {
4877 if (Style
.Language
== FormatStyle::LK_TextProto
||
4878 (Style
.Language
== FormatStyle::LK_Proto
&& Left
.is(TT_DictLiteral
))) {
4879 return !Style
.Cpp11BracedListStyle
;
4881 return Right
.is(TT_TemplateCloser
) && Left
.is(TT_TemplateCloser
) &&
4882 ((Style
.Standard
< FormatStyle::LS_Cpp11
) ||
4883 ShouldAddSpacesInAngles());
4885 if (Right
.isOneOf(tok::arrow
, tok::arrowstar
, tok::periodstar
) ||
4886 Left
.isOneOf(tok::arrow
, tok::period
, tok::arrowstar
, tok::periodstar
) ||
4887 (Right
.is(tok::period
) && Right
.isNot(TT_DesignatedInitializerPeriod
))) {
4890 if (!Style
.SpaceBeforeAssignmentOperators
&& Left
.isNot(TT_TemplateCloser
) &&
4891 Right
.getPrecedence() == prec::Assignment
) {
4894 if (Style
.Language
== FormatStyle::LK_Java
&& Right
.is(tok::coloncolon
) &&
4895 (Left
.is(tok::identifier
) || Left
.is(tok::kw_this
))) {
4898 if (Right
.is(tok::coloncolon
) && Left
.is(tok::identifier
)) {
4899 // Generally don't remove existing spaces between an identifier and "::".
4900 // The identifier might actually be a macro name such as ALWAYS_INLINE. If
4901 // this turns out to be too lenient, add analysis of the identifier itself.
4902 return Right
.hasWhitespaceBefore();
4904 if (Right
.is(tok::coloncolon
) &&
4905 !Left
.isOneOf(tok::l_brace
, tok::comment
, tok::l_paren
)) {
4906 // Put a space between < and :: in vector< ::std::string >
4907 return (Left
.is(TT_TemplateOpener
) &&
4908 ((Style
.Standard
< FormatStyle::LS_Cpp11
) ||
4909 ShouldAddSpacesInAngles())) ||
4910 !(Left
.isOneOf(tok::l_paren
, tok::r_paren
, tok::l_square
,
4911 tok::kw___super
, TT_TemplateOpener
,
4912 TT_TemplateCloser
)) ||
4913 (Left
.is(tok::l_paren
) && Style
.SpacesInParensOptions
.Other
);
4915 if ((Left
.is(TT_TemplateOpener
)) != (Right
.is(TT_TemplateCloser
)))
4916 return ShouldAddSpacesInAngles();
4917 // Space before TT_StructuredBindingLSquare.
4918 if (Right
.is(TT_StructuredBindingLSquare
)) {
4919 return !Left
.isOneOf(tok::amp
, tok::ampamp
) ||
4920 getTokenReferenceAlignment(Left
) != FormatStyle::PAS_Right
;
4922 // Space before & or && following a TT_StructuredBindingLSquare.
4923 if (Right
.Next
&& Right
.Next
->is(TT_StructuredBindingLSquare
) &&
4924 Right
.isOneOf(tok::amp
, tok::ampamp
)) {
4925 return getTokenReferenceAlignment(Right
) != FormatStyle::PAS_Left
;
4927 if ((Right
.is(TT_BinaryOperator
) && Left
.isNot(tok::l_paren
)) ||
4928 (Left
.isOneOf(TT_BinaryOperator
, TT_ConditionalExpr
) &&
4929 Right
.isNot(tok::r_paren
))) {
4932 if (Right
.is(TT_TemplateOpener
) && Left
.is(tok::r_paren
) &&
4933 Left
.MatchingParen
&&
4934 Left
.MatchingParen
->is(TT_OverloadedOperatorLParen
)) {
4937 if (Right
.is(tok::less
) && Left
.isNot(tok::l_paren
) &&
4938 Line
.Type
== LT_ImportStatement
) {
4941 if (Right
.is(TT_TrailingUnaryOperator
))
4943 if (Left
.is(TT_RegexLiteral
))
4945 return spaceRequiredBetween(Line
, Left
, Right
);
4948 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
4949 static bool isAllmanBrace(const FormatToken
&Tok
) {
4950 return Tok
.is(tok::l_brace
) && Tok
.is(BK_Block
) &&
4951 !Tok
.isOneOf(TT_ObjCBlockLBrace
, TT_LambdaLBrace
, TT_DictLiteral
);
4954 // Returns 'true' if 'Tok' is a function argument.
4955 static bool IsFunctionArgument(const FormatToken
&Tok
) {
4956 return Tok
.MatchingParen
&& Tok
.MatchingParen
->Next
&&
4957 Tok
.MatchingParen
->Next
->isOneOf(tok::comma
, tok::r_paren
);
4961 isItAnEmptyLambdaAllowed(const FormatToken
&Tok
,
4962 FormatStyle::ShortLambdaStyle ShortLambdaOption
) {
4963 return Tok
.Children
.empty() && ShortLambdaOption
!= FormatStyle::SLS_None
;
4966 static bool isAllmanLambdaBrace(const FormatToken
&Tok
) {
4967 return Tok
.is(tok::l_brace
) && Tok
.is(BK_Block
) &&
4968 !Tok
.isOneOf(TT_ObjCBlockLBrace
, TT_DictLiteral
);
4971 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine
&Line
,
4972 const FormatToken
&Right
) const {
4973 const FormatToken
&Left
= *Right
.Previous
;
4974 if (Right
.NewlinesBefore
> 1 && Style
.MaxEmptyLinesToKeep
> 0)
4977 if (Style
.isCSharp()) {
4978 if (Left
.is(TT_FatArrow
) && Right
.is(tok::l_brace
) &&
4979 Style
.BraceWrapping
.AfterFunction
) {
4982 if (Right
.is(TT_CSharpNamedArgumentColon
) ||
4983 Left
.is(TT_CSharpNamedArgumentColon
)) {
4986 if (Right
.is(TT_CSharpGenericTypeConstraint
))
4988 if (Right
.Next
&& Right
.Next
->is(TT_FatArrow
) &&
4989 (Right
.is(tok::numeric_constant
) ||
4990 (Right
.is(tok::identifier
) && Right
.TokenText
== "_"))) {
4994 // Break after C# [...] and before public/protected/private/internal.
4995 if (Left
.is(TT_AttributeSquare
) && Left
.is(tok::r_square
) &&
4996 (Right
.isAccessSpecifier(/*ColonRequired=*/false) ||
4997 Right
.is(Keywords
.kw_internal
))) {
5000 // Break between ] and [ but only when there are really 2 attributes.
5001 if (Left
.is(TT_AttributeSquare
) && Right
.is(TT_AttributeSquare
) &&
5002 Left
.is(tok::r_square
) && Right
.is(tok::l_square
)) {
5006 } else if (Style
.isJavaScript()) {
5007 // FIXME: This might apply to other languages and token kinds.
5008 if (Right
.is(tok::string_literal
) && Left
.is(tok::plus
) && Left
.Previous
&&
5009 Left
.Previous
->is(tok::string_literal
)) {
5012 if (Left
.is(TT_DictLiteral
) && Left
.is(tok::l_brace
) && Line
.Level
== 0 &&
5013 Left
.Previous
&& Left
.Previous
->is(tok::equal
) &&
5014 Line
.First
->isOneOf(tok::identifier
, Keywords
.kw_import
, tok::kw_export
,
5016 // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match
5018 !Line
.First
->isOneOf(Keywords
.kw_var
, Keywords
.kw_let
)) {
5019 // Object literals on the top level of a file are treated as "enum-style".
5020 // Each key/value pair is put on a separate line, instead of bin-packing.
5023 if (Left
.is(tok::l_brace
) && Line
.Level
== 0 &&
5024 (Line
.startsWith(tok::kw_enum
) ||
5025 Line
.startsWith(tok::kw_const
, tok::kw_enum
) ||
5026 Line
.startsWith(tok::kw_export
, tok::kw_enum
) ||
5027 Line
.startsWith(tok::kw_export
, tok::kw_const
, tok::kw_enum
))) {
5028 // JavaScript top-level enum key/value pairs are put on separate lines
5029 // instead of bin-packing.
5032 if (Right
.is(tok::r_brace
) && Left
.is(tok::l_brace
) && Left
.Previous
&&
5033 Left
.Previous
->is(TT_FatArrow
)) {
5034 // JS arrow function (=> {...}).
5035 switch (Style
.AllowShortLambdasOnASingleLine
) {
5036 case FormatStyle::SLS_All
:
5038 case FormatStyle::SLS_None
:
5040 case FormatStyle::SLS_Empty
:
5041 return !Left
.Children
.empty();
5042 case FormatStyle::SLS_Inline
:
5043 // allow one-lining inline (e.g. in function call args) and empty arrow
5045 return (Left
.NestingLevel
== 0 && Line
.Level
== 0) &&
5046 !Left
.Children
.empty();
5048 llvm_unreachable("Unknown FormatStyle::ShortLambdaStyle enum");
5051 if (Right
.is(tok::r_brace
) && Left
.is(tok::l_brace
) &&
5052 !Left
.Children
.empty()) {
5053 // Support AllowShortFunctionsOnASingleLine for JavaScript.
5054 return Style
.AllowShortFunctionsOnASingleLine
== FormatStyle::SFS_None
||
5055 Style
.AllowShortFunctionsOnASingleLine
== FormatStyle::SFS_Empty
||
5056 (Left
.NestingLevel
== 0 && Line
.Level
== 0 &&
5057 Style
.AllowShortFunctionsOnASingleLine
&
5058 FormatStyle::SFS_InlineOnly
);
5060 } else if (Style
.Language
== FormatStyle::LK_Java
) {
5061 if (Right
.is(tok::plus
) && Left
.is(tok::string_literal
) && Right
.Next
&&
5062 Right
.Next
->is(tok::string_literal
)) {
5065 } else if (Style
.isVerilog()) {
5066 // Break between assignments.
5067 if (Left
.is(TT_VerilogAssignComma
))
5069 // Break between ports of different types.
5070 if (Left
.is(TT_VerilogTypeComma
))
5072 // Break between ports in a module instantiation and after the parameter
5074 if (Style
.VerilogBreakBetweenInstancePorts
&&
5075 (Left
.is(TT_VerilogInstancePortComma
) ||
5076 (Left
.is(tok::r_paren
) && Keywords
.isVerilogIdentifier(Right
) &&
5077 Left
.MatchingParen
&&
5078 Left
.MatchingParen
->is(TT_VerilogInstancePortLParen
)))) {
5081 // Break after labels. In Verilog labels don't have the 'case' keyword, so
5082 // it is hard to identify them in UnwrappedLineParser.
5083 if (!Keywords
.isVerilogBegin(Right
) && Keywords
.isVerilogEndOfLabel(Left
))
5085 } else if (Style
.BreakAdjacentStringLiterals
&&
5086 (Style
.isCpp() || Style
.isProto() ||
5087 Style
.Language
== FormatStyle::LK_TableGen
)) {
5088 if (Left
.isStringLiteral() && Right
.isStringLiteral())
5092 // Basic JSON newline processing.
5093 if (Style
.isJson()) {
5094 // Always break after a JSON record opener.
5097 if (Left
.is(TT_DictLiteral
) && Left
.is(tok::l_brace
))
5099 // Always break after a JSON array opener based on BreakArrays.
5100 if ((Left
.is(TT_ArrayInitializerLSquare
) && Left
.is(tok::l_square
) &&
5101 Right
.isNot(tok::r_square
)) ||
5102 Left
.is(tok::comma
)) {
5103 if (Right
.is(tok::l_brace
))
5105 // scan to the right if an we see an object or an array inside
5107 for (const auto *Tok
= &Right
; Tok
; Tok
= Tok
->Next
) {
5108 if (Tok
->isOneOf(tok::l_brace
, tok::l_square
))
5110 if (Tok
->isOneOf(tok::r_brace
, tok::r_square
))
5113 return Style
.BreakArrays
;
5117 if (Line
.startsWith(tok::kw_asm
) && Right
.is(TT_InlineASMColon
) &&
5118 Style
.BreakBeforeInlineASMColon
== FormatStyle::BBIAS_Always
) {
5122 // If the last token before a '}', ']', or ')' is a comma or a trailing
5123 // comment, the intention is to insert a line break after it in order to make
5124 // shuffling around entries easier. Import statements, especially in
5125 // JavaScript, can be an exception to this rule.
5126 if (Style
.JavaScriptWrapImports
|| Line
.Type
!= LT_ImportStatement
) {
5127 const FormatToken
*BeforeClosingBrace
= nullptr;
5128 if ((Left
.isOneOf(tok::l_brace
, TT_ArrayInitializerLSquare
) ||
5129 (Style
.isJavaScript() && Left
.is(tok::l_paren
))) &&
5130 Left
.isNot(BK_Block
) && Left
.MatchingParen
) {
5131 BeforeClosingBrace
= Left
.MatchingParen
->Previous
;
5132 } else if (Right
.MatchingParen
&&
5133 (Right
.MatchingParen
->isOneOf(tok::l_brace
,
5134 TT_ArrayInitializerLSquare
) ||
5135 (Style
.isJavaScript() &&
5136 Right
.MatchingParen
->is(tok::l_paren
)))) {
5137 BeforeClosingBrace
= &Left
;
5139 if (BeforeClosingBrace
&& (BeforeClosingBrace
->is(tok::comma
) ||
5140 BeforeClosingBrace
->isTrailingComment())) {
5145 if (Right
.is(tok::comment
)) {
5146 return Left
.isNot(BK_BracedInit
) && Left
.isNot(TT_CtorInitializerColon
) &&
5147 (Right
.NewlinesBefore
> 0 && Right
.HasUnescapedNewline
);
5149 if (Left
.isTrailingComment())
5151 if (Left
.IsUnterminatedLiteral
)
5153 if (Right
.is(TT_RequiresClause
)) {
5154 switch (Style
.RequiresClausePosition
) {
5155 case FormatStyle::RCPS_OwnLine
:
5156 case FormatStyle::RCPS_WithFollowing
:
5162 // Can break after template<> declaration
5163 if (Left
.ClosesTemplateDeclaration
&& Left
.MatchingParen
&&
5164 Left
.MatchingParen
->NestingLevel
== 0) {
5165 // Put concepts on the next line e.g.
5166 // template<typename T>
5168 if (Right
.is(tok::kw_concept
))
5169 return Style
.BreakBeforeConceptDeclarations
== FormatStyle::BBCDS_Always
;
5170 return Style
.AlwaysBreakTemplateDeclarations
== FormatStyle::BTDS_Yes
;
5172 if (Left
.ClosesRequiresClause
&& Right
.isNot(tok::semi
)) {
5173 switch (Style
.RequiresClausePosition
) {
5174 case FormatStyle::RCPS_OwnLine
:
5175 case FormatStyle::RCPS_WithPreceding
:
5181 if (Style
.PackConstructorInitializers
== FormatStyle::PCIS_Never
) {
5182 if (Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeColon
&&
5183 (Left
.is(TT_CtorInitializerComma
) ||
5184 Right
.is(TT_CtorInitializerColon
))) {
5188 if (Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
&&
5189 Left
.isOneOf(TT_CtorInitializerColon
, TT_CtorInitializerComma
)) {
5193 if (Style
.PackConstructorInitializers
< FormatStyle::PCIS_CurrentLine
&&
5194 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
&&
5195 Right
.isOneOf(TT_CtorInitializerComma
, TT_CtorInitializerColon
)) {
5198 if (Style
.PackConstructorInitializers
== FormatStyle::PCIS_NextLineOnly
) {
5199 if ((Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeColon
||
5200 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
) &&
5201 Right
.is(TT_CtorInitializerColon
)) {
5205 if (Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
&&
5206 Left
.is(TT_CtorInitializerColon
)) {
5210 // Break only if we have multiple inheritance.
5211 if (Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
&&
5212 Right
.is(TT_InheritanceComma
)) {
5215 if (Style
.BreakInheritanceList
== FormatStyle::BILS_AfterComma
&&
5216 Left
.is(TT_InheritanceComma
)) {
5219 if (Right
.is(tok::string_literal
) && Right
.TokenText
.starts_with("R\"")) {
5220 // Multiline raw string literals are special wrt. line breaks. The author
5221 // has made a deliberate choice and might have aligned the contents of the
5222 // string literal accordingly. Thus, we try keep existing line breaks.
5223 return Right
.IsMultiline
&& Right
.NewlinesBefore
> 0;
5225 if ((Left
.is(tok::l_brace
) || (Left
.is(tok::less
) && Left
.Previous
&&
5226 Left
.Previous
->is(tok::equal
))) &&
5227 Right
.NestingLevel
== 1 && Style
.Language
== FormatStyle::LK_Proto
) {
5228 // Don't put enums or option definitions onto single lines in protocol
5232 if (Right
.is(TT_InlineASMBrace
))
5233 return Right
.HasUnescapedNewline
;
5235 if (isAllmanBrace(Left
) || isAllmanBrace(Right
)) {
5236 auto *FirstNonComment
= Line
.getFirstNonComment();
5237 bool AccessSpecifier
=
5239 FirstNonComment
->isOneOf(Keywords
.kw_internal
, tok::kw_public
,
5240 tok::kw_private
, tok::kw_protected
);
5242 if (Style
.BraceWrapping
.AfterEnum
) {
5243 if (Line
.startsWith(tok::kw_enum
) ||
5244 Line
.startsWith(tok::kw_typedef
, tok::kw_enum
)) {
5247 // Ensure BraceWrapping for `public enum A {`.
5248 if (AccessSpecifier
&& FirstNonComment
->Next
&&
5249 FirstNonComment
->Next
->is(tok::kw_enum
)) {
5254 // Ensure BraceWrapping for `public interface A {`.
5255 if (Style
.BraceWrapping
.AfterClass
&&
5256 ((AccessSpecifier
&& FirstNonComment
->Next
&&
5257 FirstNonComment
->Next
->is(Keywords
.kw_interface
)) ||
5258 Line
.startsWith(Keywords
.kw_interface
))) {
5262 // Don't attempt to interpret struct return types as structs.
5263 if (Right
.isNot(TT_FunctionLBrace
)) {
5264 return (Line
.startsWith(tok::kw_class
) &&
5265 Style
.BraceWrapping
.AfterClass
) ||
5266 (Line
.startsWith(tok::kw_struct
) &&
5267 Style
.BraceWrapping
.AfterStruct
);
5271 if (Left
.is(TT_ObjCBlockLBrace
) &&
5272 Style
.AllowShortBlocksOnASingleLine
== FormatStyle::SBS_Never
) {
5276 // Ensure wrapping after __attribute__((XX)) and @interface etc.
5277 if (Left
.isOneOf(TT_AttributeRParen
, TT_AttributeMacro
) &&
5278 Right
.is(TT_ObjCDecl
)) {
5282 if (Left
.is(TT_LambdaLBrace
)) {
5283 if (IsFunctionArgument(Left
) &&
5284 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Inline
) {
5288 if (Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_None
||
5289 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Inline
||
5290 (!Left
.Children
.empty() &&
5291 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Empty
)) {
5296 if (Style
.BraceWrapping
.BeforeLambdaBody
&& Right
.is(TT_LambdaLBrace
) &&
5297 (Left
.isPointerOrReference() || Left
.is(TT_TemplateCloser
))) {
5301 // Put multiple Java annotation on a new line.
5302 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
5303 Left
.is(TT_LeadingJavaAnnotation
) &&
5304 Right
.isNot(TT_LeadingJavaAnnotation
) && Right
.isNot(tok::l_paren
) &&
5305 (Line
.Last
->is(tok::l_brace
) || Style
.BreakAfterJavaFieldAnnotations
)) {
5309 if (Right
.is(TT_ProtoExtensionLSquare
))
5312 // In text proto instances if a submessage contains at least 2 entries and at
5313 // least one of them is a submessage, like A { ... B { ... } ... },
5314 // put all of the entries of A on separate lines by forcing the selector of
5315 // the submessage B to be put on a newline.
5317 // Example: these can stay on one line:
5318 // a { scalar_1: 1 scalar_2: 2 }
5319 // a { b { key: value } }
5321 // and these entries need to be on a new line even if putting them all in one
5322 // line is under the column limit:
5328 // We enforce this by breaking before a submessage field that has previous
5329 // siblings, *and* breaking before a field that follows a submessage field.
5331 // Be careful to exclude the case [proto.ext] { ... } since the `]` is
5332 // the TT_SelectorName there, but we don't want to break inside the brackets.
5334 // Another edge case is @submessage { key: value }, which is a common
5335 // substitution placeholder. In this case we want to keep `@` and `submessage`
5338 // We ensure elsewhere that extensions are always on their own line.
5339 if (Style
.isProto() && Right
.is(TT_SelectorName
) &&
5340 Right
.isNot(tok::r_square
) && Right
.Next
) {
5341 // Keep `@submessage` together in:
5342 // @submessage { key: value }
5343 if (Left
.is(tok::at
))
5345 // Look for the scope opener after selector in cases like:
5348 // selector: @base { ...
5349 FormatToken
*LBrace
= Right
.Next
;
5350 if (LBrace
&& LBrace
->is(tok::colon
)) {
5351 LBrace
= LBrace
->Next
;
5352 if (LBrace
&& LBrace
->is(tok::at
)) {
5353 LBrace
= LBrace
->Next
;
5355 LBrace
= LBrace
->Next
;
5359 // The scope opener is one of {, [, <:
5364 // In case of selector { ... }, the l_brace is TT_DictLiteral.
5365 // In case of an empty selector {}, the l_brace is not TT_DictLiteral,
5366 // so we check for immediately following r_brace.
5367 ((LBrace
->is(tok::l_brace
) &&
5368 (LBrace
->is(TT_DictLiteral
) ||
5369 (LBrace
->Next
&& LBrace
->Next
->is(tok::r_brace
)))) ||
5370 LBrace
->is(TT_ArrayInitializerLSquare
) || LBrace
->is(tok::less
))) {
5371 // If Left.ParameterCount is 0, then this submessage entry is not the
5372 // first in its parent submessage, and we want to break before this entry.
5373 // If Left.ParameterCount is greater than 0, then its parent submessage
5374 // might contain 1 or more entries and we want to break before this entry
5375 // if it contains at least 2 entries. We deal with this case later by
5376 // detecting and breaking before the next entry in the parent submessage.
5377 if (Left
.ParameterCount
== 0)
5379 // However, if this submessage is the first entry in its parent
5380 // submessage, Left.ParameterCount might be 1 in some cases.
5381 // We deal with this case later by detecting an entry
5382 // following a closing paren of this submessage.
5385 // If this is an entry immediately following a submessage, it will be
5386 // preceded by a closing paren of that submessage, like in:
5387 // left---. .---right
5389 // sub: { ... } key: value
5390 // If there was a comment between `}` an `key` above, then `key` would be
5391 // put on a new line anyways.
5392 if (Left
.isOneOf(tok::r_brace
, tok::greater
, tok::r_square
))
5399 bool TokenAnnotator::canBreakBefore(const AnnotatedLine
&Line
,
5400 const FormatToken
&Right
) const {
5401 const FormatToken
&Left
= *Right
.Previous
;
5402 // Language-specific stuff.
5403 if (Style
.isCSharp()) {
5404 if (Left
.isOneOf(TT_CSharpNamedArgumentColon
, TT_AttributeColon
) ||
5405 Right
.isOneOf(TT_CSharpNamedArgumentColon
, TT_AttributeColon
)) {
5408 // Only break after commas for generic type constraints.
5409 if (Line
.First
->is(TT_CSharpGenericTypeConstraint
))
5410 return Left
.is(TT_CSharpGenericTypeConstraintComma
);
5411 // Keep nullable operators attached to their identifiers.
5412 if (Right
.is(TT_CSharpNullable
))
5414 } else if (Style
.Language
== FormatStyle::LK_Java
) {
5415 if (Left
.isOneOf(Keywords
.kw_throws
, Keywords
.kw_extends
,
5416 Keywords
.kw_implements
)) {
5419 if (Right
.isOneOf(Keywords
.kw_throws
, Keywords
.kw_extends
,
5420 Keywords
.kw_implements
)) {
5423 } else if (Style
.isJavaScript()) {
5424 const FormatToken
*NonComment
= Right
.getPreviousNonComment();
5426 NonComment
->isOneOf(
5427 tok::kw_return
, Keywords
.kw_yield
, tok::kw_continue
, tok::kw_break
,
5428 tok::kw_throw
, Keywords
.kw_interface
, Keywords
.kw_type
,
5429 tok::kw_static
, tok::kw_public
, tok::kw_private
, tok::kw_protected
,
5430 Keywords
.kw_readonly
, Keywords
.kw_override
, Keywords
.kw_abstract
,
5431 Keywords
.kw_get
, Keywords
.kw_set
, Keywords
.kw_async
,
5432 Keywords
.kw_await
)) {
5433 return false; // Otherwise automatic semicolon insertion would trigger.
5435 if (Right
.NestingLevel
== 0 &&
5436 (Left
.Tok
.getIdentifierInfo() ||
5437 Left
.isOneOf(tok::r_square
, tok::r_paren
)) &&
5438 Right
.isOneOf(tok::l_square
, tok::l_paren
)) {
5439 return false; // Otherwise automatic semicolon insertion would trigger.
5441 if (NonComment
&& NonComment
->is(tok::identifier
) &&
5442 NonComment
->TokenText
== "asserts") {
5445 if (Left
.is(TT_FatArrow
) && Right
.is(tok::l_brace
))
5447 if (Left
.is(TT_JsTypeColon
))
5449 // Don't wrap between ":" and "!" of a strict prop init ("field!: type;").
5450 if (Left
.is(tok::exclaim
) && Right
.is(tok::colon
))
5452 // Look for is type annotations like:
5453 // function f(): a is B { ... }
5454 // Do not break before is in these cases.
5455 if (Right
.is(Keywords
.kw_is
)) {
5456 const FormatToken
*Next
= Right
.getNextNonComment();
5457 // If `is` is followed by a colon, it's likely that it's a dict key, so
5458 // ignore it for this check.
5459 // For example this is common in Polymer:
5464 if (!Next
|| Next
->isNot(tok::colon
))
5467 if (Left
.is(Keywords
.kw_in
))
5468 return Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_None
;
5469 if (Right
.is(Keywords
.kw_in
))
5470 return Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_None
;
5471 if (Right
.is(Keywords
.kw_as
))
5472 return false; // must not break before as in 'x as type' casts
5473 if (Right
.isOneOf(Keywords
.kw_extends
, Keywords
.kw_infer
)) {
5474 // extends and infer can appear as keywords in conditional types:
5475 // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types
5476 // do not break before them, as the expressions are subject to ASI.
5479 if (Left
.is(Keywords
.kw_as
))
5481 if (Left
.is(TT_NonNullAssertion
))
5483 if (Left
.is(Keywords
.kw_declare
) &&
5484 Right
.isOneOf(Keywords
.kw_module
, tok::kw_namespace
,
5485 Keywords
.kw_function
, tok::kw_class
, tok::kw_enum
,
5486 Keywords
.kw_interface
, Keywords
.kw_type
, Keywords
.kw_var
,
5487 Keywords
.kw_let
, tok::kw_const
)) {
5488 // See grammar for 'declare' statements at:
5489 // https://github.com/Microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md#A.10
5492 if (Left
.isOneOf(Keywords
.kw_module
, tok::kw_namespace
) &&
5493 Right
.isOneOf(tok::identifier
, tok::string_literal
)) {
5494 return false; // must not break in "module foo { ...}"
5496 if (Right
.is(TT_TemplateString
) && Right
.closesScope())
5498 // Don't split tagged template literal so there is a break between the tag
5499 // identifier and template string.
5500 if (Left
.is(tok::identifier
) && Right
.is(TT_TemplateString
))
5502 if (Left
.is(TT_TemplateString
) && Left
.opensScope())
5506 if (Left
.is(tok::at
))
5508 if (Left
.Tok
.getObjCKeywordID() == tok::objc_interface
)
5510 if (Left
.isOneOf(TT_JavaAnnotation
, TT_LeadingJavaAnnotation
))
5511 return Right
.isNot(tok::l_paren
);
5512 if (Right
.is(TT_PointerOrReference
)) {
5513 return Line
.IsMultiVariableDeclStmt
||
5514 (getTokenPointerOrReferenceAlignment(Right
) ==
5515 FormatStyle::PAS_Right
&&
5516 (!Right
.Next
|| Right
.Next
->isNot(TT_FunctionDeclarationName
)));
5518 if (Right
.isOneOf(TT_StartOfName
, TT_FunctionDeclarationName
) ||
5519 Right
.is(tok::kw_operator
)) {
5522 if (Left
.is(TT_PointerOrReference
))
5524 if (Right
.isTrailingComment()) {
5525 // We rely on MustBreakBefore being set correctly here as we should not
5526 // change the "binding" behavior of a comment.
5527 // The first comment in a braced lists is always interpreted as belonging to
5528 // the first list element. Otherwise, it should be placed outside of the
5530 return Left
.is(BK_BracedInit
) ||
5531 (Left
.is(TT_CtorInitializerColon
) && Right
.NewlinesBefore
> 0 &&
5532 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
);
5534 if (Left
.is(tok::question
) && Right
.is(tok::colon
))
5536 if (Right
.is(TT_ConditionalExpr
) || Right
.is(tok::question
))
5537 return Style
.BreakBeforeTernaryOperators
;
5538 if (Left
.is(TT_ConditionalExpr
) || Left
.is(tok::question
))
5539 return !Style
.BreakBeforeTernaryOperators
;
5540 if (Left
.is(TT_InheritanceColon
))
5541 return Style
.BreakInheritanceList
== FormatStyle::BILS_AfterColon
;
5542 if (Right
.is(TT_InheritanceColon
))
5543 return Style
.BreakInheritanceList
!= FormatStyle::BILS_AfterColon
;
5544 if (Right
.is(TT_ObjCMethodExpr
) && Right
.isNot(tok::r_square
) &&
5545 Left
.isNot(TT_SelectorName
)) {
5549 if (Right
.is(tok::colon
) &&
5550 !Right
.isOneOf(TT_CtorInitializerColon
, TT_InlineASMColon
)) {
5553 if (Left
.is(tok::colon
) && Left
.isOneOf(TT_DictLiteral
, TT_ObjCMethodExpr
)) {
5554 if (Style
.isProto()) {
5555 if (!Style
.AlwaysBreakBeforeMultilineStrings
&& Right
.isStringLiteral())
5557 // Prevent cases like:
5560 // { key: valueeeeeeeeeeee }
5562 // when the snippet does not fit into one line.
5566 // key: valueeeeeeeeeeee
5569 // instead, even if it is longer by one line.
5571 // Note that this allows the "{" to go over the column limit
5572 // when the column limit is just between ":" and "{", but that does
5573 // not happen too often and alternative formattings in this case are
5576 // The code covers the cases:
5578 // submessage: { ... }
5579 // submessage: < ... >
5580 // repeated: [ ... ]
5581 if (((Right
.is(tok::l_brace
) || Right
.is(tok::less
)) &&
5582 Right
.is(TT_DictLiteral
)) ||
5583 Right
.is(TT_ArrayInitializerLSquare
)) {
5589 if (Right
.is(tok::r_square
) && Right
.MatchingParen
&&
5590 Right
.MatchingParen
->is(TT_ProtoExtensionLSquare
)) {
5593 if (Right
.is(TT_SelectorName
) || (Right
.is(tok::identifier
) && Right
.Next
&&
5594 Right
.Next
->is(TT_ObjCMethodExpr
))) {
5595 return Left
.isNot(tok::period
); // FIXME: Properly parse ObjC calls.
5597 if (Left
.is(tok::r_paren
) && Line
.Type
== LT_ObjCProperty
)
5599 if (Right
.is(tok::kw_concept
))
5600 return Style
.BreakBeforeConceptDeclarations
!= FormatStyle::BBCDS_Never
;
5601 if (Right
.is(TT_RequiresClause
))
5603 if (Left
.ClosesTemplateDeclaration
|| Left
.is(TT_FunctionAnnotationRParen
))
5605 if (Left
.ClosesRequiresClause
)
5607 if (Right
.isOneOf(TT_RangeBasedForLoopColon
, TT_OverloadedOperatorLParen
,
5608 TT_OverloadedOperator
)) {
5611 if (Left
.is(TT_RangeBasedForLoopColon
))
5613 if (Right
.is(TT_RangeBasedForLoopColon
))
5615 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_TemplateOpener
))
5617 if ((Left
.is(tok::greater
) && Right
.is(tok::greater
)) ||
5618 (Left
.is(tok::less
) && Right
.is(tok::less
))) {
5621 if (Right
.is(TT_BinaryOperator
) &&
5622 Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_None
&&
5623 (Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_All
||
5624 Right
.getPrecedence() != prec::Assignment
)) {
5627 if (Left
.isOneOf(TT_TemplateCloser
, TT_UnaryOperator
) ||
5628 Left
.is(tok::kw_operator
)) {
5631 if (Left
.is(tok::equal
) && !Right
.isOneOf(tok::kw_default
, tok::kw_delete
) &&
5632 Line
.Type
== LT_VirtualFunctionDecl
&& Left
.NestingLevel
== 0) {
5635 if (Left
.is(tok::equal
) && Right
.is(tok::l_brace
) &&
5636 !Style
.Cpp11BracedListStyle
) {
5639 if (Left
.is(TT_AttributeLParen
) ||
5640 (Left
.is(tok::l_paren
) && Left
.is(TT_TypeDeclarationParen
))) {
5643 if (Left
.is(tok::l_paren
) && Left
.Previous
&&
5644 (Left
.Previous
->isOneOf(TT_BinaryOperator
, TT_CastRParen
))) {
5647 if (Right
.is(TT_ImplicitStringLiteral
))
5650 if (Right
.is(TT_TemplateCloser
))
5652 if (Right
.is(tok::r_square
) && Right
.MatchingParen
&&
5653 Right
.MatchingParen
->is(TT_LambdaLSquare
)) {
5657 // We only break before r_brace if there was a corresponding break before
5658 // the l_brace, which is tracked by BreakBeforeClosingBrace.
5659 if (Right
.is(tok::r_brace
)) {
5660 return Right
.MatchingParen
&& (Right
.MatchingParen
->is(BK_Block
) ||
5661 (Right
.isBlockIndentedInitRBrace(Style
)));
5664 // We only break before r_paren if we're in a block indented context.
5665 if (Right
.is(tok::r_paren
)) {
5666 if (Style
.AlignAfterOpenBracket
!= FormatStyle::BAS_BlockIndent
||
5667 !Right
.MatchingParen
) {
5670 auto Next
= Right
.Next
;
5671 if (Next
&& Next
->is(tok::r_paren
))
5673 if (Next
&& Next
->is(tok::l_paren
))
5675 const FormatToken
*Previous
= Right
.MatchingParen
->Previous
;
5676 return !(Previous
&& (Previous
->is(tok::kw_for
) || Previous
->isIf()));
5679 // Allow breaking after a trailing annotation, e.g. after a method
5681 if (Left
.is(TT_TrailingAnnotation
)) {
5682 return !Right
.isOneOf(tok::l_brace
, tok::semi
, tok::equal
, tok::l_paren
,
5683 tok::less
, tok::coloncolon
);
5686 if (Right
.isAttribute())
5689 if (Right
.is(tok::l_square
) && Right
.is(TT_AttributeSquare
))
5690 return Left
.isNot(TT_AttributeSquare
);
5692 if (Left
.is(tok::identifier
) && Right
.is(tok::string_literal
))
5695 if (Right
.is(tok::identifier
) && Right
.Next
&& Right
.Next
->is(TT_DictLiteral
))
5698 if (Left
.is(TT_CtorInitializerColon
)) {
5699 return Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
&&
5700 (!Right
.isTrailingComment() || Right
.NewlinesBefore
> 0);
5702 if (Right
.is(TT_CtorInitializerColon
))
5703 return Style
.BreakConstructorInitializers
!= FormatStyle::BCIS_AfterColon
;
5704 if (Left
.is(TT_CtorInitializerComma
) &&
5705 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
) {
5708 if (Right
.is(TT_CtorInitializerComma
) &&
5709 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
) {
5712 if (Left
.is(TT_InheritanceComma
) &&
5713 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
) {
5716 if (Right
.is(TT_InheritanceComma
) &&
5717 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
) {
5720 if (Left
.is(TT_ArrayInitializerLSquare
))
5722 if (Right
.is(tok::kw_typename
) && Left
.isNot(tok::kw_const
))
5724 if ((Left
.isBinaryOperator() || Left
.is(TT_BinaryOperator
)) &&
5725 !Left
.isOneOf(tok::arrowstar
, tok::lessless
) &&
5726 Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_All
&&
5727 (Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_None
||
5728 Left
.getPrecedence() == prec::Assignment
)) {
5731 if ((Left
.is(TT_AttributeSquare
) && Right
.is(tok::l_square
)) ||
5732 (Left
.is(tok::r_square
) && Right
.is(TT_AttributeSquare
))) {
5736 auto ShortLambdaOption
= Style
.AllowShortLambdasOnASingleLine
;
5737 if (Style
.BraceWrapping
.BeforeLambdaBody
&& Right
.is(TT_LambdaLBrace
)) {
5738 if (isAllmanLambdaBrace(Left
))
5739 return !isItAnEmptyLambdaAllowed(Left
, ShortLambdaOption
);
5740 if (isAllmanLambdaBrace(Right
))
5741 return !isItAnEmptyLambdaAllowed(Right
, ShortLambdaOption
);
5744 if (Right
.is(tok::kw_noexcept
) && Right
.is(TT_TrailingAnnotation
)) {
5745 switch (Style
.AllowBreakBeforeNoexceptSpecifier
) {
5746 case FormatStyle::BBNSS_Never
:
5748 case FormatStyle::BBNSS_Always
:
5750 case FormatStyle::BBNSS_OnlyWithParen
:
5751 return Right
.Next
&& Right
.Next
->is(tok::l_paren
);
5755 return Left
.isOneOf(tok::comma
, tok::coloncolon
, tok::semi
, tok::l_brace
,
5756 tok::kw_class
, tok::kw_struct
, tok::comment
) ||
5757 Right
.isMemberAccess() ||
5758 Right
.isOneOf(TT_TrailingReturnArrow
, tok::lessless
, tok::colon
,
5759 tok::l_square
, tok::at
) ||
5760 (Left
.is(tok::r_paren
) &&
5761 Right
.isOneOf(tok::identifier
, tok::kw_const
)) ||
5762 (Left
.is(tok::l_paren
) && Right
.isNot(tok::r_paren
)) ||
5763 (Left
.is(TT_TemplateOpener
) && Right
.isNot(TT_TemplateCloser
));
5766 void TokenAnnotator::printDebugInfo(const AnnotatedLine
&Line
) const {
5767 llvm::errs() << "AnnotatedTokens(L=" << Line
.Level
<< ", P=" << Line
.PPLevel
5768 << ", T=" << Line
.Type
<< ", C=" << Line
.IsContinuation
5770 const FormatToken
*Tok
= Line
.First
;
5772 llvm::errs() << " M=" << Tok
->MustBreakBefore
5773 << " C=" << Tok
->CanBreakBefore
5774 << " T=" << getTokenTypeName(Tok
->getType())
5775 << " S=" << Tok
->SpacesRequiredBefore
5776 << " F=" << Tok
->Finalized
<< " B=" << Tok
->BlockParameterCount
5777 << " BK=" << Tok
->getBlockKind() << " P=" << Tok
->SplitPenalty
5778 << " Name=" << Tok
->Tok
.getName() << " L=" << Tok
->TotalLength
5779 << " PPK=" << Tok
->getPackingKind() << " FakeLParens=";
5780 for (prec::Level LParen
: Tok
->FakeLParens
)
5781 llvm::errs() << LParen
<< "/";
5782 llvm::errs() << " FakeRParens=" << Tok
->FakeRParens
;
5783 llvm::errs() << " II=" << Tok
->Tok
.getIdentifierInfo();
5784 llvm::errs() << " Text='" << Tok
->TokenText
<< "'\n";
5786 assert(Tok
== Line
.Last
);
5789 llvm::errs() << "----\n";
5792 FormatStyle::PointerAlignmentStyle
5793 TokenAnnotator::getTokenReferenceAlignment(const FormatToken
&Reference
) const {
5794 assert(Reference
.isOneOf(tok::amp
, tok::ampamp
));
5795 switch (Style
.ReferenceAlignment
) {
5796 case FormatStyle::RAS_Pointer
:
5797 return Style
.PointerAlignment
;
5798 case FormatStyle::RAS_Left
:
5799 return FormatStyle::PAS_Left
;
5800 case FormatStyle::RAS_Right
:
5801 return FormatStyle::PAS_Right
;
5802 case FormatStyle::RAS_Middle
:
5803 return FormatStyle::PAS_Middle
;
5805 assert(0); //"Unhandled value of ReferenceAlignment"
5806 return Style
.PointerAlignment
;
5809 FormatStyle::PointerAlignmentStyle
5810 TokenAnnotator::getTokenPointerOrReferenceAlignment(
5811 const FormatToken
&PointerOrReference
) const {
5812 if (PointerOrReference
.isOneOf(tok::amp
, tok::ampamp
)) {
5813 switch (Style
.ReferenceAlignment
) {
5814 case FormatStyle::RAS_Pointer
:
5815 return Style
.PointerAlignment
;
5816 case FormatStyle::RAS_Left
:
5817 return FormatStyle::PAS_Left
;
5818 case FormatStyle::RAS_Right
:
5819 return FormatStyle::PAS_Right
;
5820 case FormatStyle::RAS_Middle
:
5821 return FormatStyle::PAS_Middle
;
5824 assert(PointerOrReference
.is(tok::star
));
5825 return Style
.PointerAlignment
;
5828 } // namespace format
5829 } // namespace clang