clang 23.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 // A pair of parentheses before an l_brace in C starts a compound literal
2925 // and is not a cast.
2926 if (Style.Language != FormatStyle::LK_C && AfterRParen->is(tok::l_brace) &&
2927 AfterRParen->getBlockKind() == BK_BracedInit) {
2928 return true;
2929 }
2930
2931 // If the next token after the parenthesis is a unary operator, assume
2932 // that this is cast, unless there are unexpected tokens inside the
2933 // parenthesis.
2934 const bool NextIsAmpOrStar = AfterRParen->isOneOf(tok::amp, tok::star);
2935 if (!(AfterRParen->isUnaryOperator() || NextIsAmpOrStar) ||
2936 AfterRParen->is(tok::plus) ||
2937 AfterRParen->Next->isNoneOf(tok::identifier, tok::numeric_constant)) {
2938 return false;
2939 }
2940
2941 if (NextIsAmpOrStar &&
2942 (AfterRParen->Next->is(tok::numeric_constant) || Line.InPPDirective)) {
2943 return false;
2944 }
2945
2946 if (Line.InPPDirective && AfterRParen->is(tok::minus))
2947 return false;
2948
2949 const auto *Prev = BeforeRParen;
2950
2951 // Look for a function pointer type, e.g. `(*)()`.
2952 if (Prev->is(tok::r_paren)) {
2953 if (Prev->is(TT_CastRParen))
2954 return false;
2955 Prev = Prev->MatchingParen;
2956 if (!Prev)
2957 return false;
2958 Prev = Prev->Previous;
2959 if (!Prev || Prev->isNot(tok::r_paren))
2960 return false;
2961 Prev = Prev->MatchingParen;
2962 return Prev && Prev->is(TT_FunctionTypeLParen);
2963 }
2964
2965 // Search for unexpected tokens.
2966 for (Prev = BeforeRParen; Prev != LParen; Prev = Prev->Previous)
2967 if (Prev->isNoneOf(tok::kw_const, tok::identifier, tok::coloncolon))
2968 return false;
2969
2970 return true;
2971 }
2972
2973 /// Returns true if the token is used as a unary operator.
2974 bool determineUnaryOperatorByUsage(const FormatToken &Tok) {
2975 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2976 if (!PrevToken)
2977 return true;
2978
2979 // These keywords are deliberately not included here because they may
2980 // precede only one of unary star/amp and plus/minus but not both. They are
2981 // either included in determineStarAmpUsage or determinePlusMinusCaretUsage.
2982 //
2983 // @ - It may be followed by a unary `-` in Objective-C literals. We don't
2984 // know how they can be followed by a star or amp.
2985 if (PrevToken->isOneOf(
2986 TT_ConditionalExpr, tok::l_paren, tok::comma, tok::colon, tok::semi,
2987 tok::equal, tok::question, tok::l_square, tok::l_brace,
2988 tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,
2989 tok::kw_delete, tok::kw_return, tok::kw_throw)) {
2990 return true;
2991 }
2992
2993 // We put sizeof here instead of only in determineStarAmpUsage. In the cases
2994 // where the unary `+` operator is overloaded, it is reasonable to write
2995 // things like `sizeof +x`. Like commit 446d6ec996c6c3.
2996 if (PrevToken->is(tok::kw_sizeof))
2997 return true;
2998
2999 // A sequence of leading unary operators.
3000 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
3001 return true;
3002
3003 // There can't be two consecutive binary operators.
3004 if (PrevToken->is(TT_BinaryOperator))
3005 return true;
3006
3007 return false;
3008 }
3009
3010 /// Return the type of the given token assuming it is * or &.
3011 TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,
3012 bool InTemplateArgument) {
3013 if (Style.isJavaScript())
3014 return TT_BinaryOperator;
3015
3016 // && in C# must be a binary operator.
3017 if (Style.isCSharp() && Tok.is(tok::ampamp))
3018 return TT_BinaryOperator;
3019
3020 if (Style.isVerilog()) {
3021 // In Verilog, `*` can only be a binary operator. `&` can be either unary
3022 // or binary. `*` also includes `*>` in module path declarations in
3023 // specify blocks because merged tokens take the type of the first one by
3024 // default.
3025 if (Tok.is(tok::star))
3026 return TT_BinaryOperator;
3027 return determineUnaryOperatorByUsage(Tok) ? TT_UnaryOperator
3028 : TT_BinaryOperator;
3029 }
3030
3031 const FormatToken *PrevToken = Tok.getPreviousNonComment();
3032 if (!PrevToken)
3033 return TT_UnaryOperator;
3034 if (PrevToken->isTypeName(LangOpts))
3035 return TT_PointerOrReference;
3036 if (PrevToken->isPlacementOperator() && Tok.is(tok::ampamp))
3037 return TT_BinaryOperator;
3038
3039 auto *NextToken = Tok.getNextNonComment();
3040 if (!NextToken)
3041 return TT_PointerOrReference;
3042 if (NextToken->is(tok::greater))
3043 return TT_PointerOrReference;
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 (CurrentPrecedence > prec::Conditional &&
3280 CurrentPrecedence < prec::PointerToMember) {
3281 // When BreakBinaryOperations is globally OnePerLine (no per-operator
3282 // rules), flatten all precedence levels so that every operator is
3283 // treated equally for line-breaking purposes. With per-operator rules
3284 // we must preserve natural precedence so that higher-precedence
3285 // sub-expressions (e.g. `x << 8` inside a `|` chain) stay grouped;
3286 // mustBreakBinaryOperation() handles the forced breaks instead.
3287 if (Style.BreakBinaryOperations.PerOperator.empty() &&
3288 Style.BreakBinaryOperations.Default ==
3289 FormatStyle::BBO_OnePerLine) {
3290 CurrentPrecedence = prec::Additive;
3291 }
3292 }
3293
3294 if (Precedence == CurrentPrecedence && Current &&
3295 Current->is(TT_SelectorName)) {
3296 if (LatestOperator)
3297 addFakeParenthesis(Start, prec::Level(Precedence));
3298 Start = Current;
3299 }
3300
3301 if ((Style.isCSharp() || Style.isJavaScript() || Style.isJava()) &&
3302 Precedence == prec::Additive && Current) {
3303 // A string can be broken without parentheses around it when it is
3304 // already in a sequence of strings joined by `+` signs.
3305 FormatToken *Prev = Current->getPreviousNonComment();
3306 if (Prev && Prev->is(tok::string_literal) &&
3307 (Prev == Start || Prev->endsSequence(tok::string_literal, tok::plus,
3308 TT_StringInConcatenation))) {
3309 Prev->setType(TT_StringInConcatenation);
3310 }
3311 }
3312
3313 // At the end of the line or when an operator with lower precedence is
3314 // found, insert fake parenthesis and return.
3315 if (!Current ||
3316 (Current->closesScope() &&
3317 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
3318 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
3319 (CurrentPrecedence == prec::Conditional &&
3320 Precedence == prec::Assignment && Current->is(tok::colon))) {
3321 break;
3322 }
3323
3324 // Consume scopes: (), [], <> and {}
3325 // In addition to that we handle require clauses as scope, so that the
3326 // constraints in that are correctly indented.
3327 if (Current->opensScope() ||
3328 Current->isOneOf(TT_RequiresClause,
3329 TT_RequiresClauseInARequiresExpression)) {
3330 // In fragment of a JavaScript template string can look like '}..${' and
3331 // thus close a scope and open a new one at the same time.
3332 while (Current && (!Current->closesScope() || Current->opensScope())) {
3333 next();
3334 parse();
3335 }
3336 next();
3337 } else {
3338 // Operator found.
3339 if (CurrentPrecedence == Precedence) {
3340 if (LatestOperator)
3341 LatestOperator->NextOperator = Current;
3342 LatestOperator = Current;
3343 Current->OperatorIndex = OperatorIndex;
3344 ++OperatorIndex;
3345 }
3346 next(/*SkipPastLeadingComments=*/Precedence > 0);
3347 }
3348 }
3349
3350 // Group variables of the same type.
3351 if (Style.isVerilog() && Precedence == prec::Comma && VerilogFirstOfType)
3352 addFakeParenthesis(VerilogFirstOfType, prec::Comma);
3353
3354 if (LatestOperator && (Current || Precedence > 0)) {
3355 // The requires clauses do not neccessarily end in a semicolon or a brace,
3356 // but just go over to struct/class or a function declaration, we need to
3357 // intervene so that the fake right paren is inserted correctly.
3358 auto End =
3359 (Start->Previous &&
3360 Start->Previous->isOneOf(TT_RequiresClause,
3361 TT_RequiresClauseInARequiresExpression))
3362 ? [this]() {
3363 auto Ret = Current ? Current : Line.Last;
3364 while (!Ret->ClosesRequiresClause && Ret->Previous)
3365 Ret = Ret->Previous;
3366 return Ret;
3367 }()
3368 : nullptr;
3369
3370 if (Precedence == PrecedenceArrowAndPeriod) {
3371 // Call expressions don't have a binary operator precedence.
3372 addFakeParenthesis(Start, prec::Unknown, End);
3373 } else {
3374 addFakeParenthesis(Start, prec::Level(Precedence), End);
3375 }
3376 }
3377 }
3378
3379private:
3380 /// Gets the precedence (+1) of the given token for binary operators
3381 /// and other tokens that we treat like binary operators.
3382 int getCurrentPrecedence() {
3383 if (Current) {
3384 const FormatToken *NextNonComment = Current->getNextNonComment();
3385 if (Current->is(TT_ConditionalExpr))
3386 return prec::Conditional;
3387 if (NextNonComment && Current->is(TT_SelectorName) &&
3388 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
3389 (Style.isProto() && NextNonComment->is(tok::less)))) {
3390 return prec::Assignment;
3391 }
3392 if (Current->is(TT_JsComputedPropertyName))
3393 return prec::Assignment;
3394 if (Current->is(TT_LambdaArrow))
3395 return prec::Comma;
3396 if (Current->is(TT_FatArrow))
3397 return prec::Assignment;
3398 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
3399 (Current->is(tok::comment) && NextNonComment &&
3400 NextNonComment->is(TT_SelectorName))) {
3401 return 0;
3402 }
3403 if (Current->is(TT_RangeBasedForLoopColon))
3404 return prec::Comma;
3405 if ((Style.isJava() || Style.isJavaScript()) &&
3406 Current->is(Keywords.kw_instanceof)) {
3407 return prec::Relational;
3408 }
3409 if (Style.isJavaScript() &&
3410 Current->isOneOf(Keywords.kw_in, Keywords.kw_as)) {
3411 return prec::Relational;
3412 }
3413 if (Current->isOneOf(TT_BinaryOperator, tok::comma))
3414 return Current->getPrecedence();
3415 if (Current->isOneOf(tok::period, tok::arrow) &&
3416 Current->isNot(TT_TrailingReturnArrow)) {
3417 return PrecedenceArrowAndPeriod;
3418 }
3419 if ((Style.isJava() || Style.isJavaScript()) &&
3420 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
3421 Keywords.kw_throws)) {
3422 return 0;
3423 }
3424 // In Verilog case labels are not on separate lines straight out of
3425 // UnwrappedLineParser. The colon is not part of an expression.
3426 if (Style.isVerilog() && Current->is(tok::colon))
3427 return 0;
3428 }
3429 return -1;
3430 }
3431
3432 void addFakeParenthesis(FormatToken *Start, prec::Level Precedence,
3433 FormatToken *End = nullptr) {
3434 // Do not assign fake parenthesis to tokens that are part of an
3435 // unexpanded macro call. The line within the macro call contains
3436 // the parenthesis and commas, and we will not find operators within
3437 // that structure.
3438 if (Start->MacroParent)
3439 return;
3440
3441 Start->FakeLParens.push_back(Precedence);
3442 if (Precedence > prec::Unknown)
3443 Start->StartsBinaryExpression = true;
3444 if (!End && Current)
3445 End = Current->getPreviousNonComment();
3446 if (End) {
3447 ++End->FakeRParens;
3448 if (Precedence > prec::Unknown)
3449 End->EndsBinaryExpression = true;
3450 }
3451 }
3452
3453 /// Parse unary operator expressions and surround them with fake
3454 /// parentheses if appropriate.
3455 void parseUnaryOperator() {
3456 SmallVector<FormatToken *, 2> Tokens;
3457 while (Current && Current->is(TT_UnaryOperator)) {
3458 Tokens.push_back(Current);
3459 next();
3460 }
3461 parse(PrecedenceArrowAndPeriod);
3462 for (FormatToken *Token : reverse(Tokens)) {
3463 // The actual precedence doesn't matter.
3464 addFakeParenthesis(Token, prec::Unknown);
3465 }
3466 }
3467
3468 void parseConditionalExpr() {
3469 while (Current && Current->isTrailingComment())
3470 next();
3471 FormatToken *Start = Current;
3472 parse(prec::LogicalOr);
3473 if (!Current || Current->isNot(tok::question))
3474 return;
3475 next();
3476 parse(prec::Assignment);
3477 if (!Current || Current->isNot(TT_ConditionalExpr))
3478 return;
3479 next();
3480 parse(prec::Assignment);
3481 addFakeParenthesis(Start, prec::Conditional);
3482 }
3483
3484 void next(bool SkipPastLeadingComments = true) {
3485 if (Current)
3486 Current = Current->Next;
3487 while (Current &&
3488 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
3489 Current->isTrailingComment()) {
3490 Current = Current->Next;
3491 }
3492 }
3493
3494 // Add fake parenthesis around declarations of the same type for example in a
3495 // module prototype. Return the first port / variable of the current type.
3496 FormatToken *verilogGroupDecl(FormatToken *FirstOfType,
3497 FormatToken *PreviousComma) {
3498 if (!Current)
3499 return nullptr;
3500
3501 FormatToken *Start = Current;
3502
3503 // Skip attributes.
3504 while (Start->startsSequence(tok::l_paren, tok::star)) {
3505 if (!(Start = Start->MatchingParen) ||
3506 !(Start = Start->getNextNonComment())) {
3507 return nullptr;
3508 }
3509 }
3510
3511 FormatToken *Tok = Start;
3512
3513 if (Tok->is(Keywords.kw_assign))
3514 Tok = Tok->getNextNonComment();
3515
3516 // Skip any type qualifiers to find the first identifier. It may be either a
3517 // new type name or a variable name. There can be several type qualifiers
3518 // preceding a variable name, and we can not tell them apart by looking at
3519 // the word alone since a macro can be defined as either a type qualifier or
3520 // a variable name. Thus we use the last word before the dimensions instead
3521 // of the first word as the candidate for the variable or type name.
3522 FormatToken *First = nullptr;
3523 while (Tok) {
3524 FormatToken *Next = Tok->getNextNonComment();
3525
3526 if (Tok->is(tok::hash)) {
3527 // Start of a macro expansion.
3528 First = Tok;
3529 Tok = Next;
3530 if (Tok)
3531 Tok = Tok->getNextNonComment();
3532 } else if (Tok->is(tok::hashhash)) {
3533 // Concatenation. Skip.
3534 Tok = Next;
3535 if (Tok)
3536 Tok = Tok->getNextNonComment();
3537 } else if (Keywords.isVerilogQualifier(*Tok) ||
3538 Keywords.isVerilogIdentifier(*Tok)) {
3539 First = Tok;
3540 Tok = Next;
3541 // The name may have dots like `interface_foo.modport_foo`.
3542 while (Tok && Tok->isOneOf(tok::period, tok::coloncolon) &&
3543 (Tok = Tok->getNextNonComment())) {
3544 if (Keywords.isVerilogIdentifier(*Tok))
3545 Tok = Tok->getNextNonComment();
3546 }
3547 } else if (!Next) {
3548 Tok = nullptr;
3549 } else if (Tok->is(tok::l_paren)) {
3550 // Make sure the parenthesized list is a drive strength. Otherwise the
3551 // statement may be a module instantiation in which case we have already
3552 // found the instance name.
3553 if (Next->isOneOf(
3554 Keywords.kw_highz0, Keywords.kw_highz1, Keywords.kw_large,
3555 Keywords.kw_medium, Keywords.kw_pull0, Keywords.kw_pull1,
3556 Keywords.kw_small, Keywords.kw_strong0, Keywords.kw_strong1,
3557 Keywords.kw_supply0, Keywords.kw_supply1, Keywords.kw_weak0,
3558 Keywords.kw_weak1)) {
3559 Tok->setType(TT_VerilogStrength);
3560 Tok = Tok->MatchingParen;
3561 if (Tok) {
3562 Tok->setType(TT_VerilogStrength);
3563 Tok = Tok->getNextNonComment();
3564 }
3565 } else {
3566 break;
3567 }
3568 } else if (Tok->is(Keywords.kw_verilogHash)) {
3569 // Delay control.
3570 if (Next->is(tok::l_paren))
3571 Next = Next->MatchingParen;
3572 if (Next)
3573 Tok = Next->getNextNonComment();
3574 } else {
3575 break;
3576 }
3577 }
3578
3579 // Find the second identifier. If it exists it will be the name.
3580 FormatToken *Second = nullptr;
3581 // Dimensions.
3582 while (Tok && Tok->is(tok::l_square) && (Tok = Tok->MatchingParen))
3583 Tok = Tok->getNextNonComment();
3584 if (Tok && (Tok->is(tok::hash) || Keywords.isVerilogIdentifier(*Tok)))
3585 Second = Tok;
3586
3587 // If the second identifier doesn't exist and there are qualifiers, the type
3588 // is implied.
3589 FormatToken *TypedName = nullptr;
3590 if (Second) {
3591 TypedName = Second;
3592 if (First && First->is(TT_Unknown))
3593 First->setType(TT_VerilogDimensionedTypeName);
3594 } else if (First != Start) {
3595 // If 'First' is null, then this isn't a declaration, 'TypedName' gets set
3596 // to null as intended.
3597 TypedName = First;
3598 }
3599
3600 if (TypedName) {
3601 // This is a declaration with a new type.
3602 if (TypedName->is(TT_Unknown))
3603 TypedName->setType(TT_StartOfName);
3604 // Group variables of the previous type.
3605 if (FirstOfType && PreviousComma) {
3606 PreviousComma->setType(TT_VerilogTypeComma);
3607 addFakeParenthesis(FirstOfType, prec::Comma, PreviousComma->Previous);
3608 }
3609
3610 FirstOfType = TypedName;
3611
3612 // Don't let higher precedence handle the qualifiers. For example if we
3613 // have:
3614 // parameter x = 0
3615 // We skip `parameter` here. This way the fake parentheses for the
3616 // assignment will be around `x = 0`.
3617 while (Current && Current != FirstOfType) {
3618 if (Current->opensScope()) {
3619 next();
3620 parse();
3621 }
3622 next();
3623 }
3624 }
3625
3626 return FirstOfType;
3627 }
3628
3629 const FormatStyle &Style;
3630 const AdditionalKeywords &Keywords;
3631 const AnnotatedLine &Line;
3632 FormatToken *Current;
3633};
3634
3635} // end anonymous namespace
3636
3638 SmallVectorImpl<AnnotatedLine *> &Lines) const {
3639 const AnnotatedLine *NextNonCommentLine = nullptr;
3640 for (AnnotatedLine *Line : reverse(Lines)) {
3641 assert(Line->First);
3642
3643 // If the comment is currently aligned with the line immediately following
3644 // it, that's probably intentional and we should keep it.
3645 if (NextNonCommentLine && NextNonCommentLine->First->NewlinesBefore < 2 &&
3646 Line->isComment() && !isClangFormatOff(Line->First->TokenText) &&
3647 NextNonCommentLine->First->OriginalColumn ==
3648 Line->First->OriginalColumn) {
3649 const bool PPDirectiveOrImportStmt =
3650 NextNonCommentLine->Type == LT_PreprocessorDirective ||
3651 NextNonCommentLine->Type == LT_ImportStatement;
3652 if (PPDirectiveOrImportStmt)
3654 // Align comments for preprocessor lines with the # in column 0 if
3655 // preprocessor lines are not indented. Otherwise, align with the next
3656 // line.
3657 Line->Level = Style.IndentPPDirectives < FormatStyle::PPDIS_BeforeHash &&
3658 PPDirectiveOrImportStmt
3659 ? 0
3660 : NextNonCommentLine->Level;
3661 } else {
3662 NextNonCommentLine = Line->First->isNot(tok::r_brace) ? Line : nullptr;
3663 }
3664
3665 setCommentLineLevels(Line->Children);
3666 }
3667}
3668
3669static unsigned maxNestingDepth(const AnnotatedLine &Line) {
3670 unsigned Result = 0;
3671 for (const auto *Tok = Line.First; Tok; Tok = Tok->Next)
3672 Result = std::max(Result, Tok->NestingLevel);
3673 return Result;
3674}
3675
3676// Returns the token after the first qualifier of the name, or nullptr if there
3677// is no qualifier.
3679 assert(Tok);
3680
3681 // Qualified names must start with an identifier.
3682 if (Tok->isNot(tok::identifier))
3683 return nullptr;
3684
3685 Tok = Tok->getNextNonComment();
3686 if (!Tok)
3687 return nullptr;
3688
3689 // Consider: A::B::B()
3690 // Tok --^
3691 if (Tok->is(tok::coloncolon))
3692 return Tok->getNextNonComment();
3693
3694 // Consider: A<float>::B<int>::B()
3695 // Tok --^
3696 if (Tok->is(TT_TemplateOpener)) {
3697 Tok = Tok->MatchingParen;
3698 if (!Tok)
3699 return nullptr;
3700
3701 Tok = Tok->getNextNonComment();
3702 if (!Tok)
3703 return nullptr;
3704 }
3705
3706 return Tok->is(tok::coloncolon) ? Tok->getNextNonComment() : nullptr;
3707}
3708
3709// Returns the name of a function with no return type, e.g. a constructor or
3710// destructor.
3712 FormatToken *&OpeningParen) {
3713 for (FormatToken *Tok = Line.getFirstNonComment(), *Name = nullptr; Tok;
3714 Tok = Tok->getNextNonComment()) {
3715 // Skip C++11 attributes both before and after the function name.
3716 if (Tok->is(TT_AttributeLSquare)) {
3717 Tok = Tok->MatchingParen;
3718 if (!Tok)
3719 return nullptr;
3720 continue;
3721 }
3722
3723 // Make sure the name is followed by a pair of parentheses.
3724 if (Name) {
3725 if (Tok->is(tok::l_paren) && Tok->is(TT_Unknown) && Tok->MatchingParen) {
3726 OpeningParen = Tok;
3727 return Name;
3728 }
3729 return nullptr;
3730 }
3731
3732 // Skip keywords that may precede the constructor/destructor name.
3733 if (Tok->isOneOf(tok::kw_friend, tok::kw_inline, tok::kw_virtual,
3734 tok::kw_constexpr, tok::kw_consteval, tok::kw_explicit)) {
3735 continue;
3736 }
3737
3738 // Skip past template typename declarations that may precede the
3739 // constructor/destructor name.
3740 if (Tok->is(tok::kw_template)) {
3741 Tok = Tok->getNextNonComment();
3742 if (!Tok)
3743 return nullptr;
3744
3745 // If the next token after the template keyword is not an opening bracket,
3746 // it is a template instantiation, and not a function.
3747 if (Tok->isNot(TT_TemplateOpener))
3748 return nullptr;
3749
3750 Tok = Tok->MatchingParen;
3751 if (!Tok)
3752 return nullptr;
3753
3754 continue;
3755 }
3756
3757 // A qualified name may start from the global namespace.
3758 if (Tok->is(tok::coloncolon)) {
3759 Tok = Tok->Next;
3760 if (!Tok)
3761 return nullptr;
3762 }
3763
3764 // Skip to the unqualified part of the name.
3765 while (auto *Next = skipNameQualifier(Tok))
3766 Tok = Next;
3767
3768 // Skip the `~` if a destructor name.
3769 if (Tok->is(tok::tilde)) {
3770 Tok = Tok->Next;
3771 if (!Tok)
3772 return nullptr;
3773 }
3774
3775 // Make sure the name is not already annotated, e.g. as NamespaceMacro.
3776 if (Tok->isNot(tok::identifier) || Tok->isNot(TT_Unknown))
3777 return nullptr;
3778
3779 Name = Tok;
3780 }
3781
3782 return nullptr;
3783}
3784
3785// Checks if Tok is a constructor/destructor name qualified by its class name.
3786static bool isCtorOrDtorName(const FormatToken *Tok) {
3787 assert(Tok && Tok->is(tok::identifier));
3788 const auto *Prev = Tok->Previous;
3789
3790 if (Prev && Prev->is(tok::tilde))
3791 Prev = Prev->Previous;
3792
3793 // Consider: A::A() and A<int>::A()
3794 if (!Prev || (!Prev->endsSequence(tok::coloncolon, tok::identifier) &&
3795 !Prev->endsSequence(tok::coloncolon, TT_TemplateCloser))) {
3796 return false;
3797 }
3798
3799 assert(Prev->Previous);
3800 if (Prev->Previous->is(TT_TemplateCloser) && Prev->Previous->MatchingParen) {
3801 Prev = Prev->Previous->MatchingParen;
3802 assert(Prev->Previous);
3803 }
3804
3805 return Prev->Previous->TokenText == Tok->TokenText;
3806}
3807
3809 if (!Line.InMacroBody)
3810 MacroBodyScopes.clear();
3811
3812 auto &ScopeStack = Line.InMacroBody ? MacroBodyScopes : Scopes;
3813 AnnotatingParser Parser(Style, Line, Keywords, ScopeStack);
3814 Line.Type = Parser.parseLine();
3815
3816 if (!Line.Children.empty()) {
3817 ScopeStack.push_back(ST_Other);
3818 const bool InRequiresExpression = Line.Type == LT_RequiresExpression;
3819 for (auto &Child : Line.Children) {
3820 if (InRequiresExpression &&
3821 Child->First->isNoneOf(tok::kw_typename, tok::kw_requires,
3822 TT_CompoundRequirementLBrace)) {
3823 Child->Type = LT_SimpleRequirement;
3824 }
3825 annotate(*Child);
3826 }
3827 // ScopeStack can become empty if Child has an unmatched `}`.
3828 if (!ScopeStack.empty())
3829 ScopeStack.pop_back();
3830 }
3831
3832 // With very deep nesting, ExpressionParser uses lots of stack and the
3833 // formatting algorithm is very slow. We're not going to do a good job here
3834 // anyway - it's probably generated code being formatted by mistake.
3835 // Just skip the whole line.
3836 if (maxNestingDepth(Line) > 50)
3837 Line.Type = LT_Invalid;
3838
3839 if (Line.Type == LT_Invalid)
3840 return;
3841
3842 ExpressionParser ExprParser(Style, Keywords, Line);
3843 ExprParser.parse();
3844
3845 if (IsCpp) {
3846 FormatToken *OpeningParen = nullptr;
3847 auto *Tok = getFunctionName(Line, OpeningParen);
3848 if (Tok && ((!ScopeStack.empty() && ScopeStack.back() == ST_Class) ||
3849 Line.endsWith(TT_FunctionLBrace) || isCtorOrDtorName(Tok))) {
3850 Tok->setFinalizedType(TT_CtorDtorDeclName);
3851 assert(OpeningParen);
3852 OpeningParen->setFinalizedType(TT_FunctionDeclarationLParen);
3853 }
3854 }
3855
3856 if (Line.startsWith(TT_ObjCMethodSpecifier))
3857 Line.Type = LT_ObjCMethodDecl;
3858 else if (Line.startsWith(TT_ObjCDecl))
3859 Line.Type = LT_ObjCDecl;
3860 else if (Line.startsWith(TT_ObjCProperty))
3861 Line.Type = LT_ObjCProperty;
3862
3863 auto *First = Line.First;
3864 First->SpacesRequiredBefore = 1;
3865 First->CanBreakBefore = First->MustBreakBefore;
3866}
3867
3868// This function heuristically determines whether 'Current' starts the name of a
3869// function declaration.
3870static bool isFunctionDeclarationName(const LangOptions &LangOpts,
3871 const FormatToken &Current,
3872 const AnnotatedLine &Line,
3873 FormatToken *&ClosingParen) {
3874 if (Current.is(TT_FunctionDeclarationName))
3875 return true;
3876
3877 if (Current.isNoneOf(tok::identifier, tok::kw_operator))
3878 return false;
3879
3880 const auto *Prev = Current.getPreviousNonComment();
3881 assert(Prev);
3882
3883 const auto &Previous = *Prev;
3884
3885 if (const auto *PrevPrev = Previous.getPreviousNonComment();
3886 PrevPrev && PrevPrev->is(TT_ObjCDecl)) {
3887 return false;
3888 }
3889
3890 auto skipOperatorName =
3891 [&LangOpts](const FormatToken *Next) -> const FormatToken * {
3892 for (; Next; Next = Next->Next) {
3893 if (Next->is(TT_OverloadedOperatorLParen))
3894 return Next;
3895 if (Next->is(TT_OverloadedOperator))
3896 continue;
3897 if (Next->isPlacementOperator() || Next->is(tok::kw_co_await)) {
3898 // For 'new[]' and 'delete[]'.
3899 if (Next->Next &&
3900 Next->Next->startsSequence(tok::l_square, tok::r_square)) {
3901 Next = Next->Next->Next;
3902 }
3903 continue;
3904 }
3905 if (Next->startsSequence(tok::l_square, tok::r_square)) {
3906 // For operator[]().
3907 Next = Next->Next;
3908 continue;
3909 }
3910 if ((Next->isTypeName(LangOpts) || Next->is(tok::identifier)) &&
3911 Next->Next && Next->Next->isPointerOrReference()) {
3912 // For operator void*(), operator char*(), operator Foo*().
3913 Next = Next->Next;
3914 continue;
3915 }
3916 if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
3917 Next = Next->MatchingParen;
3918 continue;
3919 }
3920
3921 break;
3922 }
3923 return nullptr;
3924 };
3925
3926 const auto *Next = Current.Next;
3927 const bool IsCpp = LangOpts.CXXOperatorNames || LangOpts.C11;
3928
3929 // Find parentheses of parameter list.
3930 if (Current.is(tok::kw_operator)) {
3931 if (Line.startsWith(tok::kw_friend))
3932 return true;
3933 if (Previous.Tok.getIdentifierInfo() &&
3934 Previous.isNoneOf(tok::kw_return, tok::kw_co_return)) {
3935 return true;
3936 }
3937 if (Previous.is(tok::r_paren) && Previous.is(TT_TypeDeclarationParen)) {
3938 assert(Previous.MatchingParen);
3939 assert(Previous.MatchingParen->is(tok::l_paren));
3940 assert(Previous.MatchingParen->is(TT_TypeDeclarationParen));
3941 return true;
3942 }
3943 if (!Previous.isPointerOrReference() && Previous.isNot(TT_TemplateCloser))
3944 return false;
3945 Next = skipOperatorName(Next);
3946 } else {
3947 if (Current.isNot(TT_StartOfName) || Current.NestingLevel != 0)
3948 return false;
3949 while (Next && Next->startsSequence(tok::hashhash, tok::identifier))
3950 Next = Next->Next->Next;
3951 for (; Next; Next = Next->Next) {
3952 if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
3953 Next = Next->MatchingParen;
3954 } else if (Next->is(tok::coloncolon)) {
3955 Next = Next->Next;
3956 if (!Next)
3957 return false;
3958 if (Next->is(tok::kw_operator)) {
3959 Next = skipOperatorName(Next->Next);
3960 break;
3961 }
3962 if (Next->isNot(tok::identifier))
3963 return false;
3964 } else if (isCppAttribute(IsCpp, *Next)) {
3965 Next = Next->MatchingParen;
3966 if (!Next)
3967 return false;
3968 } else if (Next->is(tok::l_paren)) {
3969 break;
3970 } else {
3971 return false;
3972 }
3973 }
3974 }
3975
3976 // Check whether parameter list can belong to a function declaration.
3977 if (!Next || Next->isNot(tok::l_paren) || !Next->MatchingParen)
3978 return false;
3979 ClosingParen = Next->MatchingParen;
3980 assert(ClosingParen->is(tok::r_paren));
3981 // If the lines ends with "{", this is likely a function definition.
3982 if (Line.Last->is(tok::l_brace))
3983 return true;
3984 if (Next->Next == ClosingParen)
3985 return true; // Empty parentheses.
3986 // If there is an &/&& after the r_paren, this is likely a function.
3987 if (ClosingParen->Next && ClosingParen->Next->is(TT_PointerOrReference))
3988 return true;
3989
3990 // Check for K&R C function definitions (and C++ function definitions with
3991 // unnamed parameters), e.g.:
3992 // int f(i)
3993 // {
3994 // return i + 1;
3995 // }
3996 // bool g(size_t = 0, bool b = false)
3997 // {
3998 // return !b;
3999 // }
4000 if (IsCpp && Next->Next && Next->Next->is(tok::identifier) &&
4001 !Line.endsWith(tok::semi)) {
4002 return true;
4003 }
4004
4005 for (const FormatToken *Tok = Next->Next; Tok && Tok != ClosingParen;
4006 Tok = Tok->Next) {
4007 if (Tok->is(TT_TypeDeclarationParen))
4008 return true;
4009 if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) {
4010 Tok = Tok->MatchingParen;
4011 continue;
4012 }
4013 if (Tok->is(tok::kw_const) || Tok->isTypeName(LangOpts) ||
4014 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
4015 return true;
4016 }
4017 if (Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) || Tok->Tok.isLiteral())
4018 return false;
4019 }
4020 return false;
4021}
4022
4023bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const {
4024 assert(Line.MightBeFunctionDecl);
4025
4026 if ((Style.BreakAfterReturnType == FormatStyle::RTBS_TopLevel ||
4027 Style.BreakAfterReturnType == FormatStyle::RTBS_TopLevelDefinitions) &&
4028 Line.Level > 0) {
4029 return false;
4030 }
4031
4032 switch (Style.BreakAfterReturnType) {
4033 case FormatStyle::RTBS_None:
4034 case FormatStyle::RTBS_Automatic:
4035 case FormatStyle::RTBS_ExceptShortType:
4036 return false;
4037 case FormatStyle::RTBS_All:
4038 case FormatStyle::RTBS_TopLevel:
4039 return true;
4040 case FormatStyle::RTBS_AllDefinitions:
4041 case FormatStyle::RTBS_TopLevelDefinitions:
4042 return Line.mightBeFunctionDefinition();
4043 }
4044
4045 return false;
4046}
4047
4049 if (Line.Computed)
4050 return;
4051
4052 Line.Computed = true;
4053
4054 for (AnnotatedLine *ChildLine : Line.Children)
4056
4057 auto *First = Line.First;
4058 First->TotalLength = First->IsMultiline
4059 ? Style.ColumnLimit
4060 : Line.FirstStartColumn + First->ColumnWidth;
4061 bool AlignArrayOfStructures =
4062 (Style.AlignArrayOfStructures != FormatStyle::AIAS_None &&
4064 if (AlignArrayOfStructures)
4065 calculateArrayInitializerColumnList(Line);
4066
4067 const auto *FirstNonComment = Line.getFirstNonComment();
4068 bool SeenName = false;
4069 bool LineIsFunctionDeclaration = false;
4070 FormatToken *AfterLastAttribute = nullptr;
4071 FormatToken *ClosingParen = nullptr;
4072
4073 for (auto *Tok = FirstNonComment && FirstNonComment->isNot(tok::kw_using)
4074 ? FirstNonComment->Next
4075 : nullptr;
4076 Tok && Tok->isNot(BK_BracedInit); Tok = Tok->Next) {
4077 if (Tok->is(TT_StartOfName))
4078 SeenName = true;
4079 if (Tok->Previous->EndsCppAttributeGroup)
4080 AfterLastAttribute = Tok;
4081 if (const bool IsCtorOrDtor = Tok->is(TT_CtorDtorDeclName);
4082 IsCtorOrDtor ||
4083 isFunctionDeclarationName(LangOpts, *Tok, Line, ClosingParen)) {
4084 if (!IsCtorOrDtor)
4085 Tok->setFinalizedType(TT_FunctionDeclarationName);
4086 LineIsFunctionDeclaration = true;
4087 SeenName = true;
4088 if (ClosingParen) {
4089 auto *OpeningParen = ClosingParen->MatchingParen;
4090 assert(OpeningParen);
4091 if (OpeningParen->is(TT_Unknown))
4092 OpeningParen->setType(TT_FunctionDeclarationLParen);
4093 }
4094 break;
4095 }
4096 }
4097
4098 if (IsCpp) {
4099 if ((LineIsFunctionDeclaration ||
4100 (FirstNonComment && FirstNonComment->is(TT_CtorDtorDeclName))) &&
4101 Line.endsWith(tok::semi, tok::r_brace)) {
4102 auto *Tok = Line.Last->Previous;
4103 while (Tok->isNot(tok::r_brace))
4104 Tok = Tok->Previous;
4105 if (auto *LBrace = Tok->MatchingParen; LBrace && LBrace->is(TT_Unknown)) {
4106 assert(LBrace->is(tok::l_brace));
4107 Tok->setBlockKind(BK_Block);
4108 LBrace->setBlockKind(BK_Block);
4109 LBrace->setFinalizedType(TT_FunctionLBrace);
4110 }
4111 }
4112
4113 if (SeenName && AfterLastAttribute &&
4114 mustBreakAfterAttributes(*AfterLastAttribute, Style)) {
4115 AfterLastAttribute->MustBreakBefore = true;
4116 if (LineIsFunctionDeclaration)
4117 Line.ReturnTypeWrapped = true;
4118 }
4119
4120 if (!LineIsFunctionDeclaration) {
4121 // Annotate */&/&& in `operator` function calls as binary operators.
4122 for (const auto *Tok = FirstNonComment; Tok; Tok = Tok->Next) {
4123 if (Tok->isNot(tok::kw_operator))
4124 continue;
4125 do {
4126 Tok = Tok->Next;
4127 } while (Tok && Tok->isNot(TT_OverloadedOperatorLParen));
4128 if (!Tok || !Tok->MatchingParen)
4129 break;
4130 const auto *LeftParen = Tok;
4131 for (Tok = Tok->Next; Tok && Tok != LeftParen->MatchingParen;
4132 Tok = Tok->Next) {
4133 if (Tok->isNot(tok::identifier))
4134 continue;
4135 auto *Next = Tok->Next;
4136 const bool NextIsBinaryOperator =
4137 Next && Next->isPointerOrReference() && Next->Next &&
4138 Next->Next->is(tok::identifier);
4139 if (!NextIsBinaryOperator)
4140 continue;
4141 Next->setType(TT_BinaryOperator);
4142 Tok = Next;
4143 }
4144 }
4145 } else if (ClosingParen) {
4146 for (auto *Tok = ClosingParen->Next; Tok; Tok = Tok->Next) {
4147 if (Tok->is(TT_CtorInitializerColon))
4148 break;
4149 if (Tok->is(tok::arrow)) {
4150 Tok->setType(TT_TrailingReturnArrow);
4151 break;
4152 }
4153 if (Tok->isNot(TT_TrailingAnnotation))
4154 continue;
4155 const auto *Next = Tok->Next;
4156 if (!Next || Next->isNot(tok::l_paren))
4157 continue;
4158 Tok = Next->MatchingParen;
4159 if (!Tok)
4160 break;
4161 }
4162 }
4163 }
4164
4165 if (First->is(TT_ElseLBrace)) {
4166 First->CanBreakBefore = true;
4167 First->MustBreakBefore = true;
4168 }
4169
4170 bool InFunctionDecl = Line.MightBeFunctionDecl;
4171 bool InParameterList = false;
4172 for (auto *Current = First->Next; Current; Current = Current->Next) {
4173 const FormatToken *Prev = Current->Previous;
4174 if (Current->is(TT_LineComment)) {
4175 if (Prev->is(BK_BracedInit) && Prev->opensScope()) {
4176 Current->SpacesRequiredBefore =
4177 (Style.Cpp11BracedListStyle == FormatStyle::BLS_AlignFirstComment &&
4178 !Style.SpacesInParensOptions.Other)
4179 ? 0
4180 : 1;
4181 } else if (Prev->is(TT_VerilogMultiLineListLParen)) {
4182 Current->SpacesRequiredBefore = 0;
4183 } else {
4184 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
4185 }
4186
4187 // If we find a trailing comment, iterate backwards to determine whether
4188 // it seems to relate to a specific parameter. If so, break before that
4189 // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
4190 // to the previous line in:
4191 // SomeFunction(a,
4192 // b, // comment
4193 // c);
4194 if (!Current->HasUnescapedNewline) {
4195 for (FormatToken *Parameter = Current->Previous; Parameter;
4196 Parameter = Parameter->Previous) {
4197 if (Parameter->isOneOf(tok::comment, tok::r_brace))
4198 break;
4199 if (Parameter->Previous && Parameter->Previous->is(tok::comma)) {
4200 if (Parameter->Previous->isNot(TT_CtorInitializerComma) &&
4201 Parameter->HasUnescapedNewline) {
4202 Parameter->MustBreakBefore = true;
4203 }
4204 break;
4205 }
4206 }
4207 }
4208 } else if (!Current->Finalized && Current->SpacesRequiredBefore == 0 &&
4209 spaceRequiredBefore(Line, *Current)) {
4210 Current->SpacesRequiredBefore = 1;
4211 }
4212
4213 const auto &Children = Prev->Children;
4214 if (!Children.empty() && Children.back()->Last->is(TT_LineComment)) {
4215 Current->MustBreakBefore = true;
4216 } else {
4217 Current->MustBreakBefore =
4218 Current->MustBreakBefore || mustBreakBefore(Line, *Current);
4219 if (!Current->MustBreakBefore && InFunctionDecl &&
4220 Current->is(TT_FunctionDeclarationName)) {
4221 Current->MustBreakBefore = mustBreakForReturnType(Line);
4222 }
4223 }
4224
4225 Current->CanBreakBefore =
4226 Current->MustBreakBefore || canBreakBefore(Line, *Current);
4227
4228 if (Current->is(TT_FunctionDeclarationLParen)) {
4229 InParameterList = true;
4230 } else if (Current->is(tok::r_paren)) {
4231 const auto *LParen = Current->MatchingParen;
4232 if (LParen && LParen->is(TT_FunctionDeclarationLParen))
4233 InParameterList = false;
4234 } else if (InParameterList &&
4235 Current->endsSequence(TT_AttributeMacro,
4236 TT_PointerOrReference)) {
4237 Current->CanBreakBefore = false;
4238 }
4239
4240 unsigned ChildSize = 0;
4241 if (Prev->Children.size() == 1) {
4242 FormatToken &LastOfChild = *Prev->Children[0]->Last;
4243 ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit
4244 : LastOfChild.TotalLength + 1;
4245 }
4246 if (Current->MustBreakBefore || Prev->Children.size() > 1 ||
4247 (Prev->Children.size() == 1 &&
4248 Prev->Children[0]->First->MustBreakBefore) ||
4249 Current->IsMultiline) {
4250 Current->TotalLength = Prev->TotalLength + Style.ColumnLimit;
4251 } else {
4252 Current->TotalLength = Prev->TotalLength + Current->ColumnWidth +
4253 ChildSize + Current->SpacesRequiredBefore;
4254 }
4255
4256 if (Current->is(TT_ControlStatementLBrace)) {
4257 if (Style.ColumnLimit > 0 &&
4258 Style.BraceWrapping.AfterControlStatement ==
4259 FormatStyle::BWACS_MultiLine &&
4260 Line.Level * Style.IndentWidth + Line.Last->TotalLength >
4261 Style.ColumnLimit) {
4262 Current->CanBreakBefore = true;
4263 Current->MustBreakBefore = true;
4264 }
4265 } else if (Current->is(TT_CtorInitializerColon)) {
4266 InFunctionDecl = false;
4267 }
4268
4269 // FIXME: Only calculate this if CanBreakBefore is true once static
4270 // initializers etc. are sorted out.
4271 // FIXME: Move magic numbers to a better place.
4272
4273 // Reduce penalty for aligning ObjC method arguments using the colon
4274 // alignment as this is the canonical way (still prefer fitting everything
4275 // into one line if possible). Trying to fit a whole expression into one
4276 // line should not force other line breaks (e.g. when ObjC method
4277 // expression is a part of other expression).
4278 Current->SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
4279 if (Style.Language == FormatStyle::LK_ObjC &&
4280 Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {
4281 if (Current->ParameterIndex == 1)
4282 Current->SplitPenalty += 5 * Current->BindingStrength;
4283 } else {
4284 Current->SplitPenalty += 20 * Current->BindingStrength;
4285 }
4286 }
4287
4288 calculateUnbreakableTailLengths(Line);
4289 unsigned IndentLevel = Line.Level;
4290 for (auto *Current = First; Current; Current = Current->Next) {
4291 if (Current->Role)
4292 Current->Role->precomputeFormattingInfos(Current);
4293 if (Current->MatchingParen &&
4294 Current->MatchingParen->opensBlockOrBlockTypeList(Style) &&
4295 IndentLevel > 0) {
4296 --IndentLevel;
4297 }
4298 Current->IndentLevel = IndentLevel;
4299 if (Current->opensBlockOrBlockTypeList(Style))
4300 ++IndentLevel;
4301 }
4302
4303 LLVM_DEBUG({ printDebugInfo(Line); });
4304}
4305
4306void TokenAnnotator::calculateUnbreakableTailLengths(
4307 AnnotatedLine &Line) const {
4308 unsigned UnbreakableTailLength = 0;
4309 FormatToken *Current = Line.Last;
4310 while (Current) {
4312 if (Current->CanBreakBefore ||
4313 Current->isOneOf(tok::comment, tok::string_literal)) {
4315 } else {
4317 Current->ColumnWidth + Current->SpacesRequiredBefore;
4318 }
4319 Current = Current->Previous;
4320 }
4321}
4322
4323void TokenAnnotator::calculateArrayInitializerColumnList(
4324 AnnotatedLine &Line) const {
4325 if (Line.First == Line.Last)
4326 return;
4327 auto *CurrentToken = Line.First;
4328 CurrentToken->ArrayInitializerLineStart = true;
4329 unsigned Depth = 0;
4330 while (CurrentToken && CurrentToken != Line.Last) {
4331 if (CurrentToken->is(tok::l_brace)) {
4332 CurrentToken->IsArrayInitializer = true;
4333 if (CurrentToken->Next)
4334 CurrentToken->Next->MustBreakBefore = true;
4335 CurrentToken =
4336 calculateInitializerColumnList(Line, CurrentToken->Next, Depth + 1);
4337 } else {
4338 CurrentToken = CurrentToken->Next;
4339 }
4340 }
4341}
4342
4343FormatToken *TokenAnnotator::calculateInitializerColumnList(
4344 AnnotatedLine &Line, FormatToken *CurrentToken, unsigned Depth) const {
4345 while (CurrentToken && CurrentToken != Line.Last) {
4346 if (CurrentToken->is(tok::l_brace))
4347 ++Depth;
4348 else if (CurrentToken->is(tok::r_brace))
4349 --Depth;
4350 if (Depth == 2 && CurrentToken->isOneOf(tok::l_brace, tok::comma)) {
4351 CurrentToken = CurrentToken->Next;
4352 if (!CurrentToken)
4353 break;
4354 CurrentToken->StartsColumn = true;
4355 CurrentToken = CurrentToken->Previous;
4356 }
4357 CurrentToken = CurrentToken->Next;
4358 }
4359 return CurrentToken;
4360}
4361
4362unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
4363 const FormatToken &Tok,
4364 bool InFunctionDecl) const {
4365 const FormatToken &Left = *Tok.Previous;
4366 const FormatToken &Right = Tok;
4367
4368 if (Left.is(tok::semi))
4369 return 0;
4370
4371 // Language specific handling.
4372 if (Style.isJava()) {
4373 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
4374 return 1;
4375 if (Right.is(Keywords.kw_implements))
4376 return 2;
4377 if (Left.is(tok::comma) && Left.NestingLevel == 0)
4378 return 3;
4379 } else if (Style.isJavaScript()) {
4380 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))
4381 return 100;
4382 if (Left.is(TT_JsTypeColon))
4383 return 35;
4384 if ((Left.is(TT_TemplateString) && Left.TokenText.ends_with("${")) ||
4385 (Right.is(TT_TemplateString) && Right.TokenText.starts_with("}"))) {
4386 return 100;
4387 }
4388 // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()".
4389 if (Left.opensScope() && Right.closesScope())
4390 return 200;
4391 } else if (Style.Language == FormatStyle::LK_Proto) {
4392 if (Right.is(tok::l_square))
4393 return 1;
4394 if (Right.is(tok::period))
4395 return 500;
4396 }
4397
4398 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
4399 return 1;
4400 if (Right.is(tok::l_square)) {
4401 if (Left.is(tok::r_square))
4402 return 200;
4403 // Slightly prefer formatting local lambda definitions like functions.
4404 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
4405 return 35;
4406 if (Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
4407 TT_ArrayInitializerLSquare,
4408 TT_DesignatedInitializerLSquare, TT_AttributeLSquare)) {
4409 return 500;
4410 }
4411 }
4412
4413 if (Left.is(tok::coloncolon))
4414 return Style.PenaltyBreakScopeResolution;
4415 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
4416 tok::kw_operator)) {
4417 if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
4418 return 3;
4419 if (Left.is(TT_StartOfName))
4420 return 110;
4421 if (InFunctionDecl && Right.NestingLevel == 0)
4422 return Style.PenaltyReturnTypeOnItsOwnLine;
4423 return 200;
4424 }
4425 if (Right.is(TT_PointerOrReference))
4426 return 190;
4427 if (Right.is(TT_LambdaArrow))
4428 return 110;
4429 if (Left.is(tok::equal) && Right.is(tok::l_brace))
4430 return 160;
4431 if (Left.is(TT_CastRParen))
4432 return 100;
4433 if (Left.isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union))
4434 return 5000;
4435 if (Left.is(tok::comment))
4436 return 1000;
4437
4438 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
4439 TT_CtorInitializerColon)) {
4440 return 2;
4441 }
4442
4443 if (Right.isMemberAccess()) {
4444 // Breaking before the "./->" of a chained call/member access is reasonably
4445 // cheap, as formatting those with one call per line is generally
4446 // desirable. In particular, it should be cheaper to break before the call
4447 // than it is to break inside a call's parameters, which could lead to weird
4448 // "hanging" indents. The exception is the very last "./->" to support this
4449 // frequent pattern:
4450 //
4451 // aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc(
4452 // dddddddd);
4453 //
4454 // which might otherwise be blown up onto many lines. Here, clang-format
4455 // won't produce "hanging" indents anyway as there is no other trailing
4456 // call.
4457 //
4458 // Also apply higher penalty is not a call as that might lead to a wrapping
4459 // like:
4460 //
4461 // aaaaaaa
4462 // .aaaaaaaaa.bbbbbbbb(cccccccc);
4463 const auto *NextOperator = Right.NextOperator;
4464 const auto Penalty = Style.PenaltyBreakBeforeMemberAccess;
4465 return NextOperator && NextOperator->Previous->closesScope()
4466 ? std::min(Penalty, 35u)
4467 : Penalty;
4468 }
4469
4470 if (Right.is(TT_TrailingAnnotation) &&
4471 (!Right.Next || Right.Next->isNot(tok::l_paren))) {
4472 // Moving trailing annotations to the next line is fine for ObjC method
4473 // declarations.
4474 if (Line.startsWith(TT_ObjCMethodSpecifier))
4475 return 10;
4476 // Generally, breaking before a trailing annotation is bad unless it is
4477 // function-like. It seems to be especially preferable to keep standard
4478 // annotations (i.e. "const", "final" and "override") on the same line.
4479 // Use a slightly higher penalty after ")" so that annotations like
4480 // "const override" are kept together.
4481 bool is_short_annotation = Right.TokenText.size() < 10;
4482 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
4483 }
4484
4485 // In for-loops, prefer breaking at ',' and ';'.
4486 if (Line.startsWith(tok::kw_for) && Left.is(tok::equal))
4487 return 4;
4488
4489 // In Objective-C method expressions, prefer breaking before "param:" over
4490 // breaking after it.
4491 if (Right.is(TT_SelectorName))
4492 return 0;
4493 if (Left.is(tok::colon)) {
4494 if (Left.is(TT_ObjCMethodExpr))
4495 return Line.MightBeFunctionDecl ? 50 : 500;
4496 if (Left.is(TT_ObjCSelector))
4497 return 500;
4498 }
4499
4500 // In Objective-C type declarations, avoid breaking after the category's
4501 // open paren (we'll prefer breaking after the protocol list's opening
4502 // angle bracket, if present).
4503 if (Line.Type == LT_ObjCDecl && Left.is(tok::l_paren) && Left.Previous &&
4504 Left.Previous->isOneOf(tok::identifier, tok::greater)) {
4505 return 500;
4506 }
4507
4508 if (Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0)
4509 return Style.PenaltyBreakOpenParenthesis;
4510 if (Left.is(tok::l_paren) && InFunctionDecl && Style.AlignAfterOpenBracket)
4511 return 100;
4512 if (Left.is(tok::l_paren) && Left.Previous &&
4513 (Left.Previous->isOneOf(tok::kw_for, tok::kw__Generic) ||
4514 Left.Previous->isIf())) {
4515 return 1000;
4516 }
4517 if (Left.is(tok::equal) && InFunctionDecl)
4518 return 110;
4519 if (Right.is(tok::r_brace))
4520 return 1;
4521 if (Left.is(TT_TemplateOpener))
4522 return 100;
4523 if (Left.opensScope()) {
4524 // If we aren't aligning after opening parens/braces we can always break
4525 // here unless the style does not want us to place all arguments on the
4526 // next line.
4527 if (!Style.AlignAfterOpenBracket &&
4528 (Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) {
4529 return 0;
4530 }
4531 if (Left.is(tok::l_brace) &&
4532 Style.Cpp11BracedListStyle == FormatStyle::BLS_Block) {
4533 return 19;
4534 }
4535 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
4536 : 19;
4537 }
4538 if (Left.is(TT_JavaAnnotation))
4539 return 50;
4540
4541 if (Left.is(TT_UnaryOperator))
4542 return 60;
4543 if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&
4544 Left.Previous->isLabelString() &&
4545 (Left.NextOperator || Left.OperatorIndex != 0)) {
4546 return 50;
4547 }
4548 if (Right.is(tok::plus) && Left.isLabelString() &&
4549 (Right.NextOperator || Right.OperatorIndex != 0)) {
4550 return 25;
4551 }
4552 if (Left.is(tok::comma))
4553 return 1;
4554 if (Right.is(tok::lessless) && Left.isLabelString() &&
4555 (Right.NextOperator || Right.OperatorIndex != 1)) {
4556 return 25;
4557 }
4558 if (Right.is(tok::lessless)) {
4559 // Breaking at a << is really cheap.
4560 if (Left.isNot(tok::r_paren) || Right.OperatorIndex > 0) {
4561 // Slightly prefer to break before the first one in log-like statements.
4562 return 2;
4563 }
4564 return 1;
4565 }
4566 if (Left.ClosesTemplateDeclaration)
4567 return Style.PenaltyBreakTemplateDeclaration;
4568 if (Left.ClosesRequiresClause)
4569 return 0;
4570 if (Left.is(TT_ConditionalExpr))
4571 return prec::Conditional;
4572 prec::Level Level = Left.getPrecedence();
4573 if (Level == prec::Unknown)
4574 Level = Right.getPrecedence();
4575 if (Level == prec::Assignment)
4576 return Style.PenaltyBreakAssignment;
4577 if (Level != prec::Unknown)
4578 return Level;
4579
4580 return 3;
4581}
4582
4583bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const {
4584 if (Style.SpaceBeforeParens == FormatStyle::SBPO_Always)
4585 return true;
4586 if (Right.is(TT_OverloadedOperatorLParen) &&
4587 Style.SpaceBeforeParensOptions.AfterOverloadedOperator) {
4588 return true;
4589 }
4590 if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
4591 Right.ParameterCount > 0) {
4592 return true;
4593 }
4594 return false;
4595}
4596
4597bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
4598 const FormatToken &Left,
4599 const FormatToken &Right) const {
4600 if (Left.is(tok::kw_return) &&
4601 Right.isNoneOf(tok::semi, tok::r_paren, tok::hashhash)) {
4602 return true;
4603 }
4604 if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen &&
4605 Right.MatchingParen->is(TT_CastRParen)) {
4606 return true;
4607 }
4608 if (Left.is(Keywords.kw_assert) && Style.isJava())
4609 return true;
4610 if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&
4611 Left.is(tok::objc_property)) {
4612 return true;
4613 }
4614 if (Right.is(tok::hashhash))
4615 return Left.is(tok::hash);
4616 if (Left.isOneOf(tok::hashhash, tok::hash))
4617 return Right.is(tok::hash);
4618 if (Style.SpacesInParens == FormatStyle::SIPO_Custom) {
4619 if (Left.is(tok::l_paren) && Right.is(tok::r_paren))
4620 return Style.SpacesInParensOptions.InEmptyParentheses;
4621 if (Style.SpacesInParensOptions.ExceptDoubleParentheses &&
4622 Left.is(tok::r_paren) && Right.is(tok::r_paren)) {
4623 auto *InnerLParen = Left.MatchingParen;
4624 if (InnerLParen && InnerLParen->Previous == Right.MatchingParen) {
4625 InnerLParen->SpacesRequiredBefore = 0;
4626 return false;
4627 }
4628 }
4629 const FormatToken *LeftParen = nullptr;
4630 if (Left.is(tok::l_paren))
4631 LeftParen = &Left;
4632 else if (Right.is(tok::r_paren) && Right.MatchingParen)
4633 LeftParen = Right.MatchingParen;
4634 if (LeftParen && (LeftParen->is(TT_ConditionLParen) ||
4635 (LeftParen->Previous &&
4636 isKeywordWithCondition(*LeftParen->Previous)))) {
4637 return Style.SpacesInParensOptions.InConditionalStatements;
4638 }
4639 }
4640
4641 // trailing return type 'auto': []() -> auto {}, auto foo() -> auto {}
4642 if (Left.is(tok::kw_auto) && Right.isOneOf(TT_LambdaLBrace, TT_FunctionLBrace,
4643 // function return type 'auto'
4644 TT_FunctionTypeLParen)) {
4645 return true;
4646 }
4647
4648 // auto{x} auto(x)
4649 if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))
4650 return false;
4651
4652 const auto *BeforeLeft = Left.Previous;
4653
4654 // operator co_await(x)
4655 if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && BeforeLeft &&
4656 BeforeLeft->is(tok::kw_operator)) {
4657 return false;
4658 }
4659 // co_await (x), co_yield (x), co_return (x)
4660 if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&
4661 Right.isNoneOf(tok::semi, tok::r_paren)) {
4662 return true;
4663 }
4664
4665 if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
4666 return (Right.is(TT_CastRParen) ||
4667 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
4668 ? Style.SpacesInParensOptions.InCStyleCasts
4669 : Style.SpacesInParensOptions.Other;
4670 }
4671 if (Right.isOneOf(tok::semi, tok::comma))
4672 return false;
4673 if (Right.is(tok::less) && Line.Type == LT_ObjCDecl) {
4674 bool IsLightweightGeneric = Right.MatchingParen &&
4675 Right.MatchingParen->Next &&
4676 Right.MatchingParen->Next->is(tok::colon);
4677 return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
4678 }
4679 if (Right.is(tok::less) && Left.is(tok::kw_template))
4680 return Style.SpaceAfterTemplateKeyword;
4681 if (Left.isOneOf(tok::exclaim, tok::tilde))
4682 return false;
4683 if (Left.is(tok::at) &&
4684 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
4685 tok::numeric_constant, tok::l_paren, tok::l_brace,
4686 tok::kw_true, tok::kw_false)) {
4687 return false;
4688 }
4689 if (Left.is(tok::colon))
4690 return Left.isNoneOf(TT_ObjCSelector, TT_ObjCMethodExpr);
4691 if (Left.is(tok::coloncolon))
4692 return false;
4693 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
4694 if (Style.isTextProto() ||
4695 (Style.Language == FormatStyle::LK_Proto &&
4696 (Left.is(TT_DictLiteral) || Right.is(TT_DictLiteral)))) {
4697 // Format empty list as `<>`.
4698 if (Left.is(tok::less) && Right.is(tok::greater))
4699 return false;
4700 return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;
4701 }
4702 // Don't attempt to format operator<(), as it is handled later.
4703 if (Right.isNot(TT_OverloadedOperatorLParen))
4704 return false;
4705 }
4706 if (Right.is(tok::ellipsis)) {
4707 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && BeforeLeft &&
4708 BeforeLeft->is(tok::kw_case));
4709 }
4710 if (Left.is(tok::l_square) && Right.is(tok::amp))
4711 return Style.SpacesInSquareBrackets;
4712 if (Right.is(TT_PointerOrReference)) {
4713 if (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) {
4714 if (!Left.MatchingParen)
4715 return true;
4716 FormatToken *TokenBeforeMatchingParen =
4717 Left.MatchingParen->getPreviousNonComment();
4718 if (!TokenBeforeMatchingParen || Left.isNot(TT_TypeDeclarationParen))
4719 return true;
4720 }
4721 // Add a space if the previous token is a pointer qualifier or the closing
4722 // parenthesis of __attribute__(()) expression and the style requires spaces
4723 // after pointer qualifiers.
4724 if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_After ||
4725 Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
4726 (Left.is(TT_AttributeRParen) ||
4727 Left.canBePointerOrReferenceQualifier())) {
4728 return true;
4729 }
4730 if (Left.Tok.isLiteral())
4731 return true;
4732 // for (auto a = 0, b = 0; const auto & c : {1, 2, 3})
4733 if (Left.isTypeOrIdentifier(LangOpts) && Right.Next && Right.Next->Next &&
4734 Right.Next->Next->is(TT_RangeBasedForLoopColon)) {
4735 return getTokenPointerOrReferenceAlignment(Right) !=
4736 FormatStyle::PAS_Left;
4737 }
4738 return Left.isNoneOf(TT_PointerOrReference, tok::l_paren) &&
4739 (getTokenPointerOrReferenceAlignment(Right) !=
4740 FormatStyle::PAS_Left ||
4741 (Line.IsMultiVariableDeclStmt &&
4742 (Left.NestingLevel == 0 ||
4743 (Left.NestingLevel == 1 && startsWithInitStatement(Line)))));
4744 }
4745 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
4746 (Left.isNot(TT_PointerOrReference) ||
4747 (getTokenPointerOrReferenceAlignment(Left) != FormatStyle::PAS_Right &&
4748 !Line.IsMultiVariableDeclStmt))) {
4749 return true;
4750 }
4751 if (Left.is(TT_PointerOrReference)) {
4752 // Add a space if the next token is a pointer qualifier and the style
4753 // requires spaces before pointer qualifiers.
4754 if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Before ||
4755 Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
4756 Right.canBePointerOrReferenceQualifier()) {
4757 return true;
4758 }
4759 // & 1
4760 if (Right.Tok.isLiteral())
4761 return true;
4762 // & /* comment
4763 if (Right.is(TT_BlockComment))
4764 return true;
4765 // foo() -> const Bar * override/final
4766 // S::foo() & noexcept/requires
4767 if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final, tok::kw_noexcept,
4768 TT_RequiresClause) &&
4769 Right.isNot(TT_StartOfName)) {
4770 return true;
4771 }
4772 // & {
4773 if (Right.is(tok::l_brace) && Right.is(BK_Block))
4774 return true;
4775 // for (auto a = 0, b = 0; const auto& c : {1, 2, 3})
4776 if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(LangOpts) && Right.Next &&
4777 Right.Next->is(TT_RangeBasedForLoopColon)) {
4778 return getTokenPointerOrReferenceAlignment(Left) !=
4779 FormatStyle::PAS_Right;
4780 }
4781 if (Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
4782 tok::l_paren)) {
4783 return false;
4784 }
4785 if (getTokenPointerOrReferenceAlignment(Left) == FormatStyle::PAS_Right)
4786 return false;
4787 // FIXME: Setting IsMultiVariableDeclStmt for the whole line is error-prone,
4788 // because it does not take into account nested scopes like lambdas.
4789 // In multi-variable declaration statements, attach */& to the variable
4790 // independently of the style. However, avoid doing it if we are in a nested
4791 // scope, e.g. lambda. We still need to special-case statements with
4792 // initializers.
4793 if (Line.IsMultiVariableDeclStmt &&
4794 (Left.NestingLevel == Line.First->NestingLevel ||
4795 ((Left.NestingLevel == Line.First->NestingLevel + 1) &&
4796 startsWithInitStatement(Line)))) {
4797 return false;
4798 }
4799 if (!BeforeLeft)
4800 return false;
4801 if (BeforeLeft->is(tok::coloncolon)) {
4802 if (Left.isNot(tok::star))
4803 return false;
4804 assert(Style.PointerAlignment != FormatStyle::PAS_Right);
4805 if (!Right.startsSequence(tok::identifier, tok::r_paren))
4806 return true;
4807 assert(Right.Next);
4808 const auto *LParen = Right.Next->MatchingParen;
4809 return !LParen || LParen->isNot(TT_FunctionTypeLParen);
4810 }
4811 return BeforeLeft->isNoneOf(tok::l_paren, tok::l_square);
4812 }
4813 // Ensure right pointer alignment with ellipsis e.g. int *...P
4814 if (Left.is(tok::ellipsis) && BeforeLeft &&
4815 BeforeLeft->isPointerOrReference()) {
4816 return Style.PointerAlignment != FormatStyle::PAS_Right;
4817 }
4818
4819 if (Right.is(tok::star) && Left.is(tok::l_paren))
4820 return false;
4821 if (Left.is(tok::star) && Right.isPointerOrReference())
4822 return false;
4823 if (Right.isPointerOrReference()) {
4824 const FormatToken *Previous = &Left;
4825 while (Previous && Previous->isNot(tok::kw_operator)) {
4826 if (Previous->is(tok::identifier) || Previous->isTypeName(LangOpts)) {
4827 Previous = Previous->getPreviousNonComment();
4828 continue;
4829 }
4830 if (Previous->is(TT_TemplateCloser) && Previous->MatchingParen) {
4831 Previous = Previous->MatchingParen->getPreviousNonComment();
4832 continue;
4833 }
4834 if (Previous->is(tok::coloncolon)) {
4835 Previous = Previous->getPreviousNonComment();
4836 continue;
4837 }
4838 break;
4839 }
4840 // Space between the type and the * in:
4841 // operator void*()
4842 // operator char*()
4843 // operator void const*()
4844 // operator void volatile*()
4845 // operator /*comment*/ const char*()
4846 // operator volatile /*comment*/ char*()
4847 // operator Foo*()
4848 // operator C<T>*()
4849 // operator std::Foo*()
4850 // operator C<T>::D<U>*()
4851 // dependent on PointerAlignment style.
4852 if (Previous) {
4853 if (Previous->endsSequence(tok::kw_operator))
4854 return Style.PointerAlignment != FormatStyle::PAS_Left;
4855 if (Previous->isOneOf(tok::kw_const, tok::kw_volatile)) {
4856 return (Style.PointerAlignment != FormatStyle::PAS_Left) ||
4857 (Style.SpaceAroundPointerQualifiers ==
4858 FormatStyle::SAPQ_After) ||
4859 (Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both);
4860 }
4861 }
4862 }
4863 if (Style.isCSharp() && Left.is(Keywords.kw_is) && Right.is(tok::l_square))
4864 return true;
4865 const auto SpaceRequiredForArrayInitializerLSquare =
4866 [](const FormatToken &LSquareTok, const FormatStyle &Style) {
4867 return Style.SpacesInContainerLiterals ||
4868 (Style.isProto() &&
4869 Style.Cpp11BracedListStyle == FormatStyle::BLS_Block &&
4870 LSquareTok.endsSequence(tok::l_square, tok::colon,
4871 TT_SelectorName));
4872 };
4873 if (Left.is(tok::l_square)) {
4874 return (Left.is(TT_ArrayInitializerLSquare) && Right.isNot(tok::r_square) &&
4875 SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||
4876 (Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
4877 TT_LambdaLSquare) &&
4878 Style.SpacesInSquareBrackets && Right.isNot(tok::r_square));
4879 }
4880 if (Right.is(tok::r_square)) {
4881 return Right.MatchingParen &&
4882 ((Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&
4883 SpaceRequiredForArrayInitializerLSquare(*Right.MatchingParen,
4884 Style)) ||
4885 (Style.SpacesInSquareBrackets &&
4886 Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
4887 TT_StructuredBindingLSquare,
4888 TT_LambdaLSquare)));
4889 }
4890 if (Right.is(tok::l_square) &&
4891 Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
4892 TT_DesignatedInitializerLSquare,
4893 TT_StructuredBindingLSquare, TT_AttributeLSquare) &&
4894 Left.isNoneOf(tok::numeric_constant, TT_DictLiteral) &&
4895 !(Left.isNot(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
4896 Right.is(TT_ArraySubscriptLSquare))) {
4897 return false;
4898 }
4899 if ((Left.is(tok::l_brace) && Left.isNot(BK_Block)) ||
4900 (Right.is(tok::r_brace) && Right.MatchingParen &&
4901 Right.MatchingParen->isNot(BK_Block))) {
4902 return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block ||
4903 Style.SpacesInParensOptions.Other;
4904 }
4905 if (Left.is(TT_BlockComment)) {
4906 // No whitespace in x(/*foo=*/1), except for JavaScript.
4907 return Style.isJavaScript() || !Left.TokenText.ends_with("=*/");
4908 }
4909
4910 // Space between template and attribute.
4911 // e.g. template <typename T> [[nodiscard]] ...
4912 if (Left.is(TT_TemplateCloser) && Right.is(TT_AttributeLSquare))
4913 return true;
4914 // Space before parentheses common for all languages
4915 if (Right.is(tok::l_paren)) {
4916 // Function declaration or definition
4917 if (Line.MightBeFunctionDecl && Right.is(TT_FunctionDeclarationLParen)) {
4918 if (spaceRequiredBeforeParens(Right))
4919 return true;
4920 const auto &Options = Style.SpaceBeforeParensOptions;
4921 return Line.mightBeFunctionDefinition()
4922 ? Options.AfterFunctionDefinitionName
4923 : Options.AfterFunctionDeclarationName;
4924 }
4925 if (Left.is(TT_TemplateCloser) && Right.isNot(TT_FunctionTypeLParen))
4926 return spaceRequiredBeforeParens(Right);
4927 if (Left.isOneOf(TT_RequiresClause,
4928 TT_RequiresClauseInARequiresExpression)) {
4929 return Style.SpaceBeforeParensOptions.AfterRequiresInClause ||
4930 spaceRequiredBeforeParens(Right);
4931 }
4932 if (Left.is(TT_RequiresExpression)) {
4933 return Style.SpaceBeforeParensOptions.AfterRequiresInExpression ||
4934 spaceRequiredBeforeParens(Right);
4935 }
4936 if (Left.isOneOf(TT_AttributeRParen, TT_AttributeRSquare))
4937 return true;
4938 if (Left.is(TT_ForEachMacro)) {
4939 return Style.SpaceBeforeParensOptions.AfterForeachMacros ||
4940 spaceRequiredBeforeParens(Right);
4941 }
4942 if (Left.is(TT_IfMacro)) {
4943 return Style.SpaceBeforeParensOptions.AfterIfMacros ||
4944 spaceRequiredBeforeParens(Right);
4945 }
4946 if (Style.SpaceBeforeParens == FormatStyle::SBPO_Custom &&
4947 Left.isPlacementOperator() &&
4948 Right.isNot(TT_OverloadedOperatorLParen) &&
4949 !(Line.MightBeFunctionDecl && Left.is(TT_FunctionDeclarationName))) {
4950 const auto *RParen = Right.MatchingParen;
4951 return Style.SpaceBeforeParensOptions.AfterPlacementOperator ||
4952 (RParen && RParen->is(TT_CastRParen));
4953 }
4954 if (Line.Type == LT_ObjCDecl)
4955 return true;
4956 if (Left.is(tok::semi))
4957 return true;
4958 if (Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch,
4959 tok::kw_case, TT_ForEachMacro, TT_ObjCForIn) ||
4960 Left.isIf(Line.Type != LT_PreprocessorDirective) ||
4961 Right.is(TT_ConditionLParen)) {
4962 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4963 spaceRequiredBeforeParens(Right);
4964 }
4965
4966 // TODO add Operator overloading specific Options to
4967 // SpaceBeforeParensOptions
4968 if (Right.is(TT_OverloadedOperatorLParen))
4969 return spaceRequiredBeforeParens(Right);
4970
4971 // Lambda
4972 if (Line.Type != LT_PreprocessorDirective && Left.is(tok::r_square) &&
4973 Left.MatchingParen && Left.MatchingParen->is(TT_LambdaLSquare)) {
4974 return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
4975 spaceRequiredBeforeParens(Right);
4976 }
4977 if (!BeforeLeft || BeforeLeft->isNoneOf(tok::period, tok::arrow)) {
4978 if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
4979 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
4980 spaceRequiredBeforeParens(Right);
4981 }
4982 if (Left.isPlacementOperator() ||
4983 (Left.is(tok::r_square) && Left.MatchingParen &&
4984 Left.MatchingParen->Previous &&
4985 Left.MatchingParen->Previous->is(tok::kw_delete))) {
4986 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never ||
4987 spaceRequiredBeforeParens(Right);
4988 }
4989 }
4990 // Handle builtins like identifiers.
4991 if (Line.Type != LT_PreprocessorDirective &&
4992 (Left.Tok.getIdentifierInfo() || Left.is(tok::r_paren))) {
4993 return spaceRequiredBeforeParens(Right);
4994 }
4995 return false;
4996 }
4997 if (Left.is(tok::at) && Right.isNot(tok::objc_not_keyword))
4998 return false;
4999 if (Right.is(TT_UnaryOperator)) {
5000 return Left.isNoneOf(tok::l_paren, tok::l_square, tok::at) &&
5001 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
5002 }
5003 // No space between the variable name and the initializer list.
5004 // A a1{1};
5005 // Verilog doesn't have such syntax, but it has word operators that are C++
5006 // identifiers like `a inside {b, c}`. So the rule is not applicable.
5007 if (!Style.isVerilog() &&
5008 (Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
5009 tok::r_paren) ||
5010 Left.isTypeName(LangOpts)) &&
5011 Right.is(tok::l_brace) && Right.getNextNonComment() &&
5012 Right.isNot(BK_Block)) {
5013 return false;
5014 }
5015 if (Left.is(tok::period) || Right.is(tok::period))
5016 return false;
5017 // u#str, U#str, L#str, u8#str
5018 // uR#str, UR#str, LR#str, u8R#str
5019 if (Right.is(tok::hash) && Left.is(tok::identifier) &&
5020 (Left.TokenText == "L" || Left.TokenText == "u" ||
5021 Left.TokenText == "U" || Left.TokenText == "u8" ||
5022 Left.TokenText == "LR" || Left.TokenText == "uR" ||
5023 Left.TokenText == "UR" || Left.TokenText == "u8R")) {
5024 return false;
5025 }
5026 if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
5027 Left.MatchingParen->Previous &&
5028 Left.MatchingParen->Previous->isOneOf(tok::period, tok::coloncolon)) {
5029 // Java call to generic function with explicit type:
5030 // A.<B<C<...>>>DoSomething();
5031 // A::<B<C<...>>>DoSomething(); // With a Java 8 method reference.
5032 return false;
5033 }
5034 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
5035 return false;
5036 if (Left.is(tok::l_brace) && Left.endsSequence(TT_DictLiteral, tok::at)) {
5037 // Objective-C dictionary literal -> no space after opening brace.
5038 return false;
5039 }
5040 if (Right.is(tok::r_brace) && Right.MatchingParen &&
5041 Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at)) {
5042 // Objective-C dictionary literal -> no space before closing brace.
5043 return false;
5044 }
5045 if (Right.is(TT_TrailingAnnotation) && Right.isOneOf(tok::amp, tok::ampamp) &&
5046 Left.isOneOf(tok::kw_const, tok::kw_volatile) &&
5047 (!Right.Next || Right.Next->is(tok::semi))) {
5048 // Match const and volatile ref-qualifiers without any additional
5049 // qualifiers such as
5050 // void Fn() const &;
5051 return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;
5052 }
5053
5054 return true;
5055}
5056
5057bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
5058 const FormatToken &Right) const {
5059 const FormatToken &Left = *Right.Previous;
5060
5061 // If the token is finalized don't touch it (as it could be in a
5062 // clang-format-off section).
5063 if (Left.Finalized)
5064 return Right.hasWhitespaceBefore();
5065
5066 const bool IsVerilog = Style.isVerilog();
5067 assert(!IsVerilog || !IsCpp);
5068
5069 // Never ever merge two words.
5070 if (Keywords.isWordLike(Right, IsVerilog) &&
5071 Keywords.isWordLike(Left, IsVerilog)) {
5072 return true;
5073 }
5074
5075 // Leave a space between * and /* to avoid C4138 `comment end` found outside
5076 // of comment.
5077 if (Left.is(tok::star) && Right.is(tok::comment))
5078 return true;
5079
5080 if (Left.is(tok::l_brace) && Right.is(tok::r_brace) &&
5081 Left.Children.empty()) {
5082 if (Left.is(BK_Block))
5083 return Style.SpaceInEmptyBraces != FormatStyle::SIEB_Never;
5084 if (Style.Cpp11BracedListStyle != FormatStyle::BLS_Block) {
5085 return Style.SpacesInParens == FormatStyle::SIPO_Custom &&
5086 Style.SpacesInParensOptions.InEmptyParentheses;
5087 }
5088 return Style.SpaceInEmptyBraces == FormatStyle::SIEB_Always;
5089 }
5090
5091 const auto *BeforeLeft = Left.Previous;
5092
5093 if (IsCpp) {
5094 if (Left.is(TT_OverloadedOperator) &&
5095 Right.isOneOf(TT_TemplateOpener, TT_TemplateCloser)) {
5096 return true;
5097 }
5098 // Space between UDL and dot: auto b = 4s .count();
5099 if (Right.is(tok::period) && Left.is(tok::numeric_constant))
5100 return true;
5101 // Space between import <iostream>.
5102 // or import .....;
5103 if (Left.is(Keywords.kw_import) &&
5104 Right.isOneOf(tok::less, tok::ellipsis) &&
5105 (!BeforeLeft || BeforeLeft->is(tok::kw_export))) {
5106 return true;
5107 }
5108 // Space between `module :` and `import :`.
5109 if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&
5110 Right.is(TT_ModulePartitionColon)) {
5111 return true;
5112 }
5113
5114 if (Right.is(TT_AfterPPDirective))
5115 return true;
5116
5117 // No space between import foo:bar but keep a space between import :bar;
5118 if (Left.is(tok::identifier) && Right.is(TT_ModulePartitionColon))
5119 return false;
5120 // No space between :bar;
5121 if (Left.is(TT_ModulePartitionColon) &&
5122 Right.isOneOf(tok::identifier, tok::kw_private)) {
5123 return false;
5124 }
5125 if (Left.is(tok::ellipsis) && Right.is(tok::identifier) &&
5126 Line.First->is(Keywords.kw_import)) {
5127 return false;
5128 }
5129 // Space in __attribute__((attr)) ::type.
5130 if (Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&
5131 Right.is(tok::coloncolon)) {
5132 return true;
5133 }
5134
5135 if (Left.is(tok::kw_operator))
5136 return Right.is(tok::coloncolon) || Style.SpaceAfterOperatorKeyword;
5137 if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) &&
5138 !Left.opensScope() && Style.SpaceBeforeCpp11BracedList) {
5139 return true;
5140 }
5141 if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) &&
5142 Right.is(TT_TemplateOpener)) {
5143 return true;
5144 }
5145 // C++ Core Guidelines suppression tag, e.g. `[[suppress(type.5)]]`.
5146 if (Left.is(tok::identifier) && Right.is(tok::numeric_constant))
5147 return Right.TokenText[0] != '.';
5148 // `Left` is a keyword (including C++ alternative operator) or identifier.
5149 if (Left.Tok.getIdentifierInfo() && Right.Tok.isLiteral())
5150 return true;
5151 } else if (Style.isProto()) {
5152 if (Right.is(tok::period) && !(BeforeLeft && BeforeLeft->is(tok::period)) &&
5153 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
5154 Keywords.kw_repeated, Keywords.kw_extend)) {
5155 return true;
5156 }
5157 if (Right.is(tok::l_paren) &&
5158 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) {
5159 return true;
5160 }
5161 if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
5162 return true;
5163 // Slashes occur in text protocol extension syntax: [type/type] { ... }.
5164 if (Left.is(tok::slash) || Right.is(tok::slash))
5165 return false;
5166 if (Left.MatchingParen &&
5167 Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
5168 Right.isOneOf(tok::l_brace, tok::less)) {
5169 return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;
5170 }
5171 // A percent is probably part of a formatting specification, such as %lld.
5172 if (Left.is(tok::percent))
5173 return false;
5174 // Preserve the existence of a space before a percent for cases like 0x%04x
5175 // and "%d %d"
5176 if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
5177 return Right.hasWhitespaceBefore();
5178 } else if (Style.isJson()) {
5179 if (Right.is(tok::colon) && Left.is(tok::string_literal))
5180 return Style.SpaceBeforeJsonColon;
5181 } else if (Style.isCSharp()) {
5182 // Require spaces around '{' and before '}' unless they appear in
5183 // interpolated strings. Interpolated strings are merged into a single token
5184 // so cannot have spaces inserted by this function.
5185
5186 // No space between 'this' and '['
5187 if (Left.is(tok::kw_this) && Right.is(tok::l_square))
5188 return false;
5189
5190 // No space between 'new' and '('
5191 if (Left.is(tok::kw_new) && Right.is(tok::l_paren))
5192 return false;
5193
5194 // Space before { (including space within '{ {').
5195 if (Right.is(tok::l_brace))
5196 return true;
5197
5198 // Spaces inside braces.
5199 if (Left.is(tok::l_brace) && Right.isNot(tok::r_brace))
5200 return true;
5201
5202 if (Left.isNot(tok::l_brace) && Right.is(tok::r_brace))
5203 return true;
5204
5205 // Spaces around '=>'.
5206 if (Left.is(TT_FatArrow) || Right.is(TT_FatArrow))
5207 return true;
5208
5209 // No spaces around attribute target colons
5210 if (Left.is(TT_AttributeColon) || Right.is(TT_AttributeColon))
5211 return false;
5212
5213 // space between type and variable e.g. Dictionary<string,string> foo;
5214 if (Left.is(TT_TemplateCloser) && Right.is(TT_StartOfName))
5215 return true;
5216
5217 // spaces inside square brackets.
5218 if (Left.is(tok::l_square) || Right.is(tok::r_square))
5219 return Style.SpacesInSquareBrackets;
5220
5221 // No space before ? in nullable types.
5222 if (Right.is(TT_CSharpNullable))
5223 return false;
5224
5225 // No space before null forgiving '!'.
5226 if (Right.is(TT_NonNullAssertion))
5227 return false;
5228
5229 // No space between consecutive commas '[,,]'.
5230 if (Left.is(tok::comma) && Right.is(tok::comma))
5231 return false;
5232
5233 // space after var in `var (key, value)`
5234 if (Left.is(Keywords.kw_var) && Right.is(tok::l_paren))
5235 return true;
5236
5237 // space between keywords and paren e.g. "using ("
5238 if (Right.is(tok::l_paren)) {
5239 if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when,
5240 Keywords.kw_lock)) {
5241 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
5242 spaceRequiredBeforeParens(Right);
5243 }
5244 }
5245
5246 // space between method modifier and opening parenthesis of a tuple return
5247 // type
5248 if ((Left.isAccessSpecifierKeyword() ||
5249 Left.isOneOf(tok::kw_virtual, tok::kw_extern, tok::kw_static,
5250 Keywords.kw_internal, Keywords.kw_abstract,
5251 Keywords.kw_sealed, Keywords.kw_override,
5252 Keywords.kw_async, Keywords.kw_unsafe)) &&
5253 Right.is(tok::l_paren)) {
5254 return true;
5255 }
5256 } else if (Style.isJavaScript()) {
5257 if (Left.is(TT_FatArrow))
5258 return true;
5259 // for await ( ...
5260 if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && BeforeLeft &&
5261 BeforeLeft->is(tok::kw_for)) {
5262 return true;
5263 }
5264 if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
5265 Right.MatchingParen) {
5266 const FormatToken *Next = Right.MatchingParen->getNextNonComment();
5267 // An async arrow function, for example: `x = async () => foo();`,
5268 // as opposed to calling a function called async: `x = async();`
5269 if (Next && Next->is(TT_FatArrow))
5270 return true;
5271 }
5272 if ((Left.is(TT_TemplateString) && Left.TokenText.ends_with("${")) ||
5273 (Right.is(TT_TemplateString) && Right.TokenText.starts_with("}"))) {
5274 return false;
5275 }
5276 // In tagged template literals ("html`bar baz`"), there is no space between
5277 // the tag identifier and the template string.
5278 if (Keywords.isJavaScriptIdentifier(Left,
5279 /* AcceptIdentifierName= */ false) &&
5280 Right.is(TT_TemplateString)) {
5281 return false;
5282 }
5283 if (Right.is(tok::star) &&
5284 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) {
5285 return false;
5286 }
5287 if (Right.isOneOf(tok::l_brace, tok::l_square) &&
5288 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,
5289 Keywords.kw_extends, Keywords.kw_implements)) {
5290 return true;
5291 }
5292 if (Right.is(tok::l_paren)) {
5293 // JS methods can use some keywords as names (e.g. `delete()`).
5294 if (Line.MustBeDeclaration && Left.Tok.getIdentifierInfo())
5295 return false;
5296 // Valid JS method names can include keywords, e.g. `foo.delete()` or
5297 // `bar.instanceof()`. Recognize call positions by preceding period.
5298 if (BeforeLeft && BeforeLeft->is(tok::period) &&
5299 Left.Tok.getIdentifierInfo()) {
5300 return false;
5301 }
5302 // Additional unary JavaScript operators that need a space after.
5303 if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
5304 tok::kw_void)) {
5305 return true;
5306 }
5307 }
5308 // `foo as const;` casts into a const type.
5309 if (Left.endsSequence(tok::kw_const, Keywords.kw_as))
5310 return false;
5311 if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
5312 tok::kw_const) ||
5313 // "of" is only a keyword if it appears after another identifier
5314 // (e.g. as "const x of y" in a for loop), or after a destructuring
5315 // operation (const [x, y] of z, const {a, b} of c).
5316 (Left.is(Keywords.kw_of) && BeforeLeft &&
5317 BeforeLeft->isOneOf(tok::identifier, tok::r_square, tok::r_brace))) &&
5318 (!BeforeLeft || BeforeLeft->isNot(tok::period))) {
5319 return true;
5320 }
5321 if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && BeforeLeft &&
5322 BeforeLeft->is(tok::period) && Right.is(tok::l_paren)) {
5323 return false;
5324 }
5325 if (Left.is(Keywords.kw_as) &&
5326 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) {
5327 return true;
5328 }
5329 if (Left.is(tok::kw_default) && BeforeLeft &&
5330 BeforeLeft->is(tok::kw_export)) {
5331 return true;
5332 }
5333 if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
5334 return true;
5335 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
5336 return false;
5337 if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
5338 return false;
5339 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
5340 Line.First->isOneOf(Keywords.kw_import, tok::kw_export)) {
5341 return false;
5342 }
5343 if (Left.is(tok::ellipsis))
5344 return false;
5345 if (Left.is(TT_TemplateCloser) &&
5346 Right.isNoneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
5347 Keywords.kw_implements, Keywords.kw_extends)) {
5348 // Type assertions ('<type>expr') are not followed by whitespace. Other
5349 // locations that should have whitespace following are identified by the
5350 // above set of follower tokens.
5351 return false;
5352 }
5353 if (Right.is(TT_NonNullAssertion))
5354 return false;
5355 if (Left.is(TT_NonNullAssertion) &&
5356 Right.isOneOf(Keywords.kw_as, Keywords.kw_in)) {
5357 return true; // "x! as string", "x! in y"
5358 }
5359 } else if (Style.isJava()) {
5360 if (Left.is(TT_CaseLabelArrow) || Right.is(TT_CaseLabelArrow))
5361 return true;
5362 if (Left.is(tok::r_square) && Right.is(tok::l_brace))
5363 return true;
5364 // spaces inside square brackets.
5365 if (Left.is(tok::l_square) || Right.is(tok::r_square))
5366 return Style.SpacesInSquareBrackets;
5367
5368 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren)) {
5369 return Style.SpaceBeforeParensOptions.AfterControlStatements ||
5370 spaceRequiredBeforeParens(Right);
5371 }
5372 if ((Left.isAccessSpecifierKeyword() ||
5373 Left.isOneOf(tok::kw_static, Keywords.kw_final, Keywords.kw_abstract,
5374 Keywords.kw_native)) &&
5375 Right.is(TT_TemplateOpener)) {
5376 return true;
5377 }
5378 } else if (IsVerilog) {
5379 // An escaped identifier ends with whitespace.
5380 if (Left.is(tok::identifier) && Left.TokenText[0] == '\\')
5381 return true;
5382 // Add space between things in a primitive's state table unless in a
5383 // transition like `(0?)`.
5384 if ((Left.is(TT_VerilogTableItem) &&
5385 Right.isNoneOf(tok::r_paren, tok::semi)) ||
5386 (Right.is(TT_VerilogTableItem) && Left.isNot(tok::l_paren))) {
5387 const FormatToken *Next = Right.getNextNonComment();
5388 return !(Next && Next->is(tok::r_paren));
5389 }
5390 // Don't add space within a delay like `#0`.
5391 if (Left.isNot(TT_BinaryOperator) &&
5392 Left.isOneOf(Keywords.kw_verilogHash, Keywords.kw_verilogHashHash)) {
5393 return false;
5394 }
5395 // Add space after a delay.
5396 if (Right.isNot(tok::semi) &&
5397 (Left.endsSequence(tok::numeric_constant, Keywords.kw_verilogHash) ||
5398 Left.endsSequence(tok::numeric_constant,
5399 Keywords.kw_verilogHashHash) ||
5400 (Left.is(tok::r_paren) && Left.MatchingParen &&
5401 Left.MatchingParen->endsSequence(tok::l_paren, tok::at)))) {
5402 return true;
5403 }
5404 // Don't add embedded spaces in a number literal like `16'h1?ax` or an array
5405 // literal like `'{}`.
5406 if (Left.is(Keywords.kw_apostrophe) ||
5407 (Left.is(TT_VerilogNumberBase) && Right.is(tok::numeric_constant))) {
5408 return false;
5409 }
5410 // Add spaces around the implication operator `->`.
5411 if (Left.is(tok::arrow) || Right.is(tok::arrow))
5412 return true;
5413 // Don't add spaces between two at signs. Like in a coverage event.
5414 // Don't add spaces between at and a sensitivity list like
5415 // `@(posedge clk)`.
5416 if (Left.is(tok::at) && Right.isOneOf(tok::l_paren, tok::star, tok::at))
5417 return false;
5418 // Add space between the type name and dimension like `logic [1:0]`.
5419 if (Right.is(tok::l_square) &&
5420 Left.isOneOf(TT_VerilogDimensionedTypeName, Keywords.kw_function)) {
5421 return true;
5422 }
5423 // In a tagged union expression, there should be a space after the tag.
5424 if (Right.isOneOf(tok::period, Keywords.kw_apostrophe) &&
5425 Keywords.isVerilogIdentifier(Left) && Left.getPreviousNonComment() &&
5426 Left.getPreviousNonComment()->is(Keywords.kw_tagged)) {
5427 return true;
5428 }
5429 // Don't add spaces between a casting type and the quote or repetition count
5430 // and the brace. The case of tagged union expressions is handled by the
5431 // previous rule.
5432 if ((Right.is(Keywords.kw_apostrophe) ||
5433 (Right.is(BK_BracedInit) && Right.is(tok::l_brace))) &&
5434 Left.isNoneOf(Keywords.kw_assign, Keywords.kw_unique) &&
5435 !Keywords.isVerilogWordOperator(Left) &&
5436 (Left.isOneOf(tok::r_square, tok::r_paren, tok::r_brace,
5437 tok::numeric_constant) ||
5438 Keywords.isWordLike(Left))) {
5439 return false;
5440 }
5441 // Don't add spaces in imports like `import foo::*;`.
5442 if ((Right.is(tok::star) && Left.is(tok::coloncolon)) ||
5443 (Left.is(tok::star) && Right.is(tok::semi))) {
5444 return false;
5445 }
5446 // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
5447 if (Left.endsSequence(tok::star, tok::l_paren) && Right.is(tok::identifier))
5448 return true;
5449 // Add space before drive strength like in `wire (strong1, pull0)`.
5450 if (Right.is(tok::l_paren) && Right.is(TT_VerilogStrength))
5451 return true;
5452 // Don't add space in a streaming concatenation like `{>>{j}}`.
5453 if ((Left.is(tok::l_brace) &&
5454 Right.isOneOf(tok::lessless, tok::greatergreater)) ||
5455 (Left.endsSequence(tok::lessless, tok::l_brace) ||
5456 Left.endsSequence(tok::greatergreater, tok::l_brace))) {
5457 return false;
5458 }
5459 } else if (Style.isTableGen()) {
5460 // Avoid to connect [ and {. [{ is start token of multiline string.
5461 if (Left.is(tok::l_square) && Right.is(tok::l_brace))
5462 return true;
5463 if (Left.is(tok::r_brace) && Right.is(tok::r_square))
5464 return true;
5465 // Do not insert around colon in DAGArg and cond operator.
5466 if (Right.isOneOf(TT_TableGenDAGArgListColon,
5467 TT_TableGenDAGArgListColonToAlign) ||
5468 Left.isOneOf(TT_TableGenDAGArgListColon,
5469 TT_TableGenDAGArgListColonToAlign)) {
5470 return false;
5471 }
5472 if (Right.is(TT_TableGenCondOperatorColon))
5473 return false;
5474 if (Left.isOneOf(TT_TableGenDAGArgOperatorID,
5475 TT_TableGenDAGArgOperatorToBreak) &&
5476 Right.isNot(TT_TableGenDAGArgCloser)) {
5477 return true;
5478 }
5479 // Do not insert bang operators and consequent openers.
5480 if (Right.isOneOf(tok::l_paren, tok::less) &&
5481 Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
5482 return false;
5483 }
5484 // Trailing paste requires space before '{' or ':', the case in name values.
5485 // Not before ';', the case in normal values.
5486 if (Left.is(TT_TableGenTrailingPasteOperator) &&
5487 Right.isOneOf(tok::l_brace, tok::colon)) {
5488 return true;
5489 }
5490 // Otherwise paste operator does not prefer space around.
5491 if (Left.is(tok::hash) || Right.is(tok::hash))
5492 return false;
5493 // Sure not to connect after defining keywords.
5494 if (Keywords.isTableGenDefinition(Left))
5495 return true;
5496 }
5497
5498 if (Left.is(TT_ImplicitStringLiteral))
5499 return Right.hasWhitespaceBefore();
5500 if (Line.Type == LT_ObjCMethodDecl) {
5501 if (Left.is(TT_ObjCMethodSpecifier))
5502 return Style.ObjCSpaceAfterMethodDeclarationPrefix;
5503 if (Left.is(tok::r_paren) && Left.isNot(TT_AttributeRParen) &&
5504 canBeObjCSelectorComponent(Right)) {
5505 // Don't space between ')' and <id> or ')' and 'new'. 'new' is not a
5506 // keyword in Objective-C, and '+ (instancetype)new;' is a standard class
5507 // method declaration.
5508 return false;
5509 }
5510 }
5511 if (Line.Type == LT_ObjCProperty &&
5512 (Right.is(tok::equal) || Left.is(tok::equal))) {
5513 return false;
5514 }
5515
5516 if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
5517 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) {
5518 return true;
5519 }
5520 if (Left.is(tok::comma) && Right.isNot(TT_OverloadedOperatorLParen) &&
5521 // In an unexpanded macro call we only find the parentheses and commas
5522 // in a line; the commas and closing parenthesis do not require a space.
5523 (Left.Children.empty() || !Left.MacroParent)) {
5524 return true;
5525 }
5526 if (Right.is(tok::comma))
5527 return false;
5528 if (Right.is(TT_ObjCBlockLParen))
5529 return true;
5530 if (Right.is(TT_CtorInitializerColon))
5531 return Style.SpaceBeforeCtorInitializerColon;
5532 if (Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)
5533 return false;
5534 if (Right.is(TT_RangeBasedForLoopColon) &&
5535 !Style.SpaceBeforeRangeBasedForLoopColon) {
5536 return false;
5537 }
5538 if (Left.is(TT_BitFieldColon)) {
5539 return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||
5540 Style.BitFieldColonSpacing == FormatStyle::BFCS_After;
5541 }
5542 if (Right.is(tok::colon)) {
5543 if (Right.is(TT_CaseLabelColon))
5544 return Style.SpaceBeforeCaseColon;
5545 if (Right.is(TT_GotoLabelColon))
5546 return false;
5547 // `private:` and `public:`.
5548 if (!Right.getNextNonComment())
5549 return false;
5550 if (Right.isOneOf(TT_ObjCSelector, TT_ObjCMethodExpr))
5551 return false;
5552 if (Left.is(tok::question))
5553 return false;
5554 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))
5555 return false;
5556 if (Right.is(TT_DictLiteral))
5557 return Style.SpacesInContainerLiterals;
5558 if (Right.is(TT_AttributeColon))
5559 return false;
5560 if (Right.is(TT_CSharpNamedArgumentColon))
5561 return false;
5562 if (Right.is(TT_GenericSelectionColon))
5563 return false;
5564 if (Right.is(TT_BitFieldColon)) {
5565 return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||
5566 Style.BitFieldColonSpacing == FormatStyle::BFCS_Before;
5567 }
5568 return true;
5569 }
5570 // Do not merge "- -" into "--".
5571 if ((Left.isOneOf(tok::minus, tok::minusminus) &&
5572 Right.isOneOf(tok::minus, tok::minusminus)) ||
5573 (Left.isOneOf(tok::plus, tok::plusplus) &&
5574 Right.isOneOf(tok::plus, tok::plusplus))) {
5575 return true;
5576 }
5577 if (Left.is(TT_UnaryOperator)) {
5578 // Lambda captures allow for a lone &, so "&]" needs to be properly
5579 // handled.
5580 if (Left.is(tok::amp) && Right.is(tok::r_square))
5581 return Style.SpacesInSquareBrackets;
5582 if (Left.isNot(tok::exclaim))
5583 return false;
5584 if (Left.TokenText == "!")
5585 return Style.SpaceAfterLogicalNot;
5586 assert(Left.TokenText == "not");
5587 return Right.isOneOf(tok::coloncolon, TT_UnaryOperator) ||
5588 (Right.is(tok::l_paren) && Style.SpaceBeforeParensOptions.AfterNot);
5589 }
5590
5591 // If the next token is a binary operator or a selector name, we have
5592 // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.
5593 if (Left.is(TT_CastRParen)) {
5594 return Style.SpaceAfterCStyleCast ||
5595 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
5596 }
5597
5598 auto ShouldAddSpacesInAngles = [this, &Right]() {
5599 if (this->Style.SpacesInAngles == FormatStyle::SIAS_Always)
5600 return true;
5601 if (this->Style.SpacesInAngles == FormatStyle::SIAS_Leave)
5602 return Right.hasWhitespaceBefore();
5603 return false;
5604 };
5605
5606 if (Left.is(tok::greater) && Right.is(tok::greater)) {
5607 if (Style.isTextProto() ||
5608 (Style.Language == FormatStyle::LK_Proto && Left.is(TT_DictLiteral))) {
5609 return Style.Cpp11BracedListStyle == FormatStyle::BLS_Block;
5610 }
5611 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
5612 ((Style.Standard < FormatStyle::LS_Cpp11) ||
5613 ShouldAddSpacesInAngles());
5614 }
5615 if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
5616 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
5617 (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod))) {
5618 return false;
5619 }
5620 if (!Style.SpaceBeforeAssignmentOperators && Left.isNot(TT_TemplateCloser) &&
5621 Right.getPrecedence() == prec::Assignment) {
5622 return false;
5623 }
5624 if (Style.isJava() && Right.is(tok::coloncolon) &&
5625 Left.isOneOf(tok::identifier, tok::kw_this)) {
5626 return false;
5627 }
5628 if (Right.is(tok::coloncolon) && Left.is(tok::identifier)) {
5629 // Generally don't remove existing spaces between an identifier and "::".
5630 // The identifier might actually be a macro name such as ALWAYS_INLINE. If
5631 // this turns out to be too lenient, add analysis of the identifier itself.
5632 return Right.hasWhitespaceBefore();
5633 }
5634 if (Right.is(tok::coloncolon) &&
5635 Left.isNoneOf(tok::l_brace, tok::comment, tok::l_paren)) {
5636 // Put a space between < and :: in vector< ::std::string >
5637 return (Left.is(TT_TemplateOpener) &&
5638 ((Style.Standard < FormatStyle::LS_Cpp11) ||
5639 ShouldAddSpacesInAngles())) ||
5640 Left.isNoneOf(tok::l_paren, tok::r_paren, tok::l_square,
5641 tok::kw___super, TT_TemplateOpener,
5642 TT_TemplateCloser) ||
5643 (Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other);
5644 }
5645 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
5646 return ShouldAddSpacesInAngles();
5647 if (Left.is(tok::r_paren) && Left.isNot(TT_TypeDeclarationParen) &&
5648 Right.is(TT_PointerOrReference) && Right.isOneOf(tok::amp, tok::ampamp)) {
5649 return true;
5650 }
5651 // Space before TT_StructuredBindingLSquare.
5652 if (Right.is(TT_StructuredBindingLSquare)) {
5653 return Left.isNoneOf(tok::amp, tok::ampamp) ||
5654 getTokenReferenceAlignment(Left) != FormatStyle::PAS_Right;
5655 }
5656 // Space before & or && following a TT_StructuredBindingLSquare.
5657 if (Right.Next && Right.Next->is(TT_StructuredBindingLSquare) &&
5658 Right.isOneOf(tok::amp, tok::ampamp)) {
5659 return getTokenReferenceAlignment(Right) != FormatStyle::PAS_Left;
5660 }
5661 if ((Right.is(TT_BinaryOperator) && Left.isNot(tok::l_paren)) ||
5662 (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
5663 Right.isNot(tok::r_paren))) {
5664 return true;
5665 }
5666 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
5667 Left.MatchingParen &&
5668 Left.MatchingParen->is(TT_OverloadedOperatorLParen)) {
5669 return false;
5670 }
5671 if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
5672 Line.Type == LT_ImportStatement) {
5673 return true;
5674 }
5675 if (Right.is(TT_TrailingUnaryOperator))
5676 return false;
5677 if (Left.is(TT_RegexLiteral))
5678 return false;
5679 return spaceRequiredBetween(Line, Left, Right);
5680}
5681
5682// Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
5683static bool isAllmanBrace(const FormatToken &Tok) {
5684 return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&
5685 Tok.isNoneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
5686}
5687
5688// Returns 'true' if 'Tok' is a function argument.
5690 return Tok.MatchingParen && Tok.MatchingParen->Next &&
5691 Tok.MatchingParen->Next->isOneOf(tok::comma, tok::r_paren,
5692 tok::r_brace);
5693}
5694
5695static bool
5697 FormatStyle::ShortLambdaStyle ShortLambdaOption) {
5698 return Tok.Children.empty() && ShortLambdaOption != FormatStyle::SLS_None;
5699}
5700
5702 return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&
5703 Tok.isNoneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
5704}
5705
5706bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
5707 const FormatToken &Right) const {
5708 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
5709 (!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) {
5710 return true;
5711 }
5712
5713 const FormatToken &Left = *Right.Previous;
5714
5715 if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
5716 Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
5717 Left.ParameterCount > 0) {
5718 return true;
5719 }
5720
5721 // Ignores the first parameter as this will be handled separately by
5722 // BreakFunctionDefinitionParameters or AlignAfterOpenBracket.
5723 if (Style.BinPackParameters == FormatStyle::BPPS_AlwaysOnePerLine &&
5724 Line.MightBeFunctionDecl && !Left.opensScope() &&
5725 startsNextParameter(Right, Style)) {
5726 return true;
5727 }
5728
5729 const auto *BeforeLeft = Left.Previous;
5730 const auto *AfterRight = Right.Next;
5731
5732 if (Style.isCSharp()) {
5733 if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) &&
5734 Style.BraceWrapping.AfterFunction) {
5735 return true;
5736 }
5737 if (Right.is(TT_CSharpNamedArgumentColon) ||
5738 Left.is(TT_CSharpNamedArgumentColon)) {
5739 return false;
5740 }
5741 if (Right.is(TT_CSharpGenericTypeConstraint))
5742 return true;
5743 if (AfterRight && AfterRight->is(TT_FatArrow) &&
5744 (Right.is(tok::numeric_constant) ||
5745 (Right.is(tok::identifier) && Right.TokenText == "_"))) {
5746 return true;
5747 }
5748
5749 // Break after C# [...] and before public/protected/private/internal.
5750 if (Left.is(TT_AttributeRSquare) &&
5751 (Right.isAccessSpecifier(/*ColonRequired=*/false) ||
5752 Right.is(Keywords.kw_internal))) {
5753 return true;
5754 }
5755 // Break between ] and [ but only when there are really 2 attributes.
5756 if (Left.is(TT_AttributeRSquare) && Right.is(TT_AttributeLSquare))
5757 return true;
5758 } else if (Style.isJavaScript()) {
5759 // FIXME: This might apply to other languages and token kinds.
5760 if (Right.is(tok::string_literal) && Left.is(tok::plus) && BeforeLeft &&
5761 BeforeLeft->is(tok::string_literal)) {
5762 return true;
5763 }
5764 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 &&
5765 BeforeLeft && BeforeLeft->is(tok::equal) &&
5766 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
5767 tok::kw_const) &&
5768 // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match
5769 // above.
5770 Line.First->isNoneOf(Keywords.kw_var, Keywords.kw_let)) {
5771 // Object literals on the top level of a file are treated as "enum-style".
5772 // Each key/value pair is put on a separate line, instead of bin-packing.
5773 return true;
5774 }
5775 if (Left.is(tok::l_brace) && Line.Level == 0 &&
5776 (Line.startsWith(tok::kw_enum) ||
5777 Line.startsWith(tok::kw_const, tok::kw_enum) ||
5778 Line.startsWith(tok::kw_export, tok::kw_enum) ||
5779 Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum))) {
5780 // JavaScript top-level enum key/value pairs are put on separate lines
5781 // instead of bin-packing.
5782 return true;
5783 }
5784 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) && BeforeLeft &&
5785 BeforeLeft->is(TT_FatArrow)) {
5786 // JS arrow function (=> {...}).
5787 switch (Style.AllowShortLambdasOnASingleLine) {
5788 case FormatStyle::SLS_All:
5789 return false;
5790 case FormatStyle::SLS_None:
5791 return true;
5792 case FormatStyle::SLS_Empty:
5793 return !Left.Children.empty();
5794 case FormatStyle::SLS_Inline:
5795 // allow one-lining inline (e.g. in function call args) and empty arrow
5796 // functions.
5797 return (Left.NestingLevel == 0 && Line.Level == 0) &&
5798 !Left.Children.empty();
5799 }
5800 llvm_unreachable("Unknown FormatStyle::ShortLambdaStyle enum");
5801 }
5802
5803 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
5804 !Left.Children.empty()) {
5805 // Support AllowShortFunctionsOnASingleLine for JavaScript.
5806 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
5807 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
5808 (Left.NestingLevel == 0 && Line.Level == 0 &&
5809 Style.AllowShortFunctionsOnASingleLine &
5810 FormatStyle::SFS_InlineOnly);
5811 }
5812 } else if (Style.isJava()) {
5813 if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
5814 AfterRight->is(tok::string_literal)) {
5815 return true;
5816 }
5817 } else if (Style.isVerilog()) {
5818 // Break between assignments.
5819 if (Left.is(TT_VerilogAssignComma))
5820 return true;
5821 // Break between ports of different types.
5822 if (Left.is(TT_VerilogTypeComma))
5823 return true;
5824 // Break between ports in a module instantiation and after the parameter
5825 // list.
5826 if (Style.VerilogBreakBetweenInstancePorts &&
5827 (Left.is(TT_VerilogInstancePortComma) ||
5828 (Left.is(tok::r_paren) && Keywords.isVerilogIdentifier(Right) &&
5829 Left.MatchingParen &&
5830 Left.MatchingParen->is(TT_VerilogInstancePortLParen)))) {
5831 return true;
5832 }
5833 // Break after labels. In Verilog labels don't have the 'case' keyword, so
5834 // it is hard to identify them in UnwrappedLineParser.
5835 if (!Keywords.isVerilogBegin(Right) && Keywords.isVerilogEndOfLabel(Left))
5836 return true;
5837 } else if (Style.BreakAdjacentStringLiterals &&
5838 (IsCpp || Style.isProto() || Style.isTableGen())) {
5839 if (Left.isStringLiteral() && Right.isStringLiteral())
5840 return true;
5841 }
5842
5843 // Basic JSON newline processing.
5844 if (Style.isJson()) {
5845 // Always break after a JSON record opener.
5846 // {
5847 // }
5848 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace))
5849 return true;
5850 // Always break after a JSON array opener based on BreakArrays.
5851 if ((Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&
5852 Right.isNot(tok::r_square)) ||
5853 Left.is(tok::comma)) {
5854 if (Right.is(tok::l_brace))
5855 return true;
5856 // scan to the right if an we see an object or an array inside
5857 // then break.
5858 for (const auto *Tok = &Right; Tok; Tok = Tok->Next) {
5859 if (Tok->isOneOf(tok::l_brace, tok::l_square))
5860 return true;
5861 if (Tok->isOneOf(tok::r_brace, tok::r_square))
5862 break;
5863 }
5864 return Style.BreakArrays;
5865 }
5866 } else if (Style.isTableGen()) {
5867 // Break the comma in side cond operators.
5868 // !cond(case1:1,
5869 // case2:0);
5870 if (Left.is(TT_TableGenCondOperatorComma))
5871 return true;
5872 if (Left.is(TT_TableGenDAGArgOperatorToBreak) &&
5873 Right.isNot(TT_TableGenDAGArgCloser)) {
5874 return true;
5875 }
5876 if (Left.is(TT_TableGenDAGArgListCommaToBreak))
5877 return true;
5878 if (Right.is(TT_TableGenDAGArgCloser) && Right.MatchingParen &&
5879 Right.MatchingParen->is(TT_TableGenDAGArgOpenerToBreak) &&
5880 &Left != Right.MatchingParen->Next) {
5881 // Check to avoid empty DAGArg such as (ins).
5882 return Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll;
5883 }
5884 }
5885
5886 if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) &&
5887 Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always) {
5888 return true;
5889 }
5890
5891 // If the last token before a '}', ']', or ')' is a comma or a trailing
5892 // comment, the intention is to insert a line break after it in order to make
5893 // shuffling around entries easier. Import statements, especially in
5894 // JavaScript, can be an exception to this rule.
5895 if (Style.JavaScriptWrapImports || Line.Type != LT_ImportStatement) {
5896 const FormatToken *BeforeClosingBrace = nullptr;
5897 if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
5898 (Style.isJavaScript() && Left.is(tok::l_paren))) &&
5899 Left.isNot(BK_Block) && Left.MatchingParen) {
5900 BeforeClosingBrace = Left.MatchingParen->Previous;
5901 } else if (Right.MatchingParen &&
5902 (Right.MatchingParen->isOneOf(tok::l_brace,
5903 TT_ArrayInitializerLSquare) ||
5904 (Style.isJavaScript() &&
5905 Right.MatchingParen->is(tok::l_paren)))) {
5906 BeforeClosingBrace = &Left;
5907 }
5908 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
5909 BeforeClosingBrace->isTrailingComment())) {
5910 return true;
5911 }
5912 }
5913
5914 if (Right.is(tok::comment)) {
5915 return Left.isNoneOf(BK_BracedInit, TT_CtorInitializerColon) &&
5916 Right.NewlinesBefore > 0 && Right.HasUnescapedNewline;
5917 }
5918 if (Left.isTrailingComment())
5919 return true;
5920 if (Left.IsUnterminatedLiteral)
5921 return true;
5922
5923 if (BeforeLeft && BeforeLeft->is(tok::lessless) &&
5924 Left.is(tok::string_literal) && Right.is(tok::lessless) && AfterRight &&
5925 AfterRight->is(tok::string_literal)) {
5926 return Right.NewlinesBefore > 0;
5927 }
5928
5929 if (Right.is(TT_RequiresClause)) {
5930 switch (Style.RequiresClausePosition) {
5931 case FormatStyle::RCPS_OwnLine:
5932 case FormatStyle::RCPS_OwnLineWithBrace:
5933 case FormatStyle::RCPS_WithFollowing:
5934 return true;
5935 default:
5936 break;
5937 }
5938 }
5939 // Can break after template<> declaration
5940 if (Left.ClosesTemplateDeclaration && Left.MatchingParen &&
5941 Left.MatchingParen->NestingLevel == 0) {
5942 // Put concepts on the next line e.g.
5943 // template<typename T>
5944 // concept ...
5945 if (Right.is(tok::kw_concept))
5946 return Style.BreakBeforeConceptDeclarations == FormatStyle::BBCDS_Always;
5947 return Style.BreakTemplateDeclarations == FormatStyle::BTDS_Yes ||
5948 (Style.BreakTemplateDeclarations == FormatStyle::BTDS_Leave &&
5949 Right.NewlinesBefore > 0);
5950 }
5951 if (Left.ClosesRequiresClause) {
5952 switch (Style.RequiresClausePosition) {
5953 case FormatStyle::RCPS_OwnLine:
5954 case FormatStyle::RCPS_WithPreceding:
5955 return Right.isNot(tok::semi);
5956 case FormatStyle::RCPS_OwnLineWithBrace:
5957 return Right.isNoneOf(tok::semi, tok::l_brace);
5958 default:
5959 break;
5960 }
5961 }
5962 if (Style.PackConstructorInitializers == FormatStyle::PCIS_Never) {
5963 if (Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon &&
5964 (Left.is(TT_CtorInitializerComma) ||
5965 Right.is(TT_CtorInitializerColon))) {
5966 return true;
5967 }
5968
5969 if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&
5970 Left.isOneOf(TT_CtorInitializerColon, TT_CtorInitializerComma)) {
5971 return true;
5972 }
5973
5974 if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterComma &&
5975 Left.is(TT_CtorInitializerComma)) {
5976 return true;
5977 }
5978 }
5979 if (Style.PackConstructorInitializers < FormatStyle::PCIS_CurrentLine &&
5980 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
5981 Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) {
5982 return true;
5983 }
5984 if (Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly) {
5985 if ((Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon ||
5986 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) &&
5987 Right.is(TT_CtorInitializerColon)) {
5988 return true;
5989 }
5990
5991 if (Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon &&
5992 Left.is(TT_CtorInitializerColon)) {
5993 return true;
5994 }
5995 }
5996 // Break only if we have multiple inheritance.
5997 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
5998 Right.is(TT_InheritanceComma)) {
5999 return true;
6000 }
6001 if (Style.BreakInheritanceList == FormatStyle::BILS_AfterComma &&
6002 Left.is(TT_InheritanceComma)) {
6003 return true;
6004 }
6005 if (Right.is(tok::string_literal) && Right.TokenText.starts_with("R\"")) {
6006 // Multiline raw string literals are special wrt. line breaks. The author
6007 // has made a deliberate choice and might have aligned the contents of the
6008 // string literal accordingly. Thus, we try keep existing line breaks.
6009 return Right.IsMultiline && Right.NewlinesBefore > 0;
6010 }
6011 if ((Left.is(tok::l_brace) ||
6012 (Left.is(tok::less) && BeforeLeft && BeforeLeft->is(tok::equal))) &&
6013 Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {
6014 // Don't put enums or option definitions onto single lines in protocol
6015 // buffers.
6016 return true;
6017 }
6018 if (Right.is(TT_InlineASMBrace))
6019 return Right.HasUnescapedNewline;
6020
6021 if (isAllmanBrace(Left) || isAllmanBrace(Right)) {
6022 auto *FirstNonComment = Line.getFirstNonComment();
6023 bool AccessSpecifier =
6024 FirstNonComment && (FirstNonComment->is(Keywords.kw_internal) ||
6025 FirstNonComment->isAccessSpecifierKeyword());
6026
6027 if (Style.BraceWrapping.AfterEnum) {
6028 if (Line.startsWith(tok::kw_enum) ||
6029 Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
6030 return true;
6031 }
6032 // Ensure BraceWrapping for `public enum A {`.
6033 if (AccessSpecifier && FirstNonComment->Next &&
6034 FirstNonComment->Next->is(tok::kw_enum)) {
6035 return true;
6036 }
6037 }
6038
6039 // Ensure BraceWrapping for `public interface A {`.
6040 if (Style.BraceWrapping.AfterClass &&
6041 ((AccessSpecifier && FirstNonComment->Next &&
6042 FirstNonComment->Next->is(Keywords.kw_interface)) ||
6043 Line.startsWith(Keywords.kw_interface))) {
6044 return true;
6045 }
6046
6047 // Don't attempt to interpret struct return types as structs.
6048 if (Right.isNot(TT_FunctionLBrace)) {
6049 return (Line.startsWith(tok::kw_class) &&
6050 Style.BraceWrapping.AfterClass) ||
6051 (Line.startsWith(tok::kw_struct) &&
6052 Style.BraceWrapping.AfterStruct);
6053 }
6054 }
6055
6056 if (Left.is(TT_ObjCBlockLBrace) &&
6057 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) {
6058 return true;
6059 }
6060
6061 // Ensure wrapping after __attribute__((XX)) and @interface etc.
6062 if (Left.isOneOf(TT_AttributeRParen, TT_AttributeMacro) &&
6063 Right.is(TT_ObjCDecl)) {
6064 return true;
6065 }
6066
6067 if (Left.is(TT_LambdaLBrace)) {
6068 if (IsFunctionArgument(Left) &&
6069 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline) {
6070 return false;
6071 }
6072
6073 if (Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_None ||
6074 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline ||
6075 (!Left.Children.empty() &&
6076 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Empty)) {
6077 return true;
6078 }
6079 }
6080
6081 if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace) &&
6082 (Left.isPointerOrReference() || Left.is(TT_TemplateCloser))) {
6083 return true;
6084 }
6085
6086 // Put multiple Java annotation on a new line.
6087 if ((Style.isJava() || Style.isJavaScript()) &&
6088 Left.is(TT_LeadingJavaAnnotation) &&
6089 Right.isNoneOf(TT_LeadingJavaAnnotation, tok::l_paren) &&
6090 (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) {
6091 return true;
6092 }
6093
6094 if (Right.is(TT_ProtoExtensionLSquare))
6095 return true;
6096
6097 // In text proto instances if a submessage contains at least 2 entries and at
6098 // least one of them is a submessage, like A { ... B { ... } ... },
6099 // put all of the entries of A on separate lines by forcing the selector of
6100 // the submessage B to be put on a newline.
6101 //
6102 // Example: these can stay on one line:
6103 // a { scalar_1: 1 scalar_2: 2 }
6104 // a { b { key: value } }
6105 //
6106 // and these entries need to be on a new line even if putting them all in one
6107 // line is under the column limit:
6108 // a {
6109 // scalar: 1
6110 // b { key: value }
6111 // }
6112 //
6113 // We enforce this by breaking before a submessage field that has previous
6114 // siblings, *and* breaking before a field that follows a submessage field.
6115 //
6116 // Be careful to exclude the case [proto.ext] { ... } since the `]` is
6117 // the TT_SelectorName there, but we don't want to break inside the brackets.
6118 //
6119 // Another edge case is @submessage { key: value }, which is a common
6120 // substitution placeholder. In this case we want to keep `@` and `submessage`
6121 // together.
6122 //
6123 // We ensure elsewhere that extensions are always on their own line.
6124 if (Style.isProto() && Right.is(TT_SelectorName) &&
6125 Right.isNot(tok::r_square) && AfterRight) {
6126 // Keep `@submessage` together in:
6127 // @submessage { key: value }
6128 if (Left.is(tok::at))
6129 return false;
6130 // Look for the scope opener after selector in cases like:
6131 // selector { ...
6132 // selector: { ...
6133 // selector: @base { ...
6134 const auto *LBrace = AfterRight;
6135 if (LBrace && LBrace->is(tok::colon)) {
6136 LBrace = LBrace->Next;
6137 if (LBrace && LBrace->is(tok::at)) {
6138 LBrace = LBrace->Next;
6139 if (LBrace)
6140 LBrace = LBrace->Next;
6141 }
6142 }
6143 if (LBrace &&
6144 // The scope opener is one of {, [, <:
6145 // selector { ... }
6146 // selector [ ... ]
6147 // selector < ... >
6148 //
6149 // In case of selector { ... }, the l_brace is TT_DictLiteral.
6150 // In case of an empty selector {}, the l_brace is not TT_DictLiteral,
6151 // so we check for immediately following r_brace.
6152 ((LBrace->is(tok::l_brace) &&
6153 (LBrace->is(TT_DictLiteral) ||
6154 (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||
6155 LBrace->isOneOf(TT_ArrayInitializerLSquare, tok::less))) {
6156 // If Left.ParameterCount is 0, then this submessage entry is not the
6157 // first in its parent submessage, and we want to break before this entry.
6158 // If Left.ParameterCount is greater than 0, then its parent submessage
6159 // might contain 1 or more entries and we want to break before this entry
6160 // if it contains at least 2 entries. We deal with this case later by
6161 // detecting and breaking before the next entry in the parent submessage.
6162 if (Left.ParameterCount == 0)
6163 return true;
6164 // However, if this submessage is the first entry in its parent
6165 // submessage, Left.ParameterCount might be 1 in some cases.
6166 // We deal with this case later by detecting an entry
6167 // following a closing paren of this submessage.
6168 }
6169
6170 // If this is an entry immediately following a submessage, it will be
6171 // preceded by a closing paren of that submessage, like in:
6172 // left---. .---right
6173 // v v
6174 // sub: { ... } key: value
6175 // If there was a comment between `}` an `key` above, then `key` would be
6176 // put on a new line anyways.
6177 if (Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))
6178 return true;
6179 }
6180
6181 return false;
6182}
6183
6184bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
6185 const FormatToken &Right) const {
6186 const FormatToken &Left = *Right.Previous;
6187 // Language-specific stuff.
6188 if (Style.isCSharp()) {
6189 if (Left.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon) ||
6190 Right.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon)) {
6191 return false;
6192 }
6193 // Only break after commas for generic type constraints.
6194 if (Line.First->is(TT_CSharpGenericTypeConstraint))
6195 return Left.is(TT_CSharpGenericTypeConstraintComma);
6196 // Keep nullable operators attached to their identifiers.
6197 if (Right.is(TT_CSharpNullable))
6198 return false;
6199 } else if (Style.isJava()) {
6200 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
6201 Keywords.kw_implements)) {
6202 return false;
6203 }
6204 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
6205 Keywords.kw_implements)) {
6206 return true;
6207 }
6208 } else if (Style.isJavaScript()) {
6209 const FormatToken *NonComment = Right.getPreviousNonComment();
6210 if (NonComment &&
6211 (NonComment->isAccessSpecifierKeyword() ||
6212 NonComment->isOneOf(
6213 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
6214 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
6215 tok::kw_static, Keywords.kw_readonly, Keywords.kw_override,
6216 Keywords.kw_abstract, Keywords.kw_get, Keywords.kw_set,
6217 Keywords.kw_async, Keywords.kw_await))) {
6218 return false; // Otherwise automatic semicolon insertion would trigger.
6219 }
6220 if (Right.NestingLevel == 0 &&
6221 (Left.Tok.getIdentifierInfo() ||
6222 Left.isOneOf(tok::r_square, tok::r_paren)) &&
6223 Right.isOneOf(tok::l_square, tok::l_paren)) {
6224 return false; // Otherwise automatic semicolon insertion would trigger.
6225 }
6226 if (NonComment && NonComment->is(tok::identifier) &&
6227 NonComment->TokenText == "asserts") {
6228 return false;
6229 }
6230 if (Left.is(TT_FatArrow) && Right.is(tok::l_brace))
6231 return false;
6232 if (Left.is(TT_JsTypeColon))
6233 return true;
6234 // Don't wrap between ":" and "!" of a strict prop init ("field!: type;").
6235 if (Left.is(tok::exclaim) && Right.is(tok::colon))
6236 return false;
6237 // Look for is type annotations like:
6238 // function f(): a is B { ... }
6239 // Do not break before is in these cases.
6240 if (Right.is(Keywords.kw_is)) {
6241 const FormatToken *Next = Right.getNextNonComment();
6242 // If `is` is followed by a colon, it's likely that it's a dict key, so
6243 // ignore it for this check.
6244 // For example this is common in Polymer:
6245 // Polymer({
6246 // is: 'name',
6247 // ...
6248 // });
6249 if (!Next || Next->isNot(tok::colon))
6250 return false;
6251 }
6252 if (Left.is(Keywords.kw_in))
6253 return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None;
6254 if (Right.is(Keywords.kw_in))
6255 return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
6256 if (Right.is(Keywords.kw_as))
6257 return false; // must not break before as in 'x as type' casts
6258 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
6259 // extends and infer can appear as keywords in conditional types:
6260 // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types
6261 // do not break before them, as the expressions are subject to ASI.
6262 return false;
6263 }
6264 if (Left.is(Keywords.kw_as))
6265 return true;
6266 if (Left.is(TT_NonNullAssertion))
6267 return true;
6268 if (Left.is(Keywords.kw_declare) &&
6269 Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
6270 Keywords.kw_function, tok::kw_class, tok::kw_enum,
6271 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
6272 Keywords.kw_let, tok::kw_const)) {
6273 // See grammar for 'declare' statements at:
6274 // https://github.com/Microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md#A.10
6275 return false;
6276 }
6277 if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
6278 Right.isOneOf(tok::identifier, tok::string_literal)) {
6279 return false; // must not break in "module foo { ...}"
6280 }
6281 if (Right.is(TT_TemplateString) && Right.closesScope())
6282 return false;
6283 // Don't split tagged template literal so there is a break between the tag
6284 // identifier and template string.
6285 if (Left.is(tok::identifier) && Right.is(TT_TemplateString))
6286 return false;
6287 if (Left.is(TT_TemplateString) && Left.opensScope())
6288 return true;
6289 } else if (Style.isTableGen()) {
6290 // Avoid to break after "def", "class", "let" and so on.
6291 if (Keywords.isTableGenDefinition(Left))
6292 return false;
6293 // Avoid to break after '(' in the cases that is in bang operators.
6294 if (Right.is(tok::l_paren)) {
6295 return Left.isNoneOf(TT_TableGenBangOperator, TT_TableGenCondOperator,
6296 TT_TemplateCloser);
6297 }
6298 // Avoid to break between the value and its suffix part.
6299 if (Left.is(TT_TableGenValueSuffix))
6300 return false;
6301 // Avoid to break around paste operator.
6302 if (Left.is(tok::hash) || Right.is(tok::hash))
6303 return false;
6304 if (Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator))
6305 return false;
6306 }
6307
6308 // We can break before an r_brace if there was a break after the matching
6309 // l_brace, which is tracked by BreakBeforeClosingBrace, or if we are in a
6310 // block-indented initialization list.
6311 if (Right.is(tok::r_brace)) {
6312 return Right.MatchingParen && (Right.MatchingParen->is(BK_Block) ||
6313 (Right.isBlockIndentedInitRBrace(Style)));
6314 }
6315
6316 // We can break before r_paren if we're in a block indented context or
6317 // a control statement with an explicit style option.
6318 if (Right.is(tok::r_paren)) {
6319 if (!Right.MatchingParen)
6320 return false;
6321 auto Next = Right.Next;
6322 if (Next && Next->is(tok::r_paren))
6323 Next = Next->Next;
6324 if (Next && Next->is(tok::l_paren))
6325 return false;
6326 const FormatToken *Previous = Right.MatchingParen->Previous;
6327 if (!Previous)
6328 return false;
6329 if (Previous->isIf())
6330 return Style.BreakBeforeCloseBracketIf;
6331 if (Previous->isLoop(Style))
6332 return Style.BreakBeforeCloseBracketLoop;
6333 if (Previous->is(tok::kw_switch))
6334 return Style.BreakBeforeCloseBracketSwitch;
6335 return Style.BreakBeforeCloseBracketFunction;
6336 }
6337
6338 if (Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) &&
6339 Right.is(TT_TrailingAnnotation) &&
6340 Style.BreakBeforeCloseBracketFunction) {
6341 return false;
6342 }
6343
6344 if (Right.is(TT_TemplateCloser))
6345 return Style.BreakBeforeTemplateCloser;
6346
6347 if (Left.isOneOf(tok::at, tok::objc_interface))
6348 return false;
6349 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
6350 return Right.isNot(tok::l_paren);
6351 if (Right.is(TT_PointerOrReference)) {
6352 return Line.IsMultiVariableDeclStmt ||
6353 (getTokenPointerOrReferenceAlignment(Right) ==
6354 FormatStyle::PAS_Right &&
6355 !(Right.Next &&
6356 Right.Next->isOneOf(TT_FunctionDeclarationName, tok::kw_const)));
6357 }
6358 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
6359 TT_ClassHeadName, TT_QtProperty, tok::kw_operator)) {
6360 return true;
6361 }
6362 if (Left.is(TT_PointerOrReference))
6363 return false;
6364 if (Right.isTrailingComment()) {
6365 // We rely on MustBreakBefore being set correctly here as we should not
6366 // change the "binding" behavior of a comment.
6367 // The first comment in a braced lists is always interpreted as belonging to
6368 // the first list element. Otherwise, it should be placed outside of the
6369 // list.
6370 return Left.is(BK_BracedInit) ||
6371 (Left.is(TT_CtorInitializerColon) && Right.NewlinesBefore > 0 &&
6372 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
6373 }
6374 if (Left.is(tok::question) && Right.is(tok::colon))
6375 return false;
6376 if (Right.isOneOf(TT_ConditionalExpr, tok::question))
6377 return Style.BreakBeforeTernaryOperators;
6378 if (Left.isOneOf(TT_ConditionalExpr, tok::question))
6379 return !Style.BreakBeforeTernaryOperators;
6380 if (Left.is(TT_InheritanceColon))
6381 return Style.BreakInheritanceList == FormatStyle::BILS_AfterColon;
6382 if (Right.is(TT_InheritanceColon))
6383 return Style.BreakInheritanceList != FormatStyle::BILS_AfterColon;
6384 // When the method parameter has no name, allow breaking before the colon.
6385 if (Right.is(TT_ObjCMethodExpr) && Right.isNot(tok::r_square) &&
6386 Left.isNot(TT_SelectorName)) {
6387 return true;
6388 }
6389
6390 if (Right.is(tok::colon) &&
6391 Right.isNoneOf(TT_CtorInitializerColon, TT_InlineASMColon,
6392 TT_BitFieldColon)) {
6393 return false;
6394 }
6395 if (Left.is(tok::colon) && Left.isOneOf(TT_ObjCSelector, TT_ObjCMethodExpr))
6396 return true;
6397 if (Left.is(tok::colon) && Left.is(TT_DictLiteral)) {
6398 if (Style.isProto()) {
6399 if (!Style.AlwaysBreakBeforeMultilineStrings && Right.isStringLiteral())
6400 return false;
6401 // Prevent cases like:
6402 //
6403 // submessage:
6404 // { key: valueeeeeeeeeeee }
6405 //
6406 // when the snippet does not fit into one line.
6407 // Prefer:
6408 //
6409 // submessage: {
6410 // key: valueeeeeeeeeeee
6411 // }
6412 //
6413 // instead, even if it is longer by one line.
6414 //
6415 // Note that this allows the "{" to go over the column limit
6416 // when the column limit is just between ":" and "{", but that does
6417 // not happen too often and alternative formattings in this case are
6418 // not much better.
6419 //
6420 // The code covers the cases:
6421 //
6422 // submessage: { ... }
6423 // submessage: < ... >
6424 // repeated: [ ... ]
6425 if ((Right.isOneOf(tok::l_brace, tok::less) &&
6426 Right.is(TT_DictLiteral)) ||
6427 Right.is(TT_ArrayInitializerLSquare)) {
6428 return false;
6429 }
6430 }
6431 return true;
6432 }
6433 if (Right.is(tok::r_square) && Right.MatchingParen &&
6434 Right.MatchingParen->is(TT_ProtoExtensionLSquare)) {
6435 return false;
6436 }
6437 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&
6438 Right.Next->is(TT_ObjCMethodExpr))) {
6439 return Left.isNot(tok::period); // FIXME: Properly parse ObjC calls.
6440 }
6441 if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty)
6442 return true;
6443 if (Right.is(tok::kw_concept))
6444 return Style.BreakBeforeConceptDeclarations != FormatStyle::BBCDS_Never;
6445 if (Right.is(TT_RequiresClause))
6446 return true;
6447 if (Left.ClosesTemplateDeclaration) {
6448 return Style.BreakTemplateDeclarations != FormatStyle::BTDS_Leave ||
6449 Right.NewlinesBefore > 0;
6450 }
6451 if (Left.is(TT_FunctionAnnotationRParen))
6452 return true;
6453 if (Left.ClosesRequiresClause)
6454 return true;
6455 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
6456 TT_OverloadedOperator)) {
6457 return false;
6458 }
6459 if (Left.is(TT_RangeBasedForLoopColon))
6460 return true;
6461 if (Right.is(TT_RangeBasedForLoopColon))
6462 return false;
6463 if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener))
6464 return true;
6465 if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
6466 (Left.is(tok::less) && Right.is(tok::less))) {
6467 return false;
6468 }
6469 if (Right.is(TT_BinaryOperator) &&
6470 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&
6471 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
6472 Right.getPrecedence() != prec::Assignment)) {
6473 return true;
6474 }
6475 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator, tok::kw_operator))
6476 return false;
6477 if (Left.is(tok::equal) && Right.isNoneOf(tok::kw_default, tok::kw_delete) &&
6478 Line.Type == LT_VirtualFunctionDecl && Left.NestingLevel == 0) {
6479 return false;
6480 }
6481 if (Left.is(tok::equal) && Right.is(tok::l_brace) &&
6482 Style.Cpp11BracedListStyle == FormatStyle::BLS_Block) {
6483 return false;
6484 }
6485 if (Left.is(TT_AttributeLParen) ||
6486 (Left.is(tok::l_paren) && Left.is(TT_TypeDeclarationParen))) {
6487 return false;
6488 }
6489 if (Left.is(tok::l_paren) && Left.Previous &&
6490 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) {
6491 return false;
6492 }
6493 if (Right.is(TT_ImplicitStringLiteral))
6494 return false;
6495
6496 if (Right.is(tok::r_square) && Right.MatchingParen &&
6497 Right.MatchingParen->is(TT_LambdaLSquare)) {
6498 return false;
6499 }
6500
6501 // Allow breaking after a trailing annotation, e.g. after a method
6502 // declaration.
6503 if (Left.is(TT_TrailingAnnotation)) {
6504 return Right.isNoneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
6505 tok::less, tok::coloncolon);
6506 }
6507
6508 if (Right.isAttribute())
6509 return true;
6510
6511 if (Right.is(TT_AttributeLSquare)) {
6512 assert(Left.isNot(tok::l_square));
6513 return true;
6514 }
6515
6516 if (Left.is(tok::identifier) && Right.is(tok::string_literal))
6517 return true;
6518
6519 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
6520 return true;
6521
6522 if (Left.is(TT_CtorInitializerColon)) {
6523 return (Style.BreakConstructorInitializers ==
6524 FormatStyle::BCIS_AfterColon ||
6525 Style.BreakConstructorInitializers ==
6526 FormatStyle::BCIS_AfterComma) &&
6527 (!Right.isTrailingComment() || Right.NewlinesBefore > 0);
6528 }
6529 if (Right.is(TT_CtorInitializerColon)) {
6530 return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon &&
6531 Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterComma;
6532 }
6533 if (Left.is(TT_CtorInitializerComma) &&
6534 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {
6535 return false;
6536 }
6537 if (Right.is(TT_CtorInitializerComma) &&
6538 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) {
6539 return true;
6540 }
6541 if (Left.is(TT_InheritanceComma) &&
6542 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma) {
6543 return false;
6544 }
6545 if (Right.is(TT_InheritanceComma) &&
6546 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma) {
6547 return true;
6548 }
6549 if (Left.is(TT_ArrayInitializerLSquare))
6550 return true;
6551 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
6552 return true;
6553 if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
6554 Left.isNoneOf(tok::arrowstar, tok::lessless) &&
6555 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
6556 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
6557 Left.getPrecedence() == prec::Assignment)) {
6558 return true;
6559 }
6560 if (Left.is(TT_AttributeLSquare) && Right.is(tok::l_square)) {
6561 assert(Right.isNot(TT_AttributeLSquare));
6562 return false;
6563 }
6564 if (Left.is(tok::r_square) && Right.is(TT_AttributeRSquare)) {
6565 assert(Left.isNot(TT_AttributeRSquare));
6566 return false;
6567 }
6568
6569 auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
6570 if (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace)) {
6571 if (isAllmanLambdaBrace(Left))
6572 return !isEmptyLambdaAllowed(Left, ShortLambdaOption);
6573 if (isAllmanLambdaBrace(Right))
6574 return !isEmptyLambdaAllowed(Right, ShortLambdaOption);
6575 }
6576
6577 if (Right.is(tok::kw_noexcept) && Right.is(TT_TrailingAnnotation)) {
6578 switch (Style.AllowBreakBeforeNoexceptSpecifier) {
6579 case FormatStyle::BBNSS_Never:
6580 return false;
6581 case FormatStyle::BBNSS_Always:
6582 return true;
6583 case FormatStyle::BBNSS_OnlyWithParen:
6584 return Right.Next && Right.Next->is(tok::l_paren);
6585 }
6586 }
6587
6588 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
6589 tok::kw_class, tok::kw_struct, tok::comment) ||
6590 Right.isMemberAccess() ||
6591 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
6592 tok::colon, tok::l_square, tok::at) ||
6593 (Left.is(tok::r_paren) &&
6594 Right.isOneOf(tok::identifier, tok::kw_const)) ||
6595 (Left.is(tok::l_paren) && Right.isNot(tok::r_paren)) ||
6596 (Left.is(TT_TemplateOpener) && Right.isNot(TT_TemplateCloser));
6597}
6598
6599void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) const {
6600 llvm::errs() << "AnnotatedTokens(L=" << Line.Level << ", P=" << Line.PPLevel
6601 << ", T=" << Line.Type << ", C=" << Line.IsContinuation
6602 << "):\n";
6603 const FormatToken *Tok = Line.First;
6604 while (Tok) {
6605 llvm::errs() << " I=" << Tok->IndentLevel << " M=" << Tok->MustBreakBefore
6606 << " C=" << Tok->CanBreakBefore
6607 << " T=" << getTokenTypeName(Tok->getType())
6608 << " S=" << Tok->SpacesRequiredBefore
6609 << " F=" << Tok->Finalized << " B=" << Tok->BlockParameterCount
6610 << " BK=" << Tok->getBlockKind() << " P=" << Tok->SplitPenalty
6611 << " Name=" << Tok->Tok.getName() << " N=" << Tok->NestingLevel
6612 << " L=" << Tok->TotalLength
6613 << " PPK=" << Tok->getPackingKind() << " FakeLParens=";
6614 for (prec::Level LParen : Tok->FakeLParens)
6615 llvm::errs() << LParen << "/";
6616 llvm::errs() << " FakeRParens=" << Tok->FakeRParens;
6617 llvm::errs() << " II=" << Tok->Tok.getIdentifierInfo();
6618 llvm::errs() << " Text='" << Tok->TokenText << "'\n";
6619 if (!Tok->Next)
6620 assert(Tok == Line.Last);
6621 Tok = Tok->Next;
6622 }
6623 llvm::errs() << "----\n";
6624}
6625
6626FormatStyle::PointerAlignmentStyle
6627TokenAnnotator::getTokenReferenceAlignment(const FormatToken &Reference) const {
6628 assert(Reference.isOneOf(tok::amp, tok::ampamp));
6629 switch (Style.ReferenceAlignment) {
6630 case FormatStyle::RAS_Pointer:
6631 return Style.PointerAlignment;
6632 case FormatStyle::RAS_Left:
6633 return FormatStyle::PAS_Left;
6634 case FormatStyle::RAS_Right:
6635 return FormatStyle::PAS_Right;
6636 case FormatStyle::RAS_Middle:
6637 return FormatStyle::PAS_Middle;
6638 }
6639 assert(0); //"Unhandled value of ReferenceAlignment"
6640 return Style.PointerAlignment;
6641}
6642
6643FormatStyle::PointerAlignmentStyle
6644TokenAnnotator::getTokenPointerOrReferenceAlignment(
6645 const FormatToken &PointerOrReference) const {
6646 if (PointerOrReference.isOneOf(tok::amp, tok::ampamp))
6647 return getTokenReferenceAlignment(PointerOrReference);
6648 assert(PointerOrReference.is(tok::star));
6649 return Style.PointerAlignment;
6650}
6651
6652} // namespace format
6653} // 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:172
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:4712
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:4316
bool startsNextParameter(const FormatToken &Current, const FormatStyle &Style)
bool Ret(InterpState &S, CodePtr &PC)
Definition Interp.h:236
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:3720
@ 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
@ Type
The name was classified as a type.
Definition Sema.h:564
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.