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