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