Bug Summary

File:clang/lib/Format/TokenAnnotator.cpp
Warning:line 203, column 25
Access to field 'ParentBracket' results in a dereference of a null pointer (loaded from variable 'Left')

Annotated Source Code

Press '?' to see keyboard shortcuts

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