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