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

source code of clang/lib/Format/TokenAnnotator.cpp