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