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