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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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