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"
17 #include "clang/Basic/SourceManager.h"
18 #include "clang/Basic/TokenKinds.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/Support/Debug.h"
21
22 #define DEBUG_TYPE "format-token-annotator"
23
24 namespace clang {
25 namespace format {
26
27 namespace {
28
29 /// Returns \c true if the token can be used as an identifier in
30 /// an Objective-C \c \@selector, \c false otherwise.
31 ///
32 /// Because getFormattingLangOpts() always lexes source code as
33 /// Objective-C++, C++ keywords like \c new and \c delete are
34 /// lexed as tok::kw_*, not tok::identifier, even for Objective-C.
35 ///
36 /// For Objective-C and Objective-C++, both identifiers and keywords
37 /// are valid inside @selector(...) (or a macro which
38 /// invokes @selector(...)). So, we allow treat any identifier or
39 /// keyword as a potential Objective-C selector component.
canBeObjCSelectorComponent(const FormatToken & Tok)40 static bool canBeObjCSelectorComponent(const FormatToken &Tok) {
41 return Tok.Tok.getIdentifierInfo() != nullptr;
42 }
43
44 /// With `Left` being '(', check if we're at either `[...](` or
45 /// `[...]<...>(`, where the [ opens a lambda capture list.
isLambdaParameterList(const FormatToken * Left)46 static bool isLambdaParameterList(const FormatToken *Left) {
47 // Skip <...> if present.
48 if (Left->Previous && Left->Previous->is(tok::greater) &&
49 Left->Previous->MatchingParen &&
50 Left->Previous->MatchingParen->is(TT_TemplateOpener))
51 Left = Left->Previous->MatchingParen;
52
53 // Check for `[...]`.
54 return Left->Previous && Left->Previous->is(tok::r_square) &&
55 Left->Previous->MatchingParen &&
56 Left->Previous->MatchingParen->is(TT_LambdaLSquare);
57 }
58
59 /// Returns \c true if the token is followed by a boolean condition, \c false
60 /// otherwise.
isKeywordWithCondition(const FormatToken & Tok)61 static bool isKeywordWithCondition(const FormatToken &Tok) {
62 return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
63 tok::kw_constexpr, tok::kw_catch);
64 }
65
66 /// A parser that gathers additional information about tokens.
67 ///
68 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
69 /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
70 /// into template parameter lists.
71 class AnnotatingParser {
72 public:
AnnotatingParser(const FormatStyle & Style,AnnotatedLine & Line,const AdditionalKeywords & Keywords)73 AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line,
74 const AdditionalKeywords &Keywords)
75 : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
76 Keywords(Keywords) {
77 Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
78 resetTokenMetadata(CurrentToken);
79 }
80
81 private:
parseAngle()82 bool parseAngle() {
83 if (!CurrentToken || !CurrentToken->Previous)
84 return false;
85 if (NonTemplateLess.count(CurrentToken->Previous))
86 return false;
87
88 const FormatToken &Previous = *CurrentToken->Previous; // The '<'.
89 if (Previous.Previous) {
90 if (Previous.Previous->Tok.isLiteral())
91 return false;
92 if (Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 &&
93 (!Previous.Previous->MatchingParen ||
94 !Previous.Previous->MatchingParen->is(TT_OverloadedOperatorLParen)))
95 return false;
96 }
97
98 FormatToken *Left = CurrentToken->Previous;
99 Left->ParentBracket = Contexts.back().ContextKind;
100 ScopedContextCreator ContextCreator(*this, tok::less, 12);
101
102 // If this angle is in the context of an expression, we need to be more
103 // hesitant to detect it as opening template parameters.
104 bool InExprContext = Contexts.back().IsExpression;
105
106 Contexts.back().IsExpression = false;
107 // If there's a template keyword before the opening angle bracket, this is a
108 // template parameter, not an argument.
109 Contexts.back().InTemplateArgument =
110 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template);
111
112 if (Style.Language == FormatStyle::LK_Java &&
113 CurrentToken->is(tok::question))
114 next();
115
116 while (CurrentToken) {
117 if (CurrentToken->is(tok::greater)) {
118 // Try to do a better job at looking for ">>" within the condition of
119 // a statement. Conservatively insert spaces between consecutive ">"
120 // tokens to prevent splitting right bitshift operators and potentially
121 // altering program semantics. This check is overly conservative and
122 // will prevent spaces from being inserted in select nested template
123 // parameter cases, but should not alter program semantics.
124 if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
125 Left->ParentBracket != tok::less &&
126 (isKeywordWithCondition(*Line.First) ||
127 CurrentToken->getStartOfNonWhitespace() ==
128 CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset(
129 -1)))
130 return false;
131 Left->MatchingParen = CurrentToken;
132 CurrentToken->MatchingParen = Left;
133 // In TT_Proto, we must distignuish between:
134 // map<key, value>
135 // msg < item: data >
136 // msg: < item: data >
137 // In TT_TextProto, map<key, value> does not occur.
138 if (Style.Language == FormatStyle::LK_TextProto ||
139 (Style.Language == FormatStyle::LK_Proto && Left->Previous &&
140 Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral)))
141 CurrentToken->setType(TT_DictLiteral);
142 else
143 CurrentToken->setType(TT_TemplateCloser);
144 next();
145 return true;
146 }
147 if (CurrentToken->is(tok::question) &&
148 Style.Language == FormatStyle::LK_Java) {
149 next();
150 continue;
151 }
152 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
153 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
154 !Style.isCSharp() && Style.Language != FormatStyle::LK_Proto &&
155 Style.Language != FormatStyle::LK_TextProto))
156 return false;
157 // If a && or || is found and interpreted as a binary operator, this set
158 // of angles is likely part of something like "a < b && c > d". If the
159 // angles are inside an expression, the ||/&& might also be a binary
160 // operator that was misinterpreted because we are parsing template
161 // parameters.
162 // FIXME: This is getting out of hand, write a decent parser.
163 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
164 CurrentToken->Previous->is(TT_BinaryOperator) &&
165 Contexts[Contexts.size() - 2].IsExpression &&
166 !Line.startsWith(tok::kw_template))
167 return false;
168 updateParameterCount(Left, CurrentToken);
169 if (Style.Language == FormatStyle::LK_Proto) {
170 if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
171 if (CurrentToken->is(tok::colon) ||
172 (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
173 Previous->isNot(tok::colon)))
174 Previous->setType(TT_SelectorName);
175 }
176 }
177 if (!consumeToken())
178 return false;
179 }
180 return false;
181 }
182
parseUntouchableParens()183 bool parseUntouchableParens() {
184 while (CurrentToken) {
185 CurrentToken->Finalized = true;
186 switch (CurrentToken->Tok.getKind()) {
187 case tok::l_paren:
188 next();
189 if (!parseUntouchableParens())
190 return false;
191 continue;
192 case tok::r_paren:
193 next();
194 return true;
195 default:
196 // no-op
197 break;
198 }
199 next();
200 }
201 return false;
202 }
203
parseParens(bool LookForDecls=false)204 bool parseParens(bool LookForDecls = false) {
205 if (!CurrentToken)
206 return false;
207 FormatToken *Left = CurrentToken->Previous;
208 assert(Left && "Unknown previous token");
209 FormatToken *PrevNonComment = Left->getPreviousNonComment();
210 Left->ParentBracket = Contexts.back().ContextKind;
211 ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);
212
213 // FIXME: This is a bit of a hack. Do better.
214 Contexts.back().ColonIsForRangeExpr =
215 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
216
217 if (Left->Previous && Left->Previous->is(TT_UntouchableMacroFunc)) {
218 Left->Finalized = true;
219 return parseUntouchableParens();
220 }
221
222 bool StartsObjCMethodExpr = false;
223 if (FormatToken *MaybeSel = Left->Previous) {
224 // @selector( starts a selector.
225 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
226 MaybeSel->Previous->is(tok::at)) {
227 StartsObjCMethodExpr = true;
228 }
229 }
230
231 if (Left->is(TT_OverloadedOperatorLParen)) {
232 Contexts.back().IsExpression = false;
233 } else if (Style.Language == FormatStyle::LK_JavaScript &&
234 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
235 Line.startsWith(tok::kw_export, Keywords.kw_type,
236 tok::identifier))) {
237 // type X = (...);
238 // export type X = (...);
239 Contexts.back().IsExpression = false;
240 } else if (Left->Previous &&
241 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_while,
242 tok::l_paren, tok::comma) ||
243 Left->Previous->isIf() ||
244 Left->Previous->is(TT_BinaryOperator))) {
245 // static_assert, if and while usually contain expressions.
246 Contexts.back().IsExpression = true;
247 } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
248 (Left->Previous->is(Keywords.kw_function) ||
249 (Left->Previous->endsSequence(tok::identifier,
250 Keywords.kw_function)))) {
251 // function(...) or function f(...)
252 Contexts.back().IsExpression = false;
253 } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
254 Left->Previous->is(TT_JsTypeColon)) {
255 // let x: (SomeType);
256 Contexts.back().IsExpression = false;
257 } else if (isLambdaParameterList(Left)) {
258 // This is a parameter list of a lambda expression.
259 Contexts.back().IsExpression = false;
260 } else if (Line.InPPDirective &&
261 (!Left->Previous || !Left->Previous->is(tok::identifier))) {
262 Contexts.back().IsExpression = true;
263 } else if (Contexts[Contexts.size() - 2].CaretFound) {
264 // This is the parameter list of an ObjC block.
265 Contexts.back().IsExpression = false;
266 } else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) {
267 // The first argument to a foreach macro is a declaration.
268 Contexts.back().IsForEachMacro = true;
269 Contexts.back().IsExpression = false;
270 } else if (Left->Previous && Left->Previous->MatchingParen &&
271 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
272 Contexts.back().IsExpression = false;
273 } else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
274 bool IsForOrCatch =
275 Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch);
276 Contexts.back().IsExpression = !IsForOrCatch;
277 }
278
279 // Infer the role of the l_paren based on the previous token if we haven't
280 // detected one one yet.
281 if (PrevNonComment && Left->is(TT_Unknown)) {
282 if (PrevNonComment->is(tok::kw___attribute)) {
283 Left->setType(TT_AttributeParen);
284 } else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
285 tok::kw_typeof, tok::kw__Atomic,
286 tok::kw___underlying_type)) {
287 Left->setType(TT_TypeDeclarationParen);
288 // decltype() and typeof() usually contain expressions.
289 if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))
290 Contexts.back().IsExpression = true;
291 }
292 }
293
294 if (StartsObjCMethodExpr) {
295 Contexts.back().ColonIsObjCMethodExpr = true;
296 Left->setType(TT_ObjCMethodExpr);
297 }
298
299 // MightBeFunctionType and ProbablyFunctionType are used for
300 // function pointer and reference types as well as Objective-C
301 // block types:
302 //
303 // void (*FunctionPointer)(void);
304 // void (&FunctionReference)(void);
305 // void (^ObjCBlock)(void);
306 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
307 bool ProbablyFunctionType =
308 CurrentToken->isOneOf(tok::star, tok::amp, tok::caret);
309 bool HasMultipleLines = false;
310 bool HasMultipleParametersOnALine = false;
311 bool MightBeObjCForRangeLoop =
312 Left->Previous && Left->Previous->is(tok::kw_for);
313 FormatToken *PossibleObjCForInToken = nullptr;
314 while (CurrentToken) {
315 // LookForDecls is set when "if (" has been seen. Check for
316 // 'identifier' '*' 'identifier' followed by not '=' -- this
317 // '*' has to be a binary operator but determineStarAmpUsage() will
318 // categorize it as an unary operator, so set the right type here.
319 if (LookForDecls && CurrentToken->Next) {
320 FormatToken *Prev = CurrentToken->getPreviousNonComment();
321 if (Prev) {
322 FormatToken *PrevPrev = Prev->getPreviousNonComment();
323 FormatToken *Next = CurrentToken->Next;
324 if (PrevPrev && PrevPrev->is(tok::identifier) &&
325 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
326 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
327 Prev->setType(TT_BinaryOperator);
328 LookForDecls = false;
329 }
330 }
331 }
332
333 if (CurrentToken->Previous->is(TT_PointerOrReference) &&
334 CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
335 tok::coloncolon))
336 ProbablyFunctionType = true;
337 if (CurrentToken->is(tok::comma))
338 MightBeFunctionType = false;
339 if (CurrentToken->Previous->is(TT_BinaryOperator))
340 Contexts.back().IsExpression = true;
341 if (CurrentToken->is(tok::r_paren)) {
342 if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next &&
343 (CurrentToken->Next->is(tok::l_paren) ||
344 (CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration)))
345 Left->setType(Left->Next->is(tok::caret) ? TT_ObjCBlockLParen
346 : TT_FunctionTypeLParen);
347 Left->MatchingParen = CurrentToken;
348 CurrentToken->MatchingParen = Left;
349
350 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
351 Left->Previous && Left->Previous->is(tok::l_paren)) {
352 // Detect the case where macros are used to generate lambdas or
353 // function bodies, e.g.:
354 // auto my_lambda = MARCO((Type *type, int i) { .. body .. });
355 for (FormatToken *Tok = Left; Tok != CurrentToken; Tok = Tok->Next) {
356 if (Tok->is(TT_BinaryOperator) &&
357 Tok->isOneOf(tok::star, tok::amp, tok::ampamp))
358 Tok->setType(TT_PointerOrReference);
359 }
360 }
361
362 if (StartsObjCMethodExpr) {
363 CurrentToken->setType(TT_ObjCMethodExpr);
364 if (Contexts.back().FirstObjCSelectorName) {
365 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
366 Contexts.back().LongestObjCSelectorName;
367 }
368 }
369
370 if (Left->is(TT_AttributeParen))
371 CurrentToken->setType(TT_AttributeParen);
372 if (Left->is(TT_TypeDeclarationParen))
373 CurrentToken->setType(TT_TypeDeclarationParen);
374 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation))
375 CurrentToken->setType(TT_JavaAnnotation);
376 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
377 CurrentToken->setType(TT_LeadingJavaAnnotation);
378 if (Left->Previous && Left->Previous->is(TT_AttributeSquare))
379 CurrentToken->setType(TT_AttributeSquare);
380
381 if (!HasMultipleLines)
382 Left->setPackingKind(PPK_Inconclusive);
383 else if (HasMultipleParametersOnALine)
384 Left->setPackingKind(PPK_BinPacked);
385 else
386 Left->setPackingKind(PPK_OnePerLine);
387
388 next();
389 return true;
390 }
391 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
392 return false;
393
394 if (CurrentToken->is(tok::l_brace))
395 Left->setType(TT_Unknown); // Not TT_ObjCBlockLParen
396 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
397 !CurrentToken->Next->HasUnescapedNewline &&
398 !CurrentToken->Next->isTrailingComment())
399 HasMultipleParametersOnALine = true;
400 if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
401 CurrentToken->Previous->isSimpleTypeSpecifier()) &&
402 !CurrentToken->is(tok::l_brace))
403 Contexts.back().IsExpression = false;
404 if (CurrentToken->isOneOf(tok::semi, tok::colon)) {
405 MightBeObjCForRangeLoop = false;
406 if (PossibleObjCForInToken) {
407 PossibleObjCForInToken->setType(TT_Unknown);
408 PossibleObjCForInToken = nullptr;
409 }
410 }
411 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
412 PossibleObjCForInToken = CurrentToken;
413 PossibleObjCForInToken->setType(TT_ObjCForIn);
414 }
415 // When we discover a 'new', we set CanBeExpression to 'false' in order to
416 // parse the type correctly. Reset that after a comma.
417 if (CurrentToken->is(tok::comma))
418 Contexts.back().CanBeExpression = true;
419
420 FormatToken *Tok = CurrentToken;
421 if (!consumeToken())
422 return false;
423 updateParameterCount(Left, Tok);
424 if (CurrentToken && CurrentToken->HasUnescapedNewline)
425 HasMultipleLines = true;
426 }
427 return false;
428 }
429
isCSharpAttributeSpecifier(const FormatToken & Tok)430 bool isCSharpAttributeSpecifier(const FormatToken &Tok) {
431 if (!Style.isCSharp())
432 return false;
433
434 // `identifier[i]` is not an attribute.
435 if (Tok.Previous && Tok.Previous->is(tok::identifier))
436 return false;
437
438 // Chains of [] in `identifier[i][j][k]` are not attributes.
439 if (Tok.Previous && Tok.Previous->is(tok::r_square)) {
440 auto *MatchingParen = Tok.Previous->MatchingParen;
441 if (!MatchingParen || MatchingParen->is(TT_ArraySubscriptLSquare))
442 return false;
443 }
444
445 const FormatToken *AttrTok = Tok.Next;
446 if (!AttrTok)
447 return false;
448
449 // Just an empty declaration e.g. string [].
450 if (AttrTok->is(tok::r_square))
451 return false;
452
453 // Move along the tokens inbetween the '[' and ']' e.g. [STAThread].
454 while (AttrTok && AttrTok->isNot(tok::r_square)) {
455 AttrTok = AttrTok->Next;
456 }
457
458 if (!AttrTok)
459 return false;
460
461 // Allow an attribute to be the only content of a file.
462 AttrTok = AttrTok->Next;
463 if (!AttrTok)
464 return true;
465
466 // Limit this to being an access modifier that follows.
467 if (AttrTok->isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
468 tok::comment, tok::kw_class, tok::kw_static,
469 tok::l_square, Keywords.kw_internal)) {
470 return true;
471 }
472
473 // incase its a [XXX] retval func(....
474 if (AttrTok->Next &&
475 AttrTok->Next->startsSequence(tok::identifier, tok::l_paren))
476 return true;
477
478 return false;
479 }
480
isCpp11AttributeSpecifier(const FormatToken & Tok)481 bool isCpp11AttributeSpecifier(const FormatToken &Tok) {
482 if (!Style.isCpp() || !Tok.startsSequence(tok::l_square, tok::l_square))
483 return false;
484 // The first square bracket is part of an ObjC array literal
485 if (Tok.Previous && Tok.Previous->is(tok::at)) {
486 return false;
487 }
488 const FormatToken *AttrTok = Tok.Next->Next;
489 if (!AttrTok)
490 return false;
491 // C++17 '[[using ns: foo, bar(baz, blech)]]'
492 // We assume nobody will name an ObjC variable 'using'.
493 if (AttrTok->startsSequence(tok::kw_using, tok::identifier, tok::colon))
494 return true;
495 if (AttrTok->isNot(tok::identifier))
496 return false;
497 while (AttrTok && !AttrTok->startsSequence(tok::r_square, tok::r_square)) {
498 // ObjC message send. We assume nobody will use : in a C++11 attribute
499 // specifier parameter, although this is technically valid:
500 // [[foo(:)]].
501 if (AttrTok->is(tok::colon) ||
502 AttrTok->startsSequence(tok::identifier, tok::identifier) ||
503 AttrTok->startsSequence(tok::r_paren, tok::identifier))
504 return false;
505 if (AttrTok->is(tok::ellipsis))
506 return true;
507 AttrTok = AttrTok->Next;
508 }
509 return AttrTok && AttrTok->startsSequence(tok::r_square, tok::r_square);
510 }
511
parseSquare()512 bool parseSquare() {
513 if (!CurrentToken)
514 return false;
515
516 // A '[' could be an index subscript (after an identifier or after
517 // ')' or ']'), it could be the start of an Objective-C method
518 // expression, it could the start of an Objective-C array literal,
519 // or it could be a C++ attribute specifier [[foo::bar]].
520 FormatToken *Left = CurrentToken->Previous;
521 Left->ParentBracket = Contexts.back().ContextKind;
522 FormatToken *Parent = Left->getPreviousNonComment();
523
524 // Cases where '>' is followed by '['.
525 // In C++, this can happen either in array of templates (foo<int>[10])
526 // or when array is a nested template type (unique_ptr<type1<type2>[]>).
527 bool CppArrayTemplates =
528 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
529 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
530 Contexts.back().InTemplateArgument);
531
532 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
533 Contexts.back().InCpp11AttributeSpecifier;
534
535 // Treat C# Attributes [STAThread] much like C++ attributes [[...]].
536 bool IsCSharpAttributeSpecifier =
537 isCSharpAttributeSpecifier(*Left) ||
538 Contexts.back().InCSharpAttributeSpecifier;
539
540 bool InsideInlineASM = Line.startsWith(tok::kw_asm);
541 bool IsCppStructuredBinding = Left->isCppStructuredBinding(Style);
542 bool StartsObjCMethodExpr =
543 !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
544 Style.isCpp() && !IsCpp11AttributeSpecifier &&
545 !IsCSharpAttributeSpecifier && Contexts.back().CanBeExpression &&
546 Left->isNot(TT_LambdaLSquare) &&
547 !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
548 (!Parent ||
549 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
550 tok::kw_return, tok::kw_throw) ||
551 Parent->isUnaryOperator() ||
552 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
553 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
554 (getBinOpPrecedence(Parent->Tok.getKind(), true, true) >
555 prec::Unknown));
556 bool ColonFound = false;
557
558 unsigned BindingIncrease = 1;
559 if (IsCppStructuredBinding) {
560 Left->setType(TT_StructuredBindingLSquare);
561 } else if (Left->is(TT_Unknown)) {
562 if (StartsObjCMethodExpr) {
563 Left->setType(TT_ObjCMethodExpr);
564 } else if (InsideInlineASM) {
565 Left->setType(TT_InlineASMSymbolicNameLSquare);
566 } else if (IsCpp11AttributeSpecifier) {
567 Left->setType(TT_AttributeSquare);
568 } else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
569 Contexts.back().ContextKind == tok::l_brace &&
570 Parent->isOneOf(tok::l_brace, tok::comma)) {
571 Left->setType(TT_JsComputedPropertyName);
572 } else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace &&
573 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
574 Left->setType(TT_DesignatedInitializerLSquare);
575 } else if (IsCSharpAttributeSpecifier) {
576 Left->setType(TT_AttributeSquare);
577 } else if (CurrentToken->is(tok::r_square) && Parent &&
578 Parent->is(TT_TemplateCloser)) {
579 Left->setType(TT_ArraySubscriptLSquare);
580 } else if (Style.Language == FormatStyle::LK_Proto ||
581 Style.Language == FormatStyle::LK_TextProto) {
582 // Square braces in LK_Proto can either be message field attributes:
583 //
584 // optional Aaa aaa = 1 [
585 // (aaa) = aaa
586 // ];
587 //
588 // extensions 123 [
589 // (aaa) = aaa
590 // ];
591 //
592 // or text proto extensions (in options):
593 //
594 // option (Aaa.options) = {
595 // [type.type/type] {
596 // key: value
597 // }
598 // }
599 //
600 // or repeated fields (in options):
601 //
602 // option (Aaa.options) = {
603 // keys: [ 1, 2, 3 ]
604 // }
605 //
606 // In the first and the third case we want to spread the contents inside
607 // the square braces; in the second we want to keep them inline.
608 Left->setType(TT_ArrayInitializerLSquare);
609 if (!Left->endsSequence(tok::l_square, tok::numeric_constant,
610 tok::equal) &&
611 !Left->endsSequence(tok::l_square, tok::numeric_constant,
612 tok::identifier) &&
613 !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) {
614 Left->setType(TT_ProtoExtensionLSquare);
615 BindingIncrease = 10;
616 }
617 } else if (!CppArrayTemplates && Parent &&
618 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
619 tok::comma, tok::l_paren, tok::l_square,
620 tok::question, tok::colon, tok::kw_return,
621 // Should only be relevant to JavaScript:
622 tok::kw_default)) {
623 Left->setType(TT_ArrayInitializerLSquare);
624 } else {
625 BindingIncrease = 10;
626 Left->setType(TT_ArraySubscriptLSquare);
627 }
628 }
629
630 ScopedContextCreator ContextCreator(*this, tok::l_square, BindingIncrease);
631 Contexts.back().IsExpression = true;
632 if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
633 Parent->is(TT_JsTypeColon))
634 Contexts.back().IsExpression = false;
635
636 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
637 Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
638 Contexts.back().InCSharpAttributeSpecifier = IsCSharpAttributeSpecifier;
639
640 while (CurrentToken) {
641 if (CurrentToken->is(tok::r_square)) {
642 if (IsCpp11AttributeSpecifier)
643 CurrentToken->setType(TT_AttributeSquare);
644 if (IsCSharpAttributeSpecifier)
645 CurrentToken->setType(TT_AttributeSquare);
646 else if (((CurrentToken->Next &&
647 CurrentToken->Next->is(tok::l_paren)) ||
648 (CurrentToken->Previous &&
649 CurrentToken->Previous->Previous == Left)) &&
650 Left->is(TT_ObjCMethodExpr)) {
651 // An ObjC method call is rarely followed by an open parenthesis. It
652 // also can't be composed of just one token, unless it's a macro that
653 // will be expanded to more tokens.
654 // FIXME: Do we incorrectly label ":" with this?
655 StartsObjCMethodExpr = false;
656 Left->setType(TT_Unknown);
657 }
658 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
659 CurrentToken->setType(TT_ObjCMethodExpr);
660 // If we haven't seen a colon yet, make sure the last identifier
661 // before the r_square is tagged as a selector name component.
662 if (!ColonFound && CurrentToken->Previous &&
663 CurrentToken->Previous->is(TT_Unknown) &&
664 canBeObjCSelectorComponent(*CurrentToken->Previous))
665 CurrentToken->Previous->setType(TT_SelectorName);
666 // determineStarAmpUsage() thinks that '*' '[' is allocating an
667 // array of pointers, but if '[' starts a selector then '*' is a
668 // binary operator.
669 if (Parent && Parent->is(TT_PointerOrReference))
670 Parent->setType(TT_BinaryOperator);
671 }
672 // An arrow after an ObjC method expression is not a lambda arrow.
673 if (CurrentToken->getType() == TT_ObjCMethodExpr &&
674 CurrentToken->Next && CurrentToken->Next->is(TT_LambdaArrow))
675 CurrentToken->Next->setType(TT_Unknown);
676 Left->MatchingParen = CurrentToken;
677 CurrentToken->MatchingParen = Left;
678 // FirstObjCSelectorName is set when a colon is found. This does
679 // not work, however, when the method has no parameters.
680 // Here, we set FirstObjCSelectorName when the end of the method call is
681 // reached, in case it was not set already.
682 if (!Contexts.back().FirstObjCSelectorName) {
683 FormatToken *Previous = CurrentToken->getPreviousNonComment();
684 if (Previous && Previous->is(TT_SelectorName)) {
685 Previous->ObjCSelectorNameParts = 1;
686 Contexts.back().FirstObjCSelectorName = Previous;
687 }
688 } else {
689 Left->ParameterCount =
690 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
691 }
692 if (Contexts.back().FirstObjCSelectorName) {
693 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
694 Contexts.back().LongestObjCSelectorName;
695 if (Left->BlockParameterCount > 1)
696 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
697 }
698 next();
699 return true;
700 }
701 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
702 return false;
703 if (CurrentToken->is(tok::colon)) {
704 if (IsCpp11AttributeSpecifier &&
705 CurrentToken->endsSequence(tok::colon, tok::identifier,
706 tok::kw_using)) {
707 // Remember that this is a [[using ns: foo]] C++ attribute, so we
708 // don't add a space before the colon (unlike other colons).
709 CurrentToken->setType(TT_AttributeColon);
710 } else if (Left->isOneOf(TT_ArraySubscriptLSquare,
711 TT_DesignatedInitializerLSquare)) {
712 Left->setType(TT_ObjCMethodExpr);
713 StartsObjCMethodExpr = true;
714 Contexts.back().ColonIsObjCMethodExpr = true;
715 if (Parent && Parent->is(tok::r_paren))
716 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
717 Parent->setType(TT_CastRParen);
718 }
719 ColonFound = true;
720 }
721 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
722 !ColonFound)
723 Left->setType(TT_ArrayInitializerLSquare);
724 FormatToken *Tok = CurrentToken;
725 if (!consumeToken())
726 return false;
727 updateParameterCount(Left, Tok);
728 }
729 return false;
730 }
731
parseBrace()732 bool parseBrace() {
733 if (CurrentToken) {
734 FormatToken *Left = CurrentToken->Previous;
735 Left->ParentBracket = Contexts.back().ContextKind;
736
737 if (Contexts.back().CaretFound)
738 Left->setType(TT_ObjCBlockLBrace);
739 Contexts.back().CaretFound = false;
740
741 ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
742 Contexts.back().ColonIsDictLiteral = true;
743 if (Left->is(BK_BracedInit))
744 Contexts.back().IsExpression = true;
745 if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
746 Left->Previous->is(TT_JsTypeColon))
747 Contexts.back().IsExpression = false;
748
749 while (CurrentToken) {
750 if (CurrentToken->is(tok::r_brace)) {
751 Left->MatchingParen = CurrentToken;
752 CurrentToken->MatchingParen = Left;
753 next();
754 return true;
755 }
756 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
757 return false;
758 updateParameterCount(Left, CurrentToken);
759 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
760 FormatToken *Previous = CurrentToken->getPreviousNonComment();
761 if (Previous->is(TT_JsTypeOptionalQuestion))
762 Previous = Previous->getPreviousNonComment();
763 if ((CurrentToken->is(tok::colon) &&
764 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
765 Style.Language == FormatStyle::LK_Proto ||
766 Style.Language == FormatStyle::LK_TextProto) {
767 Left->setType(TT_DictLiteral);
768 if (Previous->Tok.getIdentifierInfo() ||
769 Previous->is(tok::string_literal))
770 Previous->setType(TT_SelectorName);
771 }
772 if (CurrentToken->is(tok::colon) ||
773 Style.Language == FormatStyle::LK_JavaScript)
774 Left->setType(TT_DictLiteral);
775 }
776 if (CurrentToken->is(tok::comma) &&
777 Style.Language == FormatStyle::LK_JavaScript)
778 Left->setType(TT_DictLiteral);
779 if (!consumeToken())
780 return false;
781 }
782 }
783 return true;
784 }
785
updateParameterCount(FormatToken * Left,FormatToken * Current)786 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
787 // For ObjC methods, the number of parameters is calculated differently as
788 // method declarations have a different structure (the parameters are not
789 // inside a bracket scope).
790 if (Current->is(tok::l_brace) && Current->is(BK_Block))
791 ++Left->BlockParameterCount;
792 if (Current->is(tok::comma)) {
793 ++Left->ParameterCount;
794 if (!Left->Role)
795 Left->Role.reset(new CommaSeparatedList(Style));
796 Left->Role->CommaFound(Current);
797 } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
798 Left->ParameterCount = 1;
799 }
800 }
801
parseConditional()802 bool parseConditional() {
803 while (CurrentToken) {
804 if (CurrentToken->is(tok::colon)) {
805 CurrentToken->setType(TT_ConditionalExpr);
806 next();
807 return true;
808 }
809 if (!consumeToken())
810 return false;
811 }
812 return false;
813 }
814
parseTemplateDeclaration()815 bool parseTemplateDeclaration() {
816 if (CurrentToken && CurrentToken->is(tok::less)) {
817 CurrentToken->setType(TT_TemplateOpener);
818 next();
819 if (!parseAngle())
820 return false;
821 if (CurrentToken)
822 CurrentToken->Previous->ClosesTemplateDeclaration = true;
823 return true;
824 }
825 return false;
826 }
827
consumeToken()828 bool consumeToken() {
829 FormatToken *Tok = CurrentToken;
830 next();
831 switch (Tok->Tok.getKind()) {
832 case tok::plus:
833 case tok::minus:
834 if (!Tok->Previous && Line.MustBeDeclaration)
835 Tok->setType(TT_ObjCMethodSpecifier);
836 break;
837 case tok::colon:
838 if (!Tok->Previous)
839 return false;
840 // Colons from ?: are handled in parseConditional().
841 if (Style.Language == FormatStyle::LK_JavaScript) {
842 if (Contexts.back().ColonIsForRangeExpr || // colon in for loop
843 (Contexts.size() == 1 && // switch/case labels
844 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
845 Contexts.back().ContextKind == tok::l_paren || // function params
846 Contexts.back().ContextKind == tok::l_square || // array type
847 (!Contexts.back().IsExpression &&
848 Contexts.back().ContextKind == tok::l_brace) || // object type
849 (Contexts.size() == 1 &&
850 Line.MustBeDeclaration)) { // method/property declaration
851 Contexts.back().IsExpression = false;
852 Tok->setType(TT_JsTypeColon);
853 break;
854 }
855 } else if (Style.isCSharp()) {
856 if (Contexts.back().InCSharpAttributeSpecifier) {
857 Tok->setType(TT_AttributeColon);
858 break;
859 }
860 if (Contexts.back().ContextKind == tok::l_paren) {
861 Tok->setType(TT_CSharpNamedArgumentColon);
862 break;
863 }
864 }
865 if (Contexts.back().ColonIsDictLiteral ||
866 Style.Language == FormatStyle::LK_Proto ||
867 Style.Language == FormatStyle::LK_TextProto) {
868 Tok->setType(TT_DictLiteral);
869 if (Style.Language == FormatStyle::LK_TextProto) {
870 if (FormatToken *Previous = Tok->getPreviousNonComment())
871 Previous->setType(TT_SelectorName);
872 }
873 } else if (Contexts.back().ColonIsObjCMethodExpr ||
874 Line.startsWith(TT_ObjCMethodSpecifier)) {
875 Tok->setType(TT_ObjCMethodExpr);
876 const FormatToken *BeforePrevious = Tok->Previous->Previous;
877 // Ensure we tag all identifiers in method declarations as
878 // TT_SelectorName.
879 bool UnknownIdentifierInMethodDeclaration =
880 Line.startsWith(TT_ObjCMethodSpecifier) &&
881 Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
882 if (!BeforePrevious ||
883 // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
884 !(BeforePrevious->is(TT_CastRParen) ||
885 (BeforePrevious->is(TT_ObjCMethodExpr) &&
886 BeforePrevious->is(tok::colon))) ||
887 BeforePrevious->is(tok::r_square) ||
888 Contexts.back().LongestObjCSelectorName == 0 ||
889 UnknownIdentifierInMethodDeclaration) {
890 Tok->Previous->setType(TT_SelectorName);
891 if (!Contexts.back().FirstObjCSelectorName)
892 Contexts.back().FirstObjCSelectorName = Tok->Previous;
893 else if (Tok->Previous->ColumnWidth >
894 Contexts.back().LongestObjCSelectorName)
895 Contexts.back().LongestObjCSelectorName =
896 Tok->Previous->ColumnWidth;
897 Tok->Previous->ParameterIndex =
898 Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
899 ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
900 }
901 } else if (Contexts.back().ColonIsForRangeExpr) {
902 Tok->setType(TT_RangeBasedForLoopColon);
903 } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
904 Tok->setType(TT_BitFieldColon);
905 } else if (Contexts.size() == 1 &&
906 !Line.First->isOneOf(tok::kw_enum, tok::kw_case,
907 tok::kw_default)) {
908 FormatToken *Prev = Tok->getPreviousNonComment();
909 if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept))
910 Tok->setType(TT_CtorInitializerColon);
911 else if (Prev->is(tok::kw_try)) {
912 // Member initializer list within function try block.
913 FormatToken *PrevPrev = Prev->getPreviousNonComment();
914 if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept))
915 Tok->setType(TT_CtorInitializerColon);
916 } else
917 Tok->setType(TT_InheritanceColon);
918 } else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
919 (Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
920 (canBeObjCSelectorComponent(*Tok->Next) && Tok->Next->Next &&
921 Tok->Next->Next->is(tok::colon)))) {
922 // This handles a special macro in ObjC code where selectors including
923 // the colon are passed as macro arguments.
924 Tok->setType(TT_ObjCMethodExpr);
925 } else if (Contexts.back().ContextKind == tok::l_paren) {
926 Tok->setType(TT_InlineASMColon);
927 }
928 break;
929 case tok::pipe:
930 case tok::amp:
931 // | and & in declarations/type expressions represent union and
932 // intersection types, respectively.
933 if (Style.Language == FormatStyle::LK_JavaScript &&
934 !Contexts.back().IsExpression)
935 Tok->setType(TT_JsTypeOperator);
936 break;
937 case tok::kw_if:
938 case tok::kw_while:
939 if (Tok->is(tok::kw_if) && CurrentToken &&
940 CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier))
941 next();
942 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
943 next();
944 if (!parseParens(/*LookForDecls=*/true))
945 return false;
946 }
947 break;
948 case tok::kw_for:
949 if (Style.Language == FormatStyle::LK_JavaScript) {
950 // x.for and {for: ...}
951 if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
952 (Tok->Next && Tok->Next->is(tok::colon)))
953 break;
954 // JS' for await ( ...
955 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
956 next();
957 }
958 Contexts.back().ColonIsForRangeExpr = true;
959 next();
960 if (!parseParens())
961 return false;
962 break;
963 case tok::l_paren:
964 // When faced with 'operator()()', the kw_operator handler incorrectly
965 // marks the first l_paren as a OverloadedOperatorLParen. Here, we make
966 // the first two parens OverloadedOperators and the second l_paren an
967 // OverloadedOperatorLParen.
968 if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
969 Tok->Previous->MatchingParen &&
970 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
971 Tok->Previous->setType(TT_OverloadedOperator);
972 Tok->Previous->MatchingParen->setType(TT_OverloadedOperator);
973 Tok->setType(TT_OverloadedOperatorLParen);
974 }
975
976 if (!parseParens())
977 return false;
978 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
979 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
980 !Tok->is(TT_TypeDeclarationParen) &&
981 (!Tok->Previous || !Tok->Previous->isOneOf(tok::kw___attribute,
982 TT_LeadingJavaAnnotation)))
983 Line.MightBeFunctionDecl = true;
984 break;
985 case tok::l_square:
986 if (!parseSquare())
987 return false;
988 break;
989 case tok::l_brace:
990 if (Style.Language == FormatStyle::LK_TextProto) {
991 FormatToken *Previous = Tok->getPreviousNonComment();
992 if (Previous && Previous->getType() != TT_DictLiteral)
993 Previous->setType(TT_SelectorName);
994 }
995 if (!parseBrace())
996 return false;
997 break;
998 case tok::less:
999 if (parseAngle()) {
1000 Tok->setType(TT_TemplateOpener);
1001 // In TT_Proto, we must distignuish between:
1002 // map<key, value>
1003 // msg < item: data >
1004 // msg: < item: data >
1005 // In TT_TextProto, map<key, value> does not occur.
1006 if (Style.Language == FormatStyle::LK_TextProto ||
1007 (Style.Language == FormatStyle::LK_Proto && Tok->Previous &&
1008 Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
1009 Tok->setType(TT_DictLiteral);
1010 FormatToken *Previous = Tok->getPreviousNonComment();
1011 if (Previous && Previous->getType() != TT_DictLiteral)
1012 Previous->setType(TT_SelectorName);
1013 }
1014 } else {
1015 Tok->setType(TT_BinaryOperator);
1016 NonTemplateLess.insert(Tok);
1017 CurrentToken = Tok;
1018 next();
1019 }
1020 break;
1021 case tok::r_paren:
1022 case tok::r_square:
1023 return false;
1024 case tok::r_brace:
1025 // Lines can start with '}'.
1026 if (Tok->Previous)
1027 return false;
1028 break;
1029 case tok::greater:
1030 if (Style.Language != FormatStyle::LK_TextProto)
1031 Tok->setType(TT_BinaryOperator);
1032 if (Tok->Previous && Tok->Previous->is(TT_TemplateCloser))
1033 Tok->SpacesRequiredBefore = 1;
1034 break;
1035 case tok::kw_operator:
1036 if (Style.Language == FormatStyle::LK_TextProto ||
1037 Style.Language == FormatStyle::LK_Proto)
1038 break;
1039 while (CurrentToken &&
1040 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
1041 if (CurrentToken->isOneOf(tok::star, tok::amp))
1042 CurrentToken->setType(TT_PointerOrReference);
1043 consumeToken();
1044 if (CurrentToken && CurrentToken->is(tok::comma) &&
1045 CurrentToken->Previous->isNot(tok::kw_operator))
1046 break;
1047 if (CurrentToken && CurrentToken->Previous->isOneOf(
1048 TT_BinaryOperator, TT_UnaryOperator, tok::comma,
1049 tok::star, tok::arrow, tok::amp, tok::ampamp))
1050 CurrentToken->Previous->setType(TT_OverloadedOperator);
1051 }
1052 if (CurrentToken && CurrentToken->is(tok::l_paren))
1053 CurrentToken->setType(TT_OverloadedOperatorLParen);
1054 if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator))
1055 CurrentToken->Previous->setType(TT_OverloadedOperator);
1056 break;
1057 case tok::question:
1058 if (Style.Language == FormatStyle::LK_JavaScript && Tok->Next &&
1059 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
1060 tok::r_brace)) {
1061 // Question marks before semicolons, colons, etc. indicate optional
1062 // types (fields, parameters), e.g.
1063 // function(x?: string, y?) {...}
1064 // class X { y?; }
1065 Tok->setType(TT_JsTypeOptionalQuestion);
1066 break;
1067 }
1068 // Declarations cannot be conditional expressions, this can only be part
1069 // of a type declaration.
1070 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
1071 Style.Language == FormatStyle::LK_JavaScript)
1072 break;
1073 if (Style.isCSharp()) {
1074 // `Type?)`, `Type?>`, `Type? name;` and `Type? name =` can only be
1075 // nullable types.
1076 // Line.MustBeDeclaration will be true for `Type? name;`.
1077 if ((!Contexts.back().IsExpression && Line.MustBeDeclaration) ||
1078 (Tok->Next && Tok->Next->isOneOf(tok::r_paren, tok::greater)) ||
1079 (Tok->Next && Tok->Next->is(tok::identifier) && Tok->Next->Next &&
1080 Tok->Next->Next->is(tok::equal))) {
1081 Tok->setType(TT_CSharpNullable);
1082 break;
1083 }
1084 }
1085 parseConditional();
1086 break;
1087 case tok::kw_template:
1088 parseTemplateDeclaration();
1089 break;
1090 case tok::comma:
1091 if (Contexts.back().InCtorInitializer)
1092 Tok->setType(TT_CtorInitializerComma);
1093 else if (Contexts.back().InInheritanceList)
1094 Tok->setType(TT_InheritanceComma);
1095 else if (Contexts.back().FirstStartOfName &&
1096 (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
1097 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
1098 Line.IsMultiVariableDeclStmt = true;
1099 }
1100 if (Contexts.back().IsForEachMacro)
1101 Contexts.back().IsExpression = true;
1102 break;
1103 case tok::identifier:
1104 if (Tok->isOneOf(Keywords.kw___has_include,
1105 Keywords.kw___has_include_next)) {
1106 parseHasInclude();
1107 }
1108 if (Style.isCSharp() && Tok->is(Keywords.kw_where) && Tok->Next &&
1109 Tok->Next->isNot(tok::l_paren)) {
1110 Tok->setType(TT_CSharpGenericTypeConstraint);
1111 parseCSharpGenericTypeConstraint();
1112 }
1113 break;
1114 default:
1115 break;
1116 }
1117 return true;
1118 }
1119
parseCSharpGenericTypeConstraint()1120 void parseCSharpGenericTypeConstraint() {
1121 int OpenAngleBracketsCount = 0;
1122 while (CurrentToken) {
1123 if (CurrentToken->is(tok::less)) {
1124 // parseAngle is too greedy and will consume the whole line.
1125 CurrentToken->setType(TT_TemplateOpener);
1126 ++OpenAngleBracketsCount;
1127 next();
1128 } else if (CurrentToken->is(tok::greater)) {
1129 CurrentToken->setType(TT_TemplateCloser);
1130 --OpenAngleBracketsCount;
1131 next();
1132 } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) {
1133 // We allow line breaks after GenericTypeConstraintComma's
1134 // so do not flag commas in Generics as GenericTypeConstraintComma's.
1135 CurrentToken->setType(TT_CSharpGenericTypeConstraintComma);
1136 next();
1137 } else if (CurrentToken->is(Keywords.kw_where)) {
1138 CurrentToken->setType(TT_CSharpGenericTypeConstraint);
1139 next();
1140 } else if (CurrentToken->is(tok::colon)) {
1141 CurrentToken->setType(TT_CSharpGenericTypeConstraintColon);
1142 next();
1143 } else {
1144 next();
1145 }
1146 }
1147 }
1148
parseIncludeDirective()1149 void parseIncludeDirective() {
1150 if (CurrentToken && CurrentToken->is(tok::less)) {
1151 next();
1152 while (CurrentToken) {
1153 // Mark tokens up to the trailing line comments as implicit string
1154 // literals.
1155 if (CurrentToken->isNot(tok::comment) &&
1156 !CurrentToken->TokenText.startswith("//"))
1157 CurrentToken->setType(TT_ImplicitStringLiteral);
1158 next();
1159 }
1160 }
1161 }
1162
parseWarningOrError()1163 void parseWarningOrError() {
1164 next();
1165 // We still want to format the whitespace left of the first token of the
1166 // warning or error.
1167 next();
1168 while (CurrentToken) {
1169 CurrentToken->setType(TT_ImplicitStringLiteral);
1170 next();
1171 }
1172 }
1173
parsePragma()1174 void parsePragma() {
1175 next(); // Consume "pragma".
1176 if (CurrentToken &&
1177 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) {
1178 bool IsMark = CurrentToken->is(Keywords.kw_mark);
1179 next(); // Consume "mark".
1180 next(); // Consume first token (so we fix leading whitespace).
1181 while (CurrentToken) {
1182 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator))
1183 CurrentToken->setType(TT_ImplicitStringLiteral);
1184 next();
1185 }
1186 }
1187 }
1188
parseHasInclude()1189 void parseHasInclude() {
1190 if (!CurrentToken || !CurrentToken->is(tok::l_paren))
1191 return;
1192 next(); // '('
1193 parseIncludeDirective();
1194 next(); // ')'
1195 }
1196
parsePreprocessorDirective()1197 LineType parsePreprocessorDirective() {
1198 bool IsFirstToken = CurrentToken->IsFirst;
1199 LineType Type = LT_PreprocessorDirective;
1200 next();
1201 if (!CurrentToken)
1202 return Type;
1203
1204 if (Style.Language == FormatStyle::LK_JavaScript && IsFirstToken) {
1205 // JavaScript files can contain shebang lines of the form:
1206 // #!/usr/bin/env node
1207 // Treat these like C++ #include directives.
1208 while (CurrentToken) {
1209 // Tokens cannot be comments here.
1210 CurrentToken->setType(TT_ImplicitStringLiteral);
1211 next();
1212 }
1213 return LT_ImportStatement;
1214 }
1215
1216 if (CurrentToken->Tok.is(tok::numeric_constant)) {
1217 CurrentToken->SpacesRequiredBefore = 1;
1218 return Type;
1219 }
1220 // Hashes in the middle of a line can lead to any strange token
1221 // sequence.
1222 if (!CurrentToken->Tok.getIdentifierInfo())
1223 return Type;
1224 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
1225 case tok::pp_include:
1226 case tok::pp_include_next:
1227 case tok::pp_import:
1228 next();
1229 parseIncludeDirective();
1230 Type = LT_ImportStatement;
1231 break;
1232 case tok::pp_error:
1233 case tok::pp_warning:
1234 parseWarningOrError();
1235 break;
1236 case tok::pp_pragma:
1237 parsePragma();
1238 break;
1239 case tok::pp_if:
1240 case tok::pp_elif:
1241 Contexts.back().IsExpression = true;
1242 next();
1243 parseLine();
1244 break;
1245 default:
1246 break;
1247 }
1248 while (CurrentToken) {
1249 FormatToken *Tok = CurrentToken;
1250 next();
1251 if (Tok->is(tok::l_paren))
1252 parseParens();
1253 else if (Tok->isOneOf(Keywords.kw___has_include,
1254 Keywords.kw___has_include_next))
1255 parseHasInclude();
1256 }
1257 return Type;
1258 }
1259
1260 public:
parseLine()1261 LineType parseLine() {
1262 if (!CurrentToken)
1263 return LT_Invalid;
1264 NonTemplateLess.clear();
1265 if (CurrentToken->is(tok::hash))
1266 return parsePreprocessorDirective();
1267
1268 // Directly allow to 'import <string-literal>' to support protocol buffer
1269 // definitions (github.com/google/protobuf) or missing "#" (either way we
1270 // should not break the line).
1271 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
1272 if ((Style.Language == FormatStyle::LK_Java &&
1273 CurrentToken->is(Keywords.kw_package)) ||
1274 (Info && Info->getPPKeywordID() == tok::pp_import &&
1275 CurrentToken->Next &&
1276 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
1277 tok::kw_static))) {
1278 next();
1279 parseIncludeDirective();
1280 return LT_ImportStatement;
1281 }
1282
1283 // If this line starts and ends in '<' and '>', respectively, it is likely
1284 // part of "#define <a/b.h>".
1285 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
1286 parseIncludeDirective();
1287 return LT_ImportStatement;
1288 }
1289
1290 // In .proto files, top-level options and package statements are very
1291 // similar to import statements and should not be line-wrapped.
1292 if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 &&
1293 CurrentToken->isOneOf(Keywords.kw_option, Keywords.kw_package)) {
1294 next();
1295 if (CurrentToken && CurrentToken->is(tok::identifier)) {
1296 while (CurrentToken)
1297 next();
1298 return LT_ImportStatement;
1299 }
1300 }
1301
1302 bool KeywordVirtualFound = false;
1303 bool ImportStatement = false;
1304
1305 // import {...} from '...';
1306 if (Style.Language == FormatStyle::LK_JavaScript &&
1307 CurrentToken->is(Keywords.kw_import))
1308 ImportStatement = true;
1309
1310 while (CurrentToken) {
1311 if (CurrentToken->is(tok::kw_virtual))
1312 KeywordVirtualFound = true;
1313 if (Style.Language == FormatStyle::LK_JavaScript) {
1314 // export {...} from '...';
1315 // An export followed by "from 'some string';" is a re-export from
1316 // another module identified by a URI and is treated as a
1317 // LT_ImportStatement (i.e. prevent wraps on it for long URIs).
1318 // Just "export {...};" or "export class ..." should not be treated as
1319 // an import in this sense.
1320 if (Line.First->is(tok::kw_export) &&
1321 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
1322 CurrentToken->Next->isStringLiteral())
1323 ImportStatement = true;
1324 if (isClosureImportStatement(*CurrentToken))
1325 ImportStatement = true;
1326 }
1327 if (!consumeToken())
1328 return LT_Invalid;
1329 }
1330 if (KeywordVirtualFound)
1331 return LT_VirtualFunctionDecl;
1332 if (ImportStatement)
1333 return LT_ImportStatement;
1334
1335 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
1336 if (Contexts.back().FirstObjCSelectorName)
1337 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
1338 Contexts.back().LongestObjCSelectorName;
1339 return LT_ObjCMethodDecl;
1340 }
1341
1342 return LT_Other;
1343 }
1344
1345 private:
isClosureImportStatement(const FormatToken & Tok)1346 bool isClosureImportStatement(const FormatToken &Tok) {
1347 // FIXME: Closure-library specific stuff should not be hard-coded but be
1348 // configurable.
1349 return Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) &&
1350 Tok.Next->Next &&
1351 (Tok.Next->Next->TokenText == "module" ||
1352 Tok.Next->Next->TokenText == "provide" ||
1353 Tok.Next->Next->TokenText == "require" ||
1354 Tok.Next->Next->TokenText == "requireType" ||
1355 Tok.Next->Next->TokenText == "forwardDeclare") &&
1356 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
1357 }
1358
resetTokenMetadata(FormatToken * Token)1359 void resetTokenMetadata(FormatToken *Token) {
1360 if (!Token)
1361 return;
1362
1363 // Reset token type in case we have already looked at it and then
1364 // recovered from an error (e.g. failure to find the matching >).
1365 if (!CurrentToken->isOneOf(
1366 TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro,
1367 TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
1368 TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
1369 TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
1370 TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
1371 TT_UntouchableMacroFunc, TT_ConstraintJunctions,
1372 TT_StatementAttributeLikeMacro))
1373 CurrentToken->setType(TT_Unknown);
1374 CurrentToken->Role.reset();
1375 CurrentToken->MatchingParen = nullptr;
1376 CurrentToken->FakeLParens.clear();
1377 CurrentToken->FakeRParens = 0;
1378 }
1379
next()1380 void next() {
1381 if (CurrentToken) {
1382 CurrentToken->NestingLevel = Contexts.size() - 1;
1383 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
1384 modifyContext(*CurrentToken);
1385 determineTokenType(*CurrentToken);
1386 CurrentToken = CurrentToken->Next;
1387 }
1388
1389 resetTokenMetadata(CurrentToken);
1390 }
1391
1392 /// A struct to hold information valid in a specific context, e.g.
1393 /// a pair of parenthesis.
1394 struct Context {
Contextclang::format::__anon0fe692140111::AnnotatingParser::Context1395 Context(tok::TokenKind ContextKind, unsigned BindingStrength,
1396 bool IsExpression)
1397 : ContextKind(ContextKind), BindingStrength(BindingStrength),
1398 IsExpression(IsExpression) {}
1399
1400 tok::TokenKind ContextKind;
1401 unsigned BindingStrength;
1402 bool IsExpression;
1403 unsigned LongestObjCSelectorName = 0;
1404 bool ColonIsForRangeExpr = false;
1405 bool ColonIsDictLiteral = false;
1406 bool ColonIsObjCMethodExpr = false;
1407 FormatToken *FirstObjCSelectorName = nullptr;
1408 FormatToken *FirstStartOfName = nullptr;
1409 bool CanBeExpression = true;
1410 bool InTemplateArgument = false;
1411 bool InCtorInitializer = false;
1412 bool InInheritanceList = false;
1413 bool CaretFound = false;
1414 bool IsForEachMacro = false;
1415 bool InCpp11AttributeSpecifier = false;
1416 bool InCSharpAttributeSpecifier = false;
1417 };
1418
1419 /// Puts a new \c Context onto the stack \c Contexts for the lifetime
1420 /// of each instance.
1421 struct ScopedContextCreator {
1422 AnnotatingParser &P;
1423
ScopedContextCreatorclang::format::__anon0fe692140111::AnnotatingParser::ScopedContextCreator1424 ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind,
1425 unsigned Increase)
1426 : P(P) {
1427 P.Contexts.push_back(Context(ContextKind,
1428 P.Contexts.back().BindingStrength + Increase,
1429 P.Contexts.back().IsExpression));
1430 }
1431
~ScopedContextCreatorclang::format::__anon0fe692140111::AnnotatingParser::ScopedContextCreator1432 ~ScopedContextCreator() { P.Contexts.pop_back(); }
1433 };
1434
modifyContext(const FormatToken & Current)1435 void modifyContext(const FormatToken &Current) {
1436 if (Current.getPrecedence() == prec::Assignment &&
1437 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) &&
1438 // Type aliases use `type X = ...;` in TypeScript and can be exported
1439 // using `export type ...`.
1440 !(Style.Language == FormatStyle::LK_JavaScript &&
1441 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
1442 Line.startsWith(tok::kw_export, Keywords.kw_type,
1443 tok::identifier))) &&
1444 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
1445 Contexts.back().IsExpression = true;
1446 if (!Line.startsWith(TT_UnaryOperator)) {
1447 for (FormatToken *Previous = Current.Previous;
1448 Previous && Previous->Previous &&
1449 !Previous->Previous->isOneOf(tok::comma, tok::semi);
1450 Previous = Previous->Previous) {
1451 if (Previous->isOneOf(tok::r_square, tok::r_paren)) {
1452 Previous = Previous->MatchingParen;
1453 if (!Previous)
1454 break;
1455 }
1456 if (Previous->opensScope())
1457 break;
1458 if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1459 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1460 Previous->Previous && Previous->Previous->isNot(tok::equal))
1461 Previous->setType(TT_PointerOrReference);
1462 }
1463 }
1464 } else if (Current.is(tok::lessless) &&
1465 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
1466 Contexts.back().IsExpression = true;
1467 } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1468 Contexts.back().IsExpression = true;
1469 } else if (Current.is(TT_TrailingReturnArrow)) {
1470 Contexts.back().IsExpression = false;
1471 } else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1472 Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java;
1473 } else if (Current.Previous &&
1474 Current.Previous->is(TT_CtorInitializerColon)) {
1475 Contexts.back().IsExpression = true;
1476 Contexts.back().InCtorInitializer = true;
1477 } else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
1478 Contexts.back().InInheritanceList = true;
1479 } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1480 for (FormatToken *Previous = Current.Previous;
1481 Previous && Previous->isOneOf(tok::star, tok::amp);
1482 Previous = Previous->Previous)
1483 Previous->setType(TT_PointerOrReference);
1484 if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer)
1485 Contexts.back().IsExpression = false;
1486 } else if (Current.is(tok::kw_new)) {
1487 Contexts.back().CanBeExpression = false;
1488 } else if (Current.is(tok::semi) ||
1489 (Current.is(tok::exclaim) && Current.Previous &&
1490 !Current.Previous->is(tok::kw_operator))) {
1491 // This should be the condition or increment in a for-loop.
1492 // But not operator !() (can't use TT_OverloadedOperator here as its not
1493 // been annotated yet).
1494 Contexts.back().IsExpression = true;
1495 }
1496 }
1497
untilMatchingParen(FormatToken * Current)1498 static FormatToken *untilMatchingParen(FormatToken *Current) {
1499 // Used when `MatchingParen` is not yet established.
1500 int ParenLevel = 0;
1501 while (Current) {
1502 if (Current->is(tok::l_paren))
1503 ParenLevel++;
1504 if (Current->is(tok::r_paren))
1505 ParenLevel--;
1506 if (ParenLevel < 1)
1507 break;
1508 Current = Current->Next;
1509 }
1510 return Current;
1511 }
1512
isDeductionGuide(FormatToken & Current)1513 static bool isDeductionGuide(FormatToken &Current) {
1514 // Look for a deduction guide template<T> A(...) -> A<...>;
1515 if (Current.Previous && Current.Previous->is(tok::r_paren) &&
1516 Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
1517 // Find the TemplateCloser.
1518 FormatToken *TemplateCloser = Current.Next->Next;
1519 int NestingLevel = 0;
1520 while (TemplateCloser) {
1521 // Skip over an expressions in parens A<(3 < 2)>;
1522 if (TemplateCloser->is(tok::l_paren)) {
1523 // No Matching Paren yet so skip to matching paren
1524 TemplateCloser = untilMatchingParen(TemplateCloser);
1525 }
1526 if (TemplateCloser->is(tok::less))
1527 NestingLevel++;
1528 if (TemplateCloser->is(tok::greater))
1529 NestingLevel--;
1530 if (NestingLevel < 1)
1531 break;
1532 TemplateCloser = TemplateCloser->Next;
1533 }
1534 // Assuming we have found the end of the template ensure its followed
1535 // with a semi-colon.
1536 if (TemplateCloser && TemplateCloser->Next &&
1537 TemplateCloser->Next->is(tok::semi) &&
1538 Current.Previous->MatchingParen) {
1539 // Determine if the identifier `A` prior to the A<..>; is the same as
1540 // prior to the A(..)
1541 FormatToken *LeadingIdentifier =
1542 Current.Previous->MatchingParen->Previous;
1543
1544 // Differentiate a deduction guide by seeing the
1545 // > of the template prior to the leading identifier.
1546 if (LeadingIdentifier) {
1547 FormatToken *PriorLeadingIdentifier = LeadingIdentifier->Previous;
1548 // Skip back past explicit decoration
1549 if (PriorLeadingIdentifier &&
1550 PriorLeadingIdentifier->is(tok::kw_explicit))
1551 PriorLeadingIdentifier = PriorLeadingIdentifier->Previous;
1552
1553 return (PriorLeadingIdentifier &&
1554 PriorLeadingIdentifier->is(TT_TemplateCloser) &&
1555 LeadingIdentifier->TokenText == Current.Next->TokenText);
1556 }
1557 }
1558 }
1559 return false;
1560 }
1561
determineTokenType(FormatToken & Current)1562 void determineTokenType(FormatToken &Current) {
1563 if (!Current.is(TT_Unknown))
1564 // The token type is already known.
1565 return;
1566
1567 if ((Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) &&
1568 Current.is(tok::exclaim)) {
1569 if (Current.Previous) {
1570 bool IsIdentifier =
1571 Style.Language == FormatStyle::LK_JavaScript
1572 ? Keywords.IsJavaScriptIdentifier(
1573 *Current.Previous, /* AcceptIdentifierName= */ true)
1574 : Current.Previous->is(tok::identifier);
1575 if (IsIdentifier ||
1576 Current.Previous->isOneOf(
1577 tok::kw_namespace, tok::r_paren, tok::r_square, tok::r_brace,
1578 tok::kw_false, tok::kw_true, Keywords.kw_type, Keywords.kw_get,
1579 Keywords.kw_set) ||
1580 Current.Previous->Tok.isLiteral()) {
1581 Current.setType(TT_NonNullAssertion);
1582 return;
1583 }
1584 }
1585 if (Current.Next &&
1586 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1587 Current.setType(TT_NonNullAssertion);
1588 return;
1589 }
1590 }
1591
1592 // Line.MightBeFunctionDecl can only be true after the parentheses of a
1593 // function declaration have been found. In this case, 'Current' is a
1594 // trailing token of this declaration and thus cannot be a name.
1595 if (Current.is(Keywords.kw_instanceof)) {
1596 Current.setType(TT_BinaryOperator);
1597 } else if (isStartOfName(Current) &&
1598 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1599 Contexts.back().FirstStartOfName = &Current;
1600 Current.setType(TT_StartOfName);
1601 } else if (Current.is(tok::semi)) {
1602 // Reset FirstStartOfName after finding a semicolon so that a for loop
1603 // with multiple increment statements is not confused with a for loop
1604 // having multiple variable declarations.
1605 Contexts.back().FirstStartOfName = nullptr;
1606 } else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1607 AutoFound = true;
1608 } else if (Current.is(tok::arrow) &&
1609 Style.Language == FormatStyle::LK_Java) {
1610 Current.setType(TT_LambdaArrow);
1611 } else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration &&
1612 Current.NestingLevel == 0 &&
1613 !Current.Previous->is(tok::kw_operator)) {
1614 // not auto operator->() -> xxx;
1615 Current.setType(TT_TrailingReturnArrow);
1616 } else if (Current.is(tok::arrow) && Current.Previous &&
1617 Current.Previous->is(tok::r_brace)) {
1618 // Concept implicit conversion contraint needs to be treated like
1619 // a trailing return type ... } -> <type>.
1620 Current.setType(TT_TrailingReturnArrow);
1621 } else if (isDeductionGuide(Current)) {
1622 // Deduction guides trailing arrow " A(...) -> A<T>;".
1623 Current.setType(TT_TrailingReturnArrow);
1624 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1625 Current.setType(determineStarAmpUsage(
1626 Current,
1627 Contexts.back().CanBeExpression && Contexts.back().IsExpression,
1628 Contexts.back().InTemplateArgument));
1629 } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1630 Current.setType(determinePlusMinusCaretUsage(Current));
1631 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1632 Contexts.back().CaretFound = true;
1633 } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1634 Current.setType(determineIncrementUsage(Current));
1635 } else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1636 Current.setType(TT_UnaryOperator);
1637 } else if (Current.is(tok::question)) {
1638 if (Style.Language == FormatStyle::LK_JavaScript &&
1639 Line.MustBeDeclaration && !Contexts.back().IsExpression) {
1640 // In JavaScript, `interface X { foo?(): bar; }` is an optional method
1641 // on the interface, not a ternary expression.
1642 Current.setType(TT_JsTypeOptionalQuestion);
1643 } else {
1644 Current.setType(TT_ConditionalExpr);
1645 }
1646 } else if (Current.isBinaryOperator() &&
1647 (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
1648 (!Current.is(tok::greater) &&
1649 Style.Language != FormatStyle::LK_TextProto)) {
1650 Current.setType(TT_BinaryOperator);
1651 } else if (Current.is(tok::comment)) {
1652 if (Current.TokenText.startswith("/*")) {
1653 if (Current.TokenText.endswith("*/"))
1654 Current.setType(TT_BlockComment);
1655 else
1656 // The lexer has for some reason determined a comment here. But we
1657 // cannot really handle it, if it isn't properly terminated.
1658 Current.Tok.setKind(tok::unknown);
1659 } else {
1660 Current.setType(TT_LineComment);
1661 }
1662 } else if (Current.is(tok::r_paren)) {
1663 if (rParenEndsCast(Current))
1664 Current.setType(TT_CastRParen);
1665 if (Current.MatchingParen && Current.Next &&
1666 !Current.Next->isBinaryOperator() &&
1667 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1668 tok::comma, tok::period, tok::arrow,
1669 tok::coloncolon))
1670 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1671 // Make sure this isn't the return type of an Obj-C block declaration
1672 if (AfterParen->Tok.isNot(tok::caret)) {
1673 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1674 if (BeforeParen->is(tok::identifier) &&
1675 !BeforeParen->is(TT_TypenameMacro) &&
1676 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1677 (!BeforeParen->Previous ||
1678 BeforeParen->Previous->ClosesTemplateDeclaration))
1679 Current.setType(TT_FunctionAnnotationRParen);
1680 }
1681 }
1682 } else if (Current.is(tok::at) && Current.Next &&
1683 Style.Language != FormatStyle::LK_JavaScript &&
1684 Style.Language != FormatStyle::LK_Java) {
1685 // In Java & JavaScript, "@..." is a decorator or annotation. In ObjC, it
1686 // marks declarations and properties that need special formatting.
1687 switch (Current.Next->Tok.getObjCKeywordID()) {
1688 case tok::objc_interface:
1689 case tok::objc_implementation:
1690 case tok::objc_protocol:
1691 Current.setType(TT_ObjCDecl);
1692 break;
1693 case tok::objc_property:
1694 Current.setType(TT_ObjCProperty);
1695 break;
1696 default:
1697 break;
1698 }
1699 } else if (Current.is(tok::period)) {
1700 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1701 if (PreviousNoComment &&
1702 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1703 Current.setType(TT_DesignatedInitializerPeriod);
1704 else if (Style.Language == FormatStyle::LK_Java && Current.Previous &&
1705 Current.Previous->isOneOf(TT_JavaAnnotation,
1706 TT_LeadingJavaAnnotation)) {
1707 Current.setType(Current.Previous->getType());
1708 }
1709 } else if (canBeObjCSelectorComponent(Current) &&
1710 // FIXME(bug 36976): ObjC return types shouldn't use
1711 // TT_CastRParen.
1712 Current.Previous && Current.Previous->is(TT_CastRParen) &&
1713 Current.Previous->MatchingParen &&
1714 Current.Previous->MatchingParen->Previous &&
1715 Current.Previous->MatchingParen->Previous->is(
1716 TT_ObjCMethodSpecifier)) {
1717 // This is the first part of an Objective-C selector name. (If there's no
1718 // colon after this, this is the only place which annotates the identifier
1719 // as a selector.)
1720 Current.setType(TT_SelectorName);
1721 } else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept,
1722 tok::kw_requires) &&
1723 Current.Previous &&
1724 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1725 Line.MightBeFunctionDecl && Contexts.size() == 1) {
1726 // Line.MightBeFunctionDecl can only be true after the parentheses of a
1727 // function declaration have been found.
1728 Current.setType(TT_TrailingAnnotation);
1729 } else if ((Style.Language == FormatStyle::LK_Java ||
1730 Style.Language == FormatStyle::LK_JavaScript) &&
1731 Current.Previous) {
1732 if (Current.Previous->is(tok::at) &&
1733 Current.isNot(Keywords.kw_interface)) {
1734 const FormatToken &AtToken = *Current.Previous;
1735 const FormatToken *Previous = AtToken.getPreviousNonComment();
1736 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1737 Current.setType(TT_LeadingJavaAnnotation);
1738 else
1739 Current.setType(TT_JavaAnnotation);
1740 } else if (Current.Previous->is(tok::period) &&
1741 Current.Previous->isOneOf(TT_JavaAnnotation,
1742 TT_LeadingJavaAnnotation)) {
1743 Current.setType(Current.Previous->getType());
1744 }
1745 }
1746 }
1747
1748 /// Take a guess at whether \p Tok starts a name of a function or
1749 /// variable declaration.
1750 ///
1751 /// This is a heuristic based on whether \p Tok is an identifier following
1752 /// something that is likely a type.
isStartOfName(const FormatToken & Tok)1753 bool isStartOfName(const FormatToken &Tok) {
1754 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1755 return false;
1756
1757 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1758 Keywords.kw_as))
1759 return false;
1760 if (Style.Language == FormatStyle::LK_JavaScript &&
1761 Tok.Previous->is(Keywords.kw_in))
1762 return false;
1763
1764 // Skip "const" as it does not have an influence on whether this is a name.
1765 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1766 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1767 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1768
1769 if (!PreviousNotConst)
1770 return false;
1771
1772 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1773 PreviousNotConst->Previous &&
1774 PreviousNotConst->Previous->is(tok::hash);
1775
1776 if (PreviousNotConst->is(TT_TemplateCloser))
1777 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1778 PreviousNotConst->MatchingParen->Previous &&
1779 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1780 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1781
1782 if (PreviousNotConst->is(tok::r_paren) &&
1783 PreviousNotConst->is(TT_TypeDeclarationParen))
1784 return true;
1785
1786 return (!IsPPKeyword &&
1787 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1788 PreviousNotConst->is(TT_PointerOrReference) ||
1789 PreviousNotConst->isSimpleTypeSpecifier();
1790 }
1791
1792 /// Determine whether ')' is ending a cast.
rParenEndsCast(const FormatToken & Tok)1793 bool rParenEndsCast(const FormatToken &Tok) {
1794 // C-style casts are only used in C++, C# and Java.
1795 if (!Style.isCSharp() && !Style.isCpp() &&
1796 Style.Language != FormatStyle::LK_Java)
1797 return false;
1798
1799 // Empty parens aren't casts and there are no casts at the end of the line.
1800 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1801 return false;
1802
1803 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1804 if (LeftOfParens) {
1805 // If there is a closing parenthesis left of the current parentheses,
1806 // look past it as these might be chained casts.
1807 if (LeftOfParens->is(tok::r_paren)) {
1808 if (!LeftOfParens->MatchingParen ||
1809 !LeftOfParens->MatchingParen->Previous)
1810 return false;
1811 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1812 }
1813
1814 // If there is an identifier (or with a few exceptions a keyword) right
1815 // before the parentheses, this is unlikely to be a cast.
1816 if (LeftOfParens->Tok.getIdentifierInfo() &&
1817 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1818 tok::kw_delete))
1819 return false;
1820
1821 // Certain other tokens right before the parentheses are also signals that
1822 // this cannot be a cast.
1823 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1824 TT_TemplateCloser, tok::ellipsis))
1825 return false;
1826 }
1827
1828 if (Tok.Next->is(tok::question))
1829 return false;
1830
1831 // `foreach((A a, B b) in someList)` should not be seen as a cast.
1832 if (Tok.Next->is(Keywords.kw_in) && Style.isCSharp())
1833 return false;
1834
1835 // Functions which end with decorations like volatile, noexcept are unlikely
1836 // to be casts.
1837 if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
1838 tok::kw_requires, tok::kw_throw, tok::arrow,
1839 Keywords.kw_override, Keywords.kw_final) ||
1840 isCpp11AttributeSpecifier(*Tok.Next))
1841 return false;
1842
1843 // As Java has no function types, a "(" after the ")" likely means that this
1844 // is a cast.
1845 if (Style.Language == FormatStyle::LK_Java && Tok.Next->is(tok::l_paren))
1846 return true;
1847
1848 // If a (non-string) literal follows, this is likely a cast.
1849 if (Tok.Next->isNot(tok::string_literal) &&
1850 (Tok.Next->Tok.isLiteral() ||
1851 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1852 return true;
1853
1854 // Heuristically try to determine whether the parentheses contain a type.
1855 auto IsQualifiedPointerOrReference = [](FormatToken *T) {
1856 // This is used to handle cases such as x = (foo *const)&y;
1857 assert(!T->isSimpleTypeSpecifier() && "Should have already been checked");
1858 // Strip trailing qualifiers such as const or volatile when checking
1859 // whether the parens could be a cast to a pointer/reference type.
1860 while (T) {
1861 if (T->is(TT_AttributeParen)) {
1862 // Handle `x = (foo *__attribute__((foo)))&v;`:
1863 if (T->MatchingParen && T->MatchingParen->Previous &&
1864 T->MatchingParen->Previous->is(tok::kw___attribute)) {
1865 T = T->MatchingParen->Previous->Previous;
1866 continue;
1867 }
1868 } else if (T->is(TT_AttributeSquare)) {
1869 // Handle `x = (foo *[[clang::foo]])&v;`:
1870 if (T->MatchingParen && T->MatchingParen->Previous) {
1871 T = T->MatchingParen->Previous;
1872 continue;
1873 }
1874 } else if (T->canBePointerOrReferenceQualifier()) {
1875 T = T->Previous;
1876 continue;
1877 }
1878 break;
1879 }
1880 return T && T->is(TT_PointerOrReference);
1881 };
1882 bool ParensAreType =
1883 !Tok.Previous ||
1884 Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) ||
1885 Tok.Previous->isSimpleTypeSpecifier() ||
1886 IsQualifiedPointerOrReference(Tok.Previous);
1887 bool ParensCouldEndDecl =
1888 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1889 if (ParensAreType && !ParensCouldEndDecl)
1890 return true;
1891
1892 // At this point, we heuristically assume that there are no casts at the
1893 // start of the line. We assume that we have found most cases where there
1894 // are by the logic above, e.g. "(void)x;".
1895 if (!LeftOfParens)
1896 return false;
1897
1898 // Certain token types inside the parentheses mean that this can't be a
1899 // cast.
1900 for (const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
1901 Token = Token->Next)
1902 if (Token->is(TT_BinaryOperator))
1903 return false;
1904
1905 // If the following token is an identifier or 'this', this is a cast. All
1906 // cases where this can be something else are handled above.
1907 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1908 return true;
1909
1910 // Look for a cast `( x ) (`.
1911 if (Tok.Next->is(tok::l_paren) && Tok.Previous && Tok.Previous->Previous) {
1912 if (Tok.Previous->is(tok::identifier) &&
1913 Tok.Previous->Previous->is(tok::l_paren))
1914 return true;
1915 }
1916
1917 if (!Tok.Next->Next)
1918 return false;
1919
1920 // If the next token after the parenthesis is a unary operator, assume
1921 // that this is cast, unless there are unexpected tokens inside the
1922 // parenthesis.
1923 bool NextIsUnary =
1924 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1925 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1926 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1927 return false;
1928 // Search for unexpected tokens.
1929 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1930 Prev = Prev->Previous) {
1931 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1932 return false;
1933 }
1934 return true;
1935 }
1936
1937 /// Return the type of the given token assuming it is * or &.
determineStarAmpUsage(const FormatToken & Tok,bool IsExpression,bool InTemplateArgument)1938 TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,
1939 bool InTemplateArgument) {
1940 if (Style.Language == FormatStyle::LK_JavaScript)
1941 return TT_BinaryOperator;
1942
1943 // && in C# must be a binary operator.
1944 if (Style.isCSharp() && Tok.is(tok::ampamp))
1945 return TT_BinaryOperator;
1946
1947 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1948 if (!PrevToken)
1949 return TT_UnaryOperator;
1950
1951 const FormatToken *NextToken = Tok.getNextNonComment();
1952 if (!NextToken ||
1953 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_noexcept) ||
1954 NextToken->canBePointerOrReferenceQualifier() ||
1955 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1956 return TT_PointerOrReference;
1957
1958 if (PrevToken->is(tok::coloncolon))
1959 return TT_PointerOrReference;
1960
1961 if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
1962 return TT_PointerOrReference;
1963
1964 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1965 tok::comma, tok::semi, tok::kw_return, tok::colon,
1966 tok::kw_co_return, tok::kw_co_await,
1967 tok::kw_co_yield, tok::equal, tok::kw_delete,
1968 tok::kw_sizeof, tok::kw_throw) ||
1969 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1970 TT_UnaryOperator, TT_CastRParen))
1971 return TT_UnaryOperator;
1972
1973 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1974 return TT_PointerOrReference;
1975 if (NextToken->is(tok::kw_operator) && !IsExpression)
1976 return TT_PointerOrReference;
1977 if (NextToken->isOneOf(tok::comma, tok::semi))
1978 return TT_PointerOrReference;
1979
1980 if (PrevToken->Tok.isLiteral() ||
1981 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1982 tok::kw_false, tok::r_brace) ||
1983 NextToken->Tok.isLiteral() ||
1984 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1985 NextToken->isUnaryOperator() ||
1986 // If we know we're in a template argument, there are no named
1987 // declarations. Thus, having an identifier on the right-hand side
1988 // indicates a binary operator.
1989 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1990 return TT_BinaryOperator;
1991
1992 // "&&(" is quite unlikely to be two successive unary "&".
1993 if (Tok.is(tok::ampamp) && NextToken->is(tok::l_paren))
1994 return TT_BinaryOperator;
1995
1996 // This catches some cases where evaluation order is used as control flow:
1997 // aaa && aaa->f();
1998 if (NextToken->Tok.isAnyIdentifier()) {
1999 const FormatToken *NextNextToken = NextToken->getNextNonComment();
2000 if (NextNextToken && NextNextToken->is(tok::arrow))
2001 return TT_BinaryOperator;
2002 }
2003
2004 // It is very unlikely that we are going to find a pointer or reference type
2005 // definition on the RHS of an assignment.
2006 if (IsExpression && !Contexts.back().CaretFound)
2007 return TT_BinaryOperator;
2008
2009 return TT_PointerOrReference;
2010 }
2011
determinePlusMinusCaretUsage(const FormatToken & Tok)2012 TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
2013 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2014 if (!PrevToken)
2015 return TT_UnaryOperator;
2016
2017 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
2018 // This must be a sequence of leading unary operators.
2019 return TT_UnaryOperator;
2020
2021 // Use heuristics to recognize unary operators.
2022 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
2023 tok::question, tok::colon, tok::kw_return,
2024 tok::kw_case, tok::at, tok::l_brace, tok::kw_throw,
2025 tok::kw_co_return, tok::kw_co_yield))
2026 return TT_UnaryOperator;
2027
2028 // There can't be two consecutive binary operators.
2029 if (PrevToken->is(TT_BinaryOperator))
2030 return TT_UnaryOperator;
2031
2032 // Fall back to marking the token as binary operator.
2033 return TT_BinaryOperator;
2034 }
2035
2036 /// Determine whether ++/-- are pre- or post-increments/-decrements.
determineIncrementUsage(const FormatToken & Tok)2037 TokenType determineIncrementUsage(const FormatToken &Tok) {
2038 const FormatToken *PrevToken = Tok.getPreviousNonComment();
2039 if (!PrevToken || PrevToken->is(TT_CastRParen))
2040 return TT_UnaryOperator;
2041 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
2042 return TT_TrailingUnaryOperator;
2043
2044 return TT_UnaryOperator;
2045 }
2046
2047 SmallVector<Context, 8> Contexts;
2048
2049 const FormatStyle &Style;
2050 AnnotatedLine &Line;
2051 FormatToken *CurrentToken;
2052 bool AutoFound;
2053 const AdditionalKeywords &Keywords;
2054
2055 // Set of "<" tokens that do not open a template parameter list. If parseAngle
2056 // determines that a specific token can't be a template opener, it will make
2057 // same decision irrespective of the decisions for tokens leading up to it.
2058 // Store this information to prevent this from causing exponential runtime.
2059 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
2060 };
2061
2062 static const int PrecedenceUnaryOperator = prec::PointerToMember + 1;
2063 static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2;
2064
2065 /// Parses binary expressions by inserting fake parenthesis based on
2066 /// operator precedence.
2067 class ExpressionParser {
2068 public:
ExpressionParser(const FormatStyle & Style,const AdditionalKeywords & Keywords,AnnotatedLine & Line)2069 ExpressionParser(const FormatStyle &Style, const AdditionalKeywords &Keywords,
2070 AnnotatedLine &Line)
2071 : Style(Style), Keywords(Keywords), Current(Line.First) {}
2072
2073 /// Parse expressions with the given operator precedence.
parse(int Precedence=0)2074 void parse(int Precedence = 0) {
2075 // Skip 'return' and ObjC selector colons as they are not part of a binary
2076 // expression.
2077 while (Current && (Current->is(tok::kw_return) ||
2078 (Current->is(tok::colon) &&
2079 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
2080 next();
2081
2082 if (!Current || Precedence > PrecedenceArrowAndPeriod)
2083 return;
2084
2085 // Conditional expressions need to be parsed separately for proper nesting.
2086 if (Precedence == prec::Conditional) {
2087 parseConditionalExpr();
2088 return;
2089 }
2090
2091 // Parse unary operators, which all have a higher precedence than binary
2092 // operators.
2093 if (Precedence == PrecedenceUnaryOperator) {
2094 parseUnaryOperator();
2095 return;
2096 }
2097
2098 FormatToken *Start = Current;
2099 FormatToken *LatestOperator = nullptr;
2100 unsigned OperatorIndex = 0;
2101
2102 while (Current) {
2103 // Consume operators with higher precedence.
2104 parse(Precedence + 1);
2105
2106 int CurrentPrecedence = getCurrentPrecedence();
2107
2108 if (Current && Current->is(TT_SelectorName) &&
2109 Precedence == CurrentPrecedence) {
2110 if (LatestOperator)
2111 addFakeParenthesis(Start, prec::Level(Precedence));
2112 Start = Current;
2113 }
2114
2115 // At the end of the line or when an operator with higher precedence is
2116 // found, insert fake parenthesis and return.
2117 if (!Current ||
2118 (Current->closesScope() &&
2119 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
2120 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
2121 (CurrentPrecedence == prec::Conditional &&
2122 Precedence == prec::Assignment && Current->is(tok::colon))) {
2123 break;
2124 }
2125
2126 // Consume scopes: (), [], <> and {}
2127 if (Current->opensScope()) {
2128 // In fragment of a JavaScript template string can look like '}..${' and
2129 // thus close a scope and open a new one at the same time.
2130 while (Current && (!Current->closesScope() || Current->opensScope())) {
2131 next();
2132 parse();
2133 }
2134 next();
2135 } else {
2136 // Operator found.
2137 if (CurrentPrecedence == Precedence) {
2138 if (LatestOperator)
2139 LatestOperator->NextOperator = Current;
2140 LatestOperator = Current;
2141 Current->OperatorIndex = OperatorIndex;
2142 ++OperatorIndex;
2143 }
2144 next(/*SkipPastLeadingComments=*/Precedence > 0);
2145 }
2146 }
2147
2148 if (LatestOperator && (Current || Precedence > 0)) {
2149 // LatestOperator->LastOperator = true;
2150 if (Precedence == PrecedenceArrowAndPeriod) {
2151 // Call expressions don't have a binary operator precedence.
2152 addFakeParenthesis(Start, prec::Unknown);
2153 } else {
2154 addFakeParenthesis(Start, prec::Level(Precedence));
2155 }
2156 }
2157 }
2158
2159 private:
2160 /// Gets the precedence (+1) of the given token for binary operators
2161 /// and other tokens that we treat like binary operators.
getCurrentPrecedence()2162 int getCurrentPrecedence() {
2163 if (Current) {
2164 const FormatToken *NextNonComment = Current->getNextNonComment();
2165 if (Current->is(TT_ConditionalExpr))
2166 return prec::Conditional;
2167 if (NextNonComment && Current->is(TT_SelectorName) &&
2168 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
2169 ((Style.Language == FormatStyle::LK_Proto ||
2170 Style.Language == FormatStyle::LK_TextProto) &&
2171 NextNonComment->is(tok::less))))
2172 return prec::Assignment;
2173 if (Current->is(TT_JsComputedPropertyName))
2174 return prec::Assignment;
2175 if (Current->is(TT_LambdaArrow))
2176 return prec::Comma;
2177 if (Current->is(TT_FatArrow))
2178 return prec::Assignment;
2179 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
2180 (Current->is(tok::comment) && NextNonComment &&
2181 NextNonComment->is(TT_SelectorName)))
2182 return 0;
2183 if (Current->is(TT_RangeBasedForLoopColon))
2184 return prec::Comma;
2185 if ((Style.Language == FormatStyle::LK_Java ||
2186 Style.Language == FormatStyle::LK_JavaScript) &&
2187 Current->is(Keywords.kw_instanceof))
2188 return prec::Relational;
2189 if (Style.Language == FormatStyle::LK_JavaScript &&
2190 Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
2191 return prec::Relational;
2192 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
2193 return Current->getPrecedence();
2194 if (Current->isOneOf(tok::period, tok::arrow))
2195 return PrecedenceArrowAndPeriod;
2196 if ((Style.Language == FormatStyle::LK_Java ||
2197 Style.Language == FormatStyle::LK_JavaScript) &&
2198 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
2199 Keywords.kw_throws))
2200 return 0;
2201 }
2202 return -1;
2203 }
2204
addFakeParenthesis(FormatToken * Start,prec::Level Precedence)2205 void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) {
2206 Start->FakeLParens.push_back(Precedence);
2207 if (Precedence > prec::Unknown)
2208 Start->StartsBinaryExpression = true;
2209 if (Current) {
2210 FormatToken *Previous = Current->Previous;
2211 while (Previous->is(tok::comment) && Previous->Previous)
2212 Previous = Previous->Previous;
2213 ++Previous->FakeRParens;
2214 if (Precedence > prec::Unknown)
2215 Previous->EndsBinaryExpression = true;
2216 }
2217 }
2218
2219 /// Parse unary operator expressions and surround them with fake
2220 /// parentheses if appropriate.
parseUnaryOperator()2221 void parseUnaryOperator() {
2222 llvm::SmallVector<FormatToken *, 2> Tokens;
2223 while (Current && Current->is(TT_UnaryOperator)) {
2224 Tokens.push_back(Current);
2225 next();
2226 }
2227 parse(PrecedenceArrowAndPeriod);
2228 for (FormatToken *Token : llvm::reverse(Tokens))
2229 // The actual precedence doesn't matter.
2230 addFakeParenthesis(Token, prec::Unknown);
2231 }
2232
parseConditionalExpr()2233 void parseConditionalExpr() {
2234 while (Current && Current->isTrailingComment()) {
2235 next();
2236 }
2237 FormatToken *Start = Current;
2238 parse(prec::LogicalOr);
2239 if (!Current || !Current->is(tok::question))
2240 return;
2241 next();
2242 parse(prec::Assignment);
2243 if (!Current || Current->isNot(TT_ConditionalExpr))
2244 return;
2245 next();
2246 parse(prec::Assignment);
2247 addFakeParenthesis(Start, prec::Conditional);
2248 }
2249
next(bool SkipPastLeadingComments=true)2250 void next(bool SkipPastLeadingComments = true) {
2251 if (Current)
2252 Current = Current->Next;
2253 while (Current &&
2254 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
2255 Current->isTrailingComment())
2256 Current = Current->Next;
2257 }
2258
2259 const FormatStyle &Style;
2260 const AdditionalKeywords &Keywords;
2261 FormatToken *Current;
2262 };
2263
2264 } // end anonymous namespace
2265
setCommentLineLevels(SmallVectorImpl<AnnotatedLine * > & Lines)2266 void TokenAnnotator::setCommentLineLevels(
2267 SmallVectorImpl<AnnotatedLine *> &Lines) {
2268 const AnnotatedLine *NextNonCommentLine = nullptr;
2269 for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),
2270 E = Lines.rend();
2271 I != E; ++I) {
2272 bool CommentLine = true;
2273 for (const FormatToken *Tok = (*I)->First; Tok; Tok = Tok->Next) {
2274 if (!Tok->is(tok::comment)) {
2275 CommentLine = false;
2276 break;
2277 }
2278 }
2279
2280 // If the comment is currently aligned with the line immediately following
2281 // it, that's probably intentional and we should keep it.
2282 if (NextNonCommentLine && CommentLine &&
2283 NextNonCommentLine->First->NewlinesBefore <= 1 &&
2284 NextNonCommentLine->First->OriginalColumn ==
2285 (*I)->First->OriginalColumn) {
2286 // Align comments for preprocessor lines with the # in column 0 if
2287 // preprocessor lines are not indented. Otherwise, align with the next
2288 // line.
2289 (*I)->Level =
2290 (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
2291 (NextNonCommentLine->Type == LT_PreprocessorDirective ||
2292 NextNonCommentLine->Type == LT_ImportStatement))
2293 ? 0
2294 : NextNonCommentLine->Level;
2295 } else {
2296 NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
2297 }
2298
2299 setCommentLineLevels((*I)->Children);
2300 }
2301 }
2302
maxNestingDepth(const AnnotatedLine & Line)2303 static unsigned maxNestingDepth(const AnnotatedLine &Line) {
2304 unsigned Result = 0;
2305 for (const auto *Tok = Line.First; Tok != nullptr; Tok = Tok->Next)
2306 Result = std::max(Result, Tok->NestingLevel);
2307 return Result;
2308 }
2309
annotate(AnnotatedLine & Line)2310 void TokenAnnotator::annotate(AnnotatedLine &Line) {
2311 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
2312 E = Line.Children.end();
2313 I != E; ++I) {
2314 annotate(**I);
2315 }
2316 AnnotatingParser Parser(Style, Line, Keywords);
2317 Line.Type = Parser.parseLine();
2318
2319 // With very deep nesting, ExpressionParser uses lots of stack and the
2320 // formatting algorithm is very slow. We're not going to do a good job here
2321 // anyway - it's probably generated code being formatted by mistake.
2322 // Just skip the whole line.
2323 if (maxNestingDepth(Line) > 50)
2324 Line.Type = LT_Invalid;
2325
2326 if (Line.Type == LT_Invalid)
2327 return;
2328
2329 ExpressionParser ExprParser(Style, Keywords, Line);
2330 ExprParser.parse();
2331
2332 if (Line.startsWith(TT_ObjCMethodSpecifier))
2333 Line.Type = LT_ObjCMethodDecl;
2334 else if (Line.startsWith(TT_ObjCDecl))
2335 Line.Type = LT_ObjCDecl;
2336 else if (Line.startsWith(TT_ObjCProperty))
2337 Line.Type = LT_ObjCProperty;
2338
2339 Line.First->SpacesRequiredBefore = 1;
2340 Line.First->CanBreakBefore = Line.First->MustBreakBefore;
2341 }
2342
2343 // This function heuristically determines whether 'Current' starts the name of a
2344 // function declaration.
isFunctionDeclarationName(const FormatToken & Current,const AnnotatedLine & Line)2345 static bool isFunctionDeclarationName(const FormatToken &Current,
2346 const AnnotatedLine &Line) {
2347 auto skipOperatorName = [](const FormatToken *Next) -> const FormatToken * {
2348 for (; Next; Next = Next->Next) {
2349 if (Next->is(TT_OverloadedOperatorLParen))
2350 return Next;
2351 if (Next->is(TT_OverloadedOperator))
2352 continue;
2353 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
2354 // For 'new[]' and 'delete[]'.
2355 if (Next->Next &&
2356 Next->Next->startsSequence(tok::l_square, tok::r_square))
2357 Next = Next->Next->Next;
2358 continue;
2359 }
2360 if (Next->startsSequence(tok::l_square, tok::r_square)) {
2361 // For operator[]().
2362 Next = Next->Next;
2363 continue;
2364 }
2365 if ((Next->isSimpleTypeSpecifier() || Next->is(tok::identifier)) &&
2366 Next->Next && Next->Next->isOneOf(tok::star, tok::amp, tok::ampamp)) {
2367 // For operator void*(), operator char*(), operator Foo*().
2368 Next = Next->Next;
2369 continue;
2370 }
2371 if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
2372 Next = Next->MatchingParen;
2373 continue;
2374 }
2375
2376 break;
2377 }
2378 return nullptr;
2379 };
2380
2381 // Find parentheses of parameter list.
2382 const FormatToken *Next = Current.Next;
2383 if (Current.is(tok::kw_operator)) {
2384 if (Current.Previous && Current.Previous->is(tok::coloncolon))
2385 return false;
2386 Next = skipOperatorName(Next);
2387 } else {
2388 if (!Current.is(TT_StartOfName) || Current.NestingLevel != 0)
2389 return false;
2390 for (; Next; Next = Next->Next) {
2391 if (Next->is(TT_TemplateOpener)) {
2392 Next = Next->MatchingParen;
2393 } else if (Next->is(tok::coloncolon)) {
2394 Next = Next->Next;
2395 if (!Next)
2396 return false;
2397 if (Next->is(tok::kw_operator)) {
2398 Next = skipOperatorName(Next->Next);
2399 break;
2400 }
2401 if (!Next->is(tok::identifier))
2402 return false;
2403 } else if (Next->is(tok::l_paren)) {
2404 break;
2405 } else {
2406 return false;
2407 }
2408 }
2409 }
2410
2411 // Check whether parameter list can belong to a function declaration.
2412 if (!Next || !Next->is(tok::l_paren) || !Next->MatchingParen)
2413 return false;
2414 // If the lines ends with "{", this is likely an function definition.
2415 if (Line.Last->is(tok::l_brace))
2416 return true;
2417 if (Next->Next == Next->MatchingParen)
2418 return true; // Empty parentheses.
2419 // If there is an &/&& after the r_paren, this is likely a function.
2420 if (Next->MatchingParen->Next &&
2421 Next->MatchingParen->Next->is(TT_PointerOrReference))
2422 return true;
2423 for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen;
2424 Tok = Tok->Next) {
2425 if (Tok->is(TT_TypeDeclarationParen))
2426 return true;
2427 if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) {
2428 Tok = Tok->MatchingParen;
2429 continue;
2430 }
2431 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
2432 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
2433 return true;
2434 if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
2435 Tok->Tok.isLiteral())
2436 return false;
2437 }
2438 return false;
2439 }
2440
mustBreakForReturnType(const AnnotatedLine & Line) const2441 bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const {
2442 assert(Line.MightBeFunctionDecl);
2443
2444 if ((Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_TopLevel ||
2445 Style.AlwaysBreakAfterReturnType ==
2446 FormatStyle::RTBS_TopLevelDefinitions) &&
2447 Line.Level > 0)
2448 return false;
2449
2450 switch (Style.AlwaysBreakAfterReturnType) {
2451 case FormatStyle::RTBS_None:
2452 return false;
2453 case FormatStyle::RTBS_All:
2454 case FormatStyle::RTBS_TopLevel:
2455 return true;
2456 case FormatStyle::RTBS_AllDefinitions:
2457 case FormatStyle::RTBS_TopLevelDefinitions:
2458 return Line.mightBeFunctionDefinition();
2459 }
2460
2461 return false;
2462 }
2463
calculateFormattingInformation(AnnotatedLine & Line)2464 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
2465 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
2466 E = Line.Children.end();
2467 I != E; ++I) {
2468 calculateFormattingInformation(**I);
2469 }
2470
2471 Line.First->TotalLength =
2472 Line.First->IsMultiline ? Style.ColumnLimit
2473 : Line.FirstStartColumn + Line.First->ColumnWidth;
2474 FormatToken *Current = Line.First->Next;
2475 bool InFunctionDecl = Line.MightBeFunctionDecl;
2476 while (Current) {
2477 if (isFunctionDeclarationName(*Current, Line))
2478 Current->setType(TT_FunctionDeclarationName);
2479 if (Current->is(TT_LineComment)) {
2480 if (Current->Previous->is(BK_BracedInit) &&
2481 Current->Previous->opensScope())
2482 Current->SpacesRequiredBefore =
2483 (Style.Cpp11BracedListStyle && !Style.SpacesInParentheses) ? 0 : 1;
2484 else
2485 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
2486
2487 // If we find a trailing comment, iterate backwards to determine whether
2488 // it seems to relate to a specific parameter. If so, break before that
2489 // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
2490 // to the previous line in:
2491 // SomeFunction(a,
2492 // b, // comment
2493 // c);
2494 if (!Current->HasUnescapedNewline) {
2495 for (FormatToken *Parameter = Current->Previous; Parameter;
2496 Parameter = Parameter->Previous) {
2497 if (Parameter->isOneOf(tok::comment, tok::r_brace))
2498 break;
2499 if (Parameter->Previous && Parameter->Previous->is(tok::comma)) {
2500 if (!Parameter->Previous->is(TT_CtorInitializerComma) &&
2501 Parameter->HasUnescapedNewline)
2502 Parameter->MustBreakBefore = true;
2503 break;
2504 }
2505 }
2506 }
2507 } else if (Current->SpacesRequiredBefore == 0 &&
2508 spaceRequiredBefore(Line, *Current)) {
2509 Current->SpacesRequiredBefore = 1;
2510 }
2511
2512 Current->MustBreakBefore =
2513 Current->MustBreakBefore || mustBreakBefore(Line, *Current);
2514
2515 if (!Current->MustBreakBefore && InFunctionDecl &&
2516 Current->is(TT_FunctionDeclarationName))
2517 Current->MustBreakBefore = mustBreakForReturnType(Line);
2518
2519 Current->CanBreakBefore =
2520 Current->MustBreakBefore || canBreakBefore(Line, *Current);
2521 unsigned ChildSize = 0;
2522 if (Current->Previous->Children.size() == 1) {
2523 FormatToken &LastOfChild = *Current->Previous->Children[0]->Last;
2524 ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit
2525 : LastOfChild.TotalLength + 1;
2526 }
2527 const FormatToken *Prev = Current->Previous;
2528 if (Current->MustBreakBefore || Prev->Children.size() > 1 ||
2529 (Prev->Children.size() == 1 &&
2530 Prev->Children[0]->First->MustBreakBefore) ||
2531 Current->IsMultiline)
2532 Current->TotalLength = Prev->TotalLength + Style.ColumnLimit;
2533 else
2534 Current->TotalLength = Prev->TotalLength + Current->ColumnWidth +
2535 ChildSize + Current->SpacesRequiredBefore;
2536
2537 if (Current->is(TT_CtorInitializerColon))
2538 InFunctionDecl = false;
2539
2540 // FIXME: Only calculate this if CanBreakBefore is true once static
2541 // initializers etc. are sorted out.
2542 // FIXME: Move magic numbers to a better place.
2543
2544 // Reduce penalty for aligning ObjC method arguments using the colon
2545 // alignment as this is the canonical way (still prefer fitting everything
2546 // into one line if possible). Trying to fit a whole expression into one
2547 // line should not force other line breaks (e.g. when ObjC method
2548 // expression is a part of other expression).
2549 Current->SplitPenalty = splitPenalty(Line, *Current, InFunctionDecl);
2550 if (Style.Language == FormatStyle::LK_ObjC &&
2551 Current->is(TT_SelectorName) && Current->ParameterIndex > 0) {
2552 if (Current->ParameterIndex == 1)
2553 Current->SplitPenalty += 5 * Current->BindingStrength;
2554 } else {
2555 Current->SplitPenalty += 20 * Current->BindingStrength;
2556 }
2557
2558 Current = Current->Next;
2559 }
2560
2561 calculateUnbreakableTailLengths(Line);
2562 unsigned IndentLevel = Line.Level;
2563 for (Current = Line.First; Current != nullptr; Current = Current->Next) {
2564 if (Current->Role)
2565 Current->Role->precomputeFormattingInfos(Current);
2566 if (Current->MatchingParen &&
2567 Current->MatchingParen->opensBlockOrBlockTypeList(Style)) {
2568 assert(IndentLevel > 0);
2569 --IndentLevel;
2570 }
2571 Current->IndentLevel = IndentLevel;
2572 if (Current->opensBlockOrBlockTypeList(Style))
2573 ++IndentLevel;
2574 }
2575
2576 LLVM_DEBUG({ printDebugInfo(Line); });
2577 }
2578
calculateUnbreakableTailLengths(AnnotatedLine & Line)2579 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) {
2580 unsigned UnbreakableTailLength = 0;
2581 FormatToken *Current = Line.Last;
2582 while (Current) {
2583 Current->UnbreakableTailLength = UnbreakableTailLength;
2584 if (Current->CanBreakBefore ||
2585 Current->isOneOf(tok::comment, tok::string_literal)) {
2586 UnbreakableTailLength = 0;
2587 } else {
2588 UnbreakableTailLength +=
2589 Current->ColumnWidth + Current->SpacesRequiredBefore;
2590 }
2591 Current = Current->Previous;
2592 }
2593 }
2594
splitPenalty(const AnnotatedLine & Line,const FormatToken & Tok,bool InFunctionDecl)2595 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
2596 const FormatToken &Tok,
2597 bool InFunctionDecl) {
2598 const FormatToken &Left = *Tok.Previous;
2599 const FormatToken &Right = Tok;
2600
2601 if (Left.is(tok::semi))
2602 return 0;
2603
2604 if (Style.Language == FormatStyle::LK_Java) {
2605 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
2606 return 1;
2607 if (Right.is(Keywords.kw_implements))
2608 return 2;
2609 if (Left.is(tok::comma) && Left.NestingLevel == 0)
2610 return 3;
2611 } else if (Style.Language == FormatStyle::LK_JavaScript) {
2612 if (Right.is(Keywords.kw_function) && Left.isNot(tok::comma))
2613 return 100;
2614 if (Left.is(TT_JsTypeColon))
2615 return 35;
2616 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) ||
2617 (Right.is(TT_TemplateString) && Right.TokenText.startswith("}")))
2618 return 100;
2619 // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()".
2620 if (Left.opensScope() && Right.closesScope())
2621 return 200;
2622 }
2623
2624 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
2625 return 1;
2626 if (Right.is(tok::l_square)) {
2627 if (Style.Language == FormatStyle::LK_Proto)
2628 return 1;
2629 if (Left.is(tok::r_square))
2630 return 200;
2631 // Slightly prefer formatting local lambda definitions like functions.
2632 if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
2633 return 35;
2634 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2635 TT_ArrayInitializerLSquare,
2636 TT_DesignatedInitializerLSquare, TT_AttributeSquare))
2637 return 500;
2638 }
2639
2640 if (Left.is(tok::coloncolon) ||
2641 (Right.is(tok::period) && Style.Language == FormatStyle::LK_Proto))
2642 return 500;
2643 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2644 Right.is(tok::kw_operator)) {
2645 if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
2646 return 3;
2647 if (Left.is(TT_StartOfName))
2648 return 110;
2649 if (InFunctionDecl && Right.NestingLevel == 0)
2650 return Style.PenaltyReturnTypeOnItsOwnLine;
2651 return 200;
2652 }
2653 if (Right.is(TT_PointerOrReference))
2654 return 190;
2655 if (Right.is(TT_LambdaArrow))
2656 return 110;
2657 if (Left.is(tok::equal) && Right.is(tok::l_brace))
2658 return 160;
2659 if (Left.is(TT_CastRParen))
2660 return 100;
2661 if (Left.isOneOf(tok::kw_class, tok::kw_struct))
2662 return 5000;
2663 if (Left.is(tok::comment))
2664 return 1000;
2665
2666 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
2667 TT_CtorInitializerColon))
2668 return 2;
2669
2670 if (Right.isMemberAccess()) {
2671 // Breaking before the "./->" of a chained call/member access is reasonably
2672 // cheap, as formatting those with one call per line is generally
2673 // desirable. In particular, it should be cheaper to break before the call
2674 // than it is to break inside a call's parameters, which could lead to weird
2675 // "hanging" indents. The exception is the very last "./->" to support this
2676 // frequent pattern:
2677 //
2678 // aaaaaaaa.aaaaaaaa.bbbbbbb().ccccccccccccccccccccc(
2679 // dddddddd);
2680 //
2681 // which might otherwise be blown up onto many lines. Here, clang-format
2682 // won't produce "hanging" indents anyway as there is no other trailing
2683 // call.
2684 //
2685 // Also apply higher penalty is not a call as that might lead to a wrapping
2686 // like:
2687 //
2688 // aaaaaaa
2689 // .aaaaaaaaa.bbbbbbbb(cccccccc);
2690 return !Right.NextOperator || !Right.NextOperator->Previous->closesScope()
2691 ? 150
2692 : 35;
2693 }
2694
2695 if (Right.is(TT_TrailingAnnotation) &&
2696 (!Right.Next || Right.Next->isNot(tok::l_paren))) {
2697 // Moving trailing annotations to the next line is fine for ObjC method
2698 // declarations.
2699 if (Line.startsWith(TT_ObjCMethodSpecifier))
2700 return 10;
2701 // Generally, breaking before a trailing annotation is bad unless it is
2702 // function-like. It seems to be especially preferable to keep standard
2703 // annotations (i.e. "const", "final" and "override") on the same line.
2704 // Use a slightly higher penalty after ")" so that annotations like
2705 // "const override" are kept together.
2706 bool is_short_annotation = Right.TokenText.size() < 10;
2707 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
2708 }
2709
2710 // In for-loops, prefer breaking at ',' and ';'.
2711 if (Line.startsWith(tok::kw_for) && Left.is(tok::equal))
2712 return 4;
2713
2714 // In Objective-C method expressions, prefer breaking before "param:" over
2715 // breaking after it.
2716 if (Right.is(TT_SelectorName))
2717 return 0;
2718 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
2719 return Line.MightBeFunctionDecl ? 50 : 500;
2720
2721 // In Objective-C type declarations, avoid breaking after the category's
2722 // open paren (we'll prefer breaking after the protocol list's opening
2723 // angle bracket, if present).
2724 if (Line.Type == LT_ObjCDecl && Left.is(tok::l_paren) && Left.Previous &&
2725 Left.Previous->isOneOf(tok::identifier, tok::greater))
2726 return 500;
2727
2728 if (Left.is(tok::l_paren) && InFunctionDecl &&
2729 Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign)
2730 return 100;
2731 if (Left.is(tok::l_paren) && Left.Previous &&
2732 (Left.Previous->is(tok::kw_for) || Left.Previous->isIf()))
2733 return 1000;
2734 if (Left.is(tok::equal) && InFunctionDecl)
2735 return 110;
2736 if (Right.is(tok::r_brace))
2737 return 1;
2738 if (Left.is(TT_TemplateOpener))
2739 return 100;
2740 if (Left.opensScope()) {
2741 // If we aren't aligning after opening parens/braces we can always break
2742 // here unless the style does not want us to place all arguments on the
2743 // next line.
2744 if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign &&
2745 (Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine))
2746 return 0;
2747 if (Left.is(tok::l_brace) && !Style.Cpp11BracedListStyle)
2748 return 19;
2749 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
2750 : 19;
2751 }
2752 if (Left.is(TT_JavaAnnotation))
2753 return 50;
2754
2755 if (Left.is(TT_UnaryOperator))
2756 return 60;
2757 if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&
2758 Left.Previous->isLabelString() &&
2759 (Left.NextOperator || Left.OperatorIndex != 0))
2760 return 50;
2761 if (Right.is(tok::plus) && Left.isLabelString() &&
2762 (Right.NextOperator || Right.OperatorIndex != 0))
2763 return 25;
2764 if (Left.is(tok::comma))
2765 return 1;
2766 if (Right.is(tok::lessless) && Left.isLabelString() &&
2767 (Right.NextOperator || Right.OperatorIndex != 1))
2768 return 25;
2769 if (Right.is(tok::lessless)) {
2770 // Breaking at a << is really cheap.
2771 if (!Left.is(tok::r_paren) || Right.OperatorIndex > 0)
2772 // Slightly prefer to break before the first one in log-like statements.
2773 return 2;
2774 return 1;
2775 }
2776 if (Left.ClosesTemplateDeclaration)
2777 return Style.PenaltyBreakTemplateDeclaration;
2778 if (Left.is(TT_ConditionalExpr))
2779 return prec::Conditional;
2780 prec::Level Level = Left.getPrecedence();
2781 if (Level == prec::Unknown)
2782 Level = Right.getPrecedence();
2783 if (Level == prec::Assignment)
2784 return Style.PenaltyBreakAssignment;
2785 if (Level != prec::Unknown)
2786 return Level;
2787
2788 return 3;
2789 }
2790
spaceRequiredBeforeParens(const FormatToken & Right) const2791 bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const {
2792 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always ||
2793 (Style.SpaceBeforeParens == FormatStyle::SBPO_NonEmptyParentheses &&
2794 Right.ParameterCount > 0);
2795 }
2796
spaceRequiredBetween(const AnnotatedLine & Line,const FormatToken & Left,const FormatToken & Right)2797 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
2798 const FormatToken &Left,
2799 const FormatToken &Right) {
2800 if (Left.is(tok::kw_return) && Right.isNot(tok::semi))
2801 return true;
2802 if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java)
2803 return true;
2804 if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&
2805 Left.Tok.getObjCKeywordID() == tok::objc_property)
2806 return true;
2807 if (Right.is(tok::hashhash))
2808 return Left.is(tok::hash);
2809 if (Left.isOneOf(tok::hashhash, tok::hash))
2810 return Right.is(tok::hash);
2811 if ((Left.is(tok::l_paren) && Right.is(tok::r_paren)) ||
2812 (Left.is(tok::l_brace) && Left.isNot(BK_Block) &&
2813 Right.is(tok::r_brace) && Right.isNot(BK_Block)))
2814 return Style.SpaceInEmptyParentheses;
2815 if (Style.SpacesInConditionalStatement) {
2816 if (Left.is(tok::l_paren) && Left.Previous &&
2817 isKeywordWithCondition(*Left.Previous))
2818 return true;
2819 if (Right.is(tok::r_paren) && Right.MatchingParen &&
2820 Right.MatchingParen->Previous &&
2821 isKeywordWithCondition(*Right.MatchingParen->Previous))
2822 return true;
2823 }
2824
2825 // requires ( or requires(
2826 if (Right.is(tok::l_paren) && Left.is(tok::kw_requires))
2827 return spaceRequiredBeforeParens(Right);
2828 // requires clause Concept1<T> && Concept2<T>
2829 if (Left.is(TT_ConstraintJunctions) && Right.is(tok::identifier))
2830 return true;
2831
2832 if (Left.is(tok::l_paren) || Right.is(tok::r_paren))
2833 return (Right.is(TT_CastRParen) ||
2834 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
2835 ? Style.SpacesInCStyleCastParentheses
2836 : Style.SpacesInParentheses;
2837 if (Right.isOneOf(tok::semi, tok::comma))
2838 return false;
2839 if (Right.is(tok::less) && Line.Type == LT_ObjCDecl) {
2840 bool IsLightweightGeneric = Right.MatchingParen &&
2841 Right.MatchingParen->Next &&
2842 Right.MatchingParen->Next->is(tok::colon);
2843 return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
2844 }
2845 if (Right.is(tok::less) && Left.is(tok::kw_template))
2846 return Style.SpaceAfterTemplateKeyword;
2847 if (Left.isOneOf(tok::exclaim, tok::tilde))
2848 return false;
2849 if (Left.is(tok::at) &&
2850 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
2851 tok::numeric_constant, tok::l_paren, tok::l_brace,
2852 tok::kw_true, tok::kw_false))
2853 return false;
2854 if (Left.is(tok::colon))
2855 return !Left.is(TT_ObjCMethodExpr);
2856 if (Left.is(tok::coloncolon))
2857 return false;
2858 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
2859 if (Style.Language == FormatStyle::LK_TextProto ||
2860 (Style.Language == FormatStyle::LK_Proto &&
2861 (Left.is(TT_DictLiteral) || Right.is(TT_DictLiteral)))) {
2862 // Format empty list as `<>`.
2863 if (Left.is(tok::less) && Right.is(tok::greater))
2864 return false;
2865 return !Style.Cpp11BracedListStyle;
2866 }
2867 return false;
2868 }
2869 if (Right.is(tok::ellipsis))
2870 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
2871 Left.Previous->is(tok::kw_case));
2872 if (Left.is(tok::l_square) && Right.is(tok::amp))
2873 return Style.SpacesInSquareBrackets;
2874 if (Right.is(TT_PointerOrReference)) {
2875 if (Left.is(tok::r_paren) && Line.MightBeFunctionDecl) {
2876 if (!Left.MatchingParen)
2877 return true;
2878 FormatToken *TokenBeforeMatchingParen =
2879 Left.MatchingParen->getPreviousNonComment();
2880 if (!TokenBeforeMatchingParen || !Left.is(TT_TypeDeclarationParen))
2881 return true;
2882 }
2883 // Add a space if the previous token is a pointer qualifer or the closing
2884 // parenthesis of __attribute__(()) expression and the style requires spaces
2885 // after pointer qualifiers.
2886 if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_After ||
2887 Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
2888 (Left.is(TT_AttributeParen) || Left.canBePointerOrReferenceQualifier()))
2889 return true;
2890 return (Left.Tok.isLiteral() ||
2891 (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
2892 (Style.PointerAlignment != FormatStyle::PAS_Left ||
2893 (Line.IsMultiVariableDeclStmt &&
2894 (Left.NestingLevel == 0 ||
2895 (Left.NestingLevel == 1 && Line.First->is(tok::kw_for)))))));
2896 }
2897 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
2898 (!Left.is(TT_PointerOrReference) ||
2899 (Style.PointerAlignment != FormatStyle::PAS_Right &&
2900 !Line.IsMultiVariableDeclStmt)))
2901 return true;
2902 if (Left.is(TT_PointerOrReference)) {
2903 // Add a space if the next token is a pointer qualifer and the style
2904 // requires spaces before pointer qualifiers.
2905 if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Before ||
2906 Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
2907 Right.canBePointerOrReferenceQualifier())
2908 return true;
2909 return Right.Tok.isLiteral() || Right.is(TT_BlockComment) ||
2910 (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
2911 !Right.is(TT_StartOfName)) ||
2912 (Right.is(tok::l_brace) && Right.is(BK_Block)) ||
2913 (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2914 tok::l_paren) &&
2915 (Style.PointerAlignment != FormatStyle::PAS_Right &&
2916 !Line.IsMultiVariableDeclStmt) &&
2917 Left.Previous &&
2918 !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon,
2919 tok::l_square));
2920 }
2921 // Ensure right pointer alignement with ellipsis e.g. int *...P
2922 if (Left.is(tok::ellipsis) && Left.Previous &&
2923 Left.Previous->isOneOf(tok::star, tok::amp, tok::ampamp))
2924 return Style.PointerAlignment != FormatStyle::PAS_Right;
2925
2926 if (Right.is(tok::star) && Left.is(tok::l_paren))
2927 return false;
2928 if (Left.is(tok::star) && Right.isOneOf(tok::star, tok::amp, tok::ampamp))
2929 return false;
2930 if (Right.isOneOf(tok::star, tok::amp, tok::ampamp)) {
2931 const FormatToken *Previous = &Left;
2932 while (Previous && !Previous->is(tok::kw_operator)) {
2933 if (Previous->is(tok::identifier) || Previous->isSimpleTypeSpecifier()) {
2934 Previous = Previous->getPreviousNonComment();
2935 continue;
2936 }
2937 if (Previous->is(TT_TemplateCloser) && Previous->MatchingParen) {
2938 Previous = Previous->MatchingParen->getPreviousNonComment();
2939 continue;
2940 }
2941 if (Previous->is(tok::coloncolon)) {
2942 Previous = Previous->getPreviousNonComment();
2943 continue;
2944 }
2945 break;
2946 }
2947 // Space between the type and the * in:
2948 // operator void*()
2949 // operator char*()
2950 // operator void const*()
2951 // operator void volatile*()
2952 // operator /*comment*/ const char*()
2953 // operator volatile /*comment*/ char*()
2954 // operator Foo*()
2955 // operator C<T>*()
2956 // operator std::Foo*()
2957 // operator C<T>::D<U>*()
2958 // dependent on PointerAlignment style.
2959 if (Previous) {
2960 if (Previous->endsSequence(tok::kw_operator))
2961 return (Style.PointerAlignment != FormatStyle::PAS_Left);
2962 if (Previous->is(tok::kw_const) || Previous->is(tok::kw_volatile))
2963 return (Style.PointerAlignment != FormatStyle::PAS_Left) ||
2964 (Style.SpaceAroundPointerQualifiers ==
2965 FormatStyle::SAPQ_After) ||
2966 (Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both);
2967 }
2968 }
2969 const auto SpaceRequiredForArrayInitializerLSquare =
2970 [](const FormatToken &LSquareTok, const FormatStyle &Style) {
2971 return Style.SpacesInContainerLiterals ||
2972 ((Style.Language == FormatStyle::LK_Proto ||
2973 Style.Language == FormatStyle::LK_TextProto) &&
2974 !Style.Cpp11BracedListStyle &&
2975 LSquareTok.endsSequence(tok::l_square, tok::colon,
2976 TT_SelectorName));
2977 };
2978 if (Left.is(tok::l_square))
2979 return (Left.is(TT_ArrayInitializerLSquare) && Right.isNot(tok::r_square) &&
2980 SpaceRequiredForArrayInitializerLSquare(Left, Style)) ||
2981 (Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare,
2982 TT_LambdaLSquare) &&
2983 Style.SpacesInSquareBrackets && Right.isNot(tok::r_square));
2984 if (Right.is(tok::r_square))
2985 return Right.MatchingParen &&
2986 ((Right.MatchingParen->is(TT_ArrayInitializerLSquare) &&
2987 SpaceRequiredForArrayInitializerLSquare(*Right.MatchingParen,
2988 Style)) ||
2989 (Style.SpacesInSquareBrackets &&
2990 Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
2991 TT_StructuredBindingLSquare,
2992 TT_LambdaLSquare)) ||
2993 Right.MatchingParen->is(TT_AttributeParen));
2994 if (Right.is(tok::l_square) &&
2995 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2996 TT_DesignatedInitializerLSquare,
2997 TT_StructuredBindingLSquare, TT_AttributeSquare) &&
2998 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral) &&
2999 !(!Left.is(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
3000 Right.is(TT_ArraySubscriptLSquare)))
3001 return false;
3002 if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
3003 return !Left.Children.empty(); // No spaces in "{}".
3004 if ((Left.is(tok::l_brace) && Left.isNot(BK_Block)) ||
3005 (Right.is(tok::r_brace) && Right.MatchingParen &&
3006 Right.MatchingParen->isNot(BK_Block)))
3007 return Style.Cpp11BracedListStyle ? Style.SpacesInParentheses : true;
3008 if (Left.is(TT_BlockComment))
3009 // No whitespace in x(/*foo=*/1), except for JavaScript.
3010 return Style.Language == FormatStyle::LK_JavaScript ||
3011 !Left.TokenText.endswith("=*/");
3012
3013 // Space between template and attribute.
3014 // e.g. template <typename T> [[nodiscard]] ...
3015 if (Left.is(TT_TemplateCloser) && Right.is(TT_AttributeSquare))
3016 return true;
3017 if (Right.is(tok::l_paren)) {
3018 if ((Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) ||
3019 (Left.is(tok::r_square) && Left.is(TT_AttributeSquare)))
3020 return true;
3021 if (Style.SpaceBeforeParens ==
3022 FormatStyle::SBPO_ControlStatementsExceptForEachMacros &&
3023 Left.is(TT_ForEachMacro))
3024 return false;
3025 return Line.Type == LT_ObjCDecl || Left.is(tok::semi) ||
3026 (Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
3027 (Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while,
3028 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
3029 TT_ObjCForIn) ||
3030 Left.isIf(Line.Type != LT_PreprocessorDirective) ||
3031 (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
3032 tok::kw_new, tok::kw_delete) &&
3033 (!Left.Previous || Left.Previous->isNot(tok::period))))) ||
3034 (spaceRequiredBeforeParens(Right) &&
3035 (Left.is(tok::identifier) || Left.isFunctionLikeKeyword() ||
3036 Left.is(tok::r_paren) || Left.isSimpleTypeSpecifier() ||
3037 (Left.is(tok::r_square) && Left.MatchingParen &&
3038 Left.MatchingParen->is(TT_LambdaLSquare))) &&
3039 Line.Type != LT_PreprocessorDirective);
3040 }
3041 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
3042 return false;
3043 if (Right.is(TT_UnaryOperator))
3044 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
3045 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
3046 if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
3047 tok::r_paren) ||
3048 Left.isSimpleTypeSpecifier()) &&
3049 Right.is(tok::l_brace) && Right.getNextNonComment() &&
3050 Right.isNot(BK_Block))
3051 return false;
3052 if (Left.is(tok::period) || Right.is(tok::period))
3053 return false;
3054 if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText == "L")
3055 return false;
3056 if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
3057 Left.MatchingParen->Previous &&
3058 (Left.MatchingParen->Previous->is(tok::period) ||
3059 Left.MatchingParen->Previous->is(tok::coloncolon)))
3060 // Java call to generic function with explicit type:
3061 // A.<B<C<...>>>DoSomething();
3062 // A::<B<C<...>>>DoSomething(); // With a Java 8 method reference.
3063 return false;
3064 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
3065 return false;
3066 if (Left.is(tok::l_brace) && Left.endsSequence(TT_DictLiteral, tok::at))
3067 // Objective-C dictionary literal -> no space after opening brace.
3068 return false;
3069 if (Right.is(tok::r_brace) && Right.MatchingParen &&
3070 Right.MatchingParen->endsSequence(TT_DictLiteral, tok::at))
3071 // Objective-C dictionary literal -> no space before closing brace.
3072 return false;
3073 if (Right.getType() == TT_TrailingAnnotation &&
3074 Right.isOneOf(tok::amp, tok::ampamp) &&
3075 Left.isOneOf(tok::kw_const, tok::kw_volatile) &&
3076 (!Right.Next || Right.Next->is(tok::semi)))
3077 // Match const and volatile ref-qualifiers without any additional
3078 // qualifiers such as
3079 // void Fn() const &;
3080 return Style.PointerAlignment != FormatStyle::PAS_Left;
3081 return true;
3082 }
3083
spaceRequiredBefore(const AnnotatedLine & Line,const FormatToken & Right)3084 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
3085 const FormatToken &Right) {
3086 const FormatToken &Left = *Right.Previous;
3087 auto HasExistingWhitespace = [&Right]() {
3088 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
3089 };
3090 if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
3091 return true; // Never ever merge two identifiers.
3092 if (Style.isCpp()) {
3093 if (Left.is(tok::kw_operator))
3094 return Right.is(tok::coloncolon);
3095 if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) &&
3096 !Left.opensScope() && Style.SpaceBeforeCpp11BracedList)
3097 return true;
3098 } else if (Style.Language == FormatStyle::LK_Proto ||
3099 Style.Language == FormatStyle::LK_TextProto) {
3100 if (Right.is(tok::period) &&
3101 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
3102 Keywords.kw_repeated, Keywords.kw_extend))
3103 return true;
3104 if (Right.is(tok::l_paren) &&
3105 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option))
3106 return true;
3107 if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
3108 return true;
3109 // Slashes occur in text protocol extension syntax: [type/type] { ... }.
3110 if (Left.is(tok::slash) || Right.is(tok::slash))
3111 return false;
3112 if (Left.MatchingParen &&
3113 Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
3114 Right.isOneOf(tok::l_brace, tok::less))
3115 return !Style.Cpp11BracedListStyle;
3116 // A percent is probably part of a formatting specification, such as %lld.
3117 if (Left.is(tok::percent))
3118 return false;
3119 // Preserve the existence of a space before a percent for cases like 0x%04x
3120 // and "%d %d"
3121 if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
3122 return HasExistingWhitespace();
3123 } else if (Style.isCSharp()) {
3124 // Require spaces around '{' and before '}' unless they appear in
3125 // interpolated strings. Interpolated strings are merged into a single token
3126 // so cannot have spaces inserted by this function.
3127
3128 // No space between 'this' and '['
3129 if (Left.is(tok::kw_this) && Right.is(tok::l_square))
3130 return false;
3131
3132 // No space between 'new' and '('
3133 if (Left.is(tok::kw_new) && Right.is(tok::l_paren))
3134 return false;
3135
3136 // Space before { (including space within '{ {').
3137 if (Right.is(tok::l_brace))
3138 return true;
3139
3140 // Spaces inside braces.
3141 if (Left.is(tok::l_brace) && Right.isNot(tok::r_brace))
3142 return true;
3143
3144 if (Left.isNot(tok::l_brace) && Right.is(tok::r_brace))
3145 return true;
3146
3147 // Spaces around '=>'.
3148 if (Left.is(TT_FatArrow) || Right.is(TT_FatArrow))
3149 return true;
3150
3151 // No spaces around attribute target colons
3152 if (Left.is(TT_AttributeColon) || Right.is(TT_AttributeColon))
3153 return false;
3154
3155 // space between type and variable e.g. Dictionary<string,string> foo;
3156 if (Left.is(TT_TemplateCloser) && Right.is(TT_StartOfName))
3157 return true;
3158
3159 // spaces inside square brackets.
3160 if (Left.is(tok::l_square) || Right.is(tok::r_square))
3161 return Style.SpacesInSquareBrackets;
3162
3163 // No space before ? in nullable types.
3164 if (Right.is(TT_CSharpNullable))
3165 return false;
3166
3167 // No space before null forgiving '!'.
3168 if (Right.is(TT_NonNullAssertion))
3169 return false;
3170
3171 // No space between consecutive commas '[,,]'.
3172 if (Left.is(tok::comma) && Right.is(tok::comma))
3173 return false;
3174
3175 // space after var in `var (key, value)`
3176 if (Left.is(Keywords.kw_var) && Right.is(tok::l_paren))
3177 return true;
3178
3179 // space between keywords and paren e.g. "using ("
3180 if (Right.is(tok::l_paren))
3181 if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when,
3182 Keywords.kw_lock))
3183 return Style.SpaceBeforeParens == FormatStyle::SBPO_ControlStatements ||
3184 spaceRequiredBeforeParens(Right);
3185
3186 // space between method modifier and opening parenthesis of a tuple return
3187 // type
3188 if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
3189 tok::kw_virtual, tok::kw_extern, tok::kw_static,
3190 Keywords.kw_internal, Keywords.kw_abstract,
3191 Keywords.kw_sealed, Keywords.kw_override,
3192 Keywords.kw_async, Keywords.kw_unsafe) &&
3193 Right.is(tok::l_paren))
3194 return true;
3195 } else if (Style.Language == FormatStyle::LK_JavaScript) {
3196 if (Left.is(TT_FatArrow))
3197 return true;
3198 // for await ( ...
3199 if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && Left.Previous &&
3200 Left.Previous->is(tok::kw_for))
3201 return true;
3202 if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
3203 Right.MatchingParen) {
3204 const FormatToken *Next = Right.MatchingParen->getNextNonComment();
3205 // An async arrow function, for example: `x = async () => foo();`,
3206 // as opposed to calling a function called async: `x = async();`
3207 if (Next && Next->is(TT_FatArrow))
3208 return true;
3209 }
3210 if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) ||
3211 (Right.is(TT_TemplateString) && Right.TokenText.startswith("}")))
3212 return false;
3213 // In tagged template literals ("html`bar baz`"), there is no space between
3214 // the tag identifier and the template string.
3215 if (Keywords.IsJavaScriptIdentifier(Left,
3216 /* AcceptIdentifierName= */ false) &&
3217 Right.is(TT_TemplateString))
3218 return false;
3219 if (Right.is(tok::star) &&
3220 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield))
3221 return false;
3222 if (Right.isOneOf(tok::l_brace, tok::l_square) &&
3223 Left.isOneOf(Keywords.kw_function, Keywords.kw_yield,
3224 Keywords.kw_extends, Keywords.kw_implements))
3225 return true;
3226 if (Right.is(tok::l_paren)) {
3227 // JS methods can use some keywords as names (e.g. `delete()`).
3228 if (Line.MustBeDeclaration && Left.Tok.getIdentifierInfo())
3229 return false;
3230 // Valid JS method names can include keywords, e.g. `foo.delete()` or
3231 // `bar.instanceof()`. Recognize call positions by preceding period.
3232 if (Left.Previous && Left.Previous->is(tok::period) &&
3233 Left.Tok.getIdentifierInfo())
3234 return false;
3235 // Additional unary JavaScript operators that need a space after.
3236 if (Left.isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
3237 tok::kw_void))
3238 return true;
3239 }
3240 // `foo as const;` casts into a const type.
3241 if (Left.endsSequence(tok::kw_const, Keywords.kw_as)) {
3242 return false;
3243 }
3244 if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
3245 tok::kw_const) ||
3246 // "of" is only a keyword if it appears after another identifier
3247 // (e.g. as "const x of y" in a for loop), or after a destructuring
3248 // operation (const [x, y] of z, const {a, b} of c).
3249 (Left.is(Keywords.kw_of) && Left.Previous &&
3250 (Left.Previous->Tok.is(tok::identifier) ||
3251 Left.Previous->isOneOf(tok::r_square, tok::r_brace)))) &&
3252 (!Left.Previous || !Left.Previous->is(tok::period)))
3253 return true;
3254 if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous &&
3255 Left.Previous->is(tok::period) && Right.is(tok::l_paren))
3256 return false;
3257 if (Left.is(Keywords.kw_as) &&
3258 Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren))
3259 return true;
3260 if (Left.is(tok::kw_default) && Left.Previous &&
3261 Left.Previous->is(tok::kw_export))
3262 return true;
3263 if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
3264 return true;
3265 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
3266 return false;
3267 if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
3268 return false;
3269 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
3270 Line.First->isOneOf(Keywords.kw_import, tok::kw_export))
3271 return false;
3272 if (Left.is(tok::ellipsis))
3273 return false;
3274 if (Left.is(TT_TemplateCloser) &&
3275 !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
3276 Keywords.kw_implements, Keywords.kw_extends))
3277 // Type assertions ('<type>expr') are not followed by whitespace. Other
3278 // locations that should have whitespace following are identified by the
3279 // above set of follower tokens.
3280 return false;
3281 if (Right.is(TT_NonNullAssertion))
3282 return false;
3283 if (Left.is(TT_NonNullAssertion) &&
3284 Right.isOneOf(Keywords.kw_as, Keywords.kw_in))
3285 return true; // "x! as string", "x! in y"
3286 } else if (Style.Language == FormatStyle::LK_Java) {
3287 if (Left.is(tok::r_square) && Right.is(tok::l_brace))
3288 return true;
3289 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren))
3290 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never;
3291 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
3292 tok::kw_protected) ||
3293 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract,
3294 Keywords.kw_native)) &&
3295 Right.is(TT_TemplateOpener))
3296 return true;
3297 }
3298 if (Left.is(TT_ImplicitStringLiteral))
3299 return HasExistingWhitespace();
3300 if (Line.Type == LT_ObjCMethodDecl) {
3301 if (Left.is(TT_ObjCMethodSpecifier))
3302 return true;
3303 if (Left.is(tok::r_paren) && canBeObjCSelectorComponent(Right))
3304 // Don't space between ')' and <id> or ')' and 'new'. 'new' is not a
3305 // keyword in Objective-C, and '+ (instancetype)new;' is a standard class
3306 // method declaration.
3307 return false;
3308 }
3309 if (Line.Type == LT_ObjCProperty &&
3310 (Right.is(tok::equal) || Left.is(tok::equal)))
3311 return false;
3312
3313 if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
3314 Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
3315 return true;
3316 if (Right.is(TT_OverloadedOperatorLParen))
3317 return spaceRequiredBeforeParens(Right);
3318 if (Left.is(tok::comma))
3319 return true;
3320 if (Right.is(tok::comma))
3321 return false;
3322 if (Right.is(TT_ObjCBlockLParen))
3323 return true;
3324 if (Right.is(TT_CtorInitializerColon))
3325 return Style.SpaceBeforeCtorInitializerColon;
3326 if (Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon)
3327 return false;
3328 if (Right.is(TT_RangeBasedForLoopColon) &&
3329 !Style.SpaceBeforeRangeBasedForLoopColon)
3330 return false;
3331 if (Left.is(TT_BitFieldColon))
3332 return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||
3333 Style.BitFieldColonSpacing == FormatStyle::BFCS_After;
3334 if (Right.is(tok::colon)) {
3335 if (Line.First->isOneOf(tok::kw_default, tok::kw_case))
3336 return Style.SpaceBeforeCaseColon;
3337 if (!Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi))
3338 return false;
3339 if (Right.is(TT_ObjCMethodExpr))
3340 return false;
3341 if (Left.is(tok::question))
3342 return false;
3343 if (Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon))
3344 return false;
3345 if (Right.is(TT_DictLiteral))
3346 return Style.SpacesInContainerLiterals;
3347 if (Right.is(TT_AttributeColon))
3348 return false;
3349 if (Right.is(TT_CSharpNamedArgumentColon))
3350 return false;
3351 if (Right.is(TT_BitFieldColon))
3352 return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both ||
3353 Style.BitFieldColonSpacing == FormatStyle::BFCS_Before;
3354 return true;
3355 }
3356 // Do not merge "- -" into "--".
3357 if ((Left.isOneOf(tok::minus, tok::minusminus) &&
3358 Right.isOneOf(tok::minus, tok::minusminus)) ||
3359 (Left.isOneOf(tok::plus, tok::plusplus) &&
3360 Right.isOneOf(tok::plus, tok::plusplus)))
3361 return true;
3362 if (Left.is(TT_UnaryOperator)) {
3363 if (!Right.is(tok::l_paren)) {
3364 // The alternative operators for ~ and ! are "compl" and "not".
3365 // If they are used instead, we do not want to combine them with
3366 // the token to the right, unless that is a left paren.
3367 if (Left.is(tok::exclaim) && Left.TokenText == "not")
3368 return true;
3369 if (Left.is(tok::tilde) && Left.TokenText == "compl")
3370 return true;
3371 // Lambda captures allow for a lone &, so "&]" needs to be properly
3372 // handled.
3373 if (Left.is(tok::amp) && Right.is(tok::r_square))
3374 return Style.SpacesInSquareBrackets;
3375 }
3376 return (Style.SpaceAfterLogicalNot && Left.is(tok::exclaim)) ||
3377 Right.is(TT_BinaryOperator);
3378 }
3379
3380 // If the next token is a binary operator or a selector name, we have
3381 // incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.
3382 if (Left.is(TT_CastRParen))
3383 return Style.SpaceAfterCStyleCast ||
3384 Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
3385
3386 auto ShouldAddSpacesInAngles = [this, &HasExistingWhitespace]() {
3387 if (this->Style.SpacesInAngles == FormatStyle::SIAS_Always)
3388 return true;
3389 if (this->Style.SpacesInAngles == FormatStyle::SIAS_Leave)
3390 return HasExistingWhitespace();
3391 return false;
3392 };
3393
3394 if (Left.is(tok::greater) && Right.is(tok::greater)) {
3395 if (Style.Language == FormatStyle::LK_TextProto ||
3396 (Style.Language == FormatStyle::LK_Proto && Left.is(TT_DictLiteral)))
3397 return !Style.Cpp11BracedListStyle;
3398 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
3399 ((Style.Standard < FormatStyle::LS_Cpp11) ||
3400 ShouldAddSpacesInAngles());
3401 }
3402 if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
3403 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
3404 (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod)))
3405 return false;
3406 if (!Style.SpaceBeforeAssignmentOperators && Left.isNot(TT_TemplateCloser) &&
3407 Right.getPrecedence() == prec::Assignment)
3408 return false;
3409 if (Style.Language == FormatStyle::LK_Java && Right.is(tok::coloncolon) &&
3410 (Left.is(tok::identifier) || Left.is(tok::kw_this)))
3411 return false;
3412 if (Right.is(tok::coloncolon) && Left.is(tok::identifier))
3413 // Generally don't remove existing spaces between an identifier and "::".
3414 // The identifier might actually be a macro name such as ALWAYS_INLINE. If
3415 // this turns out to be too lenient, add analysis of the identifier itself.
3416 return HasExistingWhitespace();
3417 if (Right.is(tok::coloncolon) &&
3418 !Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren))
3419 // Put a space between < and :: in vector< ::std::string >
3420 return (Left.is(TT_TemplateOpener) &&
3421 ((Style.Standard < FormatStyle::LS_Cpp11) ||
3422 ShouldAddSpacesInAngles())) ||
3423 !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
3424 tok::kw___super, TT_TemplateOpener,
3425 TT_TemplateCloser)) ||
3426 (Left.is(tok::l_paren) && Style.SpacesInParentheses);
3427 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
3428 return ShouldAddSpacesInAngles();
3429 // Space before TT_StructuredBindingLSquare.
3430 if (Right.is(TT_StructuredBindingLSquare))
3431 return !Left.isOneOf(tok::amp, tok::ampamp) ||
3432 Style.PointerAlignment != FormatStyle::PAS_Right;
3433 // Space before & or && following a TT_StructuredBindingLSquare.
3434 if (Right.Next && Right.Next->is(TT_StructuredBindingLSquare) &&
3435 Right.isOneOf(tok::amp, tok::ampamp))
3436 return Style.PointerAlignment != FormatStyle::PAS_Left;
3437 if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) ||
3438 (Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
3439 !Right.is(tok::r_paren)))
3440 return true;
3441 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) &&
3442 Right.isNot(TT_FunctionTypeLParen))
3443 return spaceRequiredBeforeParens(Right);
3444 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
3445 Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen))
3446 return false;
3447 if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
3448 Line.startsWith(tok::hash))
3449 return true;
3450 if (Right.is(TT_TrailingUnaryOperator))
3451 return false;
3452 if (Left.is(TT_RegexLiteral))
3453 return false;
3454 return spaceRequiredBetween(Line, Left, Right);
3455 }
3456
3457 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
isAllmanBrace(const FormatToken & Tok)3458 static bool isAllmanBrace(const FormatToken &Tok) {
3459 return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&
3460 !Tok.isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
3461 }
3462
3463 // Returns 'true' if 'Tok' is an function argument.
IsFunctionArgument(const FormatToken & Tok)3464 static bool IsFunctionArgument(const FormatToken &Tok) {
3465 return Tok.MatchingParen && Tok.MatchingParen->Next &&
3466 Tok.MatchingParen->Next->isOneOf(tok::comma, tok::r_paren);
3467 }
3468
3469 static bool
isItAnEmptyLambdaAllowed(const FormatToken & Tok,FormatStyle::ShortLambdaStyle ShortLambdaOption)3470 isItAnEmptyLambdaAllowed(const FormatToken &Tok,
3471 FormatStyle::ShortLambdaStyle ShortLambdaOption) {
3472 return Tok.Children.empty() && ShortLambdaOption != FormatStyle::SLS_None;
3473 }
3474
3475 static bool
isItAInlineLambdaAllowed(const FormatToken & Tok,FormatStyle::ShortLambdaStyle ShortLambdaOption)3476 isItAInlineLambdaAllowed(const FormatToken &Tok,
3477 FormatStyle::ShortLambdaStyle ShortLambdaOption) {
3478 return (ShortLambdaOption == FormatStyle::SLS_Inline &&
3479 IsFunctionArgument(Tok)) ||
3480 (ShortLambdaOption == FormatStyle::SLS_All);
3481 }
3482
isOneChildWithoutMustBreakBefore(const FormatToken & Tok)3483 static bool isOneChildWithoutMustBreakBefore(const FormatToken &Tok) {
3484 if (Tok.Children.size() != 1)
3485 return false;
3486 FormatToken *curElt = Tok.Children[0]->First;
3487 while (curElt) {
3488 if (curElt->MustBreakBefore)
3489 return false;
3490 curElt = curElt->Next;
3491 }
3492 return true;
3493 }
isAllmanLambdaBrace(const FormatToken & Tok)3494 static bool isAllmanLambdaBrace(const FormatToken &Tok) {
3495 return (Tok.is(tok::l_brace) && Tok.is(BK_Block) &&
3496 !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral));
3497 }
3498
isAllmanBraceIncludedBreakableLambda(const FormatToken & Tok,FormatStyle::ShortLambdaStyle ShortLambdaOption)3499 static bool isAllmanBraceIncludedBreakableLambda(
3500 const FormatToken &Tok, FormatStyle::ShortLambdaStyle ShortLambdaOption) {
3501 if (!isAllmanLambdaBrace(Tok))
3502 return false;
3503
3504 if (isItAnEmptyLambdaAllowed(Tok, ShortLambdaOption))
3505 return false;
3506
3507 return !isItAInlineLambdaAllowed(Tok, ShortLambdaOption) ||
3508 !isOneChildWithoutMustBreakBefore(Tok);
3509 }
3510
mustBreakBefore(const AnnotatedLine & Line,const FormatToken & Right)3511 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
3512 const FormatToken &Right) {
3513 const FormatToken &Left = *Right.Previous;
3514 if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
3515 return true;
3516
3517 if (Style.isCSharp()) {
3518 if (Right.is(TT_CSharpNamedArgumentColon) ||
3519 Left.is(TT_CSharpNamedArgumentColon))
3520 return false;
3521 if (Right.is(TT_CSharpGenericTypeConstraint))
3522 return true;
3523 } else if (Style.Language == FormatStyle::LK_JavaScript) {
3524 // FIXME: This might apply to other languages and token kinds.
3525 if (Right.is(tok::string_literal) && Left.is(tok::plus) && Left.Previous &&
3526 Left.Previous->is(tok::string_literal))
3527 return true;
3528 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) && Line.Level == 0 &&
3529 Left.Previous && Left.Previous->is(tok::equal) &&
3530 Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
3531 tok::kw_const) &&
3532 // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match
3533 // above.
3534 !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let))
3535 // Object literals on the top level of a file are treated as "enum-style".
3536 // Each key/value pair is put on a separate line, instead of bin-packing.
3537 return true;
3538 if (Left.is(tok::l_brace) && Line.Level == 0 &&
3539 (Line.startsWith(tok::kw_enum) ||
3540 Line.startsWith(tok::kw_const, tok::kw_enum) ||
3541 Line.startsWith(tok::kw_export, tok::kw_enum) ||
3542 Line.startsWith(tok::kw_export, tok::kw_const, tok::kw_enum)))
3543 // JavaScript top-level enum key/value pairs are put on separate lines
3544 // instead of bin-packing.
3545 return true;
3546 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) && Left.Previous &&
3547 Left.Previous->is(TT_FatArrow)) {
3548 // JS arrow function (=> {...}).
3549 switch (Style.AllowShortLambdasOnASingleLine) {
3550 case FormatStyle::SLS_All:
3551 return false;
3552 case FormatStyle::SLS_None:
3553 return true;
3554 case FormatStyle::SLS_Empty:
3555 return !Left.Children.empty();
3556 case FormatStyle::SLS_Inline:
3557 // allow one-lining inline (e.g. in function call args) and empty arrow
3558 // functions.
3559 return (Left.NestingLevel == 0 && Line.Level == 0) &&
3560 !Left.Children.empty();
3561 }
3562 llvm_unreachable("Unknown FormatStyle::ShortLambdaStyle enum");
3563 }
3564
3565 if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
3566 !Left.Children.empty())
3567 // Support AllowShortFunctionsOnASingleLine for JavaScript.
3568 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
3569 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
3570 (Left.NestingLevel == 0 && Line.Level == 0 &&
3571 Style.AllowShortFunctionsOnASingleLine &
3572 FormatStyle::SFS_InlineOnly);
3573 } else if (Style.Language == FormatStyle::LK_Java) {
3574 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&
3575 Right.Next->is(tok::string_literal))
3576 return true;
3577 } else if (Style.Language == FormatStyle::LK_Cpp ||
3578 Style.Language == FormatStyle::LK_ObjC ||
3579 Style.Language == FormatStyle::LK_Proto ||
3580 Style.Language == FormatStyle::LK_TableGen ||
3581 Style.Language == FormatStyle::LK_TextProto) {
3582 if (Left.isStringLiteral() && Right.isStringLiteral())
3583 return true;
3584 }
3585
3586 // If the last token before a '}', ']', or ')' is a comma or a trailing
3587 // comment, the intention is to insert a line break after it in order to make
3588 // shuffling around entries easier. Import statements, especially in
3589 // JavaScript, can be an exception to this rule.
3590 if (Style.JavaScriptWrapImports || Line.Type != LT_ImportStatement) {
3591 const FormatToken *BeforeClosingBrace = nullptr;
3592 if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
3593 (Style.Language == FormatStyle::LK_JavaScript &&
3594 Left.is(tok::l_paren))) &&
3595 Left.isNot(BK_Block) && Left.MatchingParen)
3596 BeforeClosingBrace = Left.MatchingParen->Previous;
3597 else if (Right.MatchingParen &&
3598 (Right.MatchingParen->isOneOf(tok::l_brace,
3599 TT_ArrayInitializerLSquare) ||
3600 (Style.Language == FormatStyle::LK_JavaScript &&
3601 Right.MatchingParen->is(tok::l_paren))))
3602 BeforeClosingBrace = &Left;
3603 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
3604 BeforeClosingBrace->isTrailingComment()))
3605 return true;
3606 }
3607
3608 if (Right.is(tok::comment))
3609 return Left.isNot(BK_BracedInit) && Left.isNot(TT_CtorInitializerColon) &&
3610 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
3611 if (Left.isTrailingComment())
3612 return true;
3613 if (Right.Previous->IsUnterminatedLiteral)
3614 return true;
3615 if (Right.is(tok::lessless) && Right.Next &&
3616 Right.Previous->is(tok::string_literal) &&
3617 Right.Next->is(tok::string_literal))
3618 return true;
3619 // Can break after template<> declaration
3620 if (Right.Previous->ClosesTemplateDeclaration &&
3621 Right.Previous->MatchingParen &&
3622 Right.Previous->MatchingParen->NestingLevel == 0) {
3623 // Put concepts on the next line e.g.
3624 // template<typename T>
3625 // concept ...
3626 if (Right.is(tok::kw_concept))
3627 return Style.BreakBeforeConceptDeclarations;
3628 return (Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes);
3629 }
3630 if (Right.is(TT_CtorInitializerComma) &&
3631 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
3632 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
3633 return true;
3634 if (Right.is(TT_CtorInitializerColon) &&
3635 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma &&
3636 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
3637 return true;
3638 // Break only if we have multiple inheritance.
3639 if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma &&
3640 Right.is(TT_InheritanceComma))
3641 return true;
3642 if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\""))
3643 // Multiline raw string literals are special wrt. line breaks. The author
3644 // has made a deliberate choice and might have aligned the contents of the
3645 // string literal accordingly. Thus, we try keep existing line breaks.
3646 return Right.IsMultiline && Right.NewlinesBefore > 0;
3647 if ((Right.Previous->is(tok::l_brace) ||
3648 (Right.Previous->is(tok::less) && Right.Previous->Previous &&
3649 Right.Previous->Previous->is(tok::equal))) &&
3650 Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {
3651 // Don't put enums or option definitions onto single lines in protocol
3652 // buffers.
3653 return true;
3654 }
3655 if (Right.is(TT_InlineASMBrace))
3656 return Right.HasUnescapedNewline;
3657
3658 auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
3659 if (Style.BraceWrapping.BeforeLambdaBody &&
3660 (isAllmanBraceIncludedBreakableLambda(Left, ShortLambdaOption) ||
3661 isAllmanBraceIncludedBreakableLambda(Right, ShortLambdaOption))) {
3662 return true;
3663 }
3664
3665 if (isAllmanBrace(Left) || isAllmanBrace(Right))
3666 return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) ||
3667 (Line.startsWith(tok::kw_typedef, tok::kw_enum) &&
3668 Style.BraceWrapping.AfterEnum) ||
3669 (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
3670 (Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
3671 if (Left.is(TT_ObjCBlockLBrace) &&
3672 Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
3673 return true;
3674
3675 if (Left.is(TT_LambdaLBrace)) {
3676 if (IsFunctionArgument(Left) &&
3677 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline)
3678 return false;
3679
3680 if (Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_None ||
3681 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline ||
3682 (!Left.Children.empty() &&
3683 Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Empty))
3684 return true;
3685 }
3686
3687 // Put multiple Java annotation on a new line.
3688 if ((Style.Language == FormatStyle::LK_Java ||
3689 Style.Language == FormatStyle::LK_JavaScript) &&
3690 Left.is(TT_LeadingJavaAnnotation) &&
3691 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
3692 (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations))
3693 return true;
3694
3695 if (Right.is(TT_ProtoExtensionLSquare))
3696 return true;
3697
3698 // In text proto instances if a submessage contains at least 2 entries and at
3699 // least one of them is a submessage, like A { ... B { ... } ... },
3700 // put all of the entries of A on separate lines by forcing the selector of
3701 // the submessage B to be put on a newline.
3702 //
3703 // Example: these can stay on one line:
3704 // a { scalar_1: 1 scalar_2: 2 }
3705 // a { b { key: value } }
3706 //
3707 // and these entries need to be on a new line even if putting them all in one
3708 // line is under the column limit:
3709 // a {
3710 // scalar: 1
3711 // b { key: value }
3712 // }
3713 //
3714 // We enforce this by breaking before a submessage field that has previous
3715 // siblings, *and* breaking before a field that follows a submessage field.
3716 //
3717 // Be careful to exclude the case [proto.ext] { ... } since the `]` is
3718 // the TT_SelectorName there, but we don't want to break inside the brackets.
3719 //
3720 // Another edge case is @submessage { key: value }, which is a common
3721 // substitution placeholder. In this case we want to keep `@` and `submessage`
3722 // together.
3723 //
3724 // We ensure elsewhere that extensions are always on their own line.
3725 if ((Style.Language == FormatStyle::LK_Proto ||
3726 Style.Language == FormatStyle::LK_TextProto) &&
3727 Right.is(TT_SelectorName) && !Right.is(tok::r_square) && Right.Next) {
3728 // Keep `@submessage` together in:
3729 // @submessage { key: value }
3730 if (Right.Previous && Right.Previous->is(tok::at))
3731 return false;
3732 // Look for the scope opener after selector in cases like:
3733 // selector { ...
3734 // selector: { ...
3735 // selector: @base { ...
3736 FormatToken *LBrace = Right.Next;
3737 if (LBrace && LBrace->is(tok::colon)) {
3738 LBrace = LBrace->Next;
3739 if (LBrace && LBrace->is(tok::at)) {
3740 LBrace = LBrace->Next;
3741 if (LBrace)
3742 LBrace = LBrace->Next;
3743 }
3744 }
3745 if (LBrace &&
3746 // The scope opener is one of {, [, <:
3747 // selector { ... }
3748 // selector [ ... ]
3749 // selector < ... >
3750 //
3751 // In case of selector { ... }, the l_brace is TT_DictLiteral.
3752 // In case of an empty selector {}, the l_brace is not TT_DictLiteral,
3753 // so we check for immediately following r_brace.
3754 ((LBrace->is(tok::l_brace) &&
3755 (LBrace->is(TT_DictLiteral) ||
3756 (LBrace->Next && LBrace->Next->is(tok::r_brace)))) ||
3757 LBrace->is(TT_ArrayInitializerLSquare) || LBrace->is(tok::less))) {
3758 // If Left.ParameterCount is 0, then this submessage entry is not the
3759 // first in its parent submessage, and we want to break before this entry.
3760 // If Left.ParameterCount is greater than 0, then its parent submessage
3761 // might contain 1 or more entries and we want to break before this entry
3762 // if it contains at least 2 entries. We deal with this case later by
3763 // detecting and breaking before the next entry in the parent submessage.
3764 if (Left.ParameterCount == 0)
3765 return true;
3766 // However, if this submessage is the first entry in its parent
3767 // submessage, Left.ParameterCount might be 1 in some cases.
3768 // We deal with this case later by detecting an entry
3769 // following a closing paren of this submessage.
3770 }
3771
3772 // If this is an entry immediately following a submessage, it will be
3773 // preceded by a closing paren of that submessage, like in:
3774 // left---. .---right
3775 // v v
3776 // sub: { ... } key: value
3777 // If there was a comment between `}` an `key` above, then `key` would be
3778 // put on a new line anyways.
3779 if (Left.isOneOf(tok::r_brace, tok::greater, tok::r_square))
3780 return true;
3781 }
3782
3783 // Deal with lambda arguments in C++ - we want consistent line breaks whether
3784 // they happen to be at arg0, arg1 or argN. The selection is a bit nuanced
3785 // as aggressive line breaks are placed when the lambda is not the last arg.
3786 if ((Style.Language == FormatStyle::LK_Cpp ||
3787 Style.Language == FormatStyle::LK_ObjC) &&
3788 Left.is(tok::l_paren) && Left.BlockParameterCount > 0 &&
3789 !Right.isOneOf(tok::l_paren, TT_LambdaLSquare)) {
3790 // Multiple lambdas in the same function call force line breaks.
3791 if (Left.BlockParameterCount > 1)
3792 return true;
3793
3794 // A lambda followed by another arg forces a line break.
3795 if (!Left.Role)
3796 return false;
3797 auto Comma = Left.Role->lastComma();
3798 if (!Comma)
3799 return false;
3800 auto Next = Comma->getNextNonComment();
3801 if (!Next)
3802 return false;
3803 if (!Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret))
3804 return true;
3805 }
3806
3807 return false;
3808 }
3809
canBreakBefore(const AnnotatedLine & Line,const FormatToken & Right)3810 bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
3811 const FormatToken &Right) {
3812 const FormatToken &Left = *Right.Previous;
3813 // Language-specific stuff.
3814 if (Style.isCSharp()) {
3815 if (Left.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon) ||
3816 Right.isOneOf(TT_CSharpNamedArgumentColon, TT_AttributeColon))
3817 return false;
3818 // Only break after commas for generic type constraints.
3819 if (Line.First->is(TT_CSharpGenericTypeConstraint))
3820 return Left.is(TT_CSharpGenericTypeConstraintComma);
3821 // Keep nullable operators attached to their identifiers.
3822 if (Right.is(TT_CSharpNullable)) {
3823 return false;
3824 }
3825 } else if (Style.Language == FormatStyle::LK_Java) {
3826 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3827 Keywords.kw_implements))
3828 return false;
3829 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
3830 Keywords.kw_implements))
3831 return true;
3832 } else if (Style.Language == FormatStyle::LK_JavaScript) {
3833 const FormatToken *NonComment = Right.getPreviousNonComment();
3834 if (NonComment &&
3835 NonComment->isOneOf(
3836 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
3837 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
3838 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
3839 Keywords.kw_readonly, Keywords.kw_abstract, Keywords.kw_get,
3840 Keywords.kw_set, Keywords.kw_async, Keywords.kw_await))
3841 return false; // Otherwise automatic semicolon insertion would trigger.
3842 if (Right.NestingLevel == 0 &&
3843 (Left.Tok.getIdentifierInfo() ||
3844 Left.isOneOf(tok::r_square, tok::r_paren)) &&
3845 Right.isOneOf(tok::l_square, tok::l_paren))
3846 return false; // Otherwise automatic semicolon insertion would trigger.
3847 if (NonComment && NonComment->is(tok::identifier) &&
3848 NonComment->TokenText == "asserts")
3849 return false;
3850 if (Left.is(TT_FatArrow) && Right.is(tok::l_brace))
3851 return false;
3852 if (Left.is(TT_JsTypeColon))
3853 return true;
3854 // Don't wrap between ":" and "!" of a strict prop init ("field!: type;").
3855 if (Left.is(tok::exclaim) && Right.is(tok::colon))
3856 return false;
3857 // Look for is type annotations like:
3858 // function f(): a is B { ... }
3859 // Do not break before is in these cases.
3860 if (Right.is(Keywords.kw_is)) {
3861 const FormatToken *Next = Right.getNextNonComment();
3862 // If `is` is followed by a colon, it's likely that it's a dict key, so
3863 // ignore it for this check.
3864 // For example this is common in Polymer:
3865 // Polymer({
3866 // is: 'name',
3867 // ...
3868 // });
3869 if (!Next || !Next->is(tok::colon))
3870 return false;
3871 }
3872 if (Left.is(Keywords.kw_in))
3873 return Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None;
3874 if (Right.is(Keywords.kw_in))
3875 return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
3876 if (Right.is(Keywords.kw_as))
3877 return false; // must not break before as in 'x as type' casts
3878 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_infer)) {
3879 // extends and infer can appear as keywords in conditional types:
3880 // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types
3881 // do not break before them, as the expressions are subject to ASI.
3882 return false;
3883 }
3884 if (Left.is(Keywords.kw_as))
3885 return true;
3886 if (Left.is(TT_NonNullAssertion))
3887 return true;
3888 if (Left.is(Keywords.kw_declare) &&
3889 Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
3890 Keywords.kw_function, tok::kw_class, tok::kw_enum,
3891 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
3892 Keywords.kw_let, tok::kw_const))
3893 // See grammar for 'declare' statements at:
3894 // https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#A.10
3895 return false;
3896 if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
3897 Right.isOneOf(tok::identifier, tok::string_literal))
3898 return false; // must not break in "module foo { ...}"
3899 if (Right.is(TT_TemplateString) && Right.closesScope())
3900 return false;
3901 // Don't split tagged template literal so there is a break between the tag
3902 // identifier and template string.
3903 if (Left.is(tok::identifier) && Right.is(TT_TemplateString)) {
3904 return false;
3905 }
3906 if (Left.is(TT_TemplateString) && Left.opensScope())
3907 return true;
3908 }
3909
3910 if (Left.is(tok::at))
3911 return false;
3912 if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
3913 return false;
3914 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
3915 return !Right.is(tok::l_paren);
3916 if (Right.is(TT_PointerOrReference))
3917 return Line.IsMultiVariableDeclStmt ||
3918 (Style.PointerAlignment == FormatStyle::PAS_Right &&
3919 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
3920 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
3921 Right.is(tok::kw_operator))
3922 return true;
3923 if (Left.is(TT_PointerOrReference))
3924 return false;
3925 if (Right.isTrailingComment())
3926 // We rely on MustBreakBefore being set correctly here as we should not
3927 // change the "binding" behavior of a comment.
3928 // The first comment in a braced lists is always interpreted as belonging to
3929 // the first list element. Otherwise, it should be placed outside of the
3930 // list.
3931 return Left.is(BK_BracedInit) ||
3932 (Left.is(TT_CtorInitializerColon) &&
3933 Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
3934 if (Left.is(tok::question) && Right.is(tok::colon))
3935 return false;
3936 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
3937 return Style.BreakBeforeTernaryOperators;
3938 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question))
3939 return !Style.BreakBeforeTernaryOperators;
3940 if (Left.is(TT_InheritanceColon))
3941 return Style.BreakInheritanceList == FormatStyle::BILS_AfterColon;
3942 if (Right.is(TT_InheritanceColon))
3943 return Style.BreakInheritanceList != FormatStyle::BILS_AfterColon;
3944 if (Right.is(TT_ObjCMethodExpr) && !Right.is(tok::r_square) &&
3945 Left.isNot(TT_SelectorName))
3946 return true;
3947
3948 if (Right.is(tok::colon) &&
3949 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
3950 return false;
3951 if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
3952 if (Style.Language == FormatStyle::LK_Proto ||
3953 Style.Language == FormatStyle::LK_TextProto) {
3954 if (!Style.AlwaysBreakBeforeMultilineStrings && Right.isStringLiteral())
3955 return false;
3956 // Prevent cases like:
3957 //
3958 // submessage:
3959 // { key: valueeeeeeeeeeee }
3960 //
3961 // when the snippet does not fit into one line.
3962 // Prefer:
3963 //
3964 // submessage: {
3965 // key: valueeeeeeeeeeee
3966 // }
3967 //
3968 // instead, even if it is longer by one line.
3969 //
3970 // Note that this allows allows the "{" to go over the column limit
3971 // when the column limit is just between ":" and "{", but that does
3972 // not happen too often and alternative formattings in this case are
3973 // not much better.
3974 //
3975 // The code covers the cases:
3976 //
3977 // submessage: { ... }
3978 // submessage: < ... >
3979 // repeated: [ ... ]
3980 if (((Right.is(tok::l_brace) || Right.is(tok::less)) &&
3981 Right.is(TT_DictLiteral)) ||
3982 Right.is(TT_ArrayInitializerLSquare))
3983 return false;
3984 }
3985 return true;
3986 }
3987 if (Right.is(tok::r_square) && Right.MatchingParen &&
3988 Right.MatchingParen->is(TT_ProtoExtensionLSquare))
3989 return false;
3990 if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next &&
3991 Right.Next->is(TT_ObjCMethodExpr)))
3992 return Left.isNot(tok::period); // FIXME: Properly parse ObjC calls.
3993 if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty)
3994 return true;
3995 if (Left.ClosesTemplateDeclaration || Left.is(TT_FunctionAnnotationRParen))
3996 return true;
3997 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
3998 TT_OverloadedOperator))
3999 return false;
4000 if (Left.is(TT_RangeBasedForLoopColon))
4001 return true;
4002 if (Right.is(TT_RangeBasedForLoopColon))
4003 return false;
4004 if (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateOpener))
4005 return true;
4006 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
4007 Left.is(tok::kw_operator))
4008 return false;
4009 if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) &&
4010 Line.Type == LT_VirtualFunctionDecl && Left.NestingLevel == 0)
4011 return false;
4012 if (Left.is(tok::equal) && Right.is(tok::l_brace) &&
4013 !Style.Cpp11BracedListStyle)
4014 return false;
4015 if (Left.is(tok::l_paren) &&
4016 Left.isOneOf(TT_AttributeParen, TT_TypeDeclarationParen))
4017 return false;
4018 if (Left.is(tok::l_paren) && Left.Previous &&
4019 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen)))
4020 return false;
4021 if (Right.is(TT_ImplicitStringLiteral))
4022 return false;
4023
4024 if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser))
4025 return false;
4026 if (Right.is(tok::r_square) && Right.MatchingParen &&
4027 Right.MatchingParen->is(TT_LambdaLSquare))
4028 return false;
4029
4030 // We only break before r_brace if there was a corresponding break before
4031 // the l_brace, which is tracked by BreakBeforeClosingBrace.
4032 if (Right.is(tok::r_brace))
4033 return Right.MatchingParen && Right.MatchingParen->is(BK_Block);
4034
4035 // Allow breaking after a trailing annotation, e.g. after a method
4036 // declaration.
4037 if (Left.is(TT_TrailingAnnotation))
4038 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
4039 tok::less, tok::coloncolon);
4040
4041 if (Right.is(tok::kw___attribute) ||
4042 (Right.is(tok::l_square) && Right.is(TT_AttributeSquare)))
4043 return !Left.is(TT_AttributeSquare);
4044
4045 if (Left.is(tok::identifier) && Right.is(tok::string_literal))
4046 return true;
4047
4048 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
4049 return true;
4050
4051 if (Left.is(TT_CtorInitializerColon))
4052 return Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
4053 if (Right.is(TT_CtorInitializerColon))
4054 return Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon;
4055 if (Left.is(TT_CtorInitializerComma) &&
4056 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
4057 return false;
4058 if (Right.is(TT_CtorInitializerComma) &&
4059 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
4060 return true;
4061 if (Left.is(TT_InheritanceComma) &&
4062 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma)
4063 return false;
4064 if (Right.is(TT_InheritanceComma) &&
4065 Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma)
4066 return true;
4067 if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
4068 (Left.is(tok::less) && Right.is(tok::less)))
4069 return false;
4070 if (Right.is(TT_BinaryOperator) &&
4071 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&
4072 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
4073 Right.getPrecedence() != prec::Assignment))
4074 return true;
4075 if (Left.is(TT_ArrayInitializerLSquare))
4076 return true;
4077 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
4078 return true;
4079 if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
4080 !Left.isOneOf(tok::arrowstar, tok::lessless) &&
4081 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
4082 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
4083 Left.getPrecedence() == prec::Assignment))
4084 return true;
4085 if ((Left.is(TT_AttributeSquare) && Right.is(tok::l_square)) ||
4086 (Left.is(tok::r_square) && Right.is(TT_AttributeSquare)))
4087 return false;
4088
4089 auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
4090 if (Style.BraceWrapping.BeforeLambdaBody) {
4091 if (isAllmanLambdaBrace(Left))
4092 return !isItAnEmptyLambdaAllowed(Left, ShortLambdaOption);
4093 if (isAllmanLambdaBrace(Right))
4094 return !isItAnEmptyLambdaAllowed(Right, ShortLambdaOption);
4095 }
4096
4097 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
4098 tok::kw_class, tok::kw_struct, tok::comment) ||
4099 Right.isMemberAccess() ||
4100 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
4101 tok::colon, tok::l_square, tok::at) ||
4102 (Style.BraceWrapping.BeforeLambdaBody && Right.is(TT_LambdaLBrace)) ||
4103 (Left.is(tok::r_paren) &&
4104 Right.isOneOf(tok::identifier, tok::kw_const)) ||
4105 (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
4106 (Left.is(TT_TemplateOpener) && !Right.is(TT_TemplateCloser));
4107 }
4108
printDebugInfo(const AnnotatedLine & Line)4109 void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) {
4110 llvm::errs() << "AnnotatedTokens(L=" << Line.Level << "):\n";
4111 const FormatToken *Tok = Line.First;
4112 while (Tok) {
4113 llvm::errs() << " M=" << Tok->MustBreakBefore
4114 << " C=" << Tok->CanBreakBefore
4115 << " T=" << getTokenTypeName(Tok->getType())
4116 << " S=" << Tok->SpacesRequiredBefore
4117 << " F=" << Tok->Finalized << " B=" << Tok->BlockParameterCount
4118 << " BK=" << Tok->getBlockKind() << " P=" << Tok->SplitPenalty
4119 << " Name=" << Tok->Tok.getName() << " L=" << Tok->TotalLength
4120 << " PPK=" << Tok->getPackingKind() << " FakeLParens=";
4121 for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
4122 llvm::errs() << Tok->FakeLParens[i] << "/";
4123 llvm::errs() << " FakeRParens=" << Tok->FakeRParens;
4124 llvm::errs() << " II=" << Tok->Tok.getIdentifierInfo();
4125 llvm::errs() << " Text='" << Tok->TokenText << "'\n";
4126 if (!Tok->Next)
4127 assert(Tok == Line.Last);
4128 Tok = Tok->Next;
4129 }
4130 llvm::errs() << "----\n";
4131 }
4132
4133 } // namespace format
4134 } // namespace clang
4135