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