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