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