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