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