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