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"
29 /// Returns \c true if the line starts with a token that can start a statement
30 /// with an initializer.
31 static bool startsWithInitStatement(const AnnotatedLine
&Line
) {
32 return Line
.startsWith(tok::kw_for
) || Line
.startsWith(tok::kw_if
) ||
33 Line
.startsWith(tok::kw_switch
);
36 /// Returns \c true if the token can be used as an identifier in
37 /// an Objective-C \c \@selector, \c false otherwise.
39 /// Because getFormattingLangOpts() always lexes source code as
40 /// Objective-C++, C++ keywords like \c new and \c delete are
41 /// lexed as tok::kw_*, not tok::identifier, even for Objective-C.
43 /// For Objective-C and Objective-C++, both identifiers and keywords
44 /// are valid inside @selector(...) (or a macro which
45 /// invokes @selector(...)). So, we allow treat any identifier or
46 /// keyword as a potential Objective-C selector component.
47 static bool canBeObjCSelectorComponent(const FormatToken
&Tok
) {
48 return Tok
.Tok
.getIdentifierInfo() != nullptr;
51 /// With `Left` being '(', check if we're at either `[...](` or
52 /// `[...]<...>(`, where the [ opens a lambda capture list.
53 static bool isLambdaParameterList(const FormatToken
*Left
) {
54 // Skip <...> if present.
55 if (Left
->Previous
&& Left
->Previous
->is(tok::greater
) &&
56 Left
->Previous
->MatchingParen
&&
57 Left
->Previous
->MatchingParen
->is(TT_TemplateOpener
)) {
58 Left
= Left
->Previous
->MatchingParen
;
62 return Left
->Previous
&& Left
->Previous
->is(tok::r_square
) &&
63 Left
->Previous
->MatchingParen
&&
64 Left
->Previous
->MatchingParen
->is(TT_LambdaLSquare
);
67 /// Returns \c true if the token is followed by a boolean condition, \c false
69 static bool isKeywordWithCondition(const FormatToken
&Tok
) {
70 return Tok
.isOneOf(tok::kw_if
, tok::kw_for
, tok::kw_while
, tok::kw_switch
,
71 tok::kw_constexpr
, tok::kw_catch
);
74 /// A parser that gathers additional information about tokens.
76 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
77 /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
78 /// into template parameter lists.
79 class AnnotatingParser
{
81 AnnotatingParser(const FormatStyle
&Style
, AnnotatedLine
&Line
,
82 const AdditionalKeywords
&Keywords
)
83 : Style(Style
), Line(Line
), CurrentToken(Line
.First
), AutoFound(false),
85 Contexts
.push_back(Context(tok::unknown
, 1, /*IsExpression=*/false));
91 if (!CurrentToken
|| !CurrentToken
->Previous
)
93 if (NonTemplateLess
.count(CurrentToken
->Previous
))
96 const FormatToken
&Previous
= *CurrentToken
->Previous
; // The '<'.
97 if (Previous
.Previous
) {
98 if (Previous
.Previous
->Tok
.isLiteral())
100 if (Previous
.Previous
->is(tok::r_paren
) && Contexts
.size() > 1 &&
101 (!Previous
.Previous
->MatchingParen
||
102 !Previous
.Previous
->MatchingParen
->is(
103 TT_OverloadedOperatorLParen
))) {
108 FormatToken
*Left
= CurrentToken
->Previous
;
109 Left
->ParentBracket
= Contexts
.back().ContextKind
;
110 ScopedContextCreator
ContextCreator(*this, tok::less
, 12);
112 // If this angle is in the context of an expression, we need to be more
113 // hesitant to detect it as opening template parameters.
114 bool InExprContext
= Contexts
.back().IsExpression
;
116 Contexts
.back().IsExpression
= false;
117 // If there's a template keyword before the opening angle bracket, this is a
118 // template parameter, not an argument.
119 if (Left
->Previous
&& Left
->Previous
->isNot(tok::kw_template
))
120 Contexts
.back().ContextType
= Context::TemplateArgument
;
122 if (Style
.Language
== FormatStyle::LK_Java
&&
123 CurrentToken
->is(tok::question
)) {
127 while (CurrentToken
) {
128 if (CurrentToken
->is(tok::greater
)) {
129 // Try to do a better job at looking for ">>" within the condition of
130 // a statement. Conservatively insert spaces between consecutive ">"
131 // tokens to prevent splitting right bitshift operators and potentially
132 // altering program semantics. This check is overly conservative and
133 // will prevent spaces from being inserted in select nested template
134 // parameter cases, but should not alter program semantics.
135 if (CurrentToken
->Next
&& CurrentToken
->Next
->is(tok::greater
) &&
136 Left
->ParentBracket
!= tok::less
&&
137 (isKeywordWithCondition(*Line
.First
) ||
138 CurrentToken
->getStartOfNonWhitespace() ==
139 CurrentToken
->Next
->getStartOfNonWhitespace().getLocWithOffset(
143 Left
->MatchingParen
= CurrentToken
;
144 CurrentToken
->MatchingParen
= Left
;
145 // In TT_Proto, we must distignuish between:
147 // msg < item: data >
148 // msg: < item: data >
149 // In TT_TextProto, map<key, value> does not occur.
150 if (Style
.Language
== FormatStyle::LK_TextProto
||
151 (Style
.Language
== FormatStyle::LK_Proto
&& Left
->Previous
&&
152 Left
->Previous
->isOneOf(TT_SelectorName
, TT_DictLiteral
))) {
153 CurrentToken
->setType(TT_DictLiteral
);
155 CurrentToken
->setType(TT_TemplateCloser
);
160 if (CurrentToken
->is(tok::question
) &&
161 Style
.Language
== FormatStyle::LK_Java
) {
165 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::r_brace
) ||
166 (CurrentToken
->isOneOf(tok::colon
, tok::question
) && InExprContext
&&
167 !Style
.isCSharp() && Style
.Language
!= FormatStyle::LK_Proto
&&
168 Style
.Language
!= FormatStyle::LK_TextProto
)) {
171 // If a && or || is found and interpreted as a binary operator, this set
172 // of angles is likely part of something like "a < b && c > d". If the
173 // angles are inside an expression, the ||/&& might also be a binary
174 // operator that was misinterpreted because we are parsing template
176 // FIXME: This is getting out of hand, write a decent parser.
177 if (CurrentToken
->Previous
->isOneOf(tok::pipepipe
, tok::ampamp
) &&
178 CurrentToken
->Previous
->is(TT_BinaryOperator
) &&
179 Contexts
[Contexts
.size() - 2].IsExpression
&&
180 !Line
.startsWith(tok::kw_template
)) {
183 updateParameterCount(Left
, CurrentToken
);
184 if (Style
.Language
== FormatStyle::LK_Proto
) {
185 if (FormatToken
*Previous
= CurrentToken
->getPreviousNonComment()) {
186 if (CurrentToken
->is(tok::colon
) ||
187 (CurrentToken
->isOneOf(tok::l_brace
, tok::less
) &&
188 Previous
->isNot(tok::colon
))) {
189 Previous
->setType(TT_SelectorName
);
199 bool parseUntouchableParens() {
200 while (CurrentToken
) {
201 CurrentToken
->Finalized
= true;
202 switch (CurrentToken
->Tok
.getKind()) {
205 if (!parseUntouchableParens())
220 bool parseParens(bool LookForDecls
= false) {
223 assert(CurrentToken
->Previous
&& "Unknown previous token");
224 FormatToken
&OpeningParen
= *CurrentToken
->Previous
;
225 assert(OpeningParen
.is(tok::l_paren
));
226 FormatToken
*PrevNonComment
= OpeningParen
.getPreviousNonComment();
227 OpeningParen
.ParentBracket
= Contexts
.back().ContextKind
;
228 ScopedContextCreator
ContextCreator(*this, tok::l_paren
, 1);
230 // FIXME: This is a bit of a hack. Do better.
231 Contexts
.back().ColonIsForRangeExpr
=
232 Contexts
.size() == 2 && Contexts
[0].ColonIsForRangeExpr
;
234 if (OpeningParen
.Previous
&&
235 OpeningParen
.Previous
->is(TT_UntouchableMacroFunc
)) {
236 OpeningParen
.Finalized
= true;
237 return parseUntouchableParens();
240 bool StartsObjCMethodExpr
= false;
241 if (!Style
.isVerilog()) {
242 if (FormatToken
*MaybeSel
= OpeningParen
.Previous
) {
243 // @selector( starts a selector.
244 if (MaybeSel
->isObjCAtKeyword(tok::objc_selector
) &&
245 MaybeSel
->Previous
&& MaybeSel
->Previous
->is(tok::at
)) {
246 StartsObjCMethodExpr
= true;
251 if (OpeningParen
.is(TT_OverloadedOperatorLParen
)) {
252 // Find the previous kw_operator token.
253 FormatToken
*Prev
= &OpeningParen
;
254 while (!Prev
->is(tok::kw_operator
)) {
255 Prev
= Prev
->Previous
;
256 assert(Prev
&& "Expect a kw_operator prior to the OperatorLParen!");
259 // If faced with "a.operator*(argument)" or "a->operator*(argument)",
260 // i.e. the operator is called as a member function,
261 // then the argument must be an expression.
262 bool OperatorCalledAsMemberFunction
=
263 Prev
->Previous
&& Prev
->Previous
->isOneOf(tok::period
, tok::arrow
);
264 Contexts
.back().IsExpression
= OperatorCalledAsMemberFunction
;
265 } else if (Style
.isJavaScript() &&
266 (Line
.startsWith(Keywords
.kw_type
, tok::identifier
) ||
267 Line
.startsWith(tok::kw_export
, Keywords
.kw_type
,
270 // export type X = (...);
271 Contexts
.back().IsExpression
= false;
272 } else if (OpeningParen
.Previous
&&
273 (OpeningParen
.Previous
->isOneOf(tok::kw_static_assert
,
274 tok::kw_while
, tok::l_paren
,
275 tok::comma
, TT_BinaryOperator
) ||
276 OpeningParen
.Previous
->isIf())) {
277 // static_assert, if and while usually contain expressions.
278 Contexts
.back().IsExpression
= true;
279 } else if (Style
.isJavaScript() && OpeningParen
.Previous
&&
280 (OpeningParen
.Previous
->is(Keywords
.kw_function
) ||
281 (OpeningParen
.Previous
->endsSequence(tok::identifier
,
282 Keywords
.kw_function
)))) {
283 // function(...) or function f(...)
284 Contexts
.back().IsExpression
= false;
285 } else if (Style
.isJavaScript() && OpeningParen
.Previous
&&
286 OpeningParen
.Previous
->is(TT_JsTypeColon
)) {
287 // let x: (SomeType);
288 Contexts
.back().IsExpression
= false;
289 } else if (isLambdaParameterList(&OpeningParen
)) {
290 // This is a parameter list of a lambda expression.
291 Contexts
.back().IsExpression
= false;
292 } else if (Line
.InPPDirective
&&
293 (!OpeningParen
.Previous
||
294 !OpeningParen
.Previous
->is(tok::identifier
))) {
295 Contexts
.back().IsExpression
= true;
296 } else if (Contexts
[Contexts
.size() - 2].CaretFound
) {
297 // This is the parameter list of an ObjC block.
298 Contexts
.back().IsExpression
= false;
299 } else if (OpeningParen
.Previous
&&
300 OpeningParen
.Previous
->is(TT_ForEachMacro
)) {
301 // The first argument to a foreach macro is a declaration.
302 Contexts
.back().ContextType
= Context::ForEachMacro
;
303 Contexts
.back().IsExpression
= false;
304 } else if (OpeningParen
.Previous
&& OpeningParen
.Previous
->MatchingParen
&&
305 OpeningParen
.Previous
->MatchingParen
->isOneOf(
306 TT_ObjCBlockLParen
, TT_FunctionTypeLParen
)) {
307 Contexts
.back().IsExpression
= false;
308 } else if (!Line
.MustBeDeclaration
&& !Line
.InPPDirective
) {
310 OpeningParen
.Previous
&&
311 OpeningParen
.Previous
->isOneOf(tok::kw_for
, tok::kw_catch
);
312 Contexts
.back().IsExpression
= !IsForOrCatch
;
315 // Infer the role of the l_paren based on the previous token if we haven't
316 // detected one one yet.
317 if (PrevNonComment
&& OpeningParen
.is(TT_Unknown
)) {
318 if (PrevNonComment
->is(tok::kw___attribute
)) {
319 OpeningParen
.setType(TT_AttributeParen
);
320 } else if (PrevNonComment
->isOneOf(TT_TypenameMacro
, tok::kw_decltype
,
322 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,
323 #include "clang/Basic/TransformTypeTraits.def"
325 OpeningParen
.setType(TT_TypeDeclarationParen
);
326 // decltype() and typeof() usually contain expressions.
327 if (PrevNonComment
->isOneOf(tok::kw_decltype
, tok::kw_typeof
))
328 Contexts
.back().IsExpression
= true;
332 if (StartsObjCMethodExpr
) {
333 Contexts
.back().ColonIsObjCMethodExpr
= true;
334 OpeningParen
.setType(TT_ObjCMethodExpr
);
337 // MightBeFunctionType and ProbablyFunctionType are used for
338 // function pointer and reference types as well as Objective-C
341 // void (*FunctionPointer)(void);
342 // void (&FunctionReference)(void);
343 // void (&&FunctionReference)(void);
344 // void (^ObjCBlock)(void);
345 bool MightBeFunctionType
= !Contexts
[Contexts
.size() - 2].IsExpression
;
346 bool ProbablyFunctionType
=
347 CurrentToken
->isOneOf(tok::star
, tok::amp
, tok::ampamp
, tok::caret
);
348 bool HasMultipleLines
= false;
349 bool HasMultipleParametersOnALine
= false;
350 bool MightBeObjCForRangeLoop
=
351 OpeningParen
.Previous
&& OpeningParen
.Previous
->is(tok::kw_for
);
352 FormatToken
*PossibleObjCForInToken
= nullptr;
353 while (CurrentToken
) {
354 // LookForDecls is set when "if (" has been seen. Check for
355 // 'identifier' '*' 'identifier' followed by not '=' -- this
356 // '*' has to be a binary operator but determineStarAmpUsage() will
357 // categorize it as an unary operator, so set the right type here.
358 if (LookForDecls
&& CurrentToken
->Next
) {
359 FormatToken
*Prev
= CurrentToken
->getPreviousNonComment();
361 FormatToken
*PrevPrev
= Prev
->getPreviousNonComment();
362 FormatToken
*Next
= CurrentToken
->Next
;
363 if (PrevPrev
&& PrevPrev
->is(tok::identifier
) &&
364 Prev
->isOneOf(tok::star
, tok::amp
, tok::ampamp
) &&
365 CurrentToken
->is(tok::identifier
) &&
366 !Next
->isOneOf(tok::equal
, tok::l_brace
)) {
367 Prev
->setType(TT_BinaryOperator
);
368 LookForDecls
= false;
373 if (CurrentToken
->Previous
->is(TT_PointerOrReference
) &&
374 CurrentToken
->Previous
->Previous
->isOneOf(tok::l_paren
,
376 ProbablyFunctionType
= true;
378 if (CurrentToken
->is(tok::comma
))
379 MightBeFunctionType
= false;
380 if (CurrentToken
->Previous
->is(TT_BinaryOperator
))
381 Contexts
.back().IsExpression
= true;
382 if (CurrentToken
->is(tok::r_paren
)) {
383 if (OpeningParen
.isNot(TT_CppCastLParen
) && MightBeFunctionType
&&
384 ProbablyFunctionType
&& CurrentToken
->Next
&&
385 (CurrentToken
->Next
->is(tok::l_paren
) ||
386 (CurrentToken
->Next
->is(tok::l_square
) &&
387 Line
.MustBeDeclaration
))) {
388 OpeningParen
.setType(OpeningParen
.Next
->is(tok::caret
)
390 : TT_FunctionTypeLParen
);
392 OpeningParen
.MatchingParen
= CurrentToken
;
393 CurrentToken
->MatchingParen
= &OpeningParen
;
395 if (CurrentToken
->Next
&& CurrentToken
->Next
->is(tok::l_brace
) &&
396 OpeningParen
.Previous
&& OpeningParen
.Previous
->is(tok::l_paren
)) {
397 // Detect the case where macros are used to generate lambdas or
398 // function bodies, e.g.:
399 // auto my_lambda = MACRO((Type *type, int i) { .. body .. });
400 for (FormatToken
*Tok
= &OpeningParen
; Tok
!= CurrentToken
;
402 if (Tok
->is(TT_BinaryOperator
) &&
403 Tok
->isOneOf(tok::star
, tok::amp
, tok::ampamp
)) {
404 Tok
->setType(TT_PointerOrReference
);
409 if (StartsObjCMethodExpr
) {
410 CurrentToken
->setType(TT_ObjCMethodExpr
);
411 if (Contexts
.back().FirstObjCSelectorName
) {
412 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
413 Contexts
.back().LongestObjCSelectorName
;
417 if (OpeningParen
.is(TT_AttributeParen
))
418 CurrentToken
->setType(TT_AttributeParen
);
419 if (OpeningParen
.is(TT_TypeDeclarationParen
))
420 CurrentToken
->setType(TT_TypeDeclarationParen
);
421 if (OpeningParen
.Previous
&&
422 OpeningParen
.Previous
->is(TT_JavaAnnotation
)) {
423 CurrentToken
->setType(TT_JavaAnnotation
);
425 if (OpeningParen
.Previous
&&
426 OpeningParen
.Previous
->is(TT_LeadingJavaAnnotation
)) {
427 CurrentToken
->setType(TT_LeadingJavaAnnotation
);
429 if (OpeningParen
.Previous
&&
430 OpeningParen
.Previous
->is(TT_AttributeSquare
)) {
431 CurrentToken
->setType(TT_AttributeSquare
);
434 if (!HasMultipleLines
)
435 OpeningParen
.setPackingKind(PPK_Inconclusive
);
436 else if (HasMultipleParametersOnALine
)
437 OpeningParen
.setPackingKind(PPK_BinPacked
);
439 OpeningParen
.setPackingKind(PPK_OnePerLine
);
444 if (CurrentToken
->isOneOf(tok::r_square
, tok::r_brace
))
447 if (CurrentToken
->is(tok::l_brace
) && OpeningParen
.is(TT_ObjCBlockLParen
))
448 OpeningParen
.setType(TT_Unknown
);
449 if (CurrentToken
->is(tok::comma
) && CurrentToken
->Next
&&
450 !CurrentToken
->Next
->HasUnescapedNewline
&&
451 !CurrentToken
->Next
->isTrailingComment()) {
452 HasMultipleParametersOnALine
= true;
454 bool ProbablyFunctionTypeLParen
=
455 (CurrentToken
->is(tok::l_paren
) && CurrentToken
->Next
&&
456 CurrentToken
->Next
->isOneOf(tok::star
, tok::amp
, tok::caret
));
457 if ((CurrentToken
->Previous
->isOneOf(tok::kw_const
, tok::kw_auto
) ||
458 CurrentToken
->Previous
->isSimpleTypeSpecifier()) &&
459 !(CurrentToken
->is(tok::l_brace
) ||
460 (CurrentToken
->is(tok::l_paren
) && !ProbablyFunctionTypeLParen
))) {
461 Contexts
.back().IsExpression
= false;
463 if (CurrentToken
->isOneOf(tok::semi
, tok::colon
)) {
464 MightBeObjCForRangeLoop
= false;
465 if (PossibleObjCForInToken
) {
466 PossibleObjCForInToken
->setType(TT_Unknown
);
467 PossibleObjCForInToken
= nullptr;
470 if (MightBeObjCForRangeLoop
&& CurrentToken
->is(Keywords
.kw_in
)) {
471 PossibleObjCForInToken
= CurrentToken
;
472 PossibleObjCForInToken
->setType(TT_ObjCForIn
);
474 // When we discover a 'new', we set CanBeExpression to 'false' in order to
475 // parse the type correctly. Reset that after a comma.
476 if (CurrentToken
->is(tok::comma
))
477 Contexts
.back().CanBeExpression
= true;
479 FormatToken
*Tok
= CurrentToken
;
482 updateParameterCount(&OpeningParen
, Tok
);
483 if (CurrentToken
&& CurrentToken
->HasUnescapedNewline
)
484 HasMultipleLines
= true;
489 bool isCSharpAttributeSpecifier(const FormatToken
&Tok
) {
490 if (!Style
.isCSharp())
493 // `identifier[i]` is not an attribute.
494 if (Tok
.Previous
&& Tok
.Previous
->is(tok::identifier
))
497 // Chains of [] in `identifier[i][j][k]` are not attributes.
498 if (Tok
.Previous
&& Tok
.Previous
->is(tok::r_square
)) {
499 auto *MatchingParen
= Tok
.Previous
->MatchingParen
;
500 if (!MatchingParen
|| MatchingParen
->is(TT_ArraySubscriptLSquare
))
504 const FormatToken
*AttrTok
= Tok
.Next
;
508 // Just an empty declaration e.g. string [].
509 if (AttrTok
->is(tok::r_square
))
512 // Move along the tokens inbetween the '[' and ']' e.g. [STAThread].
513 while (AttrTok
&& AttrTok
->isNot(tok::r_square
))
514 AttrTok
= AttrTok
->Next
;
519 // Allow an attribute to be the only content of a file.
520 AttrTok
= AttrTok
->Next
;
524 // Limit this to being an access modifier that follows.
525 if (AttrTok
->isOneOf(tok::kw_public
, tok::kw_private
, tok::kw_protected
,
526 tok::comment
, tok::kw_class
, tok::kw_static
,
527 tok::l_square
, Keywords
.kw_internal
)) {
531 // incase its a [XXX] retval func(....
533 AttrTok
->Next
->startsSequence(tok::identifier
, tok::l_paren
)) {
540 bool isCpp11AttributeSpecifier(const FormatToken
&Tok
) {
541 if (!Style
.isCpp() || !Tok
.startsSequence(tok::l_square
, tok::l_square
))
543 // The first square bracket is part of an ObjC array literal
544 if (Tok
.Previous
&& Tok
.Previous
->is(tok::at
))
546 const FormatToken
*AttrTok
= Tok
.Next
->Next
;
549 // C++17 '[[using ns: foo, bar(baz, blech)]]'
550 // We assume nobody will name an ObjC variable 'using'.
551 if (AttrTok
->startsSequence(tok::kw_using
, tok::identifier
, tok::colon
))
553 if (AttrTok
->isNot(tok::identifier
))
555 while (AttrTok
&& !AttrTok
->startsSequence(tok::r_square
, tok::r_square
)) {
556 // ObjC message send. We assume nobody will use : in a C++11 attribute
557 // specifier parameter, although this is technically valid:
559 if (AttrTok
->is(tok::colon
) ||
560 AttrTok
->startsSequence(tok::identifier
, tok::identifier
) ||
561 AttrTok
->startsSequence(tok::r_paren
, tok::identifier
)) {
564 if (AttrTok
->is(tok::ellipsis
))
566 AttrTok
= AttrTok
->Next
;
568 return AttrTok
&& AttrTok
->startsSequence(tok::r_square
, tok::r_square
);
575 // A '[' could be an index subscript (after an identifier or after
576 // ')' or ']'), it could be the start of an Objective-C method
577 // expression, it could the start of an Objective-C array literal,
578 // or it could be a C++ attribute specifier [[foo::bar]].
579 FormatToken
*Left
= CurrentToken
->Previous
;
580 Left
->ParentBracket
= Contexts
.back().ContextKind
;
581 FormatToken
*Parent
= Left
->getPreviousNonComment();
583 // Cases where '>' is followed by '['.
584 // In C++, this can happen either in array of templates (foo<int>[10])
585 // or when array is a nested template type (unique_ptr<type1<type2>[]>).
586 bool CppArrayTemplates
=
587 Style
.isCpp() && Parent
&& Parent
->is(TT_TemplateCloser
) &&
588 (Contexts
.back().CanBeExpression
|| Contexts
.back().IsExpression
||
589 Contexts
.back().ContextType
== Context::TemplateArgument
);
591 bool IsCpp11AttributeSpecifier
= isCpp11AttributeSpecifier(*Left
) ||
592 Contexts
.back().InCpp11AttributeSpecifier
;
594 // Treat C# Attributes [STAThread] much like C++ attributes [[...]].
595 bool IsCSharpAttributeSpecifier
=
596 isCSharpAttributeSpecifier(*Left
) ||
597 Contexts
.back().InCSharpAttributeSpecifier
;
599 bool InsideInlineASM
= Line
.startsWith(tok::kw_asm
);
600 bool IsCppStructuredBinding
= Left
->isCppStructuredBinding(Style
);
601 bool StartsObjCMethodExpr
=
602 !IsCppStructuredBinding
&& !InsideInlineASM
&& !CppArrayTemplates
&&
603 Style
.isCpp() && !IsCpp11AttributeSpecifier
&&
604 !IsCSharpAttributeSpecifier
&& Contexts
.back().CanBeExpression
&&
605 Left
->isNot(TT_LambdaLSquare
) &&
606 !CurrentToken
->isOneOf(tok::l_brace
, tok::r_square
) &&
608 Parent
->isOneOf(tok::colon
, tok::l_square
, tok::l_paren
,
609 tok::kw_return
, tok::kw_throw
) ||
610 Parent
->isUnaryOperator() ||
611 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
612 Parent
->isOneOf(TT_ObjCForIn
, TT_CastRParen
) ||
613 (getBinOpPrecedence(Parent
->Tok
.getKind(), true, true) >
615 bool ColonFound
= false;
617 unsigned BindingIncrease
= 1;
618 if (IsCppStructuredBinding
) {
619 Left
->setType(TT_StructuredBindingLSquare
);
620 } else if (Left
->is(TT_Unknown
)) {
621 if (StartsObjCMethodExpr
) {
622 Left
->setType(TT_ObjCMethodExpr
);
623 } else if (InsideInlineASM
) {
624 Left
->setType(TT_InlineASMSymbolicNameLSquare
);
625 } else if (IsCpp11AttributeSpecifier
) {
626 Left
->setType(TT_AttributeSquare
);
627 } else if (Style
.isJavaScript() && Parent
&&
628 Contexts
.back().ContextKind
== tok::l_brace
&&
629 Parent
->isOneOf(tok::l_brace
, tok::comma
)) {
630 Left
->setType(TT_JsComputedPropertyName
);
631 } else if (Style
.isCpp() && Contexts
.back().ContextKind
== tok::l_brace
&&
632 Parent
&& Parent
->isOneOf(tok::l_brace
, tok::comma
)) {
633 Left
->setType(TT_DesignatedInitializerLSquare
);
634 } else if (IsCSharpAttributeSpecifier
) {
635 Left
->setType(TT_AttributeSquare
);
636 } else if (CurrentToken
->is(tok::r_square
) && Parent
&&
637 Parent
->is(TT_TemplateCloser
)) {
638 Left
->setType(TT_ArraySubscriptLSquare
);
639 } else if (Style
.Language
== FormatStyle::LK_Proto
||
640 Style
.Language
== FormatStyle::LK_TextProto
) {
641 // Square braces in LK_Proto can either be message field attributes:
643 // optional Aaa aaa = 1 [
651 // or text proto extensions (in options):
653 // option (Aaa.options) = {
654 // [type.type/type] {
659 // or repeated fields (in options):
661 // option (Aaa.options) = {
665 // In the first and the third case we want to spread the contents inside
666 // the square braces; in the second we want to keep them inline.
667 Left
->setType(TT_ArrayInitializerLSquare
);
668 if (!Left
->endsSequence(tok::l_square
, tok::numeric_constant
,
670 !Left
->endsSequence(tok::l_square
, tok::numeric_constant
,
672 !Left
->endsSequence(tok::l_square
, tok::colon
, TT_SelectorName
)) {
673 Left
->setType(TT_ProtoExtensionLSquare
);
674 BindingIncrease
= 10;
676 } else if (!CppArrayTemplates
&& Parent
&&
677 Parent
->isOneOf(TT_BinaryOperator
, TT_TemplateCloser
, tok::at
,
678 tok::comma
, tok::l_paren
, tok::l_square
,
679 tok::question
, tok::colon
, tok::kw_return
,
680 // Should only be relevant to JavaScript:
682 Left
->setType(TT_ArrayInitializerLSquare
);
684 BindingIncrease
= 10;
685 Left
->setType(TT_ArraySubscriptLSquare
);
689 ScopedContextCreator
ContextCreator(*this, tok::l_square
, BindingIncrease
);
690 Contexts
.back().IsExpression
= true;
691 if (Style
.isJavaScript() && Parent
&& Parent
->is(TT_JsTypeColon
))
692 Contexts
.back().IsExpression
= false;
694 Contexts
.back().ColonIsObjCMethodExpr
= StartsObjCMethodExpr
;
695 Contexts
.back().InCpp11AttributeSpecifier
= IsCpp11AttributeSpecifier
;
696 Contexts
.back().InCSharpAttributeSpecifier
= IsCSharpAttributeSpecifier
;
698 while (CurrentToken
) {
699 if (CurrentToken
->is(tok::r_square
)) {
700 if (IsCpp11AttributeSpecifier
)
701 CurrentToken
->setType(TT_AttributeSquare
);
702 if (IsCSharpAttributeSpecifier
) {
703 CurrentToken
->setType(TT_AttributeSquare
);
704 } else if (((CurrentToken
->Next
&&
705 CurrentToken
->Next
->is(tok::l_paren
)) ||
706 (CurrentToken
->Previous
&&
707 CurrentToken
->Previous
->Previous
== Left
)) &&
708 Left
->is(TT_ObjCMethodExpr
)) {
709 // An ObjC method call is rarely followed by an open parenthesis. It
710 // also can't be composed of just one token, unless it's a macro that
711 // will be expanded to more tokens.
712 // FIXME: Do we incorrectly label ":" with this?
713 StartsObjCMethodExpr
= false;
714 Left
->setType(TT_Unknown
);
716 if (StartsObjCMethodExpr
&& CurrentToken
->Previous
!= Left
) {
717 CurrentToken
->setType(TT_ObjCMethodExpr
);
718 // If we haven't seen a colon yet, make sure the last identifier
719 // before the r_square is tagged as a selector name component.
720 if (!ColonFound
&& CurrentToken
->Previous
&&
721 CurrentToken
->Previous
->is(TT_Unknown
) &&
722 canBeObjCSelectorComponent(*CurrentToken
->Previous
)) {
723 CurrentToken
->Previous
->setType(TT_SelectorName
);
725 // determineStarAmpUsage() thinks that '*' '[' is allocating an
726 // array of pointers, but if '[' starts a selector then '*' is a
728 if (Parent
&& Parent
->is(TT_PointerOrReference
))
729 Parent
->overwriteFixedType(TT_BinaryOperator
);
731 // An arrow after an ObjC method expression is not a lambda arrow.
732 if (CurrentToken
->getType() == TT_ObjCMethodExpr
&&
733 CurrentToken
->Next
&& CurrentToken
->Next
->is(TT_LambdaArrow
)) {
734 CurrentToken
->Next
->overwriteFixedType(TT_Unknown
);
736 Left
->MatchingParen
= CurrentToken
;
737 CurrentToken
->MatchingParen
= Left
;
738 // FirstObjCSelectorName is set when a colon is found. This does
739 // not work, however, when the method has no parameters.
740 // Here, we set FirstObjCSelectorName when the end of the method call is
741 // reached, in case it was not set already.
742 if (!Contexts
.back().FirstObjCSelectorName
) {
743 FormatToken
*Previous
= CurrentToken
->getPreviousNonComment();
744 if (Previous
&& Previous
->is(TT_SelectorName
)) {
745 Previous
->ObjCSelectorNameParts
= 1;
746 Contexts
.back().FirstObjCSelectorName
= Previous
;
749 Left
->ParameterCount
=
750 Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
752 if (Contexts
.back().FirstObjCSelectorName
) {
753 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
754 Contexts
.back().LongestObjCSelectorName
;
755 if (Left
->BlockParameterCount
> 1)
756 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
= 0;
761 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_brace
))
763 if (CurrentToken
->is(tok::colon
)) {
764 if (IsCpp11AttributeSpecifier
&&
765 CurrentToken
->endsSequence(tok::colon
, tok::identifier
,
767 // Remember that this is a [[using ns: foo]] C++ attribute, so we
768 // don't add a space before the colon (unlike other colons).
769 CurrentToken
->setType(TT_AttributeColon
);
770 } else if (!Style
.isVerilog() && !Line
.InPragmaDirective
&&
771 Left
->isOneOf(TT_ArraySubscriptLSquare
,
772 TT_DesignatedInitializerLSquare
)) {
773 Left
->setType(TT_ObjCMethodExpr
);
774 StartsObjCMethodExpr
= true;
775 Contexts
.back().ColonIsObjCMethodExpr
= true;
776 if (Parent
&& Parent
->is(tok::r_paren
)) {
777 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
778 Parent
->setType(TT_CastRParen
);
783 if (CurrentToken
->is(tok::comma
) && Left
->is(TT_ObjCMethodExpr
) &&
785 Left
->setType(TT_ArrayInitializerLSquare
);
787 FormatToken
*Tok
= CurrentToken
;
790 updateParameterCount(Left
, Tok
);
795 bool couldBeInStructArrayInitializer() const {
796 if (Contexts
.size() < 2)
798 // We want to back up no more then 2 context levels i.e.
800 const auto End
= std::next(Contexts
.rbegin(), 2);
801 auto Last
= Contexts
.rbegin();
803 for (; Last
!= End
; ++Last
)
804 if (Last
->ContextKind
== tok::l_brace
)
806 return Depth
== 2 && Last
->ContextKind
!= tok::l_brace
;
813 assert(CurrentToken
->Previous
);
814 FormatToken
&OpeningBrace
= *CurrentToken
->Previous
;
815 assert(OpeningBrace
.is(tok::l_brace
));
816 OpeningBrace
.ParentBracket
= Contexts
.back().ContextKind
;
818 if (Contexts
.back().CaretFound
)
819 OpeningBrace
.overwriteFixedType(TT_ObjCBlockLBrace
);
820 Contexts
.back().CaretFound
= false;
822 ScopedContextCreator
ContextCreator(*this, tok::l_brace
, 1);
823 Contexts
.back().ColonIsDictLiteral
= true;
824 if (OpeningBrace
.is(BK_BracedInit
))
825 Contexts
.back().IsExpression
= true;
826 if (Style
.isJavaScript() && OpeningBrace
.Previous
&&
827 OpeningBrace
.Previous
->is(TT_JsTypeColon
)) {
828 Contexts
.back().IsExpression
= false;
831 unsigned CommaCount
= 0;
832 while (CurrentToken
) {
833 if (CurrentToken
->is(tok::r_brace
)) {
834 assert(OpeningBrace
.Optional
== CurrentToken
->Optional
);
835 OpeningBrace
.MatchingParen
= CurrentToken
;
836 CurrentToken
->MatchingParen
= &OpeningBrace
;
837 if (Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
) {
838 if (OpeningBrace
.ParentBracket
== tok::l_brace
&&
839 couldBeInStructArrayInitializer() && CommaCount
> 0) {
840 Contexts
.back().ContextType
= Context::StructArrayInitializer
;
846 if (CurrentToken
->isOneOf(tok::r_paren
, tok::r_square
))
848 updateParameterCount(&OpeningBrace
, CurrentToken
);
849 if (CurrentToken
->isOneOf(tok::colon
, tok::l_brace
, tok::less
)) {
850 FormatToken
*Previous
= CurrentToken
->getPreviousNonComment();
851 if (Previous
->is(TT_JsTypeOptionalQuestion
))
852 Previous
= Previous
->getPreviousNonComment();
853 if ((CurrentToken
->is(tok::colon
) &&
854 (!Contexts
.back().ColonIsDictLiteral
|| !Style
.isCpp())) ||
855 Style
.Language
== FormatStyle::LK_Proto
||
856 Style
.Language
== FormatStyle::LK_TextProto
) {
857 OpeningBrace
.setType(TT_DictLiteral
);
858 if (Previous
->Tok
.getIdentifierInfo() ||
859 Previous
->is(tok::string_literal
)) {
860 Previous
->setType(TT_SelectorName
);
863 if (CurrentToken
->is(tok::colon
) && OpeningBrace
.is(TT_Unknown
))
864 OpeningBrace
.setType(TT_DictLiteral
);
865 else if (Style
.isJavaScript())
866 OpeningBrace
.overwriteFixedType(TT_DictLiteral
);
868 if (CurrentToken
->is(tok::comma
)) {
869 if (Style
.isJavaScript())
870 OpeningBrace
.overwriteFixedType(TT_DictLiteral
);
879 void updateParameterCount(FormatToken
*Left
, FormatToken
*Current
) {
880 // For ObjC methods, the number of parameters is calculated differently as
881 // method declarations have a different structure (the parameters are not
882 // inside a bracket scope).
883 if (Current
->is(tok::l_brace
) && Current
->is(BK_Block
))
884 ++Left
->BlockParameterCount
;
885 if (Current
->is(tok::comma
)) {
886 ++Left
->ParameterCount
;
888 Left
->Role
.reset(new CommaSeparatedList(Style
));
889 Left
->Role
->CommaFound(Current
);
890 } else if (Left
->ParameterCount
== 0 && Current
->isNot(tok::comment
)) {
891 Left
->ParameterCount
= 1;
895 bool parseConditional() {
896 while (CurrentToken
) {
897 if (CurrentToken
->is(tok::colon
)) {
898 CurrentToken
->setType(TT_ConditionalExpr
);
908 bool parseTemplateDeclaration() {
909 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
910 CurrentToken
->setType(TT_TemplateOpener
);
915 CurrentToken
->Previous
->ClosesTemplateDeclaration
= true;
921 bool consumeToken() {
922 FormatToken
*Tok
= CurrentToken
;
924 // In Verilog primitives' state tables, `:`, `?`, and `-` aren't normal
926 if (Tok
->is(TT_VerilogTableItem
))
928 switch (Tok
->Tok
.getKind()) {
931 if (!Tok
->Previous
&& Line
.MustBeDeclaration
)
932 Tok
->setType(TT_ObjCMethodSpecifier
);
937 // Colons from ?: are handled in parseConditional().
938 if (Style
.isJavaScript()) {
939 if (Contexts
.back().ColonIsForRangeExpr
|| // colon in for loop
940 (Contexts
.size() == 1 && // switch/case labels
941 !Line
.First
->isOneOf(tok::kw_enum
, tok::kw_case
)) ||
942 Contexts
.back().ContextKind
== tok::l_paren
|| // function params
943 Contexts
.back().ContextKind
== tok::l_square
|| // array type
944 (!Contexts
.back().IsExpression
&&
945 Contexts
.back().ContextKind
== tok::l_brace
) || // object type
946 (Contexts
.size() == 1 &&
947 Line
.MustBeDeclaration
)) { // method/property declaration
948 Contexts
.back().IsExpression
= false;
949 Tok
->setType(TT_JsTypeColon
);
952 } else if (Style
.isCSharp()) {
953 if (Contexts
.back().InCSharpAttributeSpecifier
) {
954 Tok
->setType(TT_AttributeColon
);
957 if (Contexts
.back().ContextKind
== tok::l_paren
) {
958 Tok
->setType(TT_CSharpNamedArgumentColon
);
961 } else if (Style
.isVerilog() && Tok
->isNot(TT_BinaryOperator
)) {
962 // The distribution weight operators are labeled
963 // TT_BinaryOperator by the lexer.
964 if (Keywords
.isVerilogEnd(*Tok
->Previous
) ||
965 Keywords
.isVerilogBegin(*Tok
->Previous
)) {
966 Tok
->setType(TT_VerilogBlockLabelColon
);
967 } else if (Contexts
.back().ContextKind
== tok::l_square
) {
968 Tok
->setType(TT_BitFieldColon
);
969 } else if (Contexts
.back().ColonIsDictLiteral
) {
970 Tok
->setType(TT_DictLiteral
);
971 } else if (Contexts
.size() == 1) {
972 // In Verilog a case label doesn't have the case keyword. We
973 // assume a colon following an expression is a case label.
974 // Colons from ?: are annotated in parseConditional().
975 Tok
->setType(TT_GotoLabelColon
);
976 if (Line
.Level
> 1 || (!Line
.InPPDirective
&& Line
.Level
> 0))
981 if (Line
.First
->isOneOf(Keywords
.kw_module
, Keywords
.kw_import
) ||
982 Line
.First
->startsSequence(tok::kw_export
, Keywords
.kw_module
) ||
983 Line
.First
->startsSequence(tok::kw_export
, Keywords
.kw_import
)) {
984 Tok
->setType(TT_ModulePartitionColon
);
985 } else if (Contexts
.back().ColonIsDictLiteral
||
986 Style
.Language
== FormatStyle::LK_Proto
||
987 Style
.Language
== FormatStyle::LK_TextProto
) {
988 Tok
->setType(TT_DictLiteral
);
989 if (Style
.Language
== FormatStyle::LK_TextProto
) {
990 if (FormatToken
*Previous
= Tok
->getPreviousNonComment())
991 Previous
->setType(TT_SelectorName
);
993 } else if (Contexts
.back().ColonIsObjCMethodExpr
||
994 Line
.startsWith(TT_ObjCMethodSpecifier
)) {
995 Tok
->setType(TT_ObjCMethodExpr
);
996 const FormatToken
*BeforePrevious
= Tok
->Previous
->Previous
;
997 // Ensure we tag all identifiers in method declarations as
999 bool UnknownIdentifierInMethodDeclaration
=
1000 Line
.startsWith(TT_ObjCMethodSpecifier
) &&
1001 Tok
->Previous
->is(tok::identifier
) && Tok
->Previous
->is(TT_Unknown
);
1002 if (!BeforePrevious
||
1003 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
1004 !(BeforePrevious
->is(TT_CastRParen
) ||
1005 (BeforePrevious
->is(TT_ObjCMethodExpr
) &&
1006 BeforePrevious
->is(tok::colon
))) ||
1007 BeforePrevious
->is(tok::r_square
) ||
1008 Contexts
.back().LongestObjCSelectorName
== 0 ||
1009 UnknownIdentifierInMethodDeclaration
) {
1010 Tok
->Previous
->setType(TT_SelectorName
);
1011 if (!Contexts
.back().FirstObjCSelectorName
) {
1012 Contexts
.back().FirstObjCSelectorName
= Tok
->Previous
;
1013 } else if (Tok
->Previous
->ColumnWidth
>
1014 Contexts
.back().LongestObjCSelectorName
) {
1015 Contexts
.back().LongestObjCSelectorName
=
1016 Tok
->Previous
->ColumnWidth
;
1018 Tok
->Previous
->ParameterIndex
=
1019 Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
1020 ++Contexts
.back().FirstObjCSelectorName
->ObjCSelectorNameParts
;
1022 } else if (Contexts
.back().ColonIsForRangeExpr
) {
1023 Tok
->setType(TT_RangeBasedForLoopColon
);
1024 } else if (CurrentToken
&& CurrentToken
->is(tok::numeric_constant
)) {
1025 Tok
->setType(TT_BitFieldColon
);
1026 } else if (Contexts
.size() == 1 &&
1027 !Line
.First
->isOneOf(tok::kw_enum
, tok::kw_case
,
1029 FormatToken
*Prev
= Tok
->getPreviousNonComment();
1032 if (Prev
->isOneOf(tok::r_paren
, tok::kw_noexcept
) ||
1033 Prev
->ClosesRequiresClause
) {
1034 Tok
->setType(TT_CtorInitializerColon
);
1035 } else if (Prev
->is(tok::kw_try
)) {
1036 // Member initializer list within function try block.
1037 FormatToken
*PrevPrev
= Prev
->getPreviousNonComment();
1040 if (PrevPrev
&& PrevPrev
->isOneOf(tok::r_paren
, tok::kw_noexcept
))
1041 Tok
->setType(TT_CtorInitializerColon
);
1043 Tok
->setType(TT_InheritanceColon
);
1045 } else if (canBeObjCSelectorComponent(*Tok
->Previous
) && Tok
->Next
&&
1046 (Tok
->Next
->isOneOf(tok::r_paren
, tok::comma
) ||
1047 (canBeObjCSelectorComponent(*Tok
->Next
) && Tok
->Next
->Next
&&
1048 Tok
->Next
->Next
->is(tok::colon
)))) {
1049 // This handles a special macro in ObjC code where selectors including
1050 // the colon are passed as macro arguments.
1051 Tok
->setType(TT_ObjCMethodExpr
);
1052 } else if (Contexts
.back().ContextKind
== tok::l_paren
&&
1053 !Line
.InPragmaDirective
) {
1054 Tok
->setType(TT_InlineASMColon
);
1059 // | and & in declarations/type expressions represent union and
1060 // intersection types, respectively.
1061 if (Style
.isJavaScript() && !Contexts
.back().IsExpression
)
1062 Tok
->setType(TT_JsTypeOperator
);
1066 CurrentToken
->isOneOf(tok::kw_constexpr
, tok::identifier
)) {
1071 if (CurrentToken
&& CurrentToken
->is(tok::l_paren
)) {
1073 if (!parseParens(/*LookForDecls=*/true))
1078 if (Style
.isJavaScript()) {
1079 // x.for and {for: ...}
1080 if ((Tok
->Previous
&& Tok
->Previous
->is(tok::period
)) ||
1081 (Tok
->Next
&& Tok
->Next
->is(tok::colon
))) {
1084 // JS' for await ( ...
1085 if (CurrentToken
&& CurrentToken
->is(Keywords
.kw_await
))
1088 if (Style
.isCpp() && CurrentToken
&& CurrentToken
->is(tok::kw_co_await
))
1090 Contexts
.back().ColonIsForRangeExpr
= true;
1091 if (!CurrentToken
|| CurrentToken
->isNot(tok::l_paren
))
1098 // When faced with 'operator()()', the kw_operator handler incorrectly
1099 // marks the first l_paren as a OverloadedOperatorLParen. Here, we make
1100 // the first two parens OverloadedOperators and the second l_paren an
1101 // OverloadedOperatorLParen.
1102 if (Tok
->Previous
&& Tok
->Previous
->is(tok::r_paren
) &&
1103 Tok
->Previous
->MatchingParen
&&
1104 Tok
->Previous
->MatchingParen
->is(TT_OverloadedOperatorLParen
)) {
1105 Tok
->Previous
->setType(TT_OverloadedOperator
);
1106 Tok
->Previous
->MatchingParen
->setType(TT_OverloadedOperator
);
1107 Tok
->setType(TT_OverloadedOperatorLParen
);
1112 if (Line
.MustBeDeclaration
&& Contexts
.size() == 1 &&
1113 !Contexts
.back().IsExpression
&& !Line
.startsWith(TT_ObjCProperty
) &&
1114 !Tok
->isOneOf(TT_TypeDeclarationParen
, TT_RequiresExpressionLParen
) &&
1116 !Tok
->Previous
->isOneOf(tok::kw___attribute
, TT_RequiresClause
,
1117 TT_LeadingJavaAnnotation
))) {
1118 Line
.MightBeFunctionDecl
= true;
1126 if (Style
.Language
== FormatStyle::LK_TextProto
) {
1127 FormatToken
*Previous
= Tok
->getPreviousNonComment();
1128 if (Previous
&& Previous
->getType() != TT_DictLiteral
)
1129 Previous
->setType(TT_SelectorName
);
1136 Tok
->setType(TT_TemplateOpener
);
1137 // In TT_Proto, we must distignuish between:
1139 // msg < item: data >
1140 // msg: < item: data >
1141 // In TT_TextProto, map<key, value> does not occur.
1142 if (Style
.Language
== FormatStyle::LK_TextProto
||
1143 (Style
.Language
== FormatStyle::LK_Proto
&& Tok
->Previous
&&
1144 Tok
->Previous
->isOneOf(TT_SelectorName
, TT_DictLiteral
))) {
1145 Tok
->setType(TT_DictLiteral
);
1146 FormatToken
*Previous
= Tok
->getPreviousNonComment();
1147 if (Previous
&& Previous
->getType() != TT_DictLiteral
)
1148 Previous
->setType(TT_SelectorName
);
1151 Tok
->setType(TT_BinaryOperator
);
1152 NonTemplateLess
.insert(Tok
);
1161 // Lines can start with '}'.
1166 if (Style
.Language
!= FormatStyle::LK_TextProto
)
1167 Tok
->setType(TT_BinaryOperator
);
1168 if (Tok
->Previous
&& Tok
->Previous
->is(TT_TemplateCloser
))
1169 Tok
->SpacesRequiredBefore
= 1;
1171 case tok::kw_operator
:
1172 if (Style
.Language
== FormatStyle::LK_TextProto
||
1173 Style
.Language
== FormatStyle::LK_Proto
) {
1176 while (CurrentToken
&&
1177 !CurrentToken
->isOneOf(tok::l_paren
, tok::semi
, tok::r_paren
)) {
1178 if (CurrentToken
->isOneOf(tok::star
, tok::amp
))
1179 CurrentToken
->setType(TT_PointerOrReference
);
1183 if (CurrentToken
->is(tok::comma
) &&
1184 CurrentToken
->Previous
->isNot(tok::kw_operator
)) {
1187 if (CurrentToken
->Previous
->isOneOf(TT_BinaryOperator
, TT_UnaryOperator
,
1188 tok::comma
, tok::star
, tok::arrow
,
1189 tok::amp
, tok::ampamp
) ||
1190 // User defined literal.
1191 CurrentToken
->Previous
->TokenText
.startswith("\"\"")) {
1192 CurrentToken
->Previous
->setType(TT_OverloadedOperator
);
1195 if (CurrentToken
&& CurrentToken
->is(tok::l_paren
))
1196 CurrentToken
->setType(TT_OverloadedOperatorLParen
);
1197 if (CurrentToken
&& CurrentToken
->Previous
->is(TT_BinaryOperator
))
1198 CurrentToken
->Previous
->setType(TT_OverloadedOperator
);
1201 if (Style
.isJavaScript() && Tok
->Next
&&
1202 Tok
->Next
->isOneOf(tok::semi
, tok::comma
, tok::colon
, tok::r_paren
,
1204 // Question marks before semicolons, colons, etc. indicate optional
1205 // types (fields, parameters), e.g.
1206 // function(x?: string, y?) {...}
1208 Tok
->setType(TT_JsTypeOptionalQuestion
);
1211 // Declarations cannot be conditional expressions, this can only be part
1212 // of a type declaration.
1213 if (Line
.MustBeDeclaration
&& !Contexts
.back().IsExpression
&&
1214 Style
.isJavaScript()) {
1217 if (Style
.isCSharp()) {
1218 // `Type?)`, `Type?>`, `Type? name;` and `Type? name =` can only be
1220 // Line.MustBeDeclaration will be true for `Type? name;`.
1221 if ((!Contexts
.back().IsExpression
&& Line
.MustBeDeclaration
) ||
1222 (Tok
->Next
&& Tok
->Next
->isOneOf(tok::r_paren
, tok::greater
)) ||
1223 (Tok
->Next
&& Tok
->Next
->is(tok::identifier
) && Tok
->Next
->Next
&&
1224 Tok
->Next
->Next
->is(tok::equal
))) {
1225 Tok
->setType(TT_CSharpNullable
);
1231 case tok::kw_template
:
1232 parseTemplateDeclaration();
1235 switch (Contexts
.back().ContextType
) {
1236 case Context::CtorInitializer
:
1237 Tok
->setType(TT_CtorInitializerComma
);
1239 case Context::InheritanceList
:
1240 Tok
->setType(TT_InheritanceComma
);
1243 if (Contexts
.back().FirstStartOfName
&&
1244 (Contexts
.size() == 1 || startsWithInitStatement(Line
))) {
1245 Contexts
.back().FirstStartOfName
->PartOfMultiVariableDeclStmt
= true;
1246 Line
.IsMultiVariableDeclStmt
= true;
1250 if (Contexts
.back().ContextType
== Context::ForEachMacro
)
1251 Contexts
.back().IsExpression
= true;
1253 case tok::kw_default
:
1254 // Unindent case labels.
1255 if (Style
.isVerilog() && Keywords
.isVerilogEndOfLabel(*Tok
) &&
1256 (Line
.Level
> 1 || (!Line
.InPPDirective
&& Line
.Level
> 0))) {
1260 case tok::identifier
:
1261 if (Tok
->isOneOf(Keywords
.kw___has_include
,
1262 Keywords
.kw___has_include_next
)) {
1265 if (Style
.isCSharp() && Tok
->is(Keywords
.kw_where
) && Tok
->Next
&&
1266 Tok
->Next
->isNot(tok::l_paren
)) {
1267 Tok
->setType(TT_CSharpGenericTypeConstraint
);
1268 parseCSharpGenericTypeConstraint();
1269 if (Tok
->getPreviousNonComment() == nullptr)
1270 Line
.IsContinuation
= true;
1274 if (Tok
->isNot(TT_LambdaArrow
) && Tok
->Previous
&&
1275 Tok
->Previous
->is(tok::kw_noexcept
)) {
1276 Tok
->setType(TT_TrailingReturnArrow
);
1285 void parseCSharpGenericTypeConstraint() {
1286 int OpenAngleBracketsCount
= 0;
1287 while (CurrentToken
) {
1288 if (CurrentToken
->is(tok::less
)) {
1289 // parseAngle is too greedy and will consume the whole line.
1290 CurrentToken
->setType(TT_TemplateOpener
);
1291 ++OpenAngleBracketsCount
;
1293 } else if (CurrentToken
->is(tok::greater
)) {
1294 CurrentToken
->setType(TT_TemplateCloser
);
1295 --OpenAngleBracketsCount
;
1297 } else if (CurrentToken
->is(tok::comma
) && OpenAngleBracketsCount
== 0) {
1298 // We allow line breaks after GenericTypeConstraintComma's
1299 // so do not flag commas in Generics as GenericTypeConstraintComma's.
1300 CurrentToken
->setType(TT_CSharpGenericTypeConstraintComma
);
1302 } else if (CurrentToken
->is(Keywords
.kw_where
)) {
1303 CurrentToken
->setType(TT_CSharpGenericTypeConstraint
);
1305 } else if (CurrentToken
->is(tok::colon
)) {
1306 CurrentToken
->setType(TT_CSharpGenericTypeConstraintColon
);
1314 void parseIncludeDirective() {
1315 if (CurrentToken
&& CurrentToken
->is(tok::less
)) {
1317 while (CurrentToken
) {
1318 // Mark tokens up to the trailing line comments as implicit string
1320 if (CurrentToken
->isNot(tok::comment
) &&
1321 !CurrentToken
->TokenText
.startswith("//")) {
1322 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1329 void parseWarningOrError() {
1331 // We still want to format the whitespace left of the first token of the
1332 // warning or error.
1334 while (CurrentToken
) {
1335 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1340 void parsePragma() {
1341 next(); // Consume "pragma".
1343 CurrentToken
->isOneOf(Keywords
.kw_mark
, Keywords
.kw_option
,
1344 Keywords
.kw_region
)) {
1345 bool IsMarkOrRegion
=
1346 CurrentToken
->isOneOf(Keywords
.kw_mark
, Keywords
.kw_region
);
1348 next(); // Consume first token (so we fix leading whitespace).
1349 while (CurrentToken
) {
1350 if (IsMarkOrRegion
|| CurrentToken
->Previous
->is(TT_BinaryOperator
)) {
1351 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1358 void parseHasInclude() {
1359 if (!CurrentToken
|| !CurrentToken
->is(tok::l_paren
))
1362 parseIncludeDirective();
1366 LineType
parsePreprocessorDirective() {
1367 bool IsFirstToken
= CurrentToken
->IsFirst
;
1368 LineType Type
= LT_PreprocessorDirective
;
1373 if (Style
.isJavaScript() && IsFirstToken
) {
1374 // JavaScript files can contain shebang lines of the form:
1375 // #!/usr/bin/env node
1376 // Treat these like C++ #include directives.
1377 while (CurrentToken
) {
1378 // Tokens cannot be comments here.
1379 CurrentToken
->setType(TT_ImplicitStringLiteral
);
1382 return LT_ImportStatement
;
1385 if (CurrentToken
->is(tok::numeric_constant
)) {
1386 CurrentToken
->SpacesRequiredBefore
= 1;
1389 // Hashes in the middle of a line can lead to any strange token
1391 if (!CurrentToken
->Tok
.getIdentifierInfo())
1393 // In Verilog macro expansions start with a backtick just like preprocessor
1394 // directives. Thus we stop if the word is not a preprocessor directive.
1395 if (Style
.isVerilog() && !Keywords
.isVerilogPPDirective(*CurrentToken
))
1397 switch (CurrentToken
->Tok
.getIdentifierInfo()->getPPKeywordID()) {
1398 case tok::pp_include
:
1399 case tok::pp_include_next
:
1400 case tok::pp_import
:
1402 parseIncludeDirective();
1403 Type
= LT_ImportStatement
;
1406 case tok::pp_warning
:
1407 parseWarningOrError();
1409 case tok::pp_pragma
:
1414 Contexts
.back().IsExpression
= true;
1421 while (CurrentToken
) {
1422 FormatToken
*Tok
= CurrentToken
;
1424 if (Tok
->is(tok::l_paren
)) {
1426 } else if (Tok
->isOneOf(Keywords
.kw___has_include
,
1427 Keywords
.kw___has_include_next
)) {
1435 LineType
parseLine() {
1438 NonTemplateLess
.clear();
1439 if (!Line
.InMacroBody
&& CurrentToken
->is(tok::hash
)) {
1440 // We were not yet allowed to use C++17 optional when this was being
1441 // written. So we used LT_Invalid to mark that the line is not a
1442 // preprocessor directive.
1443 auto Type
= parsePreprocessorDirective();
1444 if (Type
!= LT_Invalid
)
1448 // Directly allow to 'import <string-literal>' to support protocol buffer
1449 // definitions (github.com/google/protobuf) or missing "#" (either way we
1450 // should not break the line).
1451 IdentifierInfo
*Info
= CurrentToken
->Tok
.getIdentifierInfo();
1452 if ((Style
.Language
== FormatStyle::LK_Java
&&
1453 CurrentToken
->is(Keywords
.kw_package
)) ||
1454 (!Style
.isVerilog() && Info
&&
1455 Info
->getPPKeywordID() == tok::pp_import
&& CurrentToken
->Next
&&
1456 CurrentToken
->Next
->isOneOf(tok::string_literal
, tok::identifier
,
1459 parseIncludeDirective();
1460 return LT_ImportStatement
;
1463 // If this line starts and ends in '<' and '>', respectively, it is likely
1464 // part of "#define <a/b.h>".
1465 if (CurrentToken
->is(tok::less
) && Line
.Last
->is(tok::greater
)) {
1466 parseIncludeDirective();
1467 return LT_ImportStatement
;
1470 // In .proto files, top-level options and package statements are very
1471 // similar to import statements and should not be line-wrapped.
1472 if (Style
.Language
== FormatStyle::LK_Proto
&& Line
.Level
== 0 &&
1473 CurrentToken
->isOneOf(Keywords
.kw_option
, Keywords
.kw_package
)) {
1475 if (CurrentToken
&& CurrentToken
->is(tok::identifier
)) {
1476 while (CurrentToken
)
1478 return LT_ImportStatement
;
1482 bool KeywordVirtualFound
= false;
1483 bool ImportStatement
= false;
1485 // import {...} from '...';
1486 if (Style
.isJavaScript() && CurrentToken
->is(Keywords
.kw_import
))
1487 ImportStatement
= true;
1489 while (CurrentToken
) {
1490 if (CurrentToken
->is(tok::kw_virtual
))
1491 KeywordVirtualFound
= true;
1492 if (Style
.isJavaScript()) {
1493 // export {...} from '...';
1494 // An export followed by "from 'some string';" is a re-export from
1495 // another module identified by a URI and is treated as a
1496 // LT_ImportStatement (i.e. prevent wraps on it for long URIs).
1497 // Just "export {...};" or "export class ..." should not be treated as
1498 // an import in this sense.
1499 if (Line
.First
->is(tok::kw_export
) &&
1500 CurrentToken
->is(Keywords
.kw_from
) && CurrentToken
->Next
&&
1501 CurrentToken
->Next
->isStringLiteral()) {
1502 ImportStatement
= true;
1504 if (isClosureImportStatement(*CurrentToken
))
1505 ImportStatement
= true;
1507 if (!consumeToken())
1510 if (KeywordVirtualFound
)
1511 return LT_VirtualFunctionDecl
;
1512 if (ImportStatement
)
1513 return LT_ImportStatement
;
1515 if (Line
.startsWith(TT_ObjCMethodSpecifier
)) {
1516 if (Contexts
.back().FirstObjCSelectorName
) {
1517 Contexts
.back().FirstObjCSelectorName
->LongestObjCSelectorName
=
1518 Contexts
.back().LongestObjCSelectorName
;
1520 return LT_ObjCMethodDecl
;
1523 for (const auto &ctx
: Contexts
)
1524 if (ctx
.ContextType
== Context::StructArrayInitializer
)
1525 return LT_ArrayOfStructInitializer
;
1531 bool isClosureImportStatement(const FormatToken
&Tok
) {
1532 // FIXME: Closure-library specific stuff should not be hard-coded but be
1534 return Tok
.TokenText
== "goog" && Tok
.Next
&& Tok
.Next
->is(tok::period
) &&
1536 (Tok
.Next
->Next
->TokenText
== "module" ||
1537 Tok
.Next
->Next
->TokenText
== "provide" ||
1538 Tok
.Next
->Next
->TokenText
== "require" ||
1539 Tok
.Next
->Next
->TokenText
== "requireType" ||
1540 Tok
.Next
->Next
->TokenText
== "forwardDeclare") &&
1541 Tok
.Next
->Next
->Next
&& Tok
.Next
->Next
->Next
->is(tok::l_paren
);
1544 void resetTokenMetadata() {
1548 // Reset token type in case we have already looked at it and then
1549 // recovered from an error (e.g. failure to find the matching >).
1550 if (!CurrentToken
->isTypeFinalized() &&
1551 !CurrentToken
->isOneOf(
1552 TT_LambdaLSquare
, TT_LambdaLBrace
, TT_AttributeMacro
, TT_IfMacro
,
1553 TT_ForEachMacro
, TT_TypenameMacro
, TT_FunctionLBrace
,
1554 TT_ImplicitStringLiteral
, TT_InlineASMBrace
, TT_FatArrow
,
1555 TT_LambdaArrow
, TT_NamespaceMacro
, TT_OverloadedOperator
,
1556 TT_RegexLiteral
, TT_TemplateString
, TT_ObjCStringLiteral
,
1557 TT_UntouchableMacroFunc
, TT_StatementAttributeLikeMacro
,
1558 TT_FunctionLikeOrFreestandingMacro
, TT_ClassLBrace
, TT_EnumLBrace
,
1559 TT_RecordLBrace
, TT_StructLBrace
, TT_UnionLBrace
, TT_RequiresClause
,
1560 TT_RequiresClauseInARequiresExpression
, TT_RequiresExpression
,
1561 TT_RequiresExpressionLParen
, TT_RequiresExpressionLBrace
,
1562 TT_CompoundRequirementLBrace
, TT_BracedListLBrace
)) {
1563 CurrentToken
->setType(TT_Unknown
);
1565 CurrentToken
->Role
.reset();
1566 CurrentToken
->MatchingParen
= nullptr;
1567 CurrentToken
->FakeLParens
.clear();
1568 CurrentToken
->FakeRParens
= 0;
1575 CurrentToken
->NestingLevel
= Contexts
.size() - 1;
1576 CurrentToken
->BindingStrength
= Contexts
.back().BindingStrength
;
1577 modifyContext(*CurrentToken
);
1578 determineTokenType(*CurrentToken
);
1579 CurrentToken
= CurrentToken
->Next
;
1581 resetTokenMetadata();
1584 /// A struct to hold information valid in a specific context, e.g.
1585 /// a pair of parenthesis.
1587 Context(tok::TokenKind ContextKind
, unsigned BindingStrength
,
1589 : ContextKind(ContextKind
), BindingStrength(BindingStrength
),
1590 IsExpression(IsExpression
) {}
1592 tok::TokenKind ContextKind
;
1593 unsigned BindingStrength
;
1595 unsigned LongestObjCSelectorName
= 0;
1596 bool ColonIsForRangeExpr
= false;
1597 bool ColonIsDictLiteral
= false;
1598 bool ColonIsObjCMethodExpr
= false;
1599 FormatToken
*FirstObjCSelectorName
= nullptr;
1600 FormatToken
*FirstStartOfName
= nullptr;
1601 bool CanBeExpression
= true;
1602 bool CaretFound
= false;
1603 bool InCpp11AttributeSpecifier
= false;
1604 bool InCSharpAttributeSpecifier
= false;
1607 // Like the part after `:` in a constructor.
1608 // Context(...) : IsExpression(IsExpression)
1610 // Like in the parentheses in a foreach.
1612 // Like the inheritance list in a class declaration.
1613 // class Input : public IO
1615 // Like in the braced list.
1617 StructArrayInitializer
,
1618 // Like in `static_cast<int>`.
1620 } ContextType
= Unknown
;
1623 /// Puts a new \c Context onto the stack \c Contexts for the lifetime
1624 /// of each instance.
1625 struct ScopedContextCreator
{
1626 AnnotatingParser
&P
;
1628 ScopedContextCreator(AnnotatingParser
&P
, tok::TokenKind ContextKind
,
1631 P
.Contexts
.push_back(Context(ContextKind
,
1632 P
.Contexts
.back().BindingStrength
+ Increase
,
1633 P
.Contexts
.back().IsExpression
));
1636 ~ScopedContextCreator() {
1637 if (P
.Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
) {
1638 if (P
.Contexts
.back().ContextType
== Context::StructArrayInitializer
) {
1639 P
.Contexts
.pop_back();
1640 P
.Contexts
.back().ContextType
= Context::StructArrayInitializer
;
1644 P
.Contexts
.pop_back();
1648 void modifyContext(const FormatToken
&Current
) {
1649 auto AssignmentStartsExpression
= [&]() {
1650 if (Current
.getPrecedence() != prec::Assignment
)
1653 if (Line
.First
->isOneOf(tok::kw_using
, tok::kw_return
))
1655 if (Line
.First
->is(tok::kw_template
)) {
1656 assert(Current
.Previous
);
1657 if (Current
.Previous
->is(tok::kw_operator
)) {
1658 // `template ... operator=` cannot be an expression.
1662 // `template` keyword can start a variable template.
1663 const FormatToken
*Tok
= Line
.First
->getNextNonComment();
1664 assert(Tok
); // Current token is on the same line.
1665 if (Tok
->isNot(TT_TemplateOpener
)) {
1666 // Explicit template instantiations do not have `<>`.
1670 Tok
= Tok
->MatchingParen
;
1673 Tok
= Tok
->getNextNonComment();
1677 if (Tok
->isOneOf(tok::kw_class
, tok::kw_enum
, tok::kw_concept
,
1678 tok::kw_struct
, tok::kw_using
)) {
1685 // Type aliases use `type X = ...;` in TypeScript and can be exported
1686 // using `export type ...`.
1687 if (Style
.isJavaScript() &&
1688 (Line
.startsWith(Keywords
.kw_type
, tok::identifier
) ||
1689 Line
.startsWith(tok::kw_export
, Keywords
.kw_type
,
1690 tok::identifier
))) {
1694 return !Current
.Previous
|| Current
.Previous
->isNot(tok::kw_operator
);
1697 if (AssignmentStartsExpression()) {
1698 Contexts
.back().IsExpression
= true;
1699 if (!Line
.startsWith(TT_UnaryOperator
)) {
1700 for (FormatToken
*Previous
= Current
.Previous
;
1701 Previous
&& Previous
->Previous
&&
1702 !Previous
->Previous
->isOneOf(tok::comma
, tok::semi
);
1703 Previous
= Previous
->Previous
) {
1704 if (Previous
->isOneOf(tok::r_square
, tok::r_paren
)) {
1705 Previous
= Previous
->MatchingParen
;
1709 if (Previous
->opensScope())
1711 if (Previous
->isOneOf(TT_BinaryOperator
, TT_UnaryOperator
) &&
1712 Previous
->isOneOf(tok::star
, tok::amp
, tok::ampamp
) &&
1713 Previous
->Previous
&& Previous
->Previous
->isNot(tok::equal
)) {
1714 Previous
->setType(TT_PointerOrReference
);
1718 } else if (Current
.is(tok::lessless
) &&
1719 (!Current
.Previous
|| !Current
.Previous
->is(tok::kw_operator
))) {
1720 Contexts
.back().IsExpression
= true;
1721 } else if (Current
.isOneOf(tok::kw_return
, tok::kw_throw
)) {
1722 Contexts
.back().IsExpression
= true;
1723 } else if (Current
.is(TT_TrailingReturnArrow
)) {
1724 Contexts
.back().IsExpression
= false;
1725 } else if (Current
.is(TT_LambdaArrow
) || Current
.is(Keywords
.kw_assert
)) {
1726 Contexts
.back().IsExpression
= Style
.Language
== FormatStyle::LK_Java
;
1727 } else if (Current
.Previous
&&
1728 Current
.Previous
->is(TT_CtorInitializerColon
)) {
1729 Contexts
.back().IsExpression
= true;
1730 Contexts
.back().ContextType
= Context::CtorInitializer
;
1731 } else if (Current
.Previous
&& Current
.Previous
->is(TT_InheritanceColon
)) {
1732 Contexts
.back().ContextType
= Context::InheritanceList
;
1733 } else if (Current
.isOneOf(tok::r_paren
, tok::greater
, tok::comma
)) {
1734 for (FormatToken
*Previous
= Current
.Previous
;
1735 Previous
&& Previous
->isOneOf(tok::star
, tok::amp
);
1736 Previous
= Previous
->Previous
) {
1737 Previous
->setType(TT_PointerOrReference
);
1739 if (Line
.MustBeDeclaration
&&
1740 Contexts
.front().ContextType
!= Context::CtorInitializer
) {
1741 Contexts
.back().IsExpression
= false;
1743 } else if (Current
.is(tok::kw_new
)) {
1744 Contexts
.back().CanBeExpression
= false;
1745 } else if (Current
.is(tok::semi
) ||
1746 (Current
.is(tok::exclaim
) && Current
.Previous
&&
1747 !Current
.Previous
->is(tok::kw_operator
))) {
1748 // This should be the condition or increment in a for-loop.
1749 // But not operator !() (can't use TT_OverloadedOperator here as its not
1750 // been annotated yet).
1751 Contexts
.back().IsExpression
= true;
1755 static FormatToken
*untilMatchingParen(FormatToken
*Current
) {
1756 // Used when `MatchingParen` is not yet established.
1759 if (Current
->is(tok::l_paren
))
1761 if (Current
->is(tok::r_paren
))
1765 Current
= Current
->Next
;
1770 static bool isDeductionGuide(FormatToken
&Current
) {
1771 // Look for a deduction guide template<T> A(...) -> A<...>;
1772 if (Current
.Previous
&& Current
.Previous
->is(tok::r_paren
) &&
1773 Current
.startsSequence(tok::arrow
, tok::identifier
, tok::less
)) {
1774 // Find the TemplateCloser.
1775 FormatToken
*TemplateCloser
= Current
.Next
->Next
;
1776 int NestingLevel
= 0;
1777 while (TemplateCloser
) {
1778 // Skip over an expressions in parens A<(3 < 2)>;
1779 if (TemplateCloser
->is(tok::l_paren
)) {
1780 // No Matching Paren yet so skip to matching paren
1781 TemplateCloser
= untilMatchingParen(TemplateCloser
);
1782 if (!TemplateCloser
)
1785 if (TemplateCloser
->is(tok::less
))
1787 if (TemplateCloser
->is(tok::greater
))
1789 if (NestingLevel
< 1)
1791 TemplateCloser
= TemplateCloser
->Next
;
1793 // Assuming we have found the end of the template ensure its followed
1794 // with a semi-colon.
1795 if (TemplateCloser
&& TemplateCloser
->Next
&&
1796 TemplateCloser
->Next
->is(tok::semi
) &&
1797 Current
.Previous
->MatchingParen
) {
1798 // Determine if the identifier `A` prior to the A<..>; is the same as
1799 // prior to the A(..)
1800 FormatToken
*LeadingIdentifier
=
1801 Current
.Previous
->MatchingParen
->Previous
;
1803 // Differentiate a deduction guide by seeing the
1804 // > of the template prior to the leading identifier.
1805 if (LeadingIdentifier
) {
1806 FormatToken
*PriorLeadingIdentifier
= LeadingIdentifier
->Previous
;
1807 // Skip back past explicit decoration
1808 if (PriorLeadingIdentifier
&&
1809 PriorLeadingIdentifier
->is(tok::kw_explicit
)) {
1810 PriorLeadingIdentifier
= PriorLeadingIdentifier
->Previous
;
1813 return PriorLeadingIdentifier
&&
1814 (PriorLeadingIdentifier
->is(TT_TemplateCloser
) ||
1815 PriorLeadingIdentifier
->ClosesRequiresClause
) &&
1816 LeadingIdentifier
->TokenText
== Current
.Next
->TokenText
;
1823 void determineTokenType(FormatToken
&Current
) {
1824 if (!Current
.is(TT_Unknown
)) {
1825 // The token type is already known.
1829 if ((Style
.isJavaScript() || Style
.isCSharp()) &&
1830 Current
.is(tok::exclaim
)) {
1831 if (Current
.Previous
) {
1833 Style
.isJavaScript()
1834 ? Keywords
.IsJavaScriptIdentifier(
1835 *Current
.Previous
, /* AcceptIdentifierName= */ true)
1836 : Current
.Previous
->is(tok::identifier
);
1838 Current
.Previous
->isOneOf(
1839 tok::kw_default
, tok::kw_namespace
, tok::r_paren
, tok::r_square
,
1840 tok::r_brace
, tok::kw_false
, tok::kw_true
, Keywords
.kw_type
,
1841 Keywords
.kw_get
, Keywords
.kw_init
, Keywords
.kw_set
) ||
1842 Current
.Previous
->Tok
.isLiteral()) {
1843 Current
.setType(TT_NonNullAssertion
);
1848 Current
.Next
->isOneOf(TT_BinaryOperator
, Keywords
.kw_as
)) {
1849 Current
.setType(TT_NonNullAssertion
);
1854 // Line.MightBeFunctionDecl can only be true after the parentheses of a
1855 // function declaration have been found. In this case, 'Current' is a
1856 // trailing token of this declaration and thus cannot be a name.
1857 if (Current
.is(Keywords
.kw_instanceof
)) {
1858 Current
.setType(TT_BinaryOperator
);
1859 } else if (isStartOfName(Current
) &&
1860 (!Line
.MightBeFunctionDecl
|| Current
.NestingLevel
!= 0)) {
1861 Contexts
.back().FirstStartOfName
= &Current
;
1862 Current
.setType(TT_StartOfName
);
1863 } else if (Current
.is(tok::semi
)) {
1864 // Reset FirstStartOfName after finding a semicolon so that a for loop
1865 // with multiple increment statements is not confused with a for loop
1866 // having multiple variable declarations.
1867 Contexts
.back().FirstStartOfName
= nullptr;
1868 } else if (Current
.isOneOf(tok::kw_auto
, tok::kw___auto_type
)) {
1870 } else if (Current
.is(tok::arrow
) &&
1871 Style
.Language
== FormatStyle::LK_Java
) {
1872 Current
.setType(TT_LambdaArrow
);
1873 } else if (Current
.is(tok::arrow
) && AutoFound
&& Line
.MustBeDeclaration
&&
1874 Current
.NestingLevel
== 0 &&
1875 !Current
.Previous
->isOneOf(tok::kw_operator
, tok::identifier
)) {
1876 // not auto operator->() -> xxx;
1877 Current
.setType(TT_TrailingReturnArrow
);
1878 } else if (Current
.is(tok::arrow
) && Current
.Previous
&&
1879 Current
.Previous
->is(tok::r_brace
)) {
1880 // Concept implicit conversion constraint needs to be treated like
1881 // a trailing return type ... } -> <type>.
1882 Current
.setType(TT_TrailingReturnArrow
);
1883 } else if (isDeductionGuide(Current
)) {
1884 // Deduction guides trailing arrow " A(...) -> A<T>;".
1885 Current
.setType(TT_TrailingReturnArrow
);
1886 } else if (Current
.isOneOf(tok::star
, tok::amp
, tok::ampamp
)) {
1887 Current
.setType(determineStarAmpUsage(
1889 Contexts
.back().CanBeExpression
&& Contexts
.back().IsExpression
,
1890 Contexts
.back().ContextType
== Context::TemplateArgument
));
1891 } else if (Current
.isOneOf(tok::minus
, tok::plus
, tok::caret
) ||
1892 (Style
.isVerilog() && Current
.is(tok::pipe
))) {
1893 Current
.setType(determinePlusMinusCaretUsage(Current
));
1894 if (Current
.is(TT_UnaryOperator
) && Current
.is(tok::caret
))
1895 Contexts
.back().CaretFound
= true;
1896 } else if (Current
.isOneOf(tok::minusminus
, tok::plusplus
)) {
1897 Current
.setType(determineIncrementUsage(Current
));
1898 } else if (Current
.isOneOf(tok::exclaim
, tok::tilde
)) {
1899 Current
.setType(TT_UnaryOperator
);
1900 } else if (Current
.is(tok::question
)) {
1901 if (Style
.isJavaScript() && Line
.MustBeDeclaration
&&
1902 !Contexts
.back().IsExpression
) {
1903 // In JavaScript, `interface X { foo?(): bar; }` is an optional method
1904 // on the interface, not a ternary expression.
1905 Current
.setType(TT_JsTypeOptionalQuestion
);
1907 Current
.setType(TT_ConditionalExpr
);
1909 } else if (Current
.isBinaryOperator() &&
1910 (!Current
.Previous
|| Current
.Previous
->isNot(tok::l_square
)) &&
1911 (!Current
.is(tok::greater
) &&
1912 Style
.Language
!= FormatStyle::LK_TextProto
)) {
1913 Current
.setType(TT_BinaryOperator
);
1914 } else if (Current
.is(tok::comment
)) {
1915 if (Current
.TokenText
.startswith("/*")) {
1916 if (Current
.TokenText
.endswith("*/")) {
1917 Current
.setType(TT_BlockComment
);
1919 // The lexer has for some reason determined a comment here. But we
1920 // cannot really handle it, if it isn't properly terminated.
1921 Current
.Tok
.setKind(tok::unknown
);
1924 Current
.setType(TT_LineComment
);
1926 } else if (Current
.is(tok::l_paren
)) {
1927 if (lParenStartsCppCast(Current
))
1928 Current
.setType(TT_CppCastLParen
);
1929 } else if (Current
.is(tok::r_paren
)) {
1930 if (rParenEndsCast(Current
))
1931 Current
.setType(TT_CastRParen
);
1932 if (Current
.MatchingParen
&& Current
.Next
&&
1933 !Current
.Next
->isBinaryOperator() &&
1934 !Current
.Next
->isOneOf(tok::semi
, tok::colon
, tok::l_brace
,
1935 tok::comma
, tok::period
, tok::arrow
,
1936 tok::coloncolon
, tok::kw_noexcept
)) {
1937 if (FormatToken
*AfterParen
= Current
.MatchingParen
->Next
) {
1938 // Make sure this isn't the return type of an Obj-C block declaration
1939 if (AfterParen
->isNot(tok::caret
)) {
1940 if (FormatToken
*BeforeParen
= Current
.MatchingParen
->Previous
) {
1941 if (BeforeParen
->is(tok::identifier
) &&
1942 !BeforeParen
->is(TT_TypenameMacro
) &&
1943 BeforeParen
->TokenText
== BeforeParen
->TokenText
.upper() &&
1944 (!BeforeParen
->Previous
||
1945 BeforeParen
->Previous
->ClosesTemplateDeclaration
)) {
1946 Current
.setType(TT_FunctionAnnotationRParen
);
1952 } else if (Current
.is(tok::at
) && Current
.Next
&& !Style
.isJavaScript() &&
1953 Style
.Language
!= FormatStyle::LK_Java
) {
1954 // In Java & JavaScript, "@..." is a decorator or annotation. In ObjC, it
1955 // marks declarations and properties that need special formatting.
1956 switch (Current
.Next
->Tok
.getObjCKeywordID()) {
1957 case tok::objc_interface
:
1958 case tok::objc_implementation
:
1959 case tok::objc_protocol
:
1960 Current
.setType(TT_ObjCDecl
);
1962 case tok::objc_property
:
1963 Current
.setType(TT_ObjCProperty
);
1968 } else if (Current
.is(tok::period
)) {
1969 FormatToken
*PreviousNoComment
= Current
.getPreviousNonComment();
1970 if (PreviousNoComment
&&
1971 PreviousNoComment
->isOneOf(tok::comma
, tok::l_brace
)) {
1972 Current
.setType(TT_DesignatedInitializerPeriod
);
1973 } else if (Style
.Language
== FormatStyle::LK_Java
&& Current
.Previous
&&
1974 Current
.Previous
->isOneOf(TT_JavaAnnotation
,
1975 TT_LeadingJavaAnnotation
)) {
1976 Current
.setType(Current
.Previous
->getType());
1978 } else if (canBeObjCSelectorComponent(Current
) &&
1979 // FIXME(bug 36976): ObjC return types shouldn't use
1981 Current
.Previous
&& Current
.Previous
->is(TT_CastRParen
) &&
1982 Current
.Previous
->MatchingParen
&&
1983 Current
.Previous
->MatchingParen
->Previous
&&
1984 Current
.Previous
->MatchingParen
->Previous
->is(
1985 TT_ObjCMethodSpecifier
)) {
1986 // This is the first part of an Objective-C selector name. (If there's no
1987 // colon after this, this is the only place which annotates the identifier
1989 Current
.setType(TT_SelectorName
);
1990 } else if (Current
.isOneOf(tok::identifier
, tok::kw_const
, tok::kw_noexcept
,
1991 tok::kw_requires
) &&
1993 !Current
.Previous
->isOneOf(tok::equal
, tok::at
,
1994 TT_CtorInitializerComma
,
1995 TT_CtorInitializerColon
) &&
1996 Line
.MightBeFunctionDecl
&& Contexts
.size() == 1) {
1997 // Line.MightBeFunctionDecl can only be true after the parentheses of a
1998 // function declaration have been found.
1999 Current
.setType(TT_TrailingAnnotation
);
2000 } else if ((Style
.Language
== FormatStyle::LK_Java
||
2001 Style
.isJavaScript()) &&
2003 if (Current
.Previous
->is(tok::at
) &&
2004 Current
.isNot(Keywords
.kw_interface
)) {
2005 const FormatToken
&AtToken
= *Current
.Previous
;
2006 const FormatToken
*Previous
= AtToken
.getPreviousNonComment();
2007 if (!Previous
|| Previous
->is(TT_LeadingJavaAnnotation
))
2008 Current
.setType(TT_LeadingJavaAnnotation
);
2010 Current
.setType(TT_JavaAnnotation
);
2011 } else if (Current
.Previous
->is(tok::period
) &&
2012 Current
.Previous
->isOneOf(TT_JavaAnnotation
,
2013 TT_LeadingJavaAnnotation
)) {
2014 Current
.setType(Current
.Previous
->getType());
2019 /// Take a guess at whether \p Tok starts a name of a function or
2020 /// variable declaration.
2022 /// This is a heuristic based on whether \p Tok is an identifier following
2023 /// something that is likely a type.
2024 bool isStartOfName(const FormatToken
&Tok
) {
2025 if (Tok
.isNot(tok::identifier
) || !Tok
.Previous
)
2028 if (Tok
.Previous
->isOneOf(TT_LeadingJavaAnnotation
, Keywords
.kw_instanceof
,
2032 if (Style
.isJavaScript() && Tok
.Previous
->is(Keywords
.kw_in
))
2035 // Skip "const" as it does not have an influence on whether this is a name.
2036 FormatToken
*PreviousNotConst
= Tok
.getPreviousNonComment();
2038 // For javascript const can be like "let" or "var"
2039 if (!Style
.isJavaScript())
2040 while (PreviousNotConst
&& PreviousNotConst
->is(tok::kw_const
))
2041 PreviousNotConst
= PreviousNotConst
->getPreviousNonComment();
2043 if (!PreviousNotConst
)
2046 if (PreviousNotConst
->ClosesRequiresClause
)
2049 bool IsPPKeyword
= PreviousNotConst
->is(tok::identifier
) &&
2050 PreviousNotConst
->Previous
&&
2051 PreviousNotConst
->Previous
->is(tok::hash
);
2053 if (PreviousNotConst
->is(TT_TemplateCloser
)) {
2054 return PreviousNotConst
&& PreviousNotConst
->MatchingParen
&&
2055 PreviousNotConst
->MatchingParen
->Previous
&&
2056 PreviousNotConst
->MatchingParen
->Previous
->isNot(tok::period
) &&
2057 PreviousNotConst
->MatchingParen
->Previous
->isNot(tok::kw_template
);
2060 if (PreviousNotConst
->is(tok::r_paren
) &&
2061 PreviousNotConst
->is(TT_TypeDeclarationParen
)) {
2065 // If is a preprocess keyword like #define.
2070 if (PreviousNotConst
->isOneOf(tok::identifier
, tok::kw_auto
))
2074 if (PreviousNotConst
->is(TT_PointerOrReference
))
2078 if (PreviousNotConst
->isSimpleTypeSpecifier())
2082 if (Style
.Language
== FormatStyle::LK_Java
&&
2083 PreviousNotConst
->is(tok::r_square
)) {
2087 // const a = in JavaScript.
2088 return Style
.isJavaScript() && PreviousNotConst
->is(tok::kw_const
);
2091 /// Determine whether '(' is starting a C++ cast.
2092 bool lParenStartsCppCast(const FormatToken
&Tok
) {
2093 // C-style casts are only used in C++.
2097 FormatToken
*LeftOfParens
= Tok
.getPreviousNonComment();
2098 if (LeftOfParens
&& LeftOfParens
->is(TT_TemplateCloser
) &&
2099 LeftOfParens
->MatchingParen
) {
2100 auto *Prev
= LeftOfParens
->MatchingParen
->getPreviousNonComment();
2102 Prev
->isOneOf(tok::kw_const_cast
, tok::kw_dynamic_cast
,
2103 tok::kw_reinterpret_cast
, tok::kw_static_cast
)) {
2104 // FIXME: Maybe we should handle identifiers ending with "_cast",
2112 /// Determine whether ')' is ending a cast.
2113 bool rParenEndsCast(const FormatToken
&Tok
) {
2114 // C-style casts are only used in C++, C# and Java.
2115 if (!Style
.isCSharp() && !Style
.isCpp() &&
2116 Style
.Language
!= FormatStyle::LK_Java
) {
2120 // Empty parens aren't casts and there are no casts at the end of the line.
2121 if (Tok
.Previous
== Tok
.MatchingParen
|| !Tok
.Next
|| !Tok
.MatchingParen
)
2124 if (Tok
.MatchingParen
->is(TT_OverloadedOperatorLParen
))
2127 FormatToken
*LeftOfParens
= Tok
.MatchingParen
->getPreviousNonComment();
2129 // If there is a closing parenthesis left of the current
2130 // parentheses, look past it as these might be chained casts.
2131 if (LeftOfParens
->is(tok::r_paren
) &&
2132 LeftOfParens
->isNot(TT_CastRParen
)) {
2133 if (!LeftOfParens
->MatchingParen
||
2134 !LeftOfParens
->MatchingParen
->Previous
) {
2137 LeftOfParens
= LeftOfParens
->MatchingParen
->Previous
;
2140 if (LeftOfParens
->is(tok::r_square
)) {
2141 // delete[] (void *)ptr;
2142 auto MayBeArrayDelete
= [](FormatToken
*Tok
) -> FormatToken
* {
2143 if (Tok
->isNot(tok::r_square
))
2146 Tok
= Tok
->getPreviousNonComment();
2147 if (!Tok
|| Tok
->isNot(tok::l_square
))
2150 Tok
= Tok
->getPreviousNonComment();
2151 if (!Tok
|| Tok
->isNot(tok::kw_delete
))
2155 if (FormatToken
*MaybeDelete
= MayBeArrayDelete(LeftOfParens
))
2156 LeftOfParens
= MaybeDelete
;
2159 // The Condition directly below this one will see the operator arguments
2160 // as a (void *foo) cast.
2161 // void operator delete(void *foo) ATTRIB;
2162 if (LeftOfParens
->Tok
.getIdentifierInfo() && LeftOfParens
->Previous
&&
2163 LeftOfParens
->Previous
->is(tok::kw_operator
)) {
2167 // If there is an identifier (or with a few exceptions a keyword) right
2168 // before the parentheses, this is unlikely to be a cast.
2169 if (LeftOfParens
->Tok
.getIdentifierInfo() &&
2170 !LeftOfParens
->isOneOf(Keywords
.kw_in
, tok::kw_return
, tok::kw_case
,
2171 tok::kw_delete
, tok::kw_throw
)) {
2175 // Certain other tokens right before the parentheses are also signals that
2176 // this cannot be a cast.
2177 if (LeftOfParens
->isOneOf(tok::at
, tok::r_square
, TT_OverloadedOperator
,
2178 TT_TemplateCloser
, tok::ellipsis
)) {
2183 if (Tok
.Next
->is(tok::question
))
2186 // `foreach((A a, B b) in someList)` should not be seen as a cast.
2187 if (Tok
.Next
->is(Keywords
.kw_in
) && Style
.isCSharp())
2190 // Functions which end with decorations like volatile, noexcept are unlikely
2192 if (Tok
.Next
->isOneOf(tok::kw_noexcept
, tok::kw_volatile
, tok::kw_const
,
2193 tok::kw_requires
, tok::kw_throw
, tok::arrow
,
2194 Keywords
.kw_override
, Keywords
.kw_final
) ||
2195 isCpp11AttributeSpecifier(*Tok
.Next
)) {
2199 // As Java has no function types, a "(" after the ")" likely means that this
2201 if (Style
.Language
== FormatStyle::LK_Java
&& Tok
.Next
->is(tok::l_paren
))
2204 // If a (non-string) literal follows, this is likely a cast.
2205 if (Tok
.Next
->isNot(tok::string_literal
) &&
2206 (Tok
.Next
->Tok
.isLiteral() ||
2207 Tok
.Next
->isOneOf(tok::kw_sizeof
, tok::kw_alignof
))) {
2211 // Heuristically try to determine whether the parentheses contain a type.
2212 auto IsQualifiedPointerOrReference
= [](FormatToken
*T
) {
2213 // This is used to handle cases such as x = (foo *const)&y;
2214 assert(!T
->isSimpleTypeSpecifier() && "Should have already been checked");
2215 // Strip trailing qualifiers such as const or volatile when checking
2216 // whether the parens could be a cast to a pointer/reference type.
2218 if (T
->is(TT_AttributeParen
)) {
2219 // Handle `x = (foo *__attribute__((foo)))&v;`:
2220 if (T
->MatchingParen
&& T
->MatchingParen
->Previous
&&
2221 T
->MatchingParen
->Previous
->is(tok::kw___attribute
)) {
2222 T
= T
->MatchingParen
->Previous
->Previous
;
2225 } else if (T
->is(TT_AttributeSquare
)) {
2226 // Handle `x = (foo *[[clang::foo]])&v;`:
2227 if (T
->MatchingParen
&& T
->MatchingParen
->Previous
) {
2228 T
= T
->MatchingParen
->Previous
;
2231 } else if (T
->canBePointerOrReferenceQualifier()) {
2237 return T
&& T
->is(TT_PointerOrReference
);
2239 bool ParensAreType
=
2241 Tok
.Previous
->isOneOf(TT_TemplateCloser
, TT_TypeDeclarationParen
) ||
2242 Tok
.Previous
->isSimpleTypeSpecifier() ||
2243 IsQualifiedPointerOrReference(Tok
.Previous
);
2244 bool ParensCouldEndDecl
=
2245 Tok
.Next
->isOneOf(tok::equal
, tok::semi
, tok::l_brace
, tok::greater
);
2246 if (ParensAreType
&& !ParensCouldEndDecl
)
2249 // At this point, we heuristically assume that there are no casts at the
2250 // start of the line. We assume that we have found most cases where there
2251 // are by the logic above, e.g. "(void)x;".
2255 // Certain token types inside the parentheses mean that this can't be a
2257 for (const FormatToken
*Token
= Tok
.MatchingParen
->Next
; Token
!= &Tok
;
2258 Token
= Token
->Next
) {
2259 if (Token
->is(TT_BinaryOperator
))
2263 // If the following token is an identifier or 'this', this is a cast. All
2264 // cases where this can be something else are handled above.
2265 if (Tok
.Next
->isOneOf(tok::identifier
, tok::kw_this
))
2268 // Look for a cast `( x ) (`.
2269 if (Tok
.Next
->is(tok::l_paren
) && Tok
.Previous
&& Tok
.Previous
->Previous
) {
2270 if (Tok
.Previous
->is(tok::identifier
) &&
2271 Tok
.Previous
->Previous
->is(tok::l_paren
)) {
2276 if (!Tok
.Next
->Next
)
2279 // If the next token after the parenthesis is a unary operator, assume
2280 // that this is cast, unless there are unexpected tokens inside the
2283 Tok
.Next
->isUnaryOperator() || Tok
.Next
->isOneOf(tok::amp
, tok::star
);
2284 if (!NextIsUnary
|| Tok
.Next
->is(tok::plus
) ||
2285 !Tok
.Next
->Next
->isOneOf(tok::identifier
, tok::numeric_constant
)) {
2288 // Search for unexpected tokens.
2289 for (FormatToken
*Prev
= Tok
.Previous
; Prev
!= Tok
.MatchingParen
;
2290 Prev
= Prev
->Previous
) {
2291 if (!Prev
->isOneOf(tok::kw_const
, tok::identifier
, tok::coloncolon
))
2297 /// Returns true if the token is used as a unary operator.
2298 bool determineUnaryOperatorByUsage(const FormatToken
&Tok
) {
2299 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2303 // These keywords are deliberately not included here because they may
2304 // precede only one of unary star/amp and plus/minus but not both. They are
2305 // either included in determineStarAmpUsage or determinePlusMinusCaretUsage.
2307 // @ - It may be followed by a unary `-` in Objective-C literals. We don't
2308 // know how they can be followed by a star or amp.
2309 if (PrevToken
->isOneOf(
2310 TT_ConditionalExpr
, tok::l_paren
, tok::comma
, tok::colon
, tok::semi
,
2311 tok::equal
, tok::question
, tok::l_square
, tok::l_brace
,
2312 tok::kw_case
, tok::kw_co_await
, tok::kw_co_return
, tok::kw_co_yield
,
2313 tok::kw_delete
, tok::kw_return
, tok::kw_throw
)) {
2317 // We put sizeof here instead of only in determineStarAmpUsage. In the cases
2318 // where the unary `+` operator is overloaded, it is reasonable to write
2319 // things like `sizeof +x`. Like commit 446d6ec996c6c3.
2320 if (PrevToken
->is(tok::kw_sizeof
))
2323 // A sequence of leading unary operators.
2324 if (PrevToken
->isOneOf(TT_CastRParen
, TT_UnaryOperator
))
2327 // There can't be two consecutive binary operators.
2328 if (PrevToken
->is(TT_BinaryOperator
))
2334 /// Return the type of the given token assuming it is * or &.
2335 TokenType
determineStarAmpUsage(const FormatToken
&Tok
, bool IsExpression
,
2336 bool InTemplateArgument
) {
2337 if (Style
.isJavaScript())
2338 return TT_BinaryOperator
;
2340 // && in C# must be a binary operator.
2341 if (Style
.isCSharp() && Tok
.is(tok::ampamp
))
2342 return TT_BinaryOperator
;
2344 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2346 return TT_UnaryOperator
;
2348 const FormatToken
*NextToken
= Tok
.getNextNonComment();
2350 if (InTemplateArgument
&& NextToken
&& NextToken
->is(tok::kw_noexcept
))
2351 return TT_BinaryOperator
;
2354 NextToken
->isOneOf(tok::arrow
, tok::equal
, tok::kw_noexcept
) ||
2355 NextToken
->canBePointerOrReferenceQualifier() ||
2356 (NextToken
->is(tok::l_brace
) && !NextToken
->getNextNonComment())) {
2357 return TT_PointerOrReference
;
2360 if (PrevToken
->is(tok::coloncolon
))
2361 return TT_PointerOrReference
;
2363 if (PrevToken
->is(tok::r_paren
) && PrevToken
->is(TT_TypeDeclarationParen
))
2364 return TT_PointerOrReference
;
2366 if (determineUnaryOperatorByUsage(Tok
))
2367 return TT_UnaryOperator
;
2369 if (NextToken
->is(tok::l_square
) && NextToken
->isNot(TT_LambdaLSquare
))
2370 return TT_PointerOrReference
;
2371 if (NextToken
->is(tok::kw_operator
) && !IsExpression
)
2372 return TT_PointerOrReference
;
2373 if (NextToken
->isOneOf(tok::comma
, tok::semi
))
2374 return TT_PointerOrReference
;
2376 // After right braces, star tokens are likely to be pointers to struct,
2379 // This by itself is not sufficient to distinguish from multiplication
2380 // following a brace-initialized expression, as in:
2381 // int i = int{42} * 2;
2382 // In the struct case, the part of the struct declaration until the `{` and
2383 // the `}` are put on separate unwrapped lines; in the brace-initialized
2384 // case, the matching `{` is on the same unwrapped line, so check for the
2385 // presence of the matching brace to distinguish between those.
2386 if (PrevToken
->is(tok::r_brace
) && Tok
.is(tok::star
) &&
2387 !PrevToken
->MatchingParen
) {
2388 return TT_PointerOrReference
;
2391 // if (Class* obj { function() })
2392 if (PrevToken
->Tok
.isAnyIdentifier() && NextToken
->Tok
.isAnyIdentifier() &&
2393 NextToken
->Next
&& NextToken
->Next
->is(tok::l_brace
)) {
2394 return TT_PointerOrReference
;
2397 if (PrevToken
->endsSequence(tok::r_square
, tok::l_square
, tok::kw_delete
))
2398 return TT_UnaryOperator
;
2400 if (PrevToken
->Tok
.isLiteral() ||
2401 PrevToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::kw_true
,
2402 tok::kw_false
, tok::r_brace
)) {
2403 return TT_BinaryOperator
;
2406 const FormatToken
*NextNonParen
= NextToken
;
2407 while (NextNonParen
&& NextNonParen
->is(tok::l_paren
))
2408 NextNonParen
= NextNonParen
->getNextNonComment();
2409 if (NextNonParen
&& (NextNonParen
->Tok
.isLiteral() ||
2410 NextNonParen
->isOneOf(tok::kw_true
, tok::kw_false
) ||
2411 NextNonParen
->isUnaryOperator())) {
2412 return TT_BinaryOperator
;
2415 // If we know we're in a template argument, there are no named declarations.
2416 // Thus, having an identifier on the right-hand side indicates a binary
2418 if (InTemplateArgument
&& NextToken
->Tok
.isAnyIdentifier())
2419 return TT_BinaryOperator
;
2421 // "&&(" is quite unlikely to be two successive unary "&".
2422 if (Tok
.is(tok::ampamp
) && NextToken
->is(tok::l_paren
))
2423 return TT_BinaryOperator
;
2425 // This catches some cases where evaluation order is used as control flow:
2427 if (NextToken
->Tok
.isAnyIdentifier()) {
2428 const FormatToken
*NextNextToken
= NextToken
->getNextNonComment();
2429 if (NextNextToken
&& NextNextToken
->is(tok::arrow
))
2430 return TT_BinaryOperator
;
2433 // It is very unlikely that we are going to find a pointer or reference type
2434 // definition on the RHS of an assignment.
2435 if (IsExpression
&& !Contexts
.back().CaretFound
)
2436 return TT_BinaryOperator
;
2438 return TT_PointerOrReference
;
2441 TokenType
determinePlusMinusCaretUsage(const FormatToken
&Tok
) {
2442 if (determineUnaryOperatorByUsage(Tok
))
2443 return TT_UnaryOperator
;
2445 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2447 return TT_UnaryOperator
;
2449 if (PrevToken
->is(tok::at
))
2450 return TT_UnaryOperator
;
2452 // Fall back to marking the token as binary operator.
2453 return TT_BinaryOperator
;
2456 /// Determine whether ++/-- are pre- or post-increments/-decrements.
2457 TokenType
determineIncrementUsage(const FormatToken
&Tok
) {
2458 const FormatToken
*PrevToken
= Tok
.getPreviousNonComment();
2459 if (!PrevToken
|| PrevToken
->is(TT_CastRParen
))
2460 return TT_UnaryOperator
;
2461 if (PrevToken
->isOneOf(tok::r_paren
, tok::r_square
, tok::identifier
))
2462 return TT_TrailingUnaryOperator
;
2464 return TT_UnaryOperator
;
2467 SmallVector
<Context
, 8> Contexts
;
2469 const FormatStyle
&Style
;
2470 AnnotatedLine
&Line
;
2471 FormatToken
*CurrentToken
;
2473 const AdditionalKeywords
&Keywords
;
2475 // Set of "<" tokens that do not open a template parameter list. If parseAngle
2476 // determines that a specific token can't be a template opener, it will make
2477 // same decision irrespective of the decisions for tokens leading up to it.
2478 // Store this information to prevent this from causing exponential runtime.
2479 llvm::SmallPtrSet
<FormatToken
*, 16> NonTemplateLess
;
2482 static const int PrecedenceUnaryOperator
= prec::PointerToMember
+ 1;
2483 static const int PrecedenceArrowAndPeriod
= prec::PointerToMember
+ 2;
2485 /// Parses binary expressions by inserting fake parenthesis based on
2486 /// operator precedence.
2487 class ExpressionParser
{
2489 ExpressionParser(const FormatStyle
&Style
, const AdditionalKeywords
&Keywords
,
2490 AnnotatedLine
&Line
)
2491 : Style(Style
), Keywords(Keywords
), Line(Line
), Current(Line
.First
) {}
2493 /// Parse expressions with the given operator precedence.
2494 void parse(int Precedence
= 0) {
2495 // Skip 'return' and ObjC selector colons as they are not part of a binary
2497 while (Current
&& (Current
->is(tok::kw_return
) ||
2498 (Current
->is(tok::colon
) &&
2499 Current
->isOneOf(TT_ObjCMethodExpr
, TT_DictLiteral
)))) {
2503 if (!Current
|| Precedence
> PrecedenceArrowAndPeriod
)
2506 // Conditional expressions need to be parsed separately for proper nesting.
2507 if (Precedence
== prec::Conditional
) {
2508 parseConditionalExpr();
2512 // Parse unary operators, which all have a higher precedence than binary
2514 if (Precedence
== PrecedenceUnaryOperator
) {
2515 parseUnaryOperator();
2519 FormatToken
*Start
= Current
;
2520 FormatToken
*LatestOperator
= nullptr;
2521 unsigned OperatorIndex
= 0;
2524 // Consume operators with higher precedence.
2525 parse(Precedence
+ 1);
2527 int CurrentPrecedence
= getCurrentPrecedence();
2529 if (Precedence
== CurrentPrecedence
&& Current
&&
2530 Current
->is(TT_SelectorName
)) {
2532 addFakeParenthesis(Start
, prec::Level(Precedence
));
2536 // At the end of the line or when an operator with higher precedence is
2537 // found, insert fake parenthesis and return.
2539 (Current
->closesScope() &&
2540 (Current
->MatchingParen
|| Current
->is(TT_TemplateString
))) ||
2541 (CurrentPrecedence
!= -1 && CurrentPrecedence
< Precedence
) ||
2542 (CurrentPrecedence
== prec::Conditional
&&
2543 Precedence
== prec::Assignment
&& Current
->is(tok::colon
))) {
2547 // Consume scopes: (), [], <> and {}
2548 // In addition to that we handle require clauses as scope, so that the
2549 // constraints in that are correctly indented.
2550 if (Current
->opensScope() ||
2551 Current
->isOneOf(TT_RequiresClause
,
2552 TT_RequiresClauseInARequiresExpression
)) {
2553 // In fragment of a JavaScript template string can look like '}..${' and
2554 // thus close a scope and open a new one at the same time.
2555 while (Current
&& (!Current
->closesScope() || Current
->opensScope())) {
2562 if (CurrentPrecedence
== Precedence
) {
2564 LatestOperator
->NextOperator
= Current
;
2565 LatestOperator
= Current
;
2566 Current
->OperatorIndex
= OperatorIndex
;
2569 next(/*SkipPastLeadingComments=*/Precedence
> 0);
2573 if (LatestOperator
&& (Current
|| Precedence
> 0)) {
2574 // The requires clauses do not neccessarily end in a semicolon or a brace,
2575 // but just go over to struct/class or a function declaration, we need to
2576 // intervene so that the fake right paren is inserted correctly.
2579 Start
->Previous
->isOneOf(TT_RequiresClause
,
2580 TT_RequiresClauseInARequiresExpression
))
2582 auto Ret
= Current
? Current
: Line
.Last
;
2583 while (!Ret
->ClosesRequiresClause
&& Ret
->Previous
)
2584 Ret
= Ret
->Previous
;
2589 if (Precedence
== PrecedenceArrowAndPeriod
) {
2590 // Call expressions don't have a binary operator precedence.
2591 addFakeParenthesis(Start
, prec::Unknown
, End
);
2593 addFakeParenthesis(Start
, prec::Level(Precedence
), End
);
2599 /// Gets the precedence (+1) of the given token for binary operators
2600 /// and other tokens that we treat like binary operators.
2601 int getCurrentPrecedence() {
2603 const FormatToken
*NextNonComment
= Current
->getNextNonComment();
2604 if (Current
->is(TT_ConditionalExpr
))
2605 return prec::Conditional
;
2606 if (NextNonComment
&& Current
->is(TT_SelectorName
) &&
2607 (NextNonComment
->isOneOf(TT_DictLiteral
, TT_JsTypeColon
) ||
2608 ((Style
.Language
== FormatStyle::LK_Proto
||
2609 Style
.Language
== FormatStyle::LK_TextProto
) &&
2610 NextNonComment
->is(tok::less
)))) {
2611 return prec::Assignment
;
2613 if (Current
->is(TT_JsComputedPropertyName
))
2614 return prec::Assignment
;
2615 if (Current
->is(TT_LambdaArrow
))
2617 if (Current
->is(TT_FatArrow
))
2618 return prec::Assignment
;
2619 if (Current
->isOneOf(tok::semi
, TT_InlineASMColon
, TT_SelectorName
) ||
2620 (Current
->is(tok::comment
) && NextNonComment
&&
2621 NextNonComment
->is(TT_SelectorName
))) {
2624 if (Current
->is(TT_RangeBasedForLoopColon
))
2626 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
2627 Current
->is(Keywords
.kw_instanceof
)) {
2628 return prec::Relational
;
2630 if (Style
.isJavaScript() &&
2631 Current
->isOneOf(Keywords
.kw_in
, Keywords
.kw_as
)) {
2632 return prec::Relational
;
2634 if (Current
->is(TT_BinaryOperator
) || Current
->is(tok::comma
))
2635 return Current
->getPrecedence();
2636 if (Current
->isOneOf(tok::period
, tok::arrow
) &&
2637 Current
->isNot(TT_TrailingReturnArrow
)) {
2638 return PrecedenceArrowAndPeriod
;
2640 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
2641 Current
->isOneOf(Keywords
.kw_extends
, Keywords
.kw_implements
,
2642 Keywords
.kw_throws
)) {
2645 // In Verilog case labels are not on separate lines straight out of
2646 // UnwrappedLineParser. The colon is not part of an expression.
2647 if (Style
.isVerilog() && Current
->is(tok::colon
))
2653 void addFakeParenthesis(FormatToken
*Start
, prec::Level Precedence
,
2654 FormatToken
*End
= nullptr) {
2655 Start
->FakeLParens
.push_back(Precedence
);
2656 if (Precedence
> prec::Unknown
)
2657 Start
->StartsBinaryExpression
= true;
2658 if (!End
&& Current
)
2659 End
= Current
->getPreviousNonComment();
2662 if (Precedence
> prec::Unknown
)
2663 End
->EndsBinaryExpression
= true;
2667 /// Parse unary operator expressions and surround them with fake
2668 /// parentheses if appropriate.
2669 void parseUnaryOperator() {
2670 llvm::SmallVector
<FormatToken
*, 2> Tokens
;
2671 while (Current
&& Current
->is(TT_UnaryOperator
)) {
2672 Tokens
.push_back(Current
);
2675 parse(PrecedenceArrowAndPeriod
);
2676 for (FormatToken
*Token
: llvm::reverse(Tokens
)) {
2677 // The actual precedence doesn't matter.
2678 addFakeParenthesis(Token
, prec::Unknown
);
2682 void parseConditionalExpr() {
2683 while (Current
&& Current
->isTrailingComment())
2685 FormatToken
*Start
= Current
;
2686 parse(prec::LogicalOr
);
2687 if (!Current
|| !Current
->is(tok::question
))
2690 parse(prec::Assignment
);
2691 if (!Current
|| Current
->isNot(TT_ConditionalExpr
))
2694 parse(prec::Assignment
);
2695 addFakeParenthesis(Start
, prec::Conditional
);
2698 void next(bool SkipPastLeadingComments
= true) {
2700 Current
= Current
->Next
;
2702 (Current
->NewlinesBefore
== 0 || SkipPastLeadingComments
) &&
2703 Current
->isTrailingComment()) {
2704 Current
= Current
->Next
;
2708 const FormatStyle
&Style
;
2709 const AdditionalKeywords
&Keywords
;
2710 const AnnotatedLine
&Line
;
2711 FormatToken
*Current
;
2714 } // end anonymous namespace
2716 void TokenAnnotator::setCommentLineLevels(
2717 SmallVectorImpl
<AnnotatedLine
*> &Lines
) const {
2718 const AnnotatedLine
*NextNonCommentLine
= nullptr;
2719 for (AnnotatedLine
*Line
: llvm::reverse(Lines
)) {
2720 assert(Line
->First
);
2722 // If the comment is currently aligned with the line immediately following
2723 // it, that's probably intentional and we should keep it.
2724 if (NextNonCommentLine
&& Line
->isComment() &&
2725 NextNonCommentLine
->First
->NewlinesBefore
<= 1 &&
2726 NextNonCommentLine
->First
->OriginalColumn
==
2727 Line
->First
->OriginalColumn
) {
2728 const bool PPDirectiveOrImportStmt
=
2729 NextNonCommentLine
->Type
== LT_PreprocessorDirective
||
2730 NextNonCommentLine
->Type
== LT_ImportStatement
;
2731 if (PPDirectiveOrImportStmt
)
2732 Line
->Type
= LT_CommentAbovePPDirective
;
2733 // Align comments for preprocessor lines with the # in column 0 if
2734 // preprocessor lines are not indented. Otherwise, align with the next
2736 Line
->Level
= Style
.IndentPPDirectives
!= FormatStyle::PPDIS_BeforeHash
&&
2737 PPDirectiveOrImportStmt
2739 : NextNonCommentLine
->Level
;
2741 NextNonCommentLine
= Line
->First
->isNot(tok::r_brace
) ? Line
: nullptr;
2744 setCommentLineLevels(Line
->Children
);
2748 static unsigned maxNestingDepth(const AnnotatedLine
&Line
) {
2749 unsigned Result
= 0;
2750 for (const auto *Tok
= Line
.First
; Tok
!= nullptr; Tok
= Tok
->Next
)
2751 Result
= std::max(Result
, Tok
->NestingLevel
);
2755 void TokenAnnotator::annotate(AnnotatedLine
&Line
) const {
2756 for (auto &Child
: Line
.Children
)
2759 AnnotatingParser
Parser(Style
, Line
, Keywords
);
2760 Line
.Type
= Parser
.parseLine();
2762 // With very deep nesting, ExpressionParser uses lots of stack and the
2763 // formatting algorithm is very slow. We're not going to do a good job here
2764 // anyway - it's probably generated code being formatted by mistake.
2765 // Just skip the whole line.
2766 if (maxNestingDepth(Line
) > 50)
2767 Line
.Type
= LT_Invalid
;
2769 if (Line
.Type
== LT_Invalid
)
2772 ExpressionParser
ExprParser(Style
, Keywords
, Line
);
2775 if (Line
.startsWith(TT_ObjCMethodSpecifier
))
2776 Line
.Type
= LT_ObjCMethodDecl
;
2777 else if (Line
.startsWith(TT_ObjCDecl
))
2778 Line
.Type
= LT_ObjCDecl
;
2779 else if (Line
.startsWith(TT_ObjCProperty
))
2780 Line
.Type
= LT_ObjCProperty
;
2782 Line
.First
->SpacesRequiredBefore
= 1;
2783 Line
.First
->CanBreakBefore
= Line
.First
->MustBreakBefore
;
2786 // This function heuristically determines whether 'Current' starts the name of a
2787 // function declaration.
2788 static bool isFunctionDeclarationName(bool IsCpp
, const FormatToken
&Current
,
2789 const AnnotatedLine
&Line
) {
2790 auto skipOperatorName
= [](const FormatToken
*Next
) -> const FormatToken
* {
2791 for (; Next
; Next
= Next
->Next
) {
2792 if (Next
->is(TT_OverloadedOperatorLParen
))
2794 if (Next
->is(TT_OverloadedOperator
))
2796 if (Next
->isOneOf(tok::kw_new
, tok::kw_delete
)) {
2797 // For 'new[]' and 'delete[]'.
2799 Next
->Next
->startsSequence(tok::l_square
, tok::r_square
)) {
2800 Next
= Next
->Next
->Next
;
2804 if (Next
->startsSequence(tok::l_square
, tok::r_square
)) {
2805 // For operator[]().
2809 if ((Next
->isSimpleTypeSpecifier() || Next
->is(tok::identifier
)) &&
2810 Next
->Next
&& Next
->Next
->isOneOf(tok::star
, tok::amp
, tok::ampamp
)) {
2811 // For operator void*(), operator char*(), operator Foo*().
2815 if (Next
->is(TT_TemplateOpener
) && Next
->MatchingParen
) {
2816 Next
= Next
->MatchingParen
;
2825 // Find parentheses of parameter list.
2826 const FormatToken
*Next
= Current
.Next
;
2827 if (Current
.is(tok::kw_operator
)) {
2828 if (Current
.Previous
&& Current
.Previous
->is(tok::coloncolon
))
2830 Next
= skipOperatorName(Next
);
2832 if (!Current
.is(TT_StartOfName
) || Current
.NestingLevel
!= 0)
2834 for (; Next
; Next
= Next
->Next
) {
2835 if (Next
->is(TT_TemplateOpener
)) {
2836 Next
= Next
->MatchingParen
;
2837 } else if (Next
->is(tok::coloncolon
)) {
2841 if (Next
->is(tok::kw_operator
)) {
2842 Next
= skipOperatorName(Next
->Next
);
2845 if (!Next
->is(tok::identifier
))
2847 } else if (Next
->is(tok::l_paren
)) {
2855 // Check whether parameter list can belong to a function declaration.
2856 if (!Next
|| !Next
->is(tok::l_paren
) || !Next
->MatchingParen
)
2858 // If the lines ends with "{", this is likely a function definition.
2859 if (Line
.Last
->is(tok::l_brace
))
2861 if (Next
->Next
== Next
->MatchingParen
)
2862 return true; // Empty parentheses.
2863 // If there is an &/&& after the r_paren, this is likely a function.
2864 if (Next
->MatchingParen
->Next
&&
2865 Next
->MatchingParen
->Next
->is(TT_PointerOrReference
)) {
2869 // Check for K&R C function definitions (and C++ function definitions with
2870 // unnamed parameters), e.g.:
2875 // bool g(size_t = 0, bool b = false)
2879 if (IsCpp
&& Next
->Next
&& Next
->Next
->is(tok::identifier
) &&
2880 !Line
.endsWith(tok::semi
)) {
2884 for (const FormatToken
*Tok
= Next
->Next
; Tok
&& Tok
!= Next
->MatchingParen
;
2886 if (Tok
->is(TT_TypeDeclarationParen
))
2888 if (Tok
->isOneOf(tok::l_paren
, TT_TemplateOpener
) && Tok
->MatchingParen
) {
2889 Tok
= Tok
->MatchingParen
;
2892 if (Tok
->is(tok::kw_const
) || Tok
->isSimpleTypeSpecifier() ||
2893 Tok
->isOneOf(TT_PointerOrReference
, TT_StartOfName
, tok::ellipsis
)) {
2896 if (Tok
->isOneOf(tok::l_brace
, tok::string_literal
, TT_ObjCMethodExpr
) ||
2897 Tok
->Tok
.isLiteral()) {
2904 bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine
&Line
) const {
2905 assert(Line
.MightBeFunctionDecl
);
2907 if ((Style
.AlwaysBreakAfterReturnType
== FormatStyle::RTBS_TopLevel
||
2908 Style
.AlwaysBreakAfterReturnType
==
2909 FormatStyle::RTBS_TopLevelDefinitions
) &&
2914 switch (Style
.AlwaysBreakAfterReturnType
) {
2915 case FormatStyle::RTBS_None
:
2917 case FormatStyle::RTBS_All
:
2918 case FormatStyle::RTBS_TopLevel
:
2920 case FormatStyle::RTBS_AllDefinitions
:
2921 case FormatStyle::RTBS_TopLevelDefinitions
:
2922 return Line
.mightBeFunctionDefinition();
2928 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine
&Line
) const {
2929 for (AnnotatedLine
*ChildLine
: Line
.Children
)
2930 calculateFormattingInformation(*ChildLine
);
2932 Line
.First
->TotalLength
=
2933 Line
.First
->IsMultiline
? Style
.ColumnLimit
2934 : Line
.FirstStartColumn
+ Line
.First
->ColumnWidth
;
2935 FormatToken
*Current
= Line
.First
->Next
;
2936 bool InFunctionDecl
= Line
.MightBeFunctionDecl
;
2937 bool AlignArrayOfStructures
=
2938 (Style
.AlignArrayOfStructures
!= FormatStyle::AIAS_None
&&
2939 Line
.Type
== LT_ArrayOfStructInitializer
);
2940 if (AlignArrayOfStructures
)
2941 calculateArrayInitializerColumnList(Line
);
2944 if (isFunctionDeclarationName(Style
.isCpp(), *Current
, Line
))
2945 Current
->setType(TT_FunctionDeclarationName
);
2946 const FormatToken
*Prev
= Current
->Previous
;
2947 if (Current
->is(TT_LineComment
)) {
2948 if (Prev
->is(BK_BracedInit
) && Prev
->opensScope()) {
2949 Current
->SpacesRequiredBefore
=
2950 (Style
.Cpp11BracedListStyle
&& !Style
.SpacesInParentheses
) ? 0 : 1;
2952 Current
->SpacesRequiredBefore
= Style
.SpacesBeforeTrailingComments
;
2955 // If we find a trailing comment, iterate backwards to determine whether
2956 // it seems to relate to a specific parameter. If so, break before that
2957 // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
2958 // to the previous line in:
2962 if (!Current
->HasUnescapedNewline
) {
2963 for (FormatToken
*Parameter
= Current
->Previous
; Parameter
;
2964 Parameter
= Parameter
->Previous
) {
2965 if (Parameter
->isOneOf(tok::comment
, tok::r_brace
))
2967 if (Parameter
->Previous
&& Parameter
->Previous
->is(tok::comma
)) {
2968 if (!Parameter
->Previous
->is(TT_CtorInitializerComma
) &&
2969 Parameter
->HasUnescapedNewline
) {
2970 Parameter
->MustBreakBefore
= true;
2976 } else if (Current
->SpacesRequiredBefore
== 0 &&
2977 spaceRequiredBefore(Line
, *Current
)) {
2978 Current
->SpacesRequiredBefore
= 1;
2981 const auto &Children
= Prev
->Children
;
2982 if (!Children
.empty() && Children
.back()->Last
->is(TT_LineComment
)) {
2983 Current
->MustBreakBefore
= true;
2985 Current
->MustBreakBefore
=
2986 Current
->MustBreakBefore
|| mustBreakBefore(Line
, *Current
);
2987 if (!Current
->MustBreakBefore
&& InFunctionDecl
&&
2988 Current
->is(TT_FunctionDeclarationName
)) {
2989 Current
->MustBreakBefore
= mustBreakForReturnType(Line
);
2993 Current
->CanBreakBefore
=
2994 Current
->MustBreakBefore
|| canBreakBefore(Line
, *Current
);
2995 unsigned ChildSize
= 0;
2996 if (Prev
->Children
.size() == 1) {
2997 FormatToken
&LastOfChild
= *Prev
->Children
[0]->Last
;
2998 ChildSize
= LastOfChild
.isTrailingComment() ? Style
.ColumnLimit
2999 : LastOfChild
.TotalLength
+ 1;
3001 if (Current
->MustBreakBefore
|| Prev
->Children
.size() > 1 ||
3002 (Prev
->Children
.size() == 1 &&
3003 Prev
->Children
[0]->First
->MustBreakBefore
) ||
3004 Current
->IsMultiline
) {
3005 Current
->TotalLength
= Prev
->TotalLength
+ Style
.ColumnLimit
;
3007 Current
->TotalLength
= Prev
->TotalLength
+ Current
->ColumnWidth
+
3008 ChildSize
+ Current
->SpacesRequiredBefore
;
3011 if (Current
->is(TT_CtorInitializerColon
))
3012 InFunctionDecl
= false;
3014 // FIXME: Only calculate this if CanBreakBefore is true once static
3015 // initializers etc. are sorted out.
3016 // FIXME: Move magic numbers to a better place.
3018 // Reduce penalty for aligning ObjC method arguments using the colon
3019 // alignment as this is the canonical way (still prefer fitting everything
3020 // into one line if possible). Trying to fit a whole expression into one
3021 // line should not force other line breaks (e.g. when ObjC method
3022 // expression is a part of other expression).
3023 Current
->SplitPenalty
= splitPenalty(Line
, *Current
, InFunctionDecl
);
3024 if (Style
.Language
== FormatStyle::LK_ObjC
&&
3025 Current
->is(TT_SelectorName
) && Current
->ParameterIndex
> 0) {
3026 if (Current
->ParameterIndex
== 1)
3027 Current
->SplitPenalty
+= 5 * Current
->BindingStrength
;
3029 Current
->SplitPenalty
+= 20 * Current
->BindingStrength
;
3032 Current
= Current
->Next
;
3035 calculateUnbreakableTailLengths(Line
);
3036 unsigned IndentLevel
= Line
.Level
;
3037 for (Current
= Line
.First
; Current
!= nullptr; Current
= Current
->Next
) {
3039 Current
->Role
->precomputeFormattingInfos(Current
);
3040 if (Current
->MatchingParen
&&
3041 Current
->MatchingParen
->opensBlockOrBlockTypeList(Style
) &&
3045 Current
->IndentLevel
= IndentLevel
;
3046 if (Current
->opensBlockOrBlockTypeList(Style
))
3050 LLVM_DEBUG({ printDebugInfo(Line
); });
3053 void TokenAnnotator::calculateUnbreakableTailLengths(
3054 AnnotatedLine
&Line
) const {
3055 unsigned UnbreakableTailLength
= 0;
3056 FormatToken
*Current
= Line
.Last
;
3058 Current
->UnbreakableTailLength
= UnbreakableTailLength
;
3059 if (Current
->CanBreakBefore
||
3060 Current
->isOneOf(tok::comment
, tok::string_literal
)) {
3061 UnbreakableTailLength
= 0;
3063 UnbreakableTailLength
+=
3064 Current
->ColumnWidth
+ Current
->SpacesRequiredBefore
;
3066 Current
= Current
->Previous
;
3070 void TokenAnnotator::calculateArrayInitializerColumnList(
3071 AnnotatedLine
&Line
) const {
3072 if (Line
.First
== Line
.Last
)
3074 auto *CurrentToken
= Line
.First
;
3075 CurrentToken
->ArrayInitializerLineStart
= true;
3077 while (CurrentToken
!= nullptr && CurrentToken
!= Line
.Last
) {
3078 if (CurrentToken
->is(tok::l_brace
)) {
3079 CurrentToken
->IsArrayInitializer
= true;
3080 if (CurrentToken
->Next
!= nullptr)
3081 CurrentToken
->Next
->MustBreakBefore
= true;
3083 calculateInitializerColumnList(Line
, CurrentToken
->Next
, Depth
+ 1);
3085 CurrentToken
= CurrentToken
->Next
;
3090 FormatToken
*TokenAnnotator::calculateInitializerColumnList(
3091 AnnotatedLine
&Line
, FormatToken
*CurrentToken
, unsigned Depth
) const {
3092 while (CurrentToken
!= nullptr && CurrentToken
!= Line
.Last
) {
3093 if (CurrentToken
->is(tok::l_brace
))
3095 else if (CurrentToken
->is(tok::r_brace
))
3097 if (Depth
== 2 && CurrentToken
->isOneOf(tok::l_brace
, tok::comma
)) {
3098 CurrentToken
= CurrentToken
->Next
;
3099 if (CurrentToken
== nullptr)
3101 CurrentToken
->StartsColumn
= true;
3102 CurrentToken
= CurrentToken
->Previous
;
3104 CurrentToken
= CurrentToken
->Next
;
3106 return CurrentToken
;
3109 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine
&Line
,
3110 const FormatToken
&Tok
,
3111 bool InFunctionDecl
) const {
3112 const FormatToken
&Left
= *Tok
.Previous
;
3113 const FormatToken
&Right
= Tok
;
3115 if (Left
.is(tok::semi
))
3118 // Language specific handling.
3119 if (Style
.Language
== FormatStyle::LK_Java
) {
3120 if (Right
.isOneOf(Keywords
.kw_extends
, Keywords
.kw_throws
))
3122 if (Right
.is(Keywords
.kw_implements
))
3124 if (Left
.is(tok::comma
) && Left
.NestingLevel
== 0)
3126 } else if (Style
.isJavaScript()) {
3127 if (Right
.is(Keywords
.kw_function
) && Left
.isNot(tok::comma
))
3129 if (Left
.is(TT_JsTypeColon
))
3131 if ((Left
.is(TT_TemplateString
) && Left
.TokenText
.endswith("${")) ||
3132 (Right
.is(TT_TemplateString
) && Right
.TokenText
.startswith("}"))) {
3135 // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()".
3136 if (Left
.opensScope() && Right
.closesScope())
3138 } else if (Style
.isProto()) {
3139 if (Right
.is(tok::l_square
))
3141 if (Right
.is(tok::period
))
3145 if (Right
.is(tok::identifier
) && Right
.Next
&& Right
.Next
->is(TT_DictLiteral
))
3147 if (Right
.is(tok::l_square
)) {
3148 if (Left
.is(tok::r_square
))
3150 // Slightly prefer formatting local lambda definitions like functions.
3151 if (Right
.is(TT_LambdaLSquare
) && Left
.is(tok::equal
))
3153 if (!Right
.isOneOf(TT_ObjCMethodExpr
, TT_LambdaLSquare
,
3154 TT_ArrayInitializerLSquare
,
3155 TT_DesignatedInitializerLSquare
, TT_AttributeSquare
)) {
3160 if (Left
.is(tok::coloncolon
))
3162 if (Right
.isOneOf(TT_StartOfName
, TT_FunctionDeclarationName
) ||
3163 Right
.is(tok::kw_operator
)) {
3164 if (Line
.startsWith(tok::kw_for
) && Right
.PartOfMultiVariableDeclStmt
)
3166 if (Left
.is(TT_StartOfName
))
3168 if (InFunctionDecl
&& Right
.NestingLevel
== 0)
3169 return Style
.PenaltyReturnTypeOnItsOwnLine
;
3172 if (Right
.is(TT_PointerOrReference
))
3174 if (Right
.is(TT_LambdaArrow
))
3176 if (Left
.is(tok::equal
) && Right
.is(tok::l_brace
))
3178 if (Left
.is(TT_CastRParen
))
3180 if (Left
.isOneOf(tok::kw_class
, tok::kw_struct
, tok::kw_union
))
3182 if (Left
.is(tok::comment
))
3185 if (Left
.isOneOf(TT_RangeBasedForLoopColon
, TT_InheritanceColon
,
3186 TT_CtorInitializerColon
)) {
3190 if (Right
.isMemberAccess()) {
3191 // Breaking before the "./->" of a chained call/member access is reasonably
3192 // cheap, as formatting those with one call per line is generally
3193 // desirable. In particular, it should be cheaper to break before the call
3194 // than it is to break inside a call's parameters, which could lead to weird
3195 // "hanging" indents. The exception is the very last "./->" to support this
3196 // frequent pattern:
3198 // aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc(
3201 // which might otherwise be blown up onto many lines. Here, clang-format
3202 // won't produce "hanging" indents anyway as there is no other trailing
3205 // Also apply higher penalty is not a call as that might lead to a wrapping
3209 // .aaaaaaaaa.bbbbbbbb(cccccccc);
3210 return !Right
.NextOperator
|| !Right
.NextOperator
->Previous
->closesScope()
3215 if (Right
.is(TT_TrailingAnnotation
) &&
3216 (!Right
.Next
|| Right
.Next
->isNot(tok::l_paren
))) {
3217 // Moving trailing annotations to the next line is fine for ObjC method
3219 if (Line
.startsWith(TT_ObjCMethodSpecifier
))
3221 // Generally, breaking before a trailing annotation is bad unless it is
3222 // function-like. It seems to be especially preferable to keep standard
3223 // annotations (i.e. "const", "final" and "override") on the same line.
3224 // Use a slightly higher penalty after ")" so that annotations like
3225 // "const override" are kept together.
3226 bool is_short_annotation
= Right
.TokenText
.size() < 10;
3227 return (Left
.is(tok::r_paren
) ? 100 : 120) + (is_short_annotation
? 50 : 0);
3230 // In for-loops, prefer breaking at ',' and ';'.
3231 if (Line
.startsWith(tok::kw_for
) && Left
.is(tok::equal
))
3234 // In Objective-C method expressions, prefer breaking before "param:" over
3235 // breaking after it.
3236 if (Right
.is(TT_SelectorName
))
3238 if (Left
.is(tok::colon
) && Left
.is(TT_ObjCMethodExpr
))
3239 return Line
.MightBeFunctionDecl
? 50 : 500;
3241 // In Objective-C type declarations, avoid breaking after the category's
3242 // open paren (we'll prefer breaking after the protocol list's opening
3243 // angle bracket, if present).
3244 if (Line
.Type
== LT_ObjCDecl
&& Left
.is(tok::l_paren
) && Left
.Previous
&&
3245 Left
.Previous
->isOneOf(tok::identifier
, tok::greater
)) {
3249 if (Left
.is(tok::l_paren
) && Style
.PenaltyBreakOpenParenthesis
!= 0)
3250 return Style
.PenaltyBreakOpenParenthesis
;
3251 if (Left
.is(tok::l_paren
) && InFunctionDecl
&&
3252 Style
.AlignAfterOpenBracket
!= FormatStyle::BAS_DontAlign
) {
3255 if (Left
.is(tok::l_paren
) && Left
.Previous
&&
3256 (Left
.Previous
->is(tok::kw_for
) || Left
.Previous
->isIf())) {
3259 if (Left
.is(tok::equal
) && InFunctionDecl
)
3261 if (Right
.is(tok::r_brace
))
3263 if (Left
.is(TT_TemplateOpener
))
3265 if (Left
.opensScope()) {
3266 // If we aren't aligning after opening parens/braces we can always break
3267 // here unless the style does not want us to place all arguments on the
3269 if (Style
.AlignAfterOpenBracket
== FormatStyle::BAS_DontAlign
&&
3270 (Left
.ParameterCount
<= 1 || Style
.AllowAllArgumentsOnNextLine
)) {
3273 if (Left
.is(tok::l_brace
) && !Style
.Cpp11BracedListStyle
)
3275 return Left
.ParameterCount
> 1 ? Style
.PenaltyBreakBeforeFirstCallParameter
3278 if (Left
.is(TT_JavaAnnotation
))
3281 if (Left
.is(TT_UnaryOperator
))
3283 if (Left
.isOneOf(tok::plus
, tok::comma
) && Left
.Previous
&&
3284 Left
.Previous
->isLabelString() &&
3285 (Left
.NextOperator
|| Left
.OperatorIndex
!= 0)) {
3288 if (Right
.is(tok::plus
) && Left
.isLabelString() &&
3289 (Right
.NextOperator
|| Right
.OperatorIndex
!= 0)) {
3292 if (Left
.is(tok::comma
))
3294 if (Right
.is(tok::lessless
) && Left
.isLabelString() &&
3295 (Right
.NextOperator
|| Right
.OperatorIndex
!= 1)) {
3298 if (Right
.is(tok::lessless
)) {
3299 // Breaking at a << is really cheap.
3300 if (!Left
.is(tok::r_paren
) || Right
.OperatorIndex
> 0) {
3301 // Slightly prefer to break before the first one in log-like statements.
3306 if (Left
.ClosesTemplateDeclaration
)
3307 return Style
.PenaltyBreakTemplateDeclaration
;
3308 if (Left
.ClosesRequiresClause
)
3310 if (Left
.is(TT_ConditionalExpr
))
3311 return prec::Conditional
;
3312 prec::Level Level
= Left
.getPrecedence();
3313 if (Level
== prec::Unknown
)
3314 Level
= Right
.getPrecedence();
3315 if (Level
== prec::Assignment
)
3316 return Style
.PenaltyBreakAssignment
;
3317 if (Level
!= prec::Unknown
)
3323 bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken
&Right
) const {
3324 if (Style
.SpaceBeforeParens
== FormatStyle::SBPO_Always
)
3326 if (Right
.is(TT_OverloadedOperatorLParen
) &&
3327 Style
.SpaceBeforeParensOptions
.AfterOverloadedOperator
) {
3330 if (Style
.SpaceBeforeParensOptions
.BeforeNonEmptyParentheses
&&
3331 Right
.ParameterCount
> 0) {
3337 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine
&Line
,
3338 const FormatToken
&Left
,
3339 const FormatToken
&Right
) const {
3340 if (Left
.is(tok::kw_return
) &&
3341 !Right
.isOneOf(tok::semi
, tok::r_paren
, tok::hashhash
)) {
3344 if (Left
.is(tok::kw_throw
) && Right
.is(tok::l_paren
) && Right
.MatchingParen
&&
3345 Right
.MatchingParen
->is(TT_CastRParen
)) {
3348 if (Style
.isJson() && Left
.is(tok::string_literal
) && Right
.is(tok::colon
))
3350 if (Left
.is(Keywords
.kw_assert
) && Style
.Language
== FormatStyle::LK_Java
)
3352 if (Style
.ObjCSpaceAfterProperty
&& Line
.Type
== LT_ObjCProperty
&&
3353 Left
.Tok
.getObjCKeywordID() == tok::objc_property
) {
3356 if (Right
.is(tok::hashhash
))
3357 return Left
.is(tok::hash
);
3358 if (Left
.isOneOf(tok::hashhash
, tok::hash
))
3359 return Right
.is(tok::hash
);
3360 if ((Left
.is(tok::l_paren
) && Right
.is(tok::r_paren
)) ||
3361 (Left
.is(tok::l_brace
) && Left
.isNot(BK_Block
) &&
3362 Right
.is(tok::r_brace
) && Right
.isNot(BK_Block
))) {
3363 return Style
.SpaceInEmptyParentheses
;
3365 if (Style
.SpacesInConditionalStatement
) {
3366 const FormatToken
*LeftParen
= nullptr;
3367 if (Left
.is(tok::l_paren
))
3369 else if (Right
.is(tok::r_paren
) && Right
.MatchingParen
)
3370 LeftParen
= Right
.MatchingParen
;
3371 if (LeftParen
&& LeftParen
->Previous
&&
3372 isKeywordWithCondition(*LeftParen
->Previous
)) {
3377 // trailing return type 'auto': []() -> auto {}, auto foo() -> auto {}
3378 if (Left
.is(tok::kw_auto
) && Right
.isOneOf(TT_LambdaLBrace
, TT_FunctionLBrace
,
3379 // function return type 'auto'
3380 TT_FunctionTypeLParen
)) {
3385 if (Left
.is(tok::kw_auto
) && Right
.isOneOf(tok::l_paren
, tok::l_brace
))
3388 // operator co_await(x)
3389 if (Right
.is(tok::l_paren
) && Left
.is(tok::kw_co_await
) && Left
.Previous
&&
3390 Left
.Previous
->is(tok::kw_operator
)) {
3393 // co_await (x), co_yield (x), co_return (x)
3394 if (Left
.isOneOf(tok::kw_co_await
, tok::kw_co_yield
, tok::kw_co_return
) &&
3395 !Right
.isOneOf(tok::semi
, tok::r_paren
)) {
3399 if (Left
.is(tok::l_paren
) || Right
.is(tok::r_paren
)) {
3400 return (Right
.is(TT_CastRParen
) ||
3401 (Left
.MatchingParen
&& Left
.MatchingParen
->is(TT_CastRParen
)))
3402 ? Style
.SpacesInCStyleCastParentheses
3403 : Style
.SpacesInParentheses
;
3405 if (Right
.isOneOf(tok::semi
, tok::comma
))
3407 if (Right
.is(tok::less
) && Line
.Type
== LT_ObjCDecl
) {
3408 bool IsLightweightGeneric
= Right
.MatchingParen
&&
3409 Right
.MatchingParen
->Next
&&
3410 Right
.MatchingParen
->Next
->is(tok::colon
);
3411 return !IsLightweightGeneric
&& Style
.ObjCSpaceBeforeProtocolList
;
3413 if (Right
.is(tok::less
) && Left
.is(tok::kw_template
))
3414 return Style
.SpaceAfterTemplateKeyword
;
3415 if (Left
.isOneOf(tok::exclaim
, tok::tilde
))
3417 if (Left
.is(tok::at
) &&
3418 Right
.isOneOf(tok::identifier
, tok::string_literal
, tok::char_constant
,
3419 tok::numeric_constant
, tok::l_paren
, tok::l_brace
,
3420 tok::kw_true
, tok::kw_false
)) {
3423 if (Left
.is(tok::colon
))
3424 return !Left
.is(TT_ObjCMethodExpr
);
3425 if (Left
.is(tok::coloncolon
))
3427 if (Left
.is(tok::less
) || Right
.isOneOf(tok::greater
, tok::less
)) {
3428 if (Style
.Language
== FormatStyle::LK_TextProto
||
3429 (Style
.Language
== FormatStyle::LK_Proto
&&
3430 (Left
.is(TT_DictLiteral
) || Right
.is(TT_DictLiteral
)))) {
3431 // Format empty list as `<>`.
3432 if (Left
.is(tok::less
) && Right
.is(tok::greater
))
3434 return !Style
.Cpp11BracedListStyle
;
3438 if (Right
.is(tok::ellipsis
)) {
3439 return Left
.Tok
.isLiteral() || (Left
.is(tok::identifier
) && Left
.Previous
&&
3440 Left
.Previous
->is(tok::kw_case
));
3442 if (Left
.is(tok::l_square
) && Right
.is(tok::amp
))
3443 return Style
.SpacesInSquareBrackets
;
3444 if (Right
.is(TT_PointerOrReference
)) {
3445 if (Left
.is(tok::r_paren
) && Line
.MightBeFunctionDecl
) {
3446 if (!Left
.MatchingParen
)
3448 FormatToken
*TokenBeforeMatchingParen
=
3449 Left
.MatchingParen
->getPreviousNonComment();
3450 if (!TokenBeforeMatchingParen
|| !Left
.is(TT_TypeDeclarationParen
))
3453 // Add a space if the previous token is a pointer qualifier or the closing
3454 // parenthesis of __attribute__(()) expression and the style requires spaces
3455 // after pointer qualifiers.
3456 if ((Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_After
||
3457 Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
) &&
3458 (Left
.is(TT_AttributeParen
) ||
3459 Left
.canBePointerOrReferenceQualifier())) {
3462 if (Left
.Tok
.isLiteral())
3464 // for (auto a = 0, b = 0; const auto & c : {1, 2, 3})
3465 if (Left
.isTypeOrIdentifier() && Right
.Next
&& Right
.Next
->Next
&&
3466 Right
.Next
->Next
->is(TT_RangeBasedForLoopColon
)) {
3467 return getTokenPointerOrReferenceAlignment(Right
) !=
3468 FormatStyle::PAS_Left
;
3470 return !Left
.isOneOf(TT_PointerOrReference
, tok::l_paren
) &&
3471 (getTokenPointerOrReferenceAlignment(Right
) !=
3472 FormatStyle::PAS_Left
||
3473 (Line
.IsMultiVariableDeclStmt
&&
3474 (Left
.NestingLevel
== 0 ||
3475 (Left
.NestingLevel
== 1 && startsWithInitStatement(Line
)))));
3477 if (Right
.is(TT_FunctionTypeLParen
) && Left
.isNot(tok::l_paren
) &&
3478 (!Left
.is(TT_PointerOrReference
) ||
3479 (getTokenPointerOrReferenceAlignment(Left
) != FormatStyle::PAS_Right
&&
3480 !Line
.IsMultiVariableDeclStmt
))) {
3483 if (Left
.is(TT_PointerOrReference
)) {
3484 // Add a space if the next token is a pointer qualifier and the style
3485 // requires spaces before pointer qualifiers.
3486 if ((Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Before
||
3487 Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
) &&
3488 Right
.canBePointerOrReferenceQualifier()) {
3492 if (Right
.Tok
.isLiteral())
3495 if (Right
.is(TT_BlockComment
))
3497 // foo() -> const Bar * override/final
3498 if (Right
.isOneOf(Keywords
.kw_override
, Keywords
.kw_final
) &&
3499 !Right
.is(TT_StartOfName
)) {
3503 if (Right
.is(tok::l_brace
) && Right
.is(BK_Block
))
3505 // for (auto a = 0, b = 0; const auto& c : {1, 2, 3})
3506 if (Left
.Previous
&& Left
.Previous
->isTypeOrIdentifier() && Right
.Next
&&
3507 Right
.Next
->is(TT_RangeBasedForLoopColon
)) {
3508 return getTokenPointerOrReferenceAlignment(Left
) !=
3509 FormatStyle::PAS_Right
;
3511 if (Right
.isOneOf(TT_PointerOrReference
, TT_ArraySubscriptLSquare
,
3515 if (getTokenPointerOrReferenceAlignment(Left
) == FormatStyle::PAS_Right
)
3517 // FIXME: Setting IsMultiVariableDeclStmt for the whole line is error-prone,
3518 // because it does not take into account nested scopes like lambdas.
3519 // In multi-variable declaration statements, attach */& to the variable
3520 // independently of the style. However, avoid doing it if we are in a nested
3521 // scope, e.g. lambda. We still need to special-case statements with
3523 if (Line
.IsMultiVariableDeclStmt
&&
3524 (Left
.NestingLevel
== Line
.First
->NestingLevel
||
3525 ((Left
.NestingLevel
== Line
.First
->NestingLevel
+ 1) &&
3526 startsWithInitStatement(Line
)))) {
3529 return Left
.Previous
&& !Left
.Previous
->isOneOf(
3530 tok::l_paren
, tok::coloncolon
, tok::l_square
);
3532 // Ensure right pointer alignment with ellipsis e.g. int *...P
3533 if (Left
.is(tok::ellipsis
) && Left
.Previous
&&
3534 Left
.Previous
->isOneOf(tok::star
, tok::amp
, tok::ampamp
)) {
3535 return Style
.PointerAlignment
!= FormatStyle::PAS_Right
;
3538 if (Right
.is(tok::star
) && Left
.is(tok::l_paren
))
3540 if (Left
.is(tok::star
) && Right
.isOneOf(tok::star
, tok::amp
, tok::ampamp
))
3542 if (Right
.isOneOf(tok::star
, tok::amp
, tok::ampamp
)) {
3543 const FormatToken
*Previous
= &Left
;
3544 while (Previous
&& !Previous
->is(tok::kw_operator
)) {
3545 if (Previous
->is(tok::identifier
) || Previous
->isSimpleTypeSpecifier()) {
3546 Previous
= Previous
->getPreviousNonComment();
3549 if (Previous
->is(TT_TemplateCloser
) && Previous
->MatchingParen
) {
3550 Previous
= Previous
->MatchingParen
->getPreviousNonComment();
3553 if (Previous
->is(tok::coloncolon
)) {
3554 Previous
= Previous
->getPreviousNonComment();
3559 // Space between the type and the * in:
3562 // operator void const*()
3563 // operator void volatile*()
3564 // operator /*comment*/ const char*()
3565 // operator volatile /*comment*/ char*()
3568 // operator std::Foo*()
3569 // operator C<T>::D<U>*()
3570 // dependent on PointerAlignment style.
3572 if (Previous
->endsSequence(tok::kw_operator
))
3573 return Style
.PointerAlignment
!= FormatStyle::PAS_Left
;
3574 if (Previous
->is(tok::kw_const
) || Previous
->is(tok::kw_volatile
)) {
3575 return (Style
.PointerAlignment
!= FormatStyle::PAS_Left
) ||
3576 (Style
.SpaceAroundPointerQualifiers
==
3577 FormatStyle::SAPQ_After
) ||
3578 (Style
.SpaceAroundPointerQualifiers
== FormatStyle::SAPQ_Both
);
3582 const auto SpaceRequiredForArrayInitializerLSquare
=
3583 [](const FormatToken
&LSquareTok
, const FormatStyle
&Style
) {
3584 return Style
.SpacesInContainerLiterals
||
3585 ((Style
.Language
== FormatStyle::LK_Proto
||
3586 Style
.Language
== FormatStyle::LK_TextProto
) &&
3587 !Style
.Cpp11BracedListStyle
&&
3588 LSquareTok
.endsSequence(tok::l_square
, tok::colon
,
3591 if (Left
.is(tok::l_square
)) {
3592 return (Left
.is(TT_ArrayInitializerLSquare
) && Right
.isNot(tok::r_square
) &&
3593 SpaceRequiredForArrayInitializerLSquare(Left
, Style
)) ||
3594 (Left
.isOneOf(TT_ArraySubscriptLSquare
, TT_StructuredBindingLSquare
,
3595 TT_LambdaLSquare
) &&
3596 Style
.SpacesInSquareBrackets
&& Right
.isNot(tok::r_square
));
3598 if (Right
.is(tok::r_square
)) {
3599 return Right
.MatchingParen
&&
3600 ((Right
.MatchingParen
->is(TT_ArrayInitializerLSquare
) &&
3601 SpaceRequiredForArrayInitializerLSquare(*Right
.MatchingParen
,
3603 (Style
.SpacesInSquareBrackets
&&
3604 Right
.MatchingParen
->isOneOf(TT_ArraySubscriptLSquare
,
3605 TT_StructuredBindingLSquare
,
3606 TT_LambdaLSquare
)) ||
3607 Right
.MatchingParen
->is(TT_AttributeParen
));
3609 if (Right
.is(tok::l_square
) &&
3610 !Right
.isOneOf(TT_ObjCMethodExpr
, TT_LambdaLSquare
,
3611 TT_DesignatedInitializerLSquare
,
3612 TT_StructuredBindingLSquare
, TT_AttributeSquare
) &&
3613 !Left
.isOneOf(tok::numeric_constant
, TT_DictLiteral
) &&
3614 !(!Left
.is(tok::r_square
) && Style
.SpaceBeforeSquareBrackets
&&
3615 Right
.is(TT_ArraySubscriptLSquare
))) {
3618 if (Left
.is(tok::l_brace
) && Right
.is(tok::r_brace
))
3619 return !Left
.Children
.empty(); // No spaces in "{}".
3620 if ((Left
.is(tok::l_brace
) && Left
.isNot(BK_Block
)) ||
3621 (Right
.is(tok::r_brace
) && Right
.MatchingParen
&&
3622 Right
.MatchingParen
->isNot(BK_Block
))) {
3623 return Style
.Cpp11BracedListStyle
? Style
.SpacesInParentheses
: true;
3625 if (Left
.is(TT_BlockComment
)) {
3626 // No whitespace in x(/*foo=*/1), except for JavaScript.
3627 return Style
.isJavaScript() || !Left
.TokenText
.endswith("=*/");
3630 // Space between template and attribute.
3631 // e.g. template <typename T> [[nodiscard]] ...
3632 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_AttributeSquare
))
3634 // Space before parentheses common for all languages
3635 if (Right
.is(tok::l_paren
)) {
3636 if (Left
.is(TT_TemplateCloser
) && Right
.isNot(TT_FunctionTypeLParen
))
3637 return spaceRequiredBeforeParens(Right
);
3638 if (Left
.isOneOf(TT_RequiresClause
,
3639 TT_RequiresClauseInARequiresExpression
)) {
3640 return Style
.SpaceBeforeParensOptions
.AfterRequiresInClause
||
3641 spaceRequiredBeforeParens(Right
);
3643 if (Left
.is(TT_RequiresExpression
)) {
3644 return Style
.SpaceBeforeParensOptions
.AfterRequiresInExpression
||
3645 spaceRequiredBeforeParens(Right
);
3647 if ((Left
.is(tok::r_paren
) && Left
.is(TT_AttributeParen
)) ||
3648 (Left
.is(tok::r_square
) && Left
.is(TT_AttributeSquare
))) {
3651 if (Left
.is(TT_ForEachMacro
)) {
3652 return Style
.SpaceBeforeParensOptions
.AfterForeachMacros
||
3653 spaceRequiredBeforeParens(Right
);
3655 if (Left
.is(TT_IfMacro
)) {
3656 return Style
.SpaceBeforeParensOptions
.AfterIfMacros
||
3657 spaceRequiredBeforeParens(Right
);
3659 if (Line
.Type
== LT_ObjCDecl
)
3661 if (Left
.is(tok::semi
))
3663 if (Left
.isOneOf(tok::pp_elif
, tok::kw_for
, tok::kw_while
, tok::kw_switch
,
3664 tok::kw_case
, TT_ForEachMacro
, TT_ObjCForIn
) ||
3665 Left
.isIf(Line
.Type
!= LT_PreprocessorDirective
) ||
3666 Right
.is(TT_ConditionLParen
)) {
3667 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
3668 spaceRequiredBeforeParens(Right
);
3671 // TODO add Operator overloading specific Options to
3672 // SpaceBeforeParensOptions
3673 if (Right
.is(TT_OverloadedOperatorLParen
))
3674 return spaceRequiredBeforeParens(Right
);
3675 // Function declaration or definition
3676 if (Line
.MightBeFunctionDecl
&& (Left
.is(TT_FunctionDeclarationName
))) {
3677 if (Line
.mightBeFunctionDefinition()) {
3678 return Style
.SpaceBeforeParensOptions
.AfterFunctionDefinitionName
||
3679 spaceRequiredBeforeParens(Right
);
3681 return Style
.SpaceBeforeParensOptions
.AfterFunctionDeclarationName
||
3682 spaceRequiredBeforeParens(Right
);
3686 if (Line
.Type
!= LT_PreprocessorDirective
&& Left
.is(tok::r_square
) &&
3687 Left
.MatchingParen
&& Left
.MatchingParen
->is(TT_LambdaLSquare
)) {
3688 return Style
.SpaceBeforeParensOptions
.AfterFunctionDefinitionName
||
3689 spaceRequiredBeforeParens(Right
);
3691 if (!Left
.Previous
|| Left
.Previous
->isNot(tok::period
)) {
3692 if (Left
.isOneOf(tok::kw_try
, Keywords
.kw___except
, tok::kw_catch
)) {
3693 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
3694 spaceRequiredBeforeParens(Right
);
3696 if (Left
.isOneOf(tok::kw_new
, tok::kw_delete
)) {
3697 return ((!Line
.MightBeFunctionDecl
|| !Left
.Previous
) &&
3698 Style
.SpaceBeforeParens
!= FormatStyle::SBPO_Never
) ||
3699 spaceRequiredBeforeParens(Right
);
3702 if (Left
.is(tok::r_square
) && Left
.MatchingParen
&&
3703 Left
.MatchingParen
->Previous
&&
3704 Left
.MatchingParen
->Previous
->is(tok::kw_delete
)) {
3705 return (Style
.SpaceBeforeParens
!= FormatStyle::SBPO_Never
) ||
3706 spaceRequiredBeforeParens(Right
);
3709 // Handle builtins like identifiers.
3710 if (Line
.Type
!= LT_PreprocessorDirective
&&
3711 (Left
.Tok
.getIdentifierInfo() || Left
.is(tok::r_paren
))) {
3712 return spaceRequiredBeforeParens(Right
);
3716 if (Left
.is(tok::at
) && Right
.Tok
.getObjCKeywordID() != tok::objc_not_keyword
)
3718 if (Right
.is(TT_UnaryOperator
)) {
3719 return !Left
.isOneOf(tok::l_paren
, tok::l_square
, tok::at
) &&
3720 (Left
.isNot(tok::colon
) || Left
.isNot(TT_ObjCMethodExpr
));
3722 if ((Left
.isOneOf(tok::identifier
, tok::greater
, tok::r_square
,
3724 Left
.isSimpleTypeSpecifier()) &&
3725 Right
.is(tok::l_brace
) && Right
.getNextNonComment() &&
3726 Right
.isNot(BK_Block
)) {
3729 if (Left
.is(tok::period
) || Right
.is(tok::period
))
3731 // u#str, U#str, L#str, u8#str
3732 // uR#str, UR#str, LR#str, u8R#str
3733 if (Right
.is(tok::hash
) && Left
.is(tok::identifier
) &&
3734 (Left
.TokenText
== "L" || Left
.TokenText
== "u" ||
3735 Left
.TokenText
== "U" || Left
.TokenText
== "u8" ||
3736 Left
.TokenText
== "LR" || Left
.TokenText
== "uR" ||
3737 Left
.TokenText
== "UR" || Left
.TokenText
== "u8R")) {
3740 if (Left
.is(TT_TemplateCloser
) && Left
.MatchingParen
&&
3741 Left
.MatchingParen
->Previous
&&
3742 (Left
.MatchingParen
->Previous
->is(tok::period
) ||
3743 Left
.MatchingParen
->Previous
->is(tok::coloncolon
))) {
3744 // Java call to generic function with explicit type:
3745 // A.<B<C<...>>>DoSomething();
3746 // A::<B<C<...>>>DoSomething(); // With a Java 8 method reference.
3749 if (Left
.is(TT_TemplateCloser
) && Right
.is(tok::l_square
))
3751 if (Left
.is(tok::l_brace
) && Left
.endsSequence(TT_DictLiteral
, tok::at
)) {
3752 // Objective-C dictionary literal -> no space after opening brace.
3755 if (Right
.is(tok::r_brace
) && Right
.MatchingParen
&&
3756 Right
.MatchingParen
->endsSequence(TT_DictLiteral
, tok::at
)) {
3757 // Objective-C dictionary literal -> no space before closing brace.
3760 if (Right
.getType() == TT_TrailingAnnotation
&&
3761 Right
.isOneOf(tok::amp
, tok::ampamp
) &&
3762 Left
.isOneOf(tok::kw_const
, tok::kw_volatile
) &&
3763 (!Right
.Next
|| Right
.Next
->is(tok::semi
))) {
3764 // Match const and volatile ref-qualifiers without any additional
3765 // qualifiers such as
3766 // void Fn() const &;
3767 return getTokenReferenceAlignment(Right
) != FormatStyle::PAS_Left
;
3773 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine
&Line
,
3774 const FormatToken
&Right
) const {
3775 const FormatToken
&Left
= *Right
.Previous
;
3777 // If the token is finalized don't touch it (as it could be in a
3778 // clang-format-off section).
3780 return Right
.hasWhitespaceBefore();
3782 // Never ever merge two words.
3783 if (Keywords
.isWordLike(Right
) && Keywords
.isWordLike(Left
))
3786 // Leave a space between * and /* to avoid C4138 `comment end` found outside
3788 if (Left
.is(tok::star
) && Right
.is(tok::comment
))
3791 if (Style
.isCpp()) {
3792 // Space between import <iostream>.
3794 if (Left
.is(Keywords
.kw_import
) && Right
.isOneOf(tok::less
, tok::ellipsis
))
3796 // Space between `module :` and `import :`.
3797 if (Left
.isOneOf(Keywords
.kw_module
, Keywords
.kw_import
) &&
3798 Right
.is(TT_ModulePartitionColon
)) {
3801 // No space between import foo:bar but keep a space between import :bar;
3802 if (Left
.is(tok::identifier
) && Right
.is(TT_ModulePartitionColon
))
3804 // No space between :bar;
3805 if (Left
.is(TT_ModulePartitionColon
) &&
3806 Right
.isOneOf(tok::identifier
, tok::kw_private
)) {
3809 if (Left
.is(tok::ellipsis
) && Right
.is(tok::identifier
) &&
3810 Line
.First
->is(Keywords
.kw_import
)) {
3813 // Space in __attribute__((attr)) ::type.
3814 if (Left
.is(TT_AttributeParen
) && Right
.is(tok::coloncolon
))
3817 if (Left
.is(tok::kw_operator
))
3818 return Right
.is(tok::coloncolon
);
3819 if (Right
.is(tok::l_brace
) && Right
.is(BK_BracedInit
) &&
3820 !Left
.opensScope() && Style
.SpaceBeforeCpp11BracedList
) {
3823 if (Left
.is(tok::less
) && Left
.is(TT_OverloadedOperator
) &&
3824 Right
.is(TT_TemplateOpener
)) {
3827 } else if (Style
.Language
== FormatStyle::LK_Proto
||
3828 Style
.Language
== FormatStyle::LK_TextProto
) {
3829 if (Right
.is(tok::period
) &&
3830 Left
.isOneOf(Keywords
.kw_optional
, Keywords
.kw_required
,
3831 Keywords
.kw_repeated
, Keywords
.kw_extend
)) {
3834 if (Right
.is(tok::l_paren
) &&
3835 Left
.isOneOf(Keywords
.kw_returns
, Keywords
.kw_option
)) {
3838 if (Right
.isOneOf(tok::l_brace
, tok::less
) && Left
.is(TT_SelectorName
))
3840 // Slashes occur in text protocol extension syntax: [type/type] { ... }.
3841 if (Left
.is(tok::slash
) || Right
.is(tok::slash
))
3843 if (Left
.MatchingParen
&&
3844 Left
.MatchingParen
->is(TT_ProtoExtensionLSquare
) &&
3845 Right
.isOneOf(tok::l_brace
, tok::less
)) {
3846 return !Style
.Cpp11BracedListStyle
;
3848 // A percent is probably part of a formatting specification, such as %lld.
3849 if (Left
.is(tok::percent
))
3851 // Preserve the existence of a space before a percent for cases like 0x%04x
3853 if (Left
.is(tok::numeric_constant
) && Right
.is(tok::percent
))
3854 return Right
.hasWhitespaceBefore();
3855 } else if (Style
.isJson()) {
3856 if (Right
.is(tok::colon
))
3858 } else if (Style
.isCSharp()) {
3859 // Require spaces around '{' and before '}' unless they appear in
3860 // interpolated strings. Interpolated strings are merged into a single token
3861 // so cannot have spaces inserted by this function.
3863 // No space between 'this' and '['
3864 if (Left
.is(tok::kw_this
) && Right
.is(tok::l_square
))
3867 // No space between 'new' and '('
3868 if (Left
.is(tok::kw_new
) && Right
.is(tok::l_paren
))
3871 // Space before { (including space within '{ {').
3872 if (Right
.is(tok::l_brace
))
3875 // Spaces inside braces.
3876 if (Left
.is(tok::l_brace
) && Right
.isNot(tok::r_brace
))
3879 if (Left
.isNot(tok::l_brace
) && Right
.is(tok::r_brace
))
3882 // Spaces around '=>'.
3883 if (Left
.is(TT_FatArrow
) || Right
.is(TT_FatArrow
))
3886 // No spaces around attribute target colons
3887 if (Left
.is(TT_AttributeColon
) || Right
.is(TT_AttributeColon
))
3890 // space between type and variable e.g. Dictionary<string,string> foo;
3891 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_StartOfName
))
3894 // spaces inside square brackets.
3895 if (Left
.is(tok::l_square
) || Right
.is(tok::r_square
))
3896 return Style
.SpacesInSquareBrackets
;
3898 // No space before ? in nullable types.
3899 if (Right
.is(TT_CSharpNullable
))
3902 // No space before null forgiving '!'.
3903 if (Right
.is(TT_NonNullAssertion
))
3906 // No space between consecutive commas '[,,]'.
3907 if (Left
.is(tok::comma
) && Right
.is(tok::comma
))
3910 // space after var in `var (key, value)`
3911 if (Left
.is(Keywords
.kw_var
) && Right
.is(tok::l_paren
))
3914 // space between keywords and paren e.g. "using ("
3915 if (Right
.is(tok::l_paren
)) {
3916 if (Left
.isOneOf(tok::kw_using
, Keywords
.kw_async
, Keywords
.kw_when
,
3917 Keywords
.kw_lock
)) {
3918 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
3919 spaceRequiredBeforeParens(Right
);
3923 // space between method modifier and opening parenthesis of a tuple return
3925 if (Left
.isOneOf(tok::kw_public
, tok::kw_private
, tok::kw_protected
,
3926 tok::kw_virtual
, tok::kw_extern
, tok::kw_static
,
3927 Keywords
.kw_internal
, Keywords
.kw_abstract
,
3928 Keywords
.kw_sealed
, Keywords
.kw_override
,
3929 Keywords
.kw_async
, Keywords
.kw_unsafe
) &&
3930 Right
.is(tok::l_paren
)) {
3933 } else if (Style
.isJavaScript()) {
3934 if (Left
.is(TT_FatArrow
))
3937 if (Right
.is(tok::l_paren
) && Left
.is(Keywords
.kw_await
) && Left
.Previous
&&
3938 Left
.Previous
->is(tok::kw_for
)) {
3941 if (Left
.is(Keywords
.kw_async
) && Right
.is(tok::l_paren
) &&
3942 Right
.MatchingParen
) {
3943 const FormatToken
*Next
= Right
.MatchingParen
->getNextNonComment();
3944 // An async arrow function, for example: `x = async () => foo();`,
3945 // as opposed to calling a function called async: `x = async();`
3946 if (Next
&& Next
->is(TT_FatArrow
))
3949 if ((Left
.is(TT_TemplateString
) && Left
.TokenText
.endswith("${")) ||
3950 (Right
.is(TT_TemplateString
) && Right
.TokenText
.startswith("}"))) {
3953 // In tagged template literals ("html`bar baz`"), there is no space between
3954 // the tag identifier and the template string.
3955 if (Keywords
.IsJavaScriptIdentifier(Left
,
3956 /* AcceptIdentifierName= */ false) &&
3957 Right
.is(TT_TemplateString
)) {
3960 if (Right
.is(tok::star
) &&
3961 Left
.isOneOf(Keywords
.kw_function
, Keywords
.kw_yield
)) {
3964 if (Right
.isOneOf(tok::l_brace
, tok::l_square
) &&
3965 Left
.isOneOf(Keywords
.kw_function
, Keywords
.kw_yield
,
3966 Keywords
.kw_extends
, Keywords
.kw_implements
)) {
3969 if (Right
.is(tok::l_paren
)) {
3970 // JS methods can use some keywords as names (e.g. `delete()`).
3971 if (Line
.MustBeDeclaration
&& Left
.Tok
.getIdentifierInfo())
3973 // Valid JS method names can include keywords, e.g. `foo.delete()` or
3974 // `bar.instanceof()`. Recognize call positions by preceding period.
3975 if (Left
.Previous
&& Left
.Previous
->is(tok::period
) &&
3976 Left
.Tok
.getIdentifierInfo()) {
3979 // Additional unary JavaScript operators that need a space after.
3980 if (Left
.isOneOf(tok::kw_throw
, Keywords
.kw_await
, Keywords
.kw_typeof
,
3985 // `foo as const;` casts into a const type.
3986 if (Left
.endsSequence(tok::kw_const
, Keywords
.kw_as
))
3988 if ((Left
.isOneOf(Keywords
.kw_let
, Keywords
.kw_var
, Keywords
.kw_in
,
3990 // "of" is only a keyword if it appears after another identifier
3991 // (e.g. as "const x of y" in a for loop), or after a destructuring
3992 // operation (const [x, y] of z, const {a, b} of c).
3993 (Left
.is(Keywords
.kw_of
) && Left
.Previous
&&
3994 (Left
.Previous
->is(tok::identifier
) ||
3995 Left
.Previous
->isOneOf(tok::r_square
, tok::r_brace
)))) &&
3996 (!Left
.Previous
|| !Left
.Previous
->is(tok::period
))) {
3999 if (Left
.isOneOf(tok::kw_for
, Keywords
.kw_as
) && Left
.Previous
&&
4000 Left
.Previous
->is(tok::period
) && Right
.is(tok::l_paren
)) {
4003 if (Left
.is(Keywords
.kw_as
) &&
4004 Right
.isOneOf(tok::l_square
, tok::l_brace
, tok::l_paren
)) {
4007 if (Left
.is(tok::kw_default
) && Left
.Previous
&&
4008 Left
.Previous
->is(tok::kw_export
)) {
4011 if (Left
.is(Keywords
.kw_is
) && Right
.is(tok::l_brace
))
4013 if (Right
.isOneOf(TT_JsTypeColon
, TT_JsTypeOptionalQuestion
))
4015 if (Left
.is(TT_JsTypeOperator
) || Right
.is(TT_JsTypeOperator
))
4017 if ((Left
.is(tok::l_brace
) || Right
.is(tok::r_brace
)) &&
4018 Line
.First
->isOneOf(Keywords
.kw_import
, tok::kw_export
)) {
4021 if (Left
.is(tok::ellipsis
))
4023 if (Left
.is(TT_TemplateCloser
) &&
4024 !Right
.isOneOf(tok::equal
, tok::l_brace
, tok::comma
, tok::l_square
,
4025 Keywords
.kw_implements
, Keywords
.kw_extends
)) {
4026 // Type assertions ('<type>expr') are not followed by whitespace. Other
4027 // locations that should have whitespace following are identified by the
4028 // above set of follower tokens.
4031 if (Right
.is(TT_NonNullAssertion
))
4033 if (Left
.is(TT_NonNullAssertion
) &&
4034 Right
.isOneOf(Keywords
.kw_as
, Keywords
.kw_in
)) {
4035 return true; // "x! as string", "x! in y"
4037 } else if (Style
.Language
== FormatStyle::LK_Java
) {
4038 if (Left
.is(tok::r_square
) && Right
.is(tok::l_brace
))
4040 if (Left
.is(Keywords
.kw_synchronized
) && Right
.is(tok::l_paren
)) {
4041 return Style
.SpaceBeforeParensOptions
.AfterControlStatements
||
4042 spaceRequiredBeforeParens(Right
);
4044 if ((Left
.isOneOf(tok::kw_static
, tok::kw_public
, tok::kw_private
,
4045 tok::kw_protected
) ||
4046 Left
.isOneOf(Keywords
.kw_final
, Keywords
.kw_abstract
,
4047 Keywords
.kw_native
)) &&
4048 Right
.is(TT_TemplateOpener
)) {
4051 } else if (Style
.isVerilog()) {
4052 // Add space between things in a primitive's state table unless in a
4053 // transition like `(0?)`.
4054 if ((Left
.is(TT_VerilogTableItem
) &&
4055 !Right
.isOneOf(tok::r_paren
, tok::semi
)) ||
4056 (Right
.is(TT_VerilogTableItem
) && Left
.isNot(tok::l_paren
))) {
4057 const FormatToken
*Next
= Right
.getNextNonComment();
4058 return !(Next
&& Next
->is(tok::r_paren
));
4060 // Don't add space within a delay like `#0`.
4061 if (Left
.isNot(TT_BinaryOperator
) &&
4062 Left
.isOneOf(Keywords
.kw_verilogHash
, Keywords
.kw_verilogHashHash
)) {
4065 // Add space after a delay.
4066 if (!Right
.is(tok::semi
) &&
4067 (Left
.endsSequence(tok::numeric_constant
, Keywords
.kw_verilogHash
) ||
4068 Left
.endsSequence(tok::numeric_constant
,
4069 Keywords
.kw_verilogHashHash
) ||
4070 (Left
.is(tok::r_paren
) && Left
.MatchingParen
&&
4071 Left
.MatchingParen
->endsSequence(tok::l_paren
, tok::at
)))) {
4074 // Don't add embedded spaces in a number literal like `16'h1?ax` or an array
4075 // literal like `'{}`.
4076 if (Left
.is(Keywords
.kw_apostrophe
) ||
4077 (Left
.is(TT_VerilogNumberBase
) && Right
.is(tok::numeric_constant
))) {
4080 // Add space between the type name and dimension like `logic [1:0]`.
4081 if (Right
.is(tok::l_square
) &&
4082 Left
.isOneOf(TT_VerilogDimensionedTypeName
, Keywords
.kw_function
)) {
4085 // Don't add spaces between a casting type and the quote or repetition count
4087 if ((Right
.is(Keywords
.kw_apostrophe
) ||
4088 (Right
.is(BK_BracedInit
) && Right
.is(tok::l_brace
))) &&
4089 !(Left
.isOneOf(Keywords
.kw_assign
, Keywords
.kw_unique
) ||
4090 Keywords
.isVerilogWordOperator(Left
)) &&
4091 (Left
.isOneOf(tok::r_square
, tok::r_paren
, tok::r_brace
,
4092 tok::numeric_constant
) ||
4093 Keywords
.isWordLike(Left
))) {
4096 // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
4097 if (Left
.endsSequence(tok::star
, tok::l_paren
) && Right
.is(tok::identifier
))
4100 if (Left
.is(TT_ImplicitStringLiteral
))
4101 return Right
.hasWhitespaceBefore();
4102 if (Line
.Type
== LT_ObjCMethodDecl
) {
4103 if (Left
.is(TT_ObjCMethodSpecifier
))
4105 if (Left
.is(tok::r_paren
) && canBeObjCSelectorComponent(Right
)) {
4106 // Don't space between ')' and <id> or ')' and 'new'. 'new' is not a
4107 // keyword in Objective-C, and '+ (instancetype)new;' is a standard class
4108 // method declaration.
4112 if (Line
.Type
== LT_ObjCProperty
&&
4113 (Right
.is(tok::equal
) || Left
.is(tok::equal
))) {
4117 if (Right
.isOneOf(TT_TrailingReturnArrow
, TT_LambdaArrow
) ||
4118 Left
.isOneOf(TT_TrailingReturnArrow
, TT_LambdaArrow
)) {
4121 if (Left
.is(tok::comma
) && !Right
.is(TT_OverloadedOperatorLParen
))
4123 if (Right
.is(tok::comma
))
4125 if (Right
.is(TT_ObjCBlockLParen
))
4127 if (Right
.is(TT_CtorInitializerColon
))
4128 return Style
.SpaceBeforeCtorInitializerColon
;
4129 if (Right
.is(TT_InheritanceColon
) && !Style
.SpaceBeforeInheritanceColon
)
4131 if (Right
.is(TT_RangeBasedForLoopColon
) &&
4132 !Style
.SpaceBeforeRangeBasedForLoopColon
) {
4135 if (Left
.is(TT_BitFieldColon
)) {
4136 return Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Both
||
4137 Style
.BitFieldColonSpacing
== FormatStyle::BFCS_After
;
4139 if (Right
.is(tok::colon
)) {
4140 if (Right
.is(TT_GotoLabelColon
) ||
4141 (!Style
.isVerilog() &&
4142 Line
.First
->isOneOf(tok::kw_default
, tok::kw_case
))) {
4143 return Style
.SpaceBeforeCaseColon
;
4145 if (Line
.First
->isOneOf(tok::kw_default
, tok::kw_case
))
4146 return Style
.SpaceBeforeCaseColon
;
4147 const FormatToken
*Next
= Right
.getNextNonComment();
4148 if (!Next
|| Next
->is(tok::semi
))
4150 if (Right
.is(TT_ObjCMethodExpr
))
4152 if (Left
.is(tok::question
))
4154 if (Right
.is(TT_InlineASMColon
) && Left
.is(tok::coloncolon
))
4156 if (Right
.is(TT_DictLiteral
))
4157 return Style
.SpacesInContainerLiterals
;
4158 if (Right
.is(TT_AttributeColon
))
4160 if (Right
.is(TT_CSharpNamedArgumentColon
))
4162 if (Right
.is(TT_BitFieldColon
)) {
4163 return Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Both
||
4164 Style
.BitFieldColonSpacing
== FormatStyle::BFCS_Before
;
4168 // Do not merge "- -" into "--".
4169 if ((Left
.isOneOf(tok::minus
, tok::minusminus
) &&
4170 Right
.isOneOf(tok::minus
, tok::minusminus
)) ||
4171 (Left
.isOneOf(tok::plus
, tok::plusplus
) &&
4172 Right
.isOneOf(tok::plus
, tok::plusplus
))) {
4175 if (Left
.is(TT_UnaryOperator
)) {
4176 if (!Right
.is(tok::l_paren
)) {
4177 // The alternative operators for ~ and ! are "compl" and "not".
4178 // If they are used instead, we do not want to combine them with
4179 // the token to the right, unless that is a left paren.
4180 if (Left
.is(tok::exclaim
) && Left
.TokenText
== "not")
4182 if (Left
.is(tok::tilde
) && Left
.TokenText
== "compl")
4184 // Lambda captures allow for a lone &, so "&]" needs to be properly
4186 if (Left
.is(tok::amp
) && Right
.is(tok::r_square
))
4187 return Style
.SpacesInSquareBrackets
;
4189 return (Style
.SpaceAfterLogicalNot
&& Left
.is(tok::exclaim
)) ||
4190 Right
.is(TT_BinaryOperator
);
4193 // If the next token is a binary operator or a selector name, we have
4194 // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.
4195 if (Left
.is(TT_CastRParen
)) {
4196 return Style
.SpaceAfterCStyleCast
||
4197 Right
.isOneOf(TT_BinaryOperator
, TT_SelectorName
);
4200 auto ShouldAddSpacesInAngles
= [this, &Right
]() {
4201 if (this->Style
.SpacesInAngles
== FormatStyle::SIAS_Always
)
4203 if (this->Style
.SpacesInAngles
== FormatStyle::SIAS_Leave
)
4204 return Right
.hasWhitespaceBefore();
4208 if (Left
.is(tok::greater
) && Right
.is(tok::greater
)) {
4209 if (Style
.Language
== FormatStyle::LK_TextProto
||
4210 (Style
.Language
== FormatStyle::LK_Proto
&& Left
.is(TT_DictLiteral
))) {
4211 return !Style
.Cpp11BracedListStyle
;
4213 return Right
.is(TT_TemplateCloser
) && Left
.is(TT_TemplateCloser
) &&
4214 ((Style
.Standard
< FormatStyle::LS_Cpp11
) ||
4215 ShouldAddSpacesInAngles());
4217 if (Right
.isOneOf(tok::arrow
, tok::arrowstar
, tok::periodstar
) ||
4218 Left
.isOneOf(tok::arrow
, tok::period
, tok::arrowstar
, tok::periodstar
) ||
4219 (Right
.is(tok::period
) && Right
.isNot(TT_DesignatedInitializerPeriod
))) {
4222 if (!Style
.SpaceBeforeAssignmentOperators
&& Left
.isNot(TT_TemplateCloser
) &&
4223 Right
.getPrecedence() == prec::Assignment
) {
4226 if (Style
.Language
== FormatStyle::LK_Java
&& Right
.is(tok::coloncolon
) &&
4227 (Left
.is(tok::identifier
) || Left
.is(tok::kw_this
))) {
4230 if (Right
.is(tok::coloncolon
) && Left
.is(tok::identifier
)) {
4231 // Generally don't remove existing spaces between an identifier and "::".
4232 // The identifier might actually be a macro name such as ALWAYS_INLINE. If
4233 // this turns out to be too lenient, add analysis of the identifier itself.
4234 return Right
.hasWhitespaceBefore();
4236 if (Right
.is(tok::coloncolon
) &&
4237 !Left
.isOneOf(tok::l_brace
, tok::comment
, tok::l_paren
)) {
4238 // Put a space between < and :: in vector< ::std::string >
4239 return (Left
.is(TT_TemplateOpener
) &&
4240 ((Style
.Standard
< FormatStyle::LS_Cpp11
) ||
4241 ShouldAddSpacesInAngles())) ||
4242 !(Left
.isOneOf(tok::l_paren
, tok::r_paren
, tok::l_square
,
4243 tok::kw___super
, TT_TemplateOpener
,
4244 TT_TemplateCloser
)) ||
4245 (Left
.is(tok::l_paren
) && Style
.SpacesInParentheses
);
4247 if ((Left
.is(TT_TemplateOpener
)) != (Right
.is(TT_TemplateCloser
)))
4248 return ShouldAddSpacesInAngles();
4249 // Space before TT_StructuredBindingLSquare.
4250 if (Right
.is(TT_StructuredBindingLSquare
)) {
4251 return !Left
.isOneOf(tok::amp
, tok::ampamp
) ||
4252 getTokenReferenceAlignment(Left
) != FormatStyle::PAS_Right
;
4254 // Space before & or && following a TT_StructuredBindingLSquare.
4255 if (Right
.Next
&& Right
.Next
->is(TT_StructuredBindingLSquare
) &&
4256 Right
.isOneOf(tok::amp
, tok::ampamp
)) {
4257 return getTokenReferenceAlignment(Right
) != FormatStyle::PAS_Left
;
4259 if ((Right
.is(TT_BinaryOperator
) && !Left
.is(tok::l_paren
)) ||
4260 (Left
.isOneOf(TT_BinaryOperator
, TT_ConditionalExpr
) &&
4261 !Right
.is(tok::r_paren
))) {
4264 if (Right
.is(TT_TemplateOpener
) && Left
.is(tok::r_paren
) &&
4265 Left
.MatchingParen
&&
4266 Left
.MatchingParen
->is(TT_OverloadedOperatorLParen
)) {
4269 if (Right
.is(tok::less
) && Left
.isNot(tok::l_paren
) &&
4270 Line
.Type
== LT_ImportStatement
) {
4273 if (Right
.is(TT_TrailingUnaryOperator
))
4275 if (Left
.is(TT_RegexLiteral
))
4277 return spaceRequiredBetween(Line
, Left
, Right
);
4280 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
4281 static bool isAllmanBrace(const FormatToken
&Tok
) {
4282 return Tok
.is(tok::l_brace
) && Tok
.is(BK_Block
) &&
4283 !Tok
.isOneOf(TT_ObjCBlockLBrace
, TT_LambdaLBrace
, TT_DictLiteral
);
4286 // Returns 'true' if 'Tok' is a function argument.
4287 static bool IsFunctionArgument(const FormatToken
&Tok
) {
4288 return Tok
.MatchingParen
&& Tok
.MatchingParen
->Next
&&
4289 Tok
.MatchingParen
->Next
->isOneOf(tok::comma
, tok::r_paren
);
4293 isItAnEmptyLambdaAllowed(const FormatToken
&Tok
,
4294 FormatStyle::ShortLambdaStyle ShortLambdaOption
) {
4295 return Tok
.Children
.empty() && ShortLambdaOption
!= FormatStyle::SLS_None
;
4298 static bool isAllmanLambdaBrace(const FormatToken
&Tok
) {
4299 return Tok
.is(tok::l_brace
) && Tok
.is(BK_Block
) &&
4300 !Tok
.isOneOf(TT_ObjCBlockLBrace
, TT_DictLiteral
);
4303 // Returns the first token on the line that is not a comment.
4304 static const FormatToken
*getFirstNonComment(const AnnotatedLine
&Line
) {
4305 const FormatToken
*Next
= Line
.First
;
4308 if (Next
->is(tok::comment
))
4309 Next
= Next
->getNextNonComment();
4313 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine
&Line
,
4314 const FormatToken
&Right
) const {
4315 const FormatToken
&Left
= *Right
.Previous
;
4316 if (Right
.NewlinesBefore
> 1 && Style
.MaxEmptyLinesToKeep
> 0)
4319 if (Style
.isCSharp()) {
4320 if (Left
.is(TT_FatArrow
) && Right
.is(tok::l_brace
) &&
4321 Style
.BraceWrapping
.AfterFunction
) {
4324 if (Right
.is(TT_CSharpNamedArgumentColon
) ||
4325 Left
.is(TT_CSharpNamedArgumentColon
)) {
4328 if (Right
.is(TT_CSharpGenericTypeConstraint
))
4330 if (Right
.Next
&& Right
.Next
->is(TT_FatArrow
) &&
4331 (Right
.is(tok::numeric_constant
) ||
4332 (Right
.is(tok::identifier
) && Right
.TokenText
== "_"))) {
4336 // Break after C# [...] and before public/protected/private/internal.
4337 if (Left
.is(TT_AttributeSquare
) && Left
.is(tok::r_square
) &&
4338 (Right
.isAccessSpecifier(/*ColonRequired=*/false) ||
4339 Right
.is(Keywords
.kw_internal
))) {
4342 // Break between ] and [ but only when there are really 2 attributes.
4343 if (Left
.is(TT_AttributeSquare
) && Right
.is(TT_AttributeSquare
) &&
4344 Left
.is(tok::r_square
) && Right
.is(tok::l_square
)) {
4348 } else if (Style
.isJavaScript()) {
4349 // FIXME: This might apply to other languages and token kinds.
4350 if (Right
.is(tok::string_literal
) && Left
.is(tok::plus
) && Left
.Previous
&&
4351 Left
.Previous
->is(tok::string_literal
)) {
4354 if (Left
.is(TT_DictLiteral
) && Left
.is(tok::l_brace
) && Line
.Level
== 0 &&
4355 Left
.Previous
&& Left
.Previous
->is(tok::equal
) &&
4356 Line
.First
->isOneOf(tok::identifier
, Keywords
.kw_import
, tok::kw_export
,
4358 // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match
4360 !Line
.First
->isOneOf(Keywords
.kw_var
, Keywords
.kw_let
)) {
4361 // Object literals on the top level of a file are treated as "enum-style".
4362 // Each key/value pair is put on a separate line, instead of bin-packing.
4365 if (Left
.is(tok::l_brace
) && Line
.Level
== 0 &&
4366 (Line
.startsWith(tok::kw_enum
) ||
4367 Line
.startsWith(tok::kw_const
, tok::kw_enum
) ||
4368 Line
.startsWith(tok::kw_export
, tok::kw_enum
) ||
4369 Line
.startsWith(tok::kw_export
, tok::kw_const
, tok::kw_enum
))) {
4370 // JavaScript top-level enum key/value pairs are put on separate lines
4371 // instead of bin-packing.
4374 if (Right
.is(tok::r_brace
) && Left
.is(tok::l_brace
) && Left
.Previous
&&
4375 Left
.Previous
->is(TT_FatArrow
)) {
4376 // JS arrow function (=> {...}).
4377 switch (Style
.AllowShortLambdasOnASingleLine
) {
4378 case FormatStyle::SLS_All
:
4380 case FormatStyle::SLS_None
:
4382 case FormatStyle::SLS_Empty
:
4383 return !Left
.Children
.empty();
4384 case FormatStyle::SLS_Inline
:
4385 // allow one-lining inline (e.g. in function call args) and empty arrow
4387 return (Left
.NestingLevel
== 0 && Line
.Level
== 0) &&
4388 !Left
.Children
.empty();
4390 llvm_unreachable("Unknown FormatStyle::ShortLambdaStyle enum");
4393 if (Right
.is(tok::r_brace
) && Left
.is(tok::l_brace
) &&
4394 !Left
.Children
.empty()) {
4395 // Support AllowShortFunctionsOnASingleLine for JavaScript.
4396 return Style
.AllowShortFunctionsOnASingleLine
== FormatStyle::SFS_None
||
4397 Style
.AllowShortFunctionsOnASingleLine
== FormatStyle::SFS_Empty
||
4398 (Left
.NestingLevel
== 0 && Line
.Level
== 0 &&
4399 Style
.AllowShortFunctionsOnASingleLine
&
4400 FormatStyle::SFS_InlineOnly
);
4402 } else if (Style
.Language
== FormatStyle::LK_Java
) {
4403 if (Right
.is(tok::plus
) && Left
.is(tok::string_literal
) && Right
.Next
&&
4404 Right
.Next
->is(tok::string_literal
)) {
4407 } else if (Style
.isVerilog()) {
4408 // Break after labels. In Verilog labels don't have the 'case' keyword, so
4409 // it is hard to identify them in UnwrappedLineParser.
4410 if (!Keywords
.isVerilogBegin(Right
) && Keywords
.isVerilogEndOfLabel(Left
))
4412 } else if (Style
.Language
== FormatStyle::LK_Cpp
||
4413 Style
.Language
== FormatStyle::LK_ObjC
||
4414 Style
.Language
== FormatStyle::LK_Proto
||
4415 Style
.Language
== FormatStyle::LK_TableGen
||
4416 Style
.Language
== FormatStyle::LK_TextProto
) {
4417 if (Left
.isStringLiteral() && Right
.isStringLiteral())
4421 // Basic JSON newline processing.
4422 if (Style
.isJson()) {
4423 // Always break after a JSON record opener.
4426 if (Left
.is(TT_DictLiteral
) && Left
.is(tok::l_brace
))
4428 // Always break after a JSON array opener based on BreakArrays.
4429 if ((Left
.is(TT_ArrayInitializerLSquare
) && Left
.is(tok::l_square
) &&
4430 Right
.isNot(tok::r_square
)) ||
4431 Left
.is(tok::comma
)) {
4432 if (Right
.is(tok::l_brace
))
4434 // scan to the right if an we see an object or an array inside
4436 for (const auto *Tok
= &Right
; Tok
; Tok
= Tok
->Next
) {
4437 if (Tok
->isOneOf(tok::l_brace
, tok::l_square
))
4439 if (Tok
->isOneOf(tok::r_brace
, tok::r_square
))
4442 return Style
.BreakArrays
;
4446 // If the last token before a '}', ']', or ')' is a comma or a trailing
4447 // comment, the intention is to insert a line break after it in order to make
4448 // shuffling around entries easier. Import statements, especially in
4449 // JavaScript, can be an exception to this rule.
4450 if (Style
.JavaScriptWrapImports
|| Line
.Type
!= LT_ImportStatement
) {
4451 const FormatToken
*BeforeClosingBrace
= nullptr;
4452 if ((Left
.isOneOf(tok::l_brace
, TT_ArrayInitializerLSquare
) ||
4453 (Style
.isJavaScript() && Left
.is(tok::l_paren
))) &&
4454 Left
.isNot(BK_Block
) && Left
.MatchingParen
) {
4455 BeforeClosingBrace
= Left
.MatchingParen
->Previous
;
4456 } else if (Right
.MatchingParen
&&
4457 (Right
.MatchingParen
->isOneOf(tok::l_brace
,
4458 TT_ArrayInitializerLSquare
) ||
4459 (Style
.isJavaScript() &&
4460 Right
.MatchingParen
->is(tok::l_paren
)))) {
4461 BeforeClosingBrace
= &Left
;
4463 if (BeforeClosingBrace
&& (BeforeClosingBrace
->is(tok::comma
) ||
4464 BeforeClosingBrace
->isTrailingComment())) {
4469 if (Right
.is(tok::comment
)) {
4470 return Left
.isNot(BK_BracedInit
) && Left
.isNot(TT_CtorInitializerColon
) &&
4471 (Right
.NewlinesBefore
> 0 && Right
.HasUnescapedNewline
);
4473 if (Left
.isTrailingComment())
4475 if (Left
.IsUnterminatedLiteral
)
4477 if (Right
.is(tok::lessless
) && Right
.Next
&& Left
.is(tok::string_literal
) &&
4478 Right
.Next
->is(tok::string_literal
)) {
4481 if (Right
.is(TT_RequiresClause
)) {
4482 switch (Style
.RequiresClausePosition
) {
4483 case FormatStyle::RCPS_OwnLine
:
4484 case FormatStyle::RCPS_WithFollowing
:
4490 // Can break after template<> declaration
4491 if (Left
.ClosesTemplateDeclaration
&& Left
.MatchingParen
&&
4492 Left
.MatchingParen
->NestingLevel
== 0) {
4493 // Put concepts on the next line e.g.
4494 // template<typename T>
4496 if (Right
.is(tok::kw_concept
))
4497 return Style
.BreakBeforeConceptDeclarations
== FormatStyle::BBCDS_Always
;
4498 return Style
.AlwaysBreakTemplateDeclarations
== FormatStyle::BTDS_Yes
;
4500 if (Left
.ClosesRequiresClause
&& Right
.isNot(tok::semi
)) {
4501 switch (Style
.RequiresClausePosition
) {
4502 case FormatStyle::RCPS_OwnLine
:
4503 case FormatStyle::RCPS_WithPreceding
:
4509 if (Style
.PackConstructorInitializers
== FormatStyle::PCIS_Never
) {
4510 if (Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeColon
&&
4511 (Left
.is(TT_CtorInitializerComma
) ||
4512 Right
.is(TT_CtorInitializerColon
))) {
4516 if (Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
&&
4517 Left
.isOneOf(TT_CtorInitializerColon
, TT_CtorInitializerComma
)) {
4521 if (Style
.PackConstructorInitializers
< FormatStyle::PCIS_CurrentLine
&&
4522 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
&&
4523 Right
.isOneOf(TT_CtorInitializerComma
, TT_CtorInitializerColon
)) {
4526 // Break only if we have multiple inheritance.
4527 if (Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
&&
4528 Right
.is(TT_InheritanceComma
)) {
4531 if (Style
.BreakInheritanceList
== FormatStyle::BILS_AfterComma
&&
4532 Left
.is(TT_InheritanceComma
)) {
4535 if (Right
.is(tok::string_literal
) && Right
.TokenText
.startswith("R\"")) {
4536 // Multiline raw string literals are special wrt. line breaks. The author
4537 // has made a deliberate choice and might have aligned the contents of the
4538 // string literal accordingly. Thus, we try keep existing line breaks.
4539 return Right
.IsMultiline
&& Right
.NewlinesBefore
> 0;
4541 if ((Left
.is(tok::l_brace
) || (Left
.is(tok::less
) && Left
.Previous
&&
4542 Left
.Previous
->is(tok::equal
))) &&
4543 Right
.NestingLevel
== 1 && Style
.Language
== FormatStyle::LK_Proto
) {
4544 // Don't put enums or option definitions onto single lines in protocol
4548 if (Right
.is(TT_InlineASMBrace
))
4549 return Right
.HasUnescapedNewline
;
4551 if (isAllmanBrace(Left
) || isAllmanBrace(Right
)) {
4552 auto FirstNonComment
= getFirstNonComment(Line
);
4553 bool AccessSpecifier
=
4555 FirstNonComment
->isOneOf(Keywords
.kw_internal
, tok::kw_public
,
4556 tok::kw_private
, tok::kw_protected
);
4558 if (Style
.BraceWrapping
.AfterEnum
) {
4559 if (Line
.startsWith(tok::kw_enum
) ||
4560 Line
.startsWith(tok::kw_typedef
, tok::kw_enum
)) {
4563 // Ensure BraceWrapping for `public enum A {`.
4564 if (AccessSpecifier
&& FirstNonComment
->Next
&&
4565 FirstNonComment
->Next
->is(tok::kw_enum
)) {
4570 // Ensure BraceWrapping for `public interface A {`.
4571 if (Style
.BraceWrapping
.AfterClass
&&
4572 ((AccessSpecifier
&& FirstNonComment
->Next
&&
4573 FirstNonComment
->Next
->is(Keywords
.kw_interface
)) ||
4574 Line
.startsWith(Keywords
.kw_interface
))) {
4578 return (Line
.startsWith(tok::kw_class
) && Style
.BraceWrapping
.AfterClass
) ||
4579 (Line
.startsWith(tok::kw_struct
) && Style
.BraceWrapping
.AfterStruct
);
4582 if (Left
.is(TT_ObjCBlockLBrace
) &&
4583 Style
.AllowShortBlocksOnASingleLine
== FormatStyle::SBS_Never
) {
4587 // Ensure wrapping after __attribute__((XX)) and @interface etc.
4588 if (Left
.is(TT_AttributeParen
) && Right
.is(TT_ObjCDecl
))
4591 if (Left
.is(TT_LambdaLBrace
)) {
4592 if (IsFunctionArgument(Left
) &&
4593 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Inline
) {
4597 if (Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_None
||
4598 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Inline
||
4599 (!Left
.Children
.empty() &&
4600 Style
.AllowShortLambdasOnASingleLine
== FormatStyle::SLS_Empty
)) {
4605 if (Style
.BraceWrapping
.BeforeLambdaBody
&& Right
.is(TT_LambdaLBrace
) &&
4606 Left
.isOneOf(tok::star
, tok::amp
, tok::ampamp
, TT_TemplateCloser
)) {
4610 // Put multiple Java annotation on a new line.
4611 if ((Style
.Language
== FormatStyle::LK_Java
|| Style
.isJavaScript()) &&
4612 Left
.is(TT_LeadingJavaAnnotation
) &&
4613 Right
.isNot(TT_LeadingJavaAnnotation
) && Right
.isNot(tok::l_paren
) &&
4614 (Line
.Last
->is(tok::l_brace
) || Style
.BreakAfterJavaFieldAnnotations
)) {
4618 if (Right
.is(TT_ProtoExtensionLSquare
))
4621 // In text proto instances if a submessage contains at least 2 entries and at
4622 // least one of them is a submessage, like A { ... B { ... } ... },
4623 // put all of the entries of A on separate lines by forcing the selector of
4624 // the submessage B to be put on a newline.
4626 // Example: these can stay on one line:
4627 // a { scalar_1: 1 scalar_2: 2 }
4628 // a { b { key: value } }
4630 // and these entries need to be on a new line even if putting them all in one
4631 // line is under the column limit:
4637 // We enforce this by breaking before a submessage field that has previous
4638 // siblings, *and* breaking before a field that follows a submessage field.
4640 // Be careful to exclude the case [proto.ext] { ... } since the `]` is
4641 // the TT_SelectorName there, but we don't want to break inside the brackets.
4643 // Another edge case is @submessage { key: value }, which is a common
4644 // substitution placeholder. In this case we want to keep `@` and `submessage`
4647 // We ensure elsewhere that extensions are always on their own line.
4648 if ((Style
.Language
== FormatStyle::LK_Proto
||
4649 Style
.Language
== FormatStyle::LK_TextProto
) &&
4650 Right
.is(TT_SelectorName
) && !Right
.is(tok::r_square
) && Right
.Next
) {
4651 // Keep `@submessage` together in:
4652 // @submessage { key: value }
4653 if (Left
.is(tok::at
))
4655 // Look for the scope opener after selector in cases like:
4658 // selector: @base { ...
4659 FormatToken
*LBrace
= Right
.Next
;
4660 if (LBrace
&& LBrace
->is(tok::colon
)) {
4661 LBrace
= LBrace
->Next
;
4662 if (LBrace
&& LBrace
->is(tok::at
)) {
4663 LBrace
= LBrace
->Next
;
4665 LBrace
= LBrace
->Next
;
4669 // The scope opener is one of {, [, <:
4674 // In case of selector { ... }, the l_brace is TT_DictLiteral.
4675 // In case of an empty selector {}, the l_brace is not TT_DictLiteral,
4676 // so we check for immediately following r_brace.
4677 ((LBrace
->is(tok::l_brace
) &&
4678 (LBrace
->is(TT_DictLiteral
) ||
4679 (LBrace
->Next
&& LBrace
->Next
->is(tok::r_brace
)))) ||
4680 LBrace
->is(TT_ArrayInitializerLSquare
) || LBrace
->is(tok::less
))) {
4681 // If Left.ParameterCount is 0, then this submessage entry is not the
4682 // first in its parent submessage, and we want to break before this entry.
4683 // If Left.ParameterCount is greater than 0, then its parent submessage
4684 // might contain 1 or more entries and we want to break before this entry
4685 // if it contains at least 2 entries. We deal with this case later by
4686 // detecting and breaking before the next entry in the parent submessage.
4687 if (Left
.ParameterCount
== 0)
4689 // However, if this submessage is the first entry in its parent
4690 // submessage, Left.ParameterCount might be 1 in some cases.
4691 // We deal with this case later by detecting an entry
4692 // following a closing paren of this submessage.
4695 // If this is an entry immediately following a submessage, it will be
4696 // preceded by a closing paren of that submessage, like in:
4697 // left---. .---right
4699 // sub: { ... } key: value
4700 // If there was a comment between `}` an `key` above, then `key` would be
4701 // put on a new line anyways.
4702 if (Left
.isOneOf(tok::r_brace
, tok::greater
, tok::r_square
))
4706 // Deal with lambda arguments in C++ - we want consistent line breaks whether
4707 // they happen to be at arg0, arg1 or argN. The selection is a bit nuanced
4708 // as aggressive line breaks are placed when the lambda is not the last arg.
4709 if ((Style
.Language
== FormatStyle::LK_Cpp
||
4710 Style
.Language
== FormatStyle::LK_ObjC
) &&
4711 Left
.is(tok::l_paren
) && Left
.BlockParameterCount
> 0 &&
4712 !Right
.isOneOf(tok::l_paren
, TT_LambdaLSquare
)) {
4713 // Multiple lambdas in the same function call force line breaks.
4714 if (Left
.BlockParameterCount
> 1)
4717 // A lambda followed by another arg forces a line break.
4720 auto Comma
= Left
.Role
->lastComma();
4723 auto Next
= Comma
->getNextNonComment();
4726 if (!Next
->isOneOf(TT_LambdaLSquare
, tok::l_brace
, tok::caret
))
4733 bool TokenAnnotator::canBreakBefore(const AnnotatedLine
&Line
,
4734 const FormatToken
&Right
) const {
4735 const FormatToken
&Left
= *Right
.Previous
;
4736 // Language-specific stuff.
4737 if (Style
.isCSharp()) {
4738 if (Left
.isOneOf(TT_CSharpNamedArgumentColon
, TT_AttributeColon
) ||
4739 Right
.isOneOf(TT_CSharpNamedArgumentColon
, TT_AttributeColon
)) {
4742 // Only break after commas for generic type constraints.
4743 if (Line
.First
->is(TT_CSharpGenericTypeConstraint
))
4744 return Left
.is(TT_CSharpGenericTypeConstraintComma
);
4745 // Keep nullable operators attached to their identifiers.
4746 if (Right
.is(TT_CSharpNullable
))
4748 } else if (Style
.Language
== FormatStyle::LK_Java
) {
4749 if (Left
.isOneOf(Keywords
.kw_throws
, Keywords
.kw_extends
,
4750 Keywords
.kw_implements
)) {
4753 if (Right
.isOneOf(Keywords
.kw_throws
, Keywords
.kw_extends
,
4754 Keywords
.kw_implements
)) {
4757 } else if (Style
.isJavaScript()) {
4758 const FormatToken
*NonComment
= Right
.getPreviousNonComment();
4760 NonComment
->isOneOf(
4761 tok::kw_return
, Keywords
.kw_yield
, tok::kw_continue
, tok::kw_break
,
4762 tok::kw_throw
, Keywords
.kw_interface
, Keywords
.kw_type
,
4763 tok::kw_static
, tok::kw_public
, tok::kw_private
, tok::kw_protected
,
4764 Keywords
.kw_readonly
, Keywords
.kw_override
, Keywords
.kw_abstract
,
4765 Keywords
.kw_get
, Keywords
.kw_set
, Keywords
.kw_async
,
4766 Keywords
.kw_await
)) {
4767 return false; // Otherwise automatic semicolon insertion would trigger.
4769 if (Right
.NestingLevel
== 0 &&
4770 (Left
.Tok
.getIdentifierInfo() ||
4771 Left
.isOneOf(tok::r_square
, tok::r_paren
)) &&
4772 Right
.isOneOf(tok::l_square
, tok::l_paren
)) {
4773 return false; // Otherwise automatic semicolon insertion would trigger.
4775 if (NonComment
&& NonComment
->is(tok::identifier
) &&
4776 NonComment
->TokenText
== "asserts") {
4779 if (Left
.is(TT_FatArrow
) && Right
.is(tok::l_brace
))
4781 if (Left
.is(TT_JsTypeColon
))
4783 // Don't wrap between ":" and "!" of a strict prop init ("field!: type;").
4784 if (Left
.is(tok::exclaim
) && Right
.is(tok::colon
))
4786 // Look for is type annotations like:
4787 // function f(): a is B { ... }
4788 // Do not break before is in these cases.
4789 if (Right
.is(Keywords
.kw_is
)) {
4790 const FormatToken
*Next
= Right
.getNextNonComment();
4791 // If `is` is followed by a colon, it's likely that it's a dict key, so
4792 // ignore it for this check.
4793 // For example this is common in Polymer:
4798 if (!Next
|| !Next
->is(tok::colon
))
4801 if (Left
.is(Keywords
.kw_in
))
4802 return Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_None
;
4803 if (Right
.is(Keywords
.kw_in
))
4804 return Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_None
;
4805 if (Right
.is(Keywords
.kw_as
))
4806 return false; // must not break before as in 'x as type' casts
4807 if (Right
.isOneOf(Keywords
.kw_extends
, Keywords
.kw_infer
)) {
4808 // extends and infer can appear as keywords in conditional types:
4809 // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types
4810 // do not break before them, as the expressions are subject to ASI.
4813 if (Left
.is(Keywords
.kw_as
))
4815 if (Left
.is(TT_NonNullAssertion
))
4817 if (Left
.is(Keywords
.kw_declare
) &&
4818 Right
.isOneOf(Keywords
.kw_module
, tok::kw_namespace
,
4819 Keywords
.kw_function
, tok::kw_class
, tok::kw_enum
,
4820 Keywords
.kw_interface
, Keywords
.kw_type
, Keywords
.kw_var
,
4821 Keywords
.kw_let
, tok::kw_const
)) {
4822 // See grammar for 'declare' statements at:
4823 // https://github.com/Microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md#A.10
4826 if (Left
.isOneOf(Keywords
.kw_module
, tok::kw_namespace
) &&
4827 Right
.isOneOf(tok::identifier
, tok::string_literal
)) {
4828 return false; // must not break in "module foo { ...}"
4830 if (Right
.is(TT_TemplateString
) && Right
.closesScope())
4832 // Don't split tagged template literal so there is a break between the tag
4833 // identifier and template string.
4834 if (Left
.is(tok::identifier
) && Right
.is(TT_TemplateString
))
4836 if (Left
.is(TT_TemplateString
) && Left
.opensScope())
4840 if (Left
.is(tok::at
))
4842 if (Left
.Tok
.getObjCKeywordID() == tok::objc_interface
)
4844 if (Left
.isOneOf(TT_JavaAnnotation
, TT_LeadingJavaAnnotation
))
4845 return !Right
.is(tok::l_paren
);
4846 if (Right
.is(TT_PointerOrReference
)) {
4847 return Line
.IsMultiVariableDeclStmt
||
4848 (getTokenPointerOrReferenceAlignment(Right
) ==
4849 FormatStyle::PAS_Right
&&
4850 (!Right
.Next
|| Right
.Next
->isNot(TT_FunctionDeclarationName
)));
4852 if (Right
.isOneOf(TT_StartOfName
, TT_FunctionDeclarationName
) ||
4853 Right
.is(tok::kw_operator
)) {
4856 if (Left
.is(TT_PointerOrReference
))
4858 if (Right
.isTrailingComment()) {
4859 // We rely on MustBreakBefore being set correctly here as we should not
4860 // change the "binding" behavior of a comment.
4861 // The first comment in a braced lists is always interpreted as belonging to
4862 // the first list element. Otherwise, it should be placed outside of the
4864 return Left
.is(BK_BracedInit
) ||
4865 (Left
.is(TT_CtorInitializerColon
) && Right
.NewlinesBefore
> 0 &&
4866 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
);
4868 if (Left
.is(tok::question
) && Right
.is(tok::colon
))
4870 if (Right
.is(TT_ConditionalExpr
) || Right
.is(tok::question
))
4871 return Style
.BreakBeforeTernaryOperators
;
4872 if (Left
.is(TT_ConditionalExpr
) || Left
.is(tok::question
))
4873 return !Style
.BreakBeforeTernaryOperators
;
4874 if (Left
.is(TT_InheritanceColon
))
4875 return Style
.BreakInheritanceList
== FormatStyle::BILS_AfterColon
;
4876 if (Right
.is(TT_InheritanceColon
))
4877 return Style
.BreakInheritanceList
!= FormatStyle::BILS_AfterColon
;
4878 if (Right
.is(TT_ObjCMethodExpr
) && !Right
.is(tok::r_square
) &&
4879 Left
.isNot(TT_SelectorName
)) {
4883 if (Right
.is(tok::colon
) &&
4884 !Right
.isOneOf(TT_CtorInitializerColon
, TT_InlineASMColon
)) {
4887 if (Left
.is(tok::colon
) && Left
.isOneOf(TT_DictLiteral
, TT_ObjCMethodExpr
)) {
4888 if (Style
.Language
== FormatStyle::LK_Proto
||
4889 Style
.Language
== FormatStyle::LK_TextProto
) {
4890 if (!Style
.AlwaysBreakBeforeMultilineStrings
&& Right
.isStringLiteral())
4892 // Prevent cases like:
4895 // { key: valueeeeeeeeeeee }
4897 // when the snippet does not fit into one line.
4901 // key: valueeeeeeeeeeee
4904 // instead, even if it is longer by one line.
4906 // Note that this allows allows the "{" to go over the column limit
4907 // when the column limit is just between ":" and "{", but that does
4908 // not happen too often and alternative formattings in this case are
4911 // The code covers the cases:
4913 // submessage: { ... }
4914 // submessage: < ... >
4915 // repeated: [ ... ]
4916 if (((Right
.is(tok::l_brace
) || Right
.is(tok::less
)) &&
4917 Right
.is(TT_DictLiteral
)) ||
4918 Right
.is(TT_ArrayInitializerLSquare
)) {
4924 if (Right
.is(tok::r_square
) && Right
.MatchingParen
&&
4925 Right
.MatchingParen
->is(TT_ProtoExtensionLSquare
)) {
4928 if (Right
.is(TT_SelectorName
) || (Right
.is(tok::identifier
) && Right
.Next
&&
4929 Right
.Next
->is(TT_ObjCMethodExpr
))) {
4930 return Left
.isNot(tok::period
); // FIXME: Properly parse ObjC calls.
4932 if (Left
.is(tok::r_paren
) && Line
.Type
== LT_ObjCProperty
)
4934 if (Right
.is(tok::kw_concept
))
4935 return Style
.BreakBeforeConceptDeclarations
!= FormatStyle::BBCDS_Never
;
4936 if (Right
.is(TT_RequiresClause
))
4938 if (Left
.ClosesTemplateDeclaration
|| Left
.is(TT_FunctionAnnotationRParen
))
4940 if (Left
.ClosesRequiresClause
)
4942 if (Right
.isOneOf(TT_RangeBasedForLoopColon
, TT_OverloadedOperatorLParen
,
4943 TT_OverloadedOperator
)) {
4946 if (Left
.is(TT_RangeBasedForLoopColon
))
4948 if (Right
.is(TT_RangeBasedForLoopColon
))
4950 if (Left
.is(TT_TemplateCloser
) && Right
.is(TT_TemplateOpener
))
4952 if ((Left
.is(tok::greater
) && Right
.is(tok::greater
)) ||
4953 (Left
.is(tok::less
) && Right
.is(tok::less
))) {
4956 if (Right
.is(TT_BinaryOperator
) &&
4957 Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_None
&&
4958 (Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_All
||
4959 Right
.getPrecedence() != prec::Assignment
)) {
4962 if (Left
.isOneOf(TT_TemplateCloser
, TT_UnaryOperator
) ||
4963 Left
.is(tok::kw_operator
)) {
4966 if (Left
.is(tok::equal
) && !Right
.isOneOf(tok::kw_default
, tok::kw_delete
) &&
4967 Line
.Type
== LT_VirtualFunctionDecl
&& Left
.NestingLevel
== 0) {
4970 if (Left
.is(tok::equal
) && Right
.is(tok::l_brace
) &&
4971 !Style
.Cpp11BracedListStyle
) {
4974 if (Left
.is(tok::l_paren
) &&
4975 Left
.isOneOf(TT_AttributeParen
, TT_TypeDeclarationParen
)) {
4978 if (Left
.is(tok::l_paren
) && Left
.Previous
&&
4979 (Left
.Previous
->isOneOf(TT_BinaryOperator
, TT_CastRParen
))) {
4982 if (Right
.is(TT_ImplicitStringLiteral
))
4985 if (Right
.is(TT_TemplateCloser
))
4987 if (Right
.is(tok::r_square
) && Right
.MatchingParen
&&
4988 Right
.MatchingParen
->is(TT_LambdaLSquare
)) {
4992 // We only break before r_brace if there was a corresponding break before
4993 // the l_brace, which is tracked by BreakBeforeClosingBrace.
4994 if (Right
.is(tok::r_brace
))
4995 return Right
.MatchingParen
&& Right
.MatchingParen
->is(BK_Block
);
4997 // We only break before r_paren if we're in a block indented context.
4998 if (Right
.is(tok::r_paren
)) {
4999 if (Style
.AlignAfterOpenBracket
!= FormatStyle::BAS_BlockIndent
||
5000 !Right
.MatchingParen
) {
5003 const FormatToken
*Previous
= Right
.MatchingParen
->Previous
;
5004 return !(Previous
&& (Previous
->is(tok::kw_for
) || Previous
->isIf()));
5007 // Allow breaking after a trailing annotation, e.g. after a method
5009 if (Left
.is(TT_TrailingAnnotation
)) {
5010 return !Right
.isOneOf(tok::l_brace
, tok::semi
, tok::equal
, tok::l_paren
,
5011 tok::less
, tok::coloncolon
);
5014 if (Right
.is(tok::kw___attribute
) ||
5015 (Right
.is(tok::l_square
) && Right
.is(TT_AttributeSquare
))) {
5016 return !Left
.is(TT_AttributeSquare
);
5019 if (Left
.is(tok::identifier
) && Right
.is(tok::string_literal
))
5022 if (Right
.is(tok::identifier
) && Right
.Next
&& Right
.Next
->is(TT_DictLiteral
))
5025 if (Left
.is(TT_CtorInitializerColon
)) {
5026 return Style
.BreakConstructorInitializers
== FormatStyle::BCIS_AfterColon
&&
5027 (!Right
.isTrailingComment() || Right
.NewlinesBefore
> 0);
5029 if (Right
.is(TT_CtorInitializerColon
))
5030 return Style
.BreakConstructorInitializers
!= FormatStyle::BCIS_AfterColon
;
5031 if (Left
.is(TT_CtorInitializerComma
) &&
5032 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
) {
5035 if (Right
.is(TT_CtorInitializerComma
) &&
5036 Style
.BreakConstructorInitializers
== FormatStyle::BCIS_BeforeComma
) {
5039 if (Left
.is(TT_InheritanceComma
) &&
5040 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
) {
5043 if (Right
.is(TT_InheritanceComma
) &&
5044 Style
.BreakInheritanceList
== FormatStyle::BILS_BeforeComma
) {
5047 if (Left
.is(TT_ArrayInitializerLSquare
))
5049 if (Right
.is(tok::kw_typename
) && Left
.isNot(tok::kw_const
))
5051 if ((Left
.isBinaryOperator() || Left
.is(TT_BinaryOperator
)) &&
5052 !Left
.isOneOf(tok::arrowstar
, tok::lessless
) &&
5053 Style
.BreakBeforeBinaryOperators
!= FormatStyle::BOS_All
&&
5054 (Style
.BreakBeforeBinaryOperators
== FormatStyle::BOS_None
||
5055 Left
.getPrecedence() == prec::Assignment
)) {
5058 if ((Left
.is(TT_AttributeSquare
) && Right
.is(tok::l_square
)) ||
5059 (Left
.is(tok::r_square
) && Right
.is(TT_AttributeSquare
))) {
5063 auto ShortLambdaOption
= Style
.AllowShortLambdasOnASingleLine
;
5064 if (Style
.BraceWrapping
.BeforeLambdaBody
&& Right
.is(TT_LambdaLBrace
)) {
5065 if (isAllmanLambdaBrace(Left
))
5066 return !isItAnEmptyLambdaAllowed(Left
, ShortLambdaOption
);
5067 if (isAllmanLambdaBrace(Right
))
5068 return !isItAnEmptyLambdaAllowed(Right
, ShortLambdaOption
);
5071 return Left
.isOneOf(tok::comma
, tok::coloncolon
, tok::semi
, tok::l_brace
,
5072 tok::kw_class
, tok::kw_struct
, tok::comment
) ||
5073 Right
.isMemberAccess() ||
5074 Right
.isOneOf(TT_TrailingReturnArrow
, TT_LambdaArrow
, tok::lessless
,
5075 tok::colon
, tok::l_square
, tok::at
) ||
5076 (Left
.is(tok::r_paren
) &&
5077 Right
.isOneOf(tok::identifier
, tok::kw_const
)) ||
5078 (Left
.is(tok::l_paren
) && !Right
.is(tok::r_paren
)) ||
5079 (Left
.is(TT_TemplateOpener
) && !Right
.is(TT_TemplateCloser
));
5082 void TokenAnnotator::printDebugInfo(const AnnotatedLine
&Line
) const {
5083 llvm::errs() << "AnnotatedTokens(L=" << Line
.Level
<< ", T=" << Line
.Type
5084 << ", C=" << Line
.IsContinuation
<< "):\n";
5085 const FormatToken
*Tok
= Line
.First
;
5087 llvm::errs() << " M=" << Tok
->MustBreakBefore
5088 << " C=" << Tok
->CanBreakBefore
5089 << " T=" << getTokenTypeName(Tok
->getType())
5090 << " S=" << Tok
->SpacesRequiredBefore
5091 << " F=" << Tok
->Finalized
<< " B=" << Tok
->BlockParameterCount
5092 << " BK=" << Tok
->getBlockKind() << " P=" << Tok
->SplitPenalty
5093 << " Name=" << Tok
->Tok
.getName() << " L=" << Tok
->TotalLength
5094 << " PPK=" << Tok
->getPackingKind() << " FakeLParens=";
5095 for (prec::Level LParen
: Tok
->FakeLParens
)
5096 llvm::errs() << LParen
<< "/";
5097 llvm::errs() << " FakeRParens=" << Tok
->FakeRParens
;
5098 llvm::errs() << " II=" << Tok
->Tok
.getIdentifierInfo();
5099 llvm::errs() << " Text='" << Tok
->TokenText
<< "'\n";
5101 assert(Tok
== Line
.Last
);
5104 llvm::errs() << "----\n";
5107 FormatStyle::PointerAlignmentStyle
5108 TokenAnnotator::getTokenReferenceAlignment(const FormatToken
&Reference
) const {
5109 assert(Reference
.isOneOf(tok::amp
, tok::ampamp
));
5110 switch (Style
.ReferenceAlignment
) {
5111 case FormatStyle::RAS_Pointer
:
5112 return Style
.PointerAlignment
;
5113 case FormatStyle::RAS_Left
:
5114 return FormatStyle::PAS_Left
;
5115 case FormatStyle::RAS_Right
:
5116 return FormatStyle::PAS_Right
;
5117 case FormatStyle::RAS_Middle
:
5118 return FormatStyle::PAS_Middle
;
5120 assert(0); //"Unhandled value of ReferenceAlignment"
5121 return Style
.PointerAlignment
;
5124 FormatStyle::PointerAlignmentStyle
5125 TokenAnnotator::getTokenPointerOrReferenceAlignment(
5126 const FormatToken
&PointerOrReference
) const {
5127 if (PointerOrReference
.isOneOf(tok::amp
, tok::ampamp
)) {
5128 switch (Style
.ReferenceAlignment
) {
5129 case FormatStyle::RAS_Pointer
:
5130 return Style
.PointerAlignment
;
5131 case FormatStyle::RAS_Left
:
5132 return FormatStyle::PAS_Left
;
5133 case FormatStyle::RAS_Right
:
5134 return FormatStyle::PAS_Right
;
5135 case FormatStyle::RAS_Middle
:
5136 return FormatStyle::PAS_Middle
;
5139 assert(PointerOrReference
.is(tok::star
));
5140 return Style
.PointerAlignment
;
5143 } // namespace format
5144 } // namespace clang