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