1 //===--- TokenAnnotator.cpp - Format C++ code -----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file implements a token annotator, i.e. creates
12 /// \c AnnotatedTokens out of \c FormatTokens with required extra information.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #include "TokenAnnotator.h"
17 #include "clang/Basic/SourceManager.h"
18 #include "llvm/Support/Debug.h"
19
20 #define DEBUG_TYPE "format-token-annotator"
21
22 namespace clang {
23 namespace format {
24
25 namespace {
26
27 /// \brief A parser that gathers additional information about tokens.
28 ///
29 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
30 /// store a parenthesis levels. It also tries to resolve matching "<" and ">"
31 /// into template parameter lists.
32 class AnnotatingParser {
33 public:
AnnotatingParser(const FormatStyle & Style,AnnotatedLine & Line,const AdditionalKeywords & Keywords)34 AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line,
35 const AdditionalKeywords &Keywords)
36 : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
37 Keywords(Keywords) {
38 Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
39 resetTokenMetadata(CurrentToken);
40 }
41
42 private:
parseAngle()43 bool parseAngle() {
44 if (!CurrentToken)
45 return false;
46 ScopedContextCreator ContextCreator(*this, tok::less, 10);
47 FormatToken *Left = CurrentToken->Previous;
48 Contexts.back().IsExpression = false;
49 // If there's a template keyword before the opening angle bracket, this is a
50 // template parameter, not an argument.
51 Contexts.back().InTemplateArgument =
52 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template);
53
54 if (Style.Language == FormatStyle::LK_Java &&
55 CurrentToken->is(tok::question))
56 next();
57
58 while (CurrentToken) {
59 if (CurrentToken->is(tok::greater)) {
60 Left->MatchingParen = CurrentToken;
61 CurrentToken->MatchingParen = Left;
62 CurrentToken->Type = TT_TemplateCloser;
63 next();
64 return true;
65 }
66 if (CurrentToken->is(tok::question) &&
67 Style.Language == FormatStyle::LK_Java) {
68 next();
69 continue;
70 }
71 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace,
72 tok::colon, tok::question))
73 return false;
74 // If a && or || is found and interpreted as a binary operator, this set
75 // of angles is likely part of something like "a < b && c > d". If the
76 // angles are inside an expression, the ||/&& might also be a binary
77 // operator that was misinterpreted because we are parsing template
78 // parameters.
79 // FIXME: This is getting out of hand, write a decent parser.
80 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
81 CurrentToken->Previous->is(TT_BinaryOperator) &&
82 Contexts[Contexts.size() - 2].IsExpression &&
83 Line.First->isNot(tok::kw_template))
84 return false;
85 updateParameterCount(Left, CurrentToken);
86 if (!consumeToken())
87 return false;
88 }
89 return false;
90 }
91
parseParens(bool LookForDecls=false)92 bool parseParens(bool LookForDecls = false) {
93 if (!CurrentToken)
94 return false;
95 ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);
96
97 // FIXME: This is a bit of a hack. Do better.
98 Contexts.back().ColonIsForRangeExpr =
99 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
100
101 bool StartsObjCMethodExpr = false;
102 FormatToken *Left = CurrentToken->Previous;
103 if (CurrentToken->is(tok::caret)) {
104 // (^ can start a block type.
105 Left->Type = TT_ObjCBlockLParen;
106 } else if (FormatToken *MaybeSel = Left->Previous) {
107 // @selector( starts a selector.
108 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
109 MaybeSel->Previous->is(tok::at)) {
110 StartsObjCMethodExpr = true;
111 }
112 }
113
114 if (Left->Previous &&
115 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_if,
116 tok::kw_while, tok::l_paren, tok::comma) ||
117 Left->Previous->is(TT_BinaryOperator))) {
118 // static_assert, if and while usually contain expressions.
119 Contexts.back().IsExpression = true;
120 } else if (Line.InPPDirective &&
121 (!Left->Previous ||
122 !Left->Previous->isOneOf(tok::identifier,
123 TT_OverloadedOperator))) {
124 Contexts.back().IsExpression = true;
125 } else if (Left->Previous && Left->Previous->is(tok::r_square) &&
126 Left->Previous->MatchingParen &&
127 Left->Previous->MatchingParen->is(TT_LambdaLSquare)) {
128 // This is a parameter list of a lambda expression.
129 Contexts.back().IsExpression = false;
130 } else if (Contexts[Contexts.size() - 2].CaretFound) {
131 // This is the parameter list of an ObjC block.
132 Contexts.back().IsExpression = false;
133 } else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) {
134 Left->Type = TT_AttributeParen;
135 } else if (Left->Previous && Left->Previous->IsForEachMacro) {
136 // The first argument to a foreach macro is a declaration.
137 Contexts.back().IsForEachMacro = true;
138 Contexts.back().IsExpression = false;
139 } else if (Left->Previous && Left->Previous->MatchingParen &&
140 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
141 Contexts.back().IsExpression = false;
142 }
143
144 if (StartsObjCMethodExpr) {
145 Contexts.back().ColonIsObjCMethodExpr = true;
146 Left->Type = TT_ObjCMethodExpr;
147 }
148
149 bool MightBeFunctionType = CurrentToken->is(tok::star);
150 bool HasMultipleLines = false;
151 bool HasMultipleParametersOnALine = false;
152 bool MightBeObjCForRangeLoop =
153 Left->Previous && Left->Previous->is(tok::kw_for);
154 while (CurrentToken) {
155 // LookForDecls is set when "if (" has been seen. Check for
156 // 'identifier' '*' 'identifier' followed by not '=' -- this
157 // '*' has to be a binary operator but determineStarAmpUsage() will
158 // categorize it as an unary operator, so set the right type here.
159 if (LookForDecls && CurrentToken->Next) {
160 FormatToken *Prev = CurrentToken->getPreviousNonComment();
161 if (Prev) {
162 FormatToken *PrevPrev = Prev->getPreviousNonComment();
163 FormatToken *Next = CurrentToken->Next;
164 if (PrevPrev && PrevPrev->is(tok::identifier) &&
165 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
166 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
167 Prev->Type = TT_BinaryOperator;
168 LookForDecls = false;
169 }
170 }
171 }
172
173 if (CurrentToken->Previous->is(TT_PointerOrReference) &&
174 CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
175 tok::coloncolon))
176 MightBeFunctionType = true;
177 if (CurrentToken->Previous->is(TT_BinaryOperator))
178 Contexts.back().IsExpression = true;
179 if (CurrentToken->is(tok::r_paren)) {
180 if (MightBeFunctionType && CurrentToken->Next &&
181 (CurrentToken->Next->is(tok::l_paren) ||
182 (CurrentToken->Next->is(tok::l_square) &&
183 !Contexts.back().IsExpression)))
184 Left->Type = TT_FunctionTypeLParen;
185 Left->MatchingParen = CurrentToken;
186 CurrentToken->MatchingParen = Left;
187
188 if (StartsObjCMethodExpr) {
189 CurrentToken->Type = TT_ObjCMethodExpr;
190 if (Contexts.back().FirstObjCSelectorName) {
191 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
192 Contexts.back().LongestObjCSelectorName;
193 }
194 }
195
196 if (Left->is(TT_AttributeParen))
197 CurrentToken->Type = TT_AttributeParen;
198 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation))
199 CurrentToken->Type = TT_JavaAnnotation;
200 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
201 CurrentToken->Type = TT_LeadingJavaAnnotation;
202
203 if (!HasMultipleLines)
204 Left->PackingKind = PPK_Inconclusive;
205 else if (HasMultipleParametersOnALine)
206 Left->PackingKind = PPK_BinPacked;
207 else
208 Left->PackingKind = PPK_OnePerLine;
209
210 next();
211 return true;
212 }
213 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
214 return false;
215
216 if (CurrentToken->is(tok::l_brace))
217 Left->Type = TT_Unknown; // Not TT_ObjCBlockLParen
218 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
219 !CurrentToken->Next->HasUnescapedNewline &&
220 !CurrentToken->Next->isTrailingComment())
221 HasMultipleParametersOnALine = true;
222 if (CurrentToken->isOneOf(tok::kw_const, tok::kw_auto) ||
223 CurrentToken->isSimpleTypeSpecifier())
224 Contexts.back().IsExpression = false;
225 if (CurrentToken->isOneOf(tok::semi, tok::colon))
226 MightBeObjCForRangeLoop = false;
227 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in))
228 CurrentToken->Type = TT_ObjCForIn;
229
230 FormatToken *Tok = CurrentToken;
231 if (!consumeToken())
232 return false;
233 updateParameterCount(Left, Tok);
234 if (CurrentToken && CurrentToken->HasUnescapedNewline)
235 HasMultipleLines = true;
236 }
237 return false;
238 }
239
parseSquare()240 bool parseSquare() {
241 if (!CurrentToken)
242 return false;
243
244 // A '[' could be an index subscript (after an identifier or after
245 // ')' or ']'), it could be the start of an Objective-C method
246 // expression, or it could the the start of an Objective-C array literal.
247 FormatToken *Left = CurrentToken->Previous;
248 FormatToken *Parent = Left->getPreviousNonComment();
249 bool StartsObjCMethodExpr =
250 Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
251 CurrentToken->isNot(tok::l_brace) &&
252 (!Parent ||
253 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
254 tok::kw_return, tok::kw_throw) ||
255 Parent->isUnaryOperator() ||
256 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
257 getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown);
258 ScopedContextCreator ContextCreator(*this, tok::l_square, 10);
259 Contexts.back().IsExpression = true;
260 bool ColonFound = false;
261
262 if (StartsObjCMethodExpr) {
263 Contexts.back().ColonIsObjCMethodExpr = true;
264 Left->Type = TT_ObjCMethodExpr;
265 } else if (Parent && Parent->is(tok::at)) {
266 Left->Type = TT_ArrayInitializerLSquare;
267 } else if (Left->is(TT_Unknown)) {
268 Left->Type = TT_ArraySubscriptLSquare;
269 }
270
271 while (CurrentToken) {
272 if (CurrentToken->is(tok::r_square)) {
273 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) &&
274 Left->is(TT_ObjCMethodExpr)) {
275 // An ObjC method call is rarely followed by an open parenthesis.
276 // FIXME: Do we incorrectly label ":" with this?
277 StartsObjCMethodExpr = false;
278 Left->Type = TT_Unknown;
279 }
280 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
281 CurrentToken->Type = TT_ObjCMethodExpr;
282 // determineStarAmpUsage() thinks that '*' '[' is allocating an
283 // array of pointers, but if '[' starts a selector then '*' is a
284 // binary operator.
285 if (Parent && Parent->is(TT_PointerOrReference))
286 Parent->Type = TT_BinaryOperator;
287 }
288 Left->MatchingParen = CurrentToken;
289 CurrentToken->MatchingParen = Left;
290 if (Contexts.back().FirstObjCSelectorName) {
291 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
292 Contexts.back().LongestObjCSelectorName;
293 if (Left->BlockParameterCount > 1)
294 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
295 }
296 next();
297 return true;
298 }
299 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
300 return false;
301 if (CurrentToken->is(tok::colon)) {
302 if (Left->is(TT_ArraySubscriptLSquare)) {
303 Left->Type = TT_ObjCMethodExpr;
304 StartsObjCMethodExpr = true;
305 Contexts.back().ColonIsObjCMethodExpr = true;
306 if (Parent && Parent->is(tok::r_paren))
307 Parent->Type = TT_CastRParen;
308 }
309 ColonFound = true;
310 }
311 if (CurrentToken->is(tok::comma) &&
312 Style.Language != FormatStyle::LK_Proto &&
313 (Left->is(TT_ArraySubscriptLSquare) ||
314 (Left->is(TT_ObjCMethodExpr) && !ColonFound)))
315 Left->Type = TT_ArrayInitializerLSquare;
316 FormatToken *Tok = CurrentToken;
317 if (!consumeToken())
318 return false;
319 updateParameterCount(Left, Tok);
320 }
321 return false;
322 }
323
parseBrace()324 bool parseBrace() {
325 if (CurrentToken) {
326 FormatToken *Left = CurrentToken->Previous;
327
328 if (Contexts.back().CaretFound)
329 Left->Type = TT_ObjCBlockLBrace;
330 Contexts.back().CaretFound = false;
331
332 ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
333 Contexts.back().ColonIsDictLiteral = true;
334 if (Left->BlockKind == BK_BracedInit)
335 Contexts.back().IsExpression = true;
336
337 while (CurrentToken) {
338 if (CurrentToken->is(tok::r_brace)) {
339 Left->MatchingParen = CurrentToken;
340 CurrentToken->MatchingParen = Left;
341 next();
342 return true;
343 }
344 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
345 return false;
346 updateParameterCount(Left, CurrentToken);
347 if (CurrentToken->isOneOf(tok::colon, tok::l_brace)) {
348 FormatToken *Previous = CurrentToken->getPreviousNonComment();
349 if ((CurrentToken->is(tok::colon) ||
350 Style.Language == FormatStyle::LK_Proto) &&
351 Previous->is(tok::identifier))
352 Previous->Type = TT_SelectorName;
353 if (CurrentToken->is(tok::colon) ||
354 Style.Language == FormatStyle::LK_JavaScript)
355 Left->Type = TT_DictLiteral;
356 }
357 if (!consumeToken())
358 return false;
359 }
360 }
361 return true;
362 }
363
updateParameterCount(FormatToken * Left,FormatToken * Current)364 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
365 if (Current->is(TT_LambdaLSquare) ||
366 (Current->is(tok::caret) && Current->is(TT_UnaryOperator)) ||
367 (Style.Language == FormatStyle::LK_JavaScript &&
368 Current->is(Keywords.kw_function))) {
369 ++Left->BlockParameterCount;
370 }
371 if (Current->is(tok::comma)) {
372 ++Left->ParameterCount;
373 if (!Left->Role)
374 Left->Role.reset(new CommaSeparatedList(Style));
375 Left->Role->CommaFound(Current);
376 } else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
377 Left->ParameterCount = 1;
378 }
379 }
380
parseConditional()381 bool parseConditional() {
382 while (CurrentToken) {
383 if (CurrentToken->is(tok::colon)) {
384 CurrentToken->Type = TT_ConditionalExpr;
385 next();
386 return true;
387 }
388 if (!consumeToken())
389 return false;
390 }
391 return false;
392 }
393
parseTemplateDeclaration()394 bool parseTemplateDeclaration() {
395 if (CurrentToken && CurrentToken->is(tok::less)) {
396 CurrentToken->Type = TT_TemplateOpener;
397 next();
398 if (!parseAngle())
399 return false;
400 if (CurrentToken)
401 CurrentToken->Previous->ClosesTemplateDeclaration = true;
402 return true;
403 }
404 return false;
405 }
406
consumeToken()407 bool consumeToken() {
408 FormatToken *Tok = CurrentToken;
409 next();
410 switch (Tok->Tok.getKind()) {
411 case tok::plus:
412 case tok::minus:
413 if (!Tok->Previous && Line.MustBeDeclaration)
414 Tok->Type = TT_ObjCMethodSpecifier;
415 break;
416 case tok::colon:
417 if (!Tok->Previous)
418 return false;
419 // Colons from ?: are handled in parseConditional().
420 if (Style.Language == FormatStyle::LK_JavaScript) {
421 if (Contexts.back().ColonIsForRangeExpr ||
422 (Contexts.size() == 1 &&
423 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
424 Contexts.back().ContextKind == tok::l_paren ||
425 Contexts.back().ContextKind == tok::l_square) {
426 Tok->Type = TT_JsTypeColon;
427 break;
428 }
429 }
430 if (Contexts.back().ColonIsDictLiteral) {
431 Tok->Type = TT_DictLiteral;
432 } else if (Contexts.back().ColonIsObjCMethodExpr ||
433 Line.First->is(TT_ObjCMethodSpecifier)) {
434 Tok->Type = TT_ObjCMethodExpr;
435 Tok->Previous->Type = TT_SelectorName;
436 if (Tok->Previous->ColumnWidth >
437 Contexts.back().LongestObjCSelectorName) {
438 Contexts.back().LongestObjCSelectorName = Tok->Previous->ColumnWidth;
439 }
440 if (!Contexts.back().FirstObjCSelectorName)
441 Contexts.back().FirstObjCSelectorName = Tok->Previous;
442 } else if (Contexts.back().ColonIsForRangeExpr) {
443 Tok->Type = TT_RangeBasedForLoopColon;
444 } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
445 Tok->Type = TT_BitFieldColon;
446 } else if (Contexts.size() == 1 &&
447 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
448 if (Tok->Previous->is(tok::r_paren))
449 Tok->Type = TT_CtorInitializerColon;
450 else
451 Tok->Type = TT_InheritanceColon;
452 } else if (Tok->Previous->is(tok::identifier) && Tok->Next &&
453 Tok->Next->isOneOf(tok::r_paren, tok::comma)) {
454 // This handles a special macro in ObjC code where selectors including
455 // the colon are passed as macro arguments.
456 Tok->Type = TT_ObjCMethodExpr;
457 } else if (Contexts.back().ContextKind == tok::l_paren) {
458 Tok->Type = TT_InlineASMColon;
459 }
460 break;
461 case tok::kw_if:
462 case tok::kw_while:
463 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
464 next();
465 if (!parseParens(/*LookForDecls=*/true))
466 return false;
467 }
468 break;
469 case tok::kw_for:
470 Contexts.back().ColonIsForRangeExpr = true;
471 next();
472 if (!parseParens())
473 return false;
474 break;
475 case tok::l_paren:
476 if (!parseParens())
477 return false;
478 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
479 !Contexts.back().IsExpression && Line.First->isNot(TT_ObjCProperty) &&
480 (!Tok->Previous ||
481 !Tok->Previous->isOneOf(tok::kw_decltype, TT_LeadingJavaAnnotation)))
482 Line.MightBeFunctionDecl = true;
483 break;
484 case tok::l_square:
485 if (!parseSquare())
486 return false;
487 break;
488 case tok::l_brace:
489 if (!parseBrace())
490 return false;
491 break;
492 case tok::less:
493 if ((!Tok->Previous ||
494 (!Tok->Previous->Tok.isLiteral() &&
495 !(Tok->Previous->is(tok::r_paren) && Contexts.size() > 1))) &&
496 parseAngle()) {
497 Tok->Type = TT_TemplateOpener;
498 } else {
499 Tok->Type = TT_BinaryOperator;
500 CurrentToken = Tok;
501 next();
502 }
503 break;
504 case tok::r_paren:
505 case tok::r_square:
506 return false;
507 case tok::r_brace:
508 // Lines can start with '}'.
509 if (Tok->Previous)
510 return false;
511 break;
512 case tok::greater:
513 Tok->Type = TT_BinaryOperator;
514 break;
515 case tok::kw_operator:
516 while (CurrentToken &&
517 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
518 if (CurrentToken->isOneOf(tok::star, tok::amp))
519 CurrentToken->Type = TT_PointerOrReference;
520 consumeToken();
521 if (CurrentToken && CurrentToken->Previous->is(TT_BinaryOperator))
522 CurrentToken->Previous->Type = TT_OverloadedOperator;
523 }
524 if (CurrentToken) {
525 CurrentToken->Type = TT_OverloadedOperatorLParen;
526 if (CurrentToken->Previous->is(TT_BinaryOperator))
527 CurrentToken->Previous->Type = TT_OverloadedOperator;
528 }
529 break;
530 case tok::question:
531 if (Style.Language == FormatStyle::LK_JavaScript && Tok->Next &&
532 Tok->Next->isOneOf(tok::colon, tok::semi, tok::r_paren,
533 tok::r_brace)) {
534 // Question marks before semicolons, colons, commas, etc. indicate
535 // optional types (fields, parameters), e.g.
536 // `function(x?: string, y?) {...}` or `class X {y?;}`
537 Tok->Type = TT_JsTypeOptionalQuestion;
538 break;
539 }
540 parseConditional();
541 break;
542 case tok::kw_template:
543 parseTemplateDeclaration();
544 break;
545 case tok::comma:
546 if (Contexts.back().FirstStartOfName && Contexts.size() == 1) {
547 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
548 Line.IsMultiVariableDeclStmt = true;
549 }
550 if (Contexts.back().InCtorInitializer)
551 Tok->Type = TT_CtorInitializerComma;
552 if (Contexts.back().IsForEachMacro)
553 Contexts.back().IsExpression = true;
554 break;
555 default:
556 break;
557 }
558 return true;
559 }
560
parseIncludeDirective()561 void parseIncludeDirective() {
562 if (CurrentToken && CurrentToken->is(tok::less)) {
563 next();
564 while (CurrentToken) {
565 if (CurrentToken->isNot(tok::comment) || CurrentToken->Next)
566 CurrentToken->Type = TT_ImplicitStringLiteral;
567 next();
568 }
569 }
570 }
571
parseWarningOrError()572 void parseWarningOrError() {
573 next();
574 // We still want to format the whitespace left of the first token of the
575 // warning or error.
576 next();
577 while (CurrentToken) {
578 CurrentToken->Type = TT_ImplicitStringLiteral;
579 next();
580 }
581 }
582
parsePragma()583 void parsePragma() {
584 next(); // Consume "pragma".
585 if (CurrentToken && CurrentToken->TokenText == "mark") {
586 next(); // Consume "mark".
587 next(); // Consume first token (so we fix leading whitespace).
588 while (CurrentToken) {
589 CurrentToken->Type = TT_ImplicitStringLiteral;
590 next();
591 }
592 }
593 }
594
parsePreprocessorDirective()595 LineType parsePreprocessorDirective() {
596 LineType Type = LT_PreprocessorDirective;
597 next();
598 if (!CurrentToken)
599 return Type;
600 if (CurrentToken->Tok.is(tok::numeric_constant)) {
601 CurrentToken->SpacesRequiredBefore = 1;
602 return Type;
603 }
604 // Hashes in the middle of a line can lead to any strange token
605 // sequence.
606 if (!CurrentToken->Tok.getIdentifierInfo())
607 return Type;
608 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
609 case tok::pp_include:
610 case tok::pp_import:
611 next();
612 parseIncludeDirective();
613 Type = LT_ImportStatement;
614 break;
615 case tok::pp_error:
616 case tok::pp_warning:
617 parseWarningOrError();
618 break;
619 case tok::pp_pragma:
620 parsePragma();
621 break;
622 case tok::pp_if:
623 case tok::pp_elif:
624 Contexts.back().IsExpression = true;
625 parseLine();
626 break;
627 default:
628 break;
629 }
630 while (CurrentToken)
631 next();
632 return Type;
633 }
634
635 public:
parseLine()636 LineType parseLine() {
637 if (CurrentToken->is(tok::hash)) {
638 return parsePreprocessorDirective();
639 }
640
641 // Directly allow to 'import <string-literal>' to support protocol buffer
642 // definitions (code.google.com/p/protobuf) or missing "#" (either way we
643 // should not break the line).
644 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
645 if ((Style.Language == FormatStyle::LK_Java &&
646 CurrentToken->is(Keywords.kw_package)) ||
647 (Info && Info->getPPKeywordID() == tok::pp_import &&
648 CurrentToken->Next &&
649 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
650 tok::kw_static))) {
651 next();
652 parseIncludeDirective();
653 return LT_ImportStatement;
654 }
655
656 // If this line starts and ends in '<' and '>', respectively, it is likely
657 // part of "#define <a/b.h>".
658 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
659 parseIncludeDirective();
660 return LT_ImportStatement;
661 }
662
663 bool KeywordVirtualFound = false;
664 bool ImportStatement = false;
665 while (CurrentToken) {
666 if (CurrentToken->is(tok::kw_virtual))
667 KeywordVirtualFound = true;
668 if (IsImportStatement(*CurrentToken))
669 ImportStatement = true;
670 if (!consumeToken())
671 return LT_Invalid;
672 }
673 if (KeywordVirtualFound)
674 return LT_VirtualFunctionDecl;
675 if (ImportStatement)
676 return LT_ImportStatement;
677
678 if (Line.First->is(TT_ObjCMethodSpecifier)) {
679 if (Contexts.back().FirstObjCSelectorName)
680 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
681 Contexts.back().LongestObjCSelectorName;
682 return LT_ObjCMethodDecl;
683 }
684
685 return LT_Other;
686 }
687
688 private:
IsImportStatement(const FormatToken & Tok)689 bool IsImportStatement(const FormatToken &Tok) {
690 // FIXME: Closure-library specific stuff should not be hard-coded but be
691 // configurable.
692 return Style.Language == FormatStyle::LK_JavaScript &&
693 Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) &&
694 Tok.Next->Next && (Tok.Next->Next->TokenText == "module" ||
695 Tok.Next->Next->TokenText == "require" ||
696 Tok.Next->Next->TokenText == "provide") &&
697 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
698 }
699
resetTokenMetadata(FormatToken * Token)700 void resetTokenMetadata(FormatToken *Token) {
701 if (!Token)
702 return;
703
704 // Reset token type in case we have already looked at it and then
705 // recovered from an error (e.g. failure to find the matching >).
706 if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_FunctionLBrace,
707 TT_ImplicitStringLiteral, TT_RegexLiteral,
708 TT_TrailingReturnArrow))
709 CurrentToken->Type = TT_Unknown;
710 CurrentToken->Role.reset();
711 CurrentToken->MatchingParen = nullptr;
712 CurrentToken->FakeLParens.clear();
713 CurrentToken->FakeRParens = 0;
714 }
715
next()716 void next() {
717 if (CurrentToken) {
718 CurrentToken->NestingLevel = Contexts.size() - 1;
719 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
720 modifyContext(*CurrentToken);
721 determineTokenType(*CurrentToken);
722 CurrentToken = CurrentToken->Next;
723 }
724
725 resetTokenMetadata(CurrentToken);
726 }
727
728 /// \brief A struct to hold information valid in a specific context, e.g.
729 /// a pair of parenthesis.
730 struct Context {
Contextclang::format::__anon7c513deb0111::AnnotatingParser::Context731 Context(tok::TokenKind ContextKind, unsigned BindingStrength,
732 bool IsExpression)
733 : ContextKind(ContextKind), BindingStrength(BindingStrength),
734 IsExpression(IsExpression) {}
735
736 tok::TokenKind ContextKind;
737 unsigned BindingStrength;
738 bool IsExpression;
739 unsigned LongestObjCSelectorName = 0;
740 bool ColonIsForRangeExpr = false;
741 bool ColonIsDictLiteral = false;
742 bool ColonIsObjCMethodExpr = false;
743 FormatToken *FirstObjCSelectorName = nullptr;
744 FormatToken *FirstStartOfName = nullptr;
745 bool CanBeExpression = true;
746 bool InTemplateArgument = false;
747 bool InCtorInitializer = false;
748 bool CaretFound = false;
749 bool IsForEachMacro = false;
750 };
751
752 /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime
753 /// of each instance.
754 struct ScopedContextCreator {
755 AnnotatingParser &P;
756
ScopedContextCreatorclang::format::__anon7c513deb0111::AnnotatingParser::ScopedContextCreator757 ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind,
758 unsigned Increase)
759 : P(P) {
760 P.Contexts.push_back(Context(ContextKind,
761 P.Contexts.back().BindingStrength + Increase,
762 P.Contexts.back().IsExpression));
763 }
764
~ScopedContextCreatorclang::format::__anon7c513deb0111::AnnotatingParser::ScopedContextCreator765 ~ScopedContextCreator() { P.Contexts.pop_back(); }
766 };
767
modifyContext(const FormatToken & Current)768 void modifyContext(const FormatToken &Current) {
769 if (Current.getPrecedence() == prec::Assignment &&
770 !Line.First->isOneOf(tok::kw_template, tok::kw_using) &&
771 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
772 Contexts.back().IsExpression = true;
773 if (!Line.First->is(TT_UnaryOperator)) {
774 for (FormatToken *Previous = Current.Previous;
775 Previous && !Previous->isOneOf(tok::comma, tok::semi);
776 Previous = Previous->Previous) {
777 if (Previous->isOneOf(tok::r_square, tok::r_paren)) {
778 Previous = Previous->MatchingParen;
779 if (!Previous)
780 break;
781 }
782 if (Previous->opensScope())
783 break;
784 if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
785 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
786 Previous->Previous && Previous->Previous->isNot(tok::equal))
787 Previous->Type = TT_PointerOrReference;
788 }
789 }
790 } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
791 Contexts.back().IsExpression = true;
792 } else if (Current.is(TT_TrailingReturnArrow)) {
793 Contexts.back().IsExpression = false;
794 } else if (Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
795 !Line.InPPDirective &&
796 (!Current.Previous ||
797 Current.Previous->isNot(tok::kw_decltype))) {
798 bool ParametersOfFunctionType =
799 Current.Previous && Current.Previous->is(tok::r_paren) &&
800 Current.Previous->MatchingParen &&
801 Current.Previous->MatchingParen->is(TT_FunctionTypeLParen);
802 bool IsForOrCatch = Current.Previous &&
803 Current.Previous->isOneOf(tok::kw_for, tok::kw_catch);
804 Contexts.back().IsExpression = !ParametersOfFunctionType && !IsForOrCatch;
805 } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
806 for (FormatToken *Previous = Current.Previous;
807 Previous && Previous->isOneOf(tok::star, tok::amp);
808 Previous = Previous->Previous)
809 Previous->Type = TT_PointerOrReference;
810 if (Line.MustBeDeclaration)
811 Contexts.back().IsExpression = Contexts.front().InCtorInitializer;
812 } else if (Current.Previous &&
813 Current.Previous->is(TT_CtorInitializerColon)) {
814 Contexts.back().IsExpression = true;
815 Contexts.back().InCtorInitializer = true;
816 } else if (Current.is(tok::kw_new)) {
817 Contexts.back().CanBeExpression = false;
818 } else if (Current.is(tok::semi) || Current.is(tok::exclaim)) {
819 // This should be the condition or increment in a for-loop.
820 Contexts.back().IsExpression = true;
821 }
822 }
823
determineTokenType(FormatToken & Current)824 void determineTokenType(FormatToken &Current) {
825 if (!Current.is(TT_Unknown))
826 // The token type is already known.
827 return;
828
829 // Line.MightBeFunctionDecl can only be true after the parentheses of a
830 // function declaration have been found. In this case, 'Current' is a
831 // trailing token of this declaration and thus cannot be a name.
832 if (Current.is(Keywords.kw_instanceof)) {
833 Current.Type = TT_BinaryOperator;
834 } else if (isStartOfName(Current) &&
835 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
836 Contexts.back().FirstStartOfName = &Current;
837 Current.Type = TT_StartOfName;
838 } else if (Current.is(tok::kw_auto)) {
839 AutoFound = true;
840 } else if (Current.is(tok::arrow) &&
841 Style.Language == FormatStyle::LK_Java) {
842 Current.Type = TT_LambdaArrow;
843 } else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration &&
844 Current.NestingLevel == 0) {
845 Current.Type = TT_TrailingReturnArrow;
846 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
847 Current.Type =
848 determineStarAmpUsage(Current, Contexts.back().CanBeExpression &&
849 Contexts.back().IsExpression,
850 Contexts.back().InTemplateArgument);
851 } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
852 Current.Type = determinePlusMinusCaretUsage(Current);
853 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
854 Contexts.back().CaretFound = true;
855 } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
856 Current.Type = determineIncrementUsage(Current);
857 } else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
858 Current.Type = TT_UnaryOperator;
859 } else if (Current.is(tok::question)) {
860 Current.Type = TT_ConditionalExpr;
861 } else if (Current.isBinaryOperator() &&
862 (!Current.Previous || Current.Previous->isNot(tok::l_square))) {
863 Current.Type = TT_BinaryOperator;
864 } else if (Current.is(tok::comment)) {
865 Current.Type =
866 Current.TokenText.startswith("/*") ? TT_BlockComment : TT_LineComment;
867 } else if (Current.is(tok::r_paren)) {
868 if (rParenEndsCast(Current))
869 Current.Type = TT_CastRParen;
870 } else if (Current.is(tok::at) && Current.Next) {
871 switch (Current.Next->Tok.getObjCKeywordID()) {
872 case tok::objc_interface:
873 case tok::objc_implementation:
874 case tok::objc_protocol:
875 Current.Type = TT_ObjCDecl;
876 break;
877 case tok::objc_property:
878 Current.Type = TT_ObjCProperty;
879 break;
880 default:
881 break;
882 }
883 } else if (Current.is(tok::period)) {
884 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
885 if (PreviousNoComment &&
886 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
887 Current.Type = TT_DesignatedInitializerPeriod;
888 else if (Style.Language == FormatStyle::LK_Java && Current.Previous &&
889 Current.Previous->isOneOf(TT_JavaAnnotation,
890 TT_LeadingJavaAnnotation)) {
891 Current.Type = Current.Previous->Type;
892 }
893 } else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
894 Current.Previous &&
895 !Current.Previous->isOneOf(tok::equal, tok::at) &&
896 Line.MightBeFunctionDecl && Contexts.size() == 1) {
897 // Line.MightBeFunctionDecl can only be true after the parentheses of a
898 // function declaration have been found.
899 Current.Type = TT_TrailingAnnotation;
900 } else if ((Style.Language == FormatStyle::LK_Java ||
901 Style.Language == FormatStyle::LK_JavaScript) &&
902 Current.Previous) {
903 if (Current.Previous->is(tok::at) &&
904 Current.isNot(Keywords.kw_interface)) {
905 const FormatToken &AtToken = *Current.Previous;
906 const FormatToken *Previous = AtToken.getPreviousNonComment();
907 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
908 Current.Type = TT_LeadingJavaAnnotation;
909 else
910 Current.Type = TT_JavaAnnotation;
911 } else if (Current.Previous->is(tok::period) &&
912 Current.Previous->isOneOf(TT_JavaAnnotation,
913 TT_LeadingJavaAnnotation)) {
914 Current.Type = Current.Previous->Type;
915 }
916 }
917 }
918
919 /// \brief Take a guess at whether \p Tok starts a name of a function or
920 /// variable declaration.
921 ///
922 /// This is a heuristic based on whether \p Tok is an identifier following
923 /// something that is likely a type.
isStartOfName(const FormatToken & Tok)924 bool isStartOfName(const FormatToken &Tok) {
925 if (Tok.isNot(tok::identifier) || !Tok.Previous)
926 return false;
927
928 if (Tok.Previous->is(TT_LeadingJavaAnnotation))
929 return false;
930
931 // Skip "const" as it does not have an influence on whether this is a name.
932 FormatToken *PreviousNotConst = Tok.Previous;
933 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
934 PreviousNotConst = PreviousNotConst->Previous;
935
936 if (!PreviousNotConst)
937 return false;
938
939 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
940 PreviousNotConst->Previous &&
941 PreviousNotConst->Previous->is(tok::hash);
942
943 if (PreviousNotConst->is(TT_TemplateCloser))
944 return PreviousNotConst && PreviousNotConst->MatchingParen &&
945 PreviousNotConst->MatchingParen->Previous &&
946 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
947 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
948
949 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
950 PreviousNotConst->MatchingParen->Previous &&
951 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
952 return true;
953
954 return (!IsPPKeyword && PreviousNotConst->is(tok::identifier)) ||
955 PreviousNotConst->is(TT_PointerOrReference) ||
956 PreviousNotConst->isSimpleTypeSpecifier();
957 }
958
959 /// \brief Determine whether ')' is ending a cast.
rParenEndsCast(const FormatToken & Tok)960 bool rParenEndsCast(const FormatToken &Tok) {
961 FormatToken *LeftOfParens = nullptr;
962 if (Tok.MatchingParen)
963 LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
964 if (LeftOfParens && LeftOfParens->is(tok::r_paren) &&
965 LeftOfParens->MatchingParen)
966 LeftOfParens = LeftOfParens->MatchingParen->Previous;
967 if (LeftOfParens && LeftOfParens->is(tok::r_square) &&
968 LeftOfParens->MatchingParen &&
969 LeftOfParens->MatchingParen->is(TT_LambdaLSquare))
970 return false;
971 if (Tok.Next) {
972 if (Tok.Next->is(tok::question))
973 return false;
974 if (Style.Language == FormatStyle::LK_JavaScript &&
975 Tok.Next->is(Keywords.kw_in))
976 return false;
977 if (Style.Language == FormatStyle::LK_Java && Tok.Next->is(tok::l_paren))
978 return true;
979 }
980 bool IsCast = false;
981 bool ParensAreEmpty = Tok.Previous == Tok.MatchingParen;
982 bool ParensAreType =
983 !Tok.Previous ||
984 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
985 Tok.Previous->isSimpleTypeSpecifier();
986 bool ParensCouldEndDecl =
987 Tok.Next && Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace);
988 bool IsSizeOfOrAlignOf =
989 LeftOfParens && LeftOfParens->isOneOf(tok::kw_sizeof, tok::kw_alignof);
990 if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf &&
991 (Contexts.size() > 1 && Contexts[Contexts.size() - 2].IsExpression))
992 IsCast = true;
993 else if (Tok.Next && Tok.Next->isNot(tok::string_literal) &&
994 (Tok.Next->Tok.isLiteral() ||
995 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
996 IsCast = true;
997 // If there is an identifier after the (), it is likely a cast, unless
998 // there is also an identifier before the ().
999 else if (LeftOfParens && Tok.Next &&
1000 (LeftOfParens->Tok.getIdentifierInfo() == nullptr ||
1001 LeftOfParens->is(tok::kw_return)) &&
1002 !LeftOfParens->isOneOf(TT_OverloadedOperator, tok::at,
1003 TT_TemplateCloser)) {
1004 if (Tok.Next->isOneOf(tok::identifier, tok::numeric_constant)) {
1005 IsCast = true;
1006 } else {
1007 // Use heuristics to recognize c style casting.
1008 FormatToken *Prev = Tok.Previous;
1009 if (Prev && Prev->isOneOf(tok::amp, tok::star))
1010 Prev = Prev->Previous;
1011
1012 if (Prev && Tok.Next && Tok.Next->Next) {
1013 bool NextIsUnary = Tok.Next->isUnaryOperator() ||
1014 Tok.Next->isOneOf(tok::amp, tok::star);
1015 IsCast =
1016 NextIsUnary && !Tok.Next->is(tok::plus) &&
1017 Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant);
1018 }
1019
1020 for (; Prev != Tok.MatchingParen; Prev = Prev->Previous) {
1021 if (!Prev || !Prev->isOneOf(tok::kw_const, tok::identifier)) {
1022 IsCast = false;
1023 break;
1024 }
1025 }
1026 }
1027 }
1028 return IsCast && !ParensAreEmpty;
1029 }
1030
1031 /// \brief Return the type of the given token assuming it is * or &.
determineStarAmpUsage(const FormatToken & Tok,bool IsExpression,bool InTemplateArgument)1032 TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,
1033 bool InTemplateArgument) {
1034 if (Style.Language == FormatStyle::LK_JavaScript)
1035 return TT_BinaryOperator;
1036
1037 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1038 if (!PrevToken)
1039 return TT_UnaryOperator;
1040
1041 const FormatToken *NextToken = Tok.getNextNonComment();
1042 if (!NextToken ||
1043 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1044 return TT_Unknown;
1045
1046 if (PrevToken->is(tok::coloncolon))
1047 return TT_PointerOrReference;
1048
1049 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1050 tok::comma, tok::semi, tok::kw_return, tok::colon,
1051 tok::equal, tok::kw_delete, tok::kw_sizeof) ||
1052 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1053 TT_UnaryOperator, TT_CastRParen))
1054 return TT_UnaryOperator;
1055
1056 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1057 return TT_PointerOrReference;
1058 if (NextToken->isOneOf(tok::kw_operator, tok::comma, tok::semi))
1059 return TT_PointerOrReference;
1060
1061 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen &&
1062 PrevToken->MatchingParen->Previous &&
1063 PrevToken->MatchingParen->Previous->isOneOf(tok::kw_typeof,
1064 tok::kw_decltype))
1065 return TT_PointerOrReference;
1066
1067 if (PrevToken->Tok.isLiteral() ||
1068 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1069 tok::kw_false, tok::r_brace) ||
1070 NextToken->Tok.isLiteral() ||
1071 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1072 NextToken->isUnaryOperator() ||
1073 // If we know we're in a template argument, there are no named
1074 // declarations. Thus, having an identifier on the right-hand side
1075 // indicates a binary operator.
1076 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1077 return TT_BinaryOperator;
1078
1079 // "&&(" is quite unlikely to be two successive unary "&".
1080 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1081 return TT_BinaryOperator;
1082
1083 // This catches some cases where evaluation order is used as control flow:
1084 // aaa && aaa->f();
1085 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1086 if (NextNextToken && NextNextToken->is(tok::arrow))
1087 return TT_BinaryOperator;
1088
1089 // It is very unlikely that we are going to find a pointer or reference type
1090 // definition on the RHS of an assignment.
1091 if (IsExpression && !Contexts.back().CaretFound)
1092 return TT_BinaryOperator;
1093
1094 return TT_PointerOrReference;
1095 }
1096
determinePlusMinusCaretUsage(const FormatToken & Tok)1097 TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
1098 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1099 if (!PrevToken || PrevToken->is(TT_CastRParen))
1100 return TT_UnaryOperator;
1101
1102 // Use heuristics to recognize unary operators.
1103 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1104 tok::question, tok::colon, tok::kw_return,
1105 tok::kw_case, tok::at, tok::l_brace))
1106 return TT_UnaryOperator;
1107
1108 // There can't be two consecutive binary operators.
1109 if (PrevToken->is(TT_BinaryOperator))
1110 return TT_UnaryOperator;
1111
1112 // Fall back to marking the token as binary operator.
1113 return TT_BinaryOperator;
1114 }
1115
1116 /// \brief Determine whether ++/-- are pre- or post-increments/-decrements.
determineIncrementUsage(const FormatToken & Tok)1117 TokenType determineIncrementUsage(const FormatToken &Tok) {
1118 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1119 if (!PrevToken || PrevToken->is(TT_CastRParen))
1120 return TT_UnaryOperator;
1121 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1122 return TT_TrailingUnaryOperator;
1123
1124 return TT_UnaryOperator;
1125 }
1126
1127 SmallVector<Context, 8> Contexts;
1128
1129 const FormatStyle &Style;
1130 AnnotatedLine &Line;
1131 FormatToken *CurrentToken;
1132 bool AutoFound;
1133 const AdditionalKeywords &Keywords;
1134 };
1135
1136 static const int PrecedenceUnaryOperator = prec::PointerToMember + 1;
1137 static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2;
1138
1139 /// \brief Parses binary expressions by inserting fake parenthesis based on
1140 /// operator precedence.
1141 class ExpressionParser {
1142 public:
ExpressionParser(const FormatStyle & Style,const AdditionalKeywords & Keywords,AnnotatedLine & Line)1143 ExpressionParser(const FormatStyle &Style, const AdditionalKeywords &Keywords,
1144 AnnotatedLine &Line)
1145 : Style(Style), Keywords(Keywords), Current(Line.First) {}
1146
1147 /// \brief Parse expressions with the given operatore precedence.
parse(int Precedence=0)1148 void parse(int Precedence = 0) {
1149 // Skip 'return' and ObjC selector colons as they are not part of a binary
1150 // expression.
1151 while (Current && (Current->is(tok::kw_return) ||
1152 (Current->is(tok::colon) &&
1153 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1154 next();
1155
1156 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1157 return;
1158
1159 // Conditional expressions need to be parsed separately for proper nesting.
1160 if (Precedence == prec::Conditional) {
1161 parseConditionalExpr();
1162 return;
1163 }
1164
1165 // Parse unary operators, which all have a higher precedence than binary
1166 // operators.
1167 if (Precedence == PrecedenceUnaryOperator) {
1168 parseUnaryOperator();
1169 return;
1170 }
1171
1172 FormatToken *Start = Current;
1173 FormatToken *LatestOperator = nullptr;
1174 unsigned OperatorIndex = 0;
1175
1176 while (Current) {
1177 // Consume operators with higher precedence.
1178 parse(Precedence + 1);
1179
1180 int CurrentPrecedence = getCurrentPrecedence();
1181
1182 if (Current && Current->is(TT_SelectorName) &&
1183 Precedence == CurrentPrecedence) {
1184 if (LatestOperator)
1185 addFakeParenthesis(Start, prec::Level(Precedence));
1186 Start = Current;
1187 }
1188
1189 // At the end of the line or when an operator with higher precedence is
1190 // found, insert fake parenthesis and return.
1191 if (!Current || (Current->closesScope() && Current->MatchingParen) ||
1192 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1193 (CurrentPrecedence == prec::Conditional &&
1194 Precedence == prec::Assignment && Current->is(tok::colon))) {
1195 break;
1196 }
1197
1198 // Consume scopes: (), [], <> and {}
1199 if (Current->opensScope()) {
1200 while (Current && !Current->closesScope()) {
1201 next();
1202 parse();
1203 }
1204 next();
1205 } else {
1206 // Operator found.
1207 if (CurrentPrecedence == Precedence) {
1208 LatestOperator = Current;
1209 Current->OperatorIndex = OperatorIndex;
1210 ++OperatorIndex;
1211 }
1212 next(/*SkipPastLeadingComments=*/Precedence > 0);
1213 }
1214 }
1215
1216 if (LatestOperator && (Current || Precedence > 0)) {
1217 LatestOperator->LastOperator = true;
1218 if (Precedence == PrecedenceArrowAndPeriod) {
1219 // Call expressions don't have a binary operator precedence.
1220 addFakeParenthesis(Start, prec::Unknown);
1221 } else {
1222 addFakeParenthesis(Start, prec::Level(Precedence));
1223 }
1224 }
1225 }
1226
1227 private:
1228 /// \brief Gets the precedence (+1) of the given token for binary operators
1229 /// and other tokens that we treat like binary operators.
getCurrentPrecedence()1230 int getCurrentPrecedence() {
1231 if (Current) {
1232 const FormatToken *NextNonComment = Current->getNextNonComment();
1233 if (Current->is(TT_ConditionalExpr))
1234 return prec::Conditional;
1235 else if (NextNonComment && NextNonComment->is(tok::colon) &&
1236 NextNonComment->is(TT_DictLiteral))
1237 return prec::Comma;
1238 else if (Current->is(TT_LambdaArrow))
1239 return prec::Comma;
1240 else if (Current->isOneOf(tok::semi, TT_InlineASMColon,
1241 TT_SelectorName) ||
1242 (Current->is(tok::comment) && NextNonComment &&
1243 NextNonComment->is(TT_SelectorName)))
1244 return 0;
1245 else if (Current->is(TT_RangeBasedForLoopColon))
1246 return prec::Comma;
1247 else if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
1248 return Current->getPrecedence();
1249 else if (Current->isOneOf(tok::period, tok::arrow))
1250 return PrecedenceArrowAndPeriod;
1251 else if (Style.Language == FormatStyle::LK_Java &&
1252 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
1253 Keywords.kw_throws))
1254 return 0;
1255 }
1256 return -1;
1257 }
1258
addFakeParenthesis(FormatToken * Start,prec::Level Precedence)1259 void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) {
1260 Start->FakeLParens.push_back(Precedence);
1261 if (Precedence > prec::Unknown)
1262 Start->StartsBinaryExpression = true;
1263 if (Current) {
1264 FormatToken *Previous = Current->Previous;
1265 while (Previous->is(tok::comment) && Previous->Previous)
1266 Previous = Previous->Previous;
1267 ++Previous->FakeRParens;
1268 if (Precedence > prec::Unknown)
1269 Previous->EndsBinaryExpression = true;
1270 }
1271 }
1272
1273 /// \brief Parse unary operator expressions and surround them with fake
1274 /// parentheses if appropriate.
parseUnaryOperator()1275 void parseUnaryOperator() {
1276 if (!Current || Current->isNot(TT_UnaryOperator)) {
1277 parse(PrecedenceArrowAndPeriod);
1278 return;
1279 }
1280
1281 FormatToken *Start = Current;
1282 next();
1283 parseUnaryOperator();
1284
1285 // The actual precedence doesn't matter.
1286 addFakeParenthesis(Start, prec::Unknown);
1287 }
1288
parseConditionalExpr()1289 void parseConditionalExpr() {
1290 while (Current && Current->isTrailingComment()) {
1291 next();
1292 }
1293 FormatToken *Start = Current;
1294 parse(prec::LogicalOr);
1295 if (!Current || !Current->is(tok::question))
1296 return;
1297 next();
1298 parse(prec::Assignment);
1299 if (!Current || Current->isNot(TT_ConditionalExpr))
1300 return;
1301 next();
1302 parse(prec::Assignment);
1303 addFakeParenthesis(Start, prec::Conditional);
1304 }
1305
next(bool SkipPastLeadingComments=true)1306 void next(bool SkipPastLeadingComments = true) {
1307 if (Current)
1308 Current = Current->Next;
1309 while (Current &&
1310 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
1311 Current->isTrailingComment())
1312 Current = Current->Next;
1313 }
1314
1315 const FormatStyle &Style;
1316 const AdditionalKeywords &Keywords;
1317 FormatToken *Current;
1318 };
1319
1320 } // end anonymous namespace
1321
setCommentLineLevels(SmallVectorImpl<AnnotatedLine * > & Lines)1322 void TokenAnnotator::setCommentLineLevels(
1323 SmallVectorImpl<AnnotatedLine *> &Lines) {
1324 const AnnotatedLine *NextNonCommentLine = nullptr;
1325 for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),
1326 E = Lines.rend();
1327 I != E; ++I) {
1328 if (NextNonCommentLine && (*I)->First->is(tok::comment) &&
1329 (*I)->First->Next == nullptr)
1330 (*I)->Level = NextNonCommentLine->Level;
1331 else
1332 NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
1333
1334 setCommentLineLevels((*I)->Children);
1335 }
1336 }
1337
annotate(AnnotatedLine & Line)1338 void TokenAnnotator::annotate(AnnotatedLine &Line) {
1339 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
1340 E = Line.Children.end();
1341 I != E; ++I) {
1342 annotate(**I);
1343 }
1344 AnnotatingParser Parser(Style, Line, Keywords);
1345 Line.Type = Parser.parseLine();
1346 if (Line.Type == LT_Invalid)
1347 return;
1348
1349 ExpressionParser ExprParser(Style, Keywords, Line);
1350 ExprParser.parse();
1351
1352 if (Line.First->is(TT_ObjCMethodSpecifier))
1353 Line.Type = LT_ObjCMethodDecl;
1354 else if (Line.First->is(TT_ObjCDecl))
1355 Line.Type = LT_ObjCDecl;
1356 else if (Line.First->is(TT_ObjCProperty))
1357 Line.Type = LT_ObjCProperty;
1358
1359 Line.First->SpacesRequiredBefore = 1;
1360 Line.First->CanBreakBefore = Line.First->MustBreakBefore;
1361 }
1362
1363 // This function heuristically determines whether 'Current' starts the name of a
1364 // function declaration.
isFunctionDeclarationName(const FormatToken & Current)1365 static bool isFunctionDeclarationName(const FormatToken &Current) {
1366 if (!Current.is(TT_StartOfName) || Current.NestingLevel != 0)
1367 return false;
1368 const FormatToken *Next = Current.Next;
1369 for (; Next; Next = Next->Next) {
1370 if (Next->is(TT_TemplateOpener)) {
1371 Next = Next->MatchingParen;
1372 } else if (Next->is(tok::coloncolon)) {
1373 Next = Next->Next;
1374 if (!Next || !Next->is(tok::identifier))
1375 return false;
1376 } else if (Next->is(tok::l_paren)) {
1377 break;
1378 } else {
1379 return false;
1380 }
1381 }
1382 if (!Next)
1383 return false;
1384 assert(Next->is(tok::l_paren));
1385 if (Next->Next == Next->MatchingParen)
1386 return true;
1387 for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen;
1388 Tok = Tok->Next) {
1389 if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
1390 Tok->isOneOf(TT_PointerOrReference, TT_StartOfName))
1391 return true;
1392 if (Tok->isOneOf(tok::l_brace, tok::string_literal) || Tok->Tok.isLiteral())
1393 return false;
1394 }
1395 return false;
1396 }
1397
calculateFormattingInformation(AnnotatedLine & Line)1398 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
1399 for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
1400 E = Line.Children.end();
1401 I != E; ++I) {
1402 calculateFormattingInformation(**I);
1403 }
1404
1405 Line.First->TotalLength =
1406 Line.First->IsMultiline ? Style.ColumnLimit : Line.First->ColumnWidth;
1407 if (!Line.First->Next)
1408 return;
1409 FormatToken *Current = Line.First->Next;
1410 bool InFunctionDecl = Line.MightBeFunctionDecl;
1411 while (Current) {
1412 if (isFunctionDeclarationName(*Current))
1413 Current->Type = TT_FunctionDeclarationName;
1414 if (Current->is(TT_LineComment)) {
1415 if (Current->Previous->BlockKind == BK_BracedInit &&
1416 Current->Previous->opensScope())
1417 Current->SpacesRequiredBefore = Style.Cpp11BracedListStyle ? 0 : 1;
1418 else
1419 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
1420
1421 // If we find a trailing comment, iterate backwards to determine whether
1422 // it seems to relate to a specific parameter. If so, break before that
1423 // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
1424 // to the previous line in:
1425 // SomeFunction(a,
1426 // b, // comment
1427 // c);
1428 if (!Current->HasUnescapedNewline) {
1429 for (FormatToken *Parameter = Current->Previous; Parameter;
1430 Parameter = Parameter->Previous) {
1431 if (Parameter->isOneOf(tok::comment, tok::r_brace))
1432 break;
1433 if (Parameter->Previous && Parameter->Previous->is(tok::comma)) {
1434 if (!Parameter->Previous->is(TT_CtorInitializerComma) &&
1435 Parameter->HasUnescapedNewline)
1436 Parameter->MustBreakBefore = true;
1437 break;
1438 }
1439 }
1440 }
1441 } else if (Current->SpacesRequiredBefore == 0 &&
1442 spaceRequiredBefore(Line, *Current)) {
1443 Current->SpacesRequiredBefore = 1;
1444 }
1445
1446 Current->MustBreakBefore =
1447 Current->MustBreakBefore || mustBreakBefore(Line, *Current);
1448
1449 if (Style.AlwaysBreakAfterDefinitionReturnType && InFunctionDecl &&
1450 Current->is(TT_FunctionDeclarationName) &&
1451 !Line.Last->isOneOf(tok::semi, tok::comment)) // Only for definitions.
1452 // FIXME: Line.Last points to other characters than tok::semi
1453 // and tok::lbrace.
1454 Current->MustBreakBefore = true;
1455
1456 Current->CanBreakBefore =
1457 Current->MustBreakBefore || canBreakBefore(Line, *Current);
1458 unsigned ChildSize = 0;
1459 if (Current->Previous->Children.size() == 1) {
1460 FormatToken &LastOfChild = *Current->Previous->Children[0]->Last;
1461 ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit
1462 : LastOfChild.TotalLength + 1;
1463 }
1464 const FormatToken *Prev = Current->Previous;
1465 if (Current->MustBreakBefore || Prev->Children.size() > 1 ||
1466 (Prev->Children.size() == 1 &&
1467 Prev->Children[0]->First->MustBreakBefore) ||
1468 Current->IsMultiline)
1469 Current->TotalLength = Prev->TotalLength + Style.ColumnLimit;
1470 else
1471 Current->TotalLength = Prev->TotalLength + Current->ColumnWidth +
1472 ChildSize + Current->SpacesRequiredBefore;
1473
1474 if (Current->is(TT_CtorInitializerColon))
1475 InFunctionDecl = false;
1476
1477 // FIXME: Only calculate this if CanBreakBefore is true once static
1478 // initializers etc. are sorted out.
1479 // FIXME: Move magic numbers to a better place.
1480 Current->SplitPenalty = 20 * Current->BindingStrength +
1481 splitPenalty(Line, *Current, InFunctionDecl);
1482
1483 Current = Current->Next;
1484 }
1485
1486 calculateUnbreakableTailLengths(Line);
1487 for (Current = Line.First; Current != nullptr; Current = Current->Next) {
1488 if (Current->Role)
1489 Current->Role->precomputeFormattingInfos(Current);
1490 }
1491
1492 DEBUG({ printDebugInfo(Line); });
1493 }
1494
calculateUnbreakableTailLengths(AnnotatedLine & Line)1495 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) {
1496 unsigned UnbreakableTailLength = 0;
1497 FormatToken *Current = Line.Last;
1498 while (Current) {
1499 Current->UnbreakableTailLength = UnbreakableTailLength;
1500 if (Current->CanBreakBefore ||
1501 Current->isOneOf(tok::comment, tok::string_literal)) {
1502 UnbreakableTailLength = 0;
1503 } else {
1504 UnbreakableTailLength +=
1505 Current->ColumnWidth + Current->SpacesRequiredBefore;
1506 }
1507 Current = Current->Previous;
1508 }
1509 }
1510
splitPenalty(const AnnotatedLine & Line,const FormatToken & Tok,bool InFunctionDecl)1511 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
1512 const FormatToken &Tok,
1513 bool InFunctionDecl) {
1514 const FormatToken &Left = *Tok.Previous;
1515 const FormatToken &Right = Tok;
1516
1517 if (Left.is(tok::semi))
1518 return 0;
1519
1520 if (Style.Language == FormatStyle::LK_Java) {
1521 if (Right.isOneOf(Keywords.kw_extends, Keywords.kw_throws))
1522 return 1;
1523 if (Right.is(Keywords.kw_implements))
1524 return 2;
1525 if (Left.is(tok::comma) && Left.NestingLevel == 0)
1526 return 3;
1527 } else if (Style.Language == FormatStyle::LK_JavaScript) {
1528 if (Right.is(Keywords.kw_function))
1529 return 100;
1530 }
1531
1532 if (Left.is(tok::comma) || (Right.is(tok::identifier) && Right.Next &&
1533 Right.Next->is(TT_DictLiteral)))
1534 return 1;
1535 if (Right.is(tok::l_square)) {
1536 if (Style.Language == FormatStyle::LK_Proto)
1537 return 1;
1538 if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare))
1539 return 500;
1540 }
1541
1542 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
1543 Right.is(tok::kw_operator)) {
1544 if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
1545 return 3;
1546 if (Left.is(TT_StartOfName))
1547 return 20;
1548 if (InFunctionDecl && Right.NestingLevel == 0)
1549 return Style.PenaltyReturnTypeOnItsOwnLine;
1550 return 200;
1551 }
1552 if (Right.is(TT_PointerOrReference))
1553 return 190;
1554 if (Right.is(TT_TrailingReturnArrow))
1555 return 110;
1556 if (Left.is(tok::equal) && Right.is(tok::l_brace))
1557 return 150;
1558 if (Left.is(TT_CastRParen))
1559 return 100;
1560 if (Left.is(tok::coloncolon) ||
1561 (Right.is(tok::period) && Style.Language == FormatStyle::LK_Proto))
1562 return 500;
1563 if (Left.isOneOf(tok::kw_class, tok::kw_struct))
1564 return 5000;
1565
1566 if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon))
1567 return 2;
1568
1569 if (Right.isMemberAccess()) {
1570 if (Left.is(tok::r_paren) && Left.MatchingParen &&
1571 Left.MatchingParen->ParameterCount > 0)
1572 return 20; // Should be smaller than breaking at a nested comma.
1573 return 150;
1574 }
1575
1576 if (Right.is(TT_TrailingAnnotation) &&
1577 (!Right.Next || Right.Next->isNot(tok::l_paren))) {
1578 // Moving trailing annotations to the next line is fine for ObjC method
1579 // declarations.
1580 if (Line.First->is(TT_ObjCMethodSpecifier))
1581
1582 return 10;
1583 // Generally, breaking before a trailing annotation is bad unless it is
1584 // function-like. It seems to be especially preferable to keep standard
1585 // annotations (i.e. "const", "final" and "override") on the same line.
1586 // Use a slightly higher penalty after ")" so that annotations like
1587 // "const override" are kept together.
1588 bool is_short_annotation = Right.TokenText.size() < 10;
1589 return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
1590 }
1591
1592 // In for-loops, prefer breaking at ',' and ';'.
1593 if (Line.First->is(tok::kw_for) && Left.is(tok::equal))
1594 return 4;
1595
1596 // In Objective-C method expressions, prefer breaking before "param:" over
1597 // breaking after it.
1598 if (Right.is(TT_SelectorName))
1599 return 0;
1600 if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
1601 return Line.MightBeFunctionDecl ? 50 : 500;
1602
1603 if (Left.is(tok::l_paren) && InFunctionDecl && Style.AlignAfterOpenBracket)
1604 return 100;
1605 if (Left.is(tok::l_paren) && Left.Previous && Left.Previous->is(tok::kw_if))
1606 return 1000;
1607 if (Left.is(tok::equal) && InFunctionDecl)
1608 return 110;
1609 if (Right.is(tok::r_brace))
1610 return 1;
1611 if (Left.is(TT_TemplateOpener))
1612 return 100;
1613 if (Left.opensScope()) {
1614 if (!Style.AlignAfterOpenBracket)
1615 return 0;
1616 return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
1617 : 19;
1618 }
1619 if (Left.is(TT_JavaAnnotation))
1620 return 50;
1621
1622 if (Right.is(tok::lessless)) {
1623 if (Left.is(tok::string_literal)) {
1624 StringRef Content = Left.TokenText;
1625 if (Content.startswith("\""))
1626 Content = Content.drop_front(1);
1627 if (Content.endswith("\""))
1628 Content = Content.drop_back(1);
1629 Content = Content.trim();
1630 if (Content.size() > 1 &&
1631 (Content.back() == ':' || Content.back() == '='))
1632 return 25;
1633 }
1634 return 1; // Breaking at a << is really cheap.
1635 }
1636 if (Left.is(TT_ConditionalExpr))
1637 return prec::Conditional;
1638 prec::Level Level = Left.getPrecedence();
1639 if (Level != prec::Unknown)
1640 return Level;
1641
1642 return 3;
1643 }
1644
spaceRequiredBetween(const AnnotatedLine & Line,const FormatToken & Left,const FormatToken & Right)1645 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
1646 const FormatToken &Left,
1647 const FormatToken &Right) {
1648 if (Left.is(tok::kw_return) && Right.isNot(tok::semi))
1649 return true;
1650 if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&
1651 Left.Tok.getObjCKeywordID() == tok::objc_property)
1652 return true;
1653 if (Right.is(tok::hashhash))
1654 return Left.is(tok::hash);
1655 if (Left.isOneOf(tok::hashhash, tok::hash))
1656 return Right.is(tok::hash);
1657 if (Left.is(tok::l_paren) && Right.is(tok::r_paren))
1658 return Style.SpaceInEmptyParentheses;
1659 if (Left.is(tok::l_paren) || Right.is(tok::r_paren))
1660 return (Right.is(TT_CastRParen) ||
1661 (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
1662 ? Style.SpacesInCStyleCastParentheses
1663 : Style.SpacesInParentheses;
1664 if (Right.isOneOf(tok::semi, tok::comma))
1665 return false;
1666 if (Right.is(tok::less) &&
1667 (Left.is(tok::kw_template) ||
1668 (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList)))
1669 return true;
1670 if (Left.isOneOf(tok::exclaim, tok::tilde))
1671 return false;
1672 if (Left.is(tok::at) &&
1673 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
1674 tok::numeric_constant, tok::l_paren, tok::l_brace,
1675 tok::kw_true, tok::kw_false))
1676 return false;
1677 if (Left.is(tok::coloncolon))
1678 return false;
1679 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less))
1680 return false;
1681 if (Right.is(tok::ellipsis))
1682 return Left.Tok.isLiteral();
1683 if (Left.is(tok::l_square) && Right.is(tok::amp))
1684 return false;
1685 if (Right.is(TT_PointerOrReference))
1686 return !(Left.is(tok::r_paren) && Left.MatchingParen &&
1687 (Left.MatchingParen->is(TT_OverloadedOperatorLParen) ||
1688 (Left.MatchingParen->Previous &&
1689 Left.MatchingParen->Previous->is(
1690 TT_FunctionDeclarationName)))) &&
1691 (Left.Tok.isLiteral() ||
1692 (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
1693 (Style.PointerAlignment != FormatStyle::PAS_Left ||
1694 Line.IsMultiVariableDeclStmt)));
1695 if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
1696 (!Left.is(TT_PointerOrReference) ||
1697 (Style.PointerAlignment != FormatStyle::PAS_Right &&
1698 !Line.IsMultiVariableDeclStmt)))
1699 return true;
1700 if (Left.is(TT_PointerOrReference))
1701 return Right.Tok.isLiteral() || Right.is(TT_BlockComment) ||
1702 (!Right.isOneOf(TT_PointerOrReference, tok::l_paren) &&
1703 (Style.PointerAlignment != FormatStyle::PAS_Right &&
1704 !Line.IsMultiVariableDeclStmt) &&
1705 Left.Previous &&
1706 !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon));
1707 if (Right.is(tok::star) && Left.is(tok::l_paren))
1708 return false;
1709 if (Left.is(tok::l_square))
1710 return (Left.is(TT_ArrayInitializerLSquare) &&
1711 Style.SpacesInContainerLiterals && Right.isNot(tok::r_square)) ||
1712 (Left.is(TT_ArraySubscriptLSquare) && Style.SpacesInSquareBrackets &&
1713 Right.isNot(tok::r_square));
1714 if (Right.is(tok::r_square))
1715 return Right.MatchingParen &&
1716 ((Style.SpacesInContainerLiterals &&
1717 Right.MatchingParen->is(TT_ArrayInitializerLSquare)) ||
1718 (Style.SpacesInSquareBrackets &&
1719 Right.MatchingParen->is(TT_ArraySubscriptLSquare)));
1720 if (Right.is(tok::l_square) &&
1721 !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare) &&
1722 !Left.isOneOf(tok::numeric_constant, TT_DictLiteral))
1723 return false;
1724 if (Left.is(tok::colon))
1725 return !Left.is(TT_ObjCMethodExpr);
1726 if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
1727 return !Left.Children.empty(); // No spaces in "{}".
1728 if ((Left.is(tok::l_brace) && Left.BlockKind != BK_Block) ||
1729 (Right.is(tok::r_brace) && Right.MatchingParen &&
1730 Right.MatchingParen->BlockKind != BK_Block))
1731 return !Style.Cpp11BracedListStyle;
1732 if (Left.is(TT_BlockComment))
1733 return !Left.TokenText.endswith("=*/");
1734 if (Right.is(tok::l_paren)) {
1735 if (Left.is(tok::r_paren) && Left.is(TT_AttributeParen))
1736 return true;
1737 return Line.Type == LT_ObjCDecl || Left.is(tok::semi) ||
1738 (Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
1739 (Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while,
1740 tok::kw_switch, tok::kw_case) ||
1741 (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
1742 tok::kw_new, tok::kw_delete) &&
1743 (!Left.Previous || Left.Previous->isNot(tok::period))) ||
1744 Left.IsForEachMacro)) ||
1745 (Style.SpaceBeforeParens == FormatStyle::SBPO_Always &&
1746 (Left.is(tok::identifier) || Left.isFunctionLikeKeyword()) &&
1747 Line.Type != LT_PreprocessorDirective);
1748 }
1749 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
1750 return false;
1751 if (Right.is(TT_UnaryOperator))
1752 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
1753 (Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
1754 if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
1755 tok::r_paren) ||
1756 Left.isSimpleTypeSpecifier()) &&
1757 Right.is(tok::l_brace) && Right.getNextNonComment() &&
1758 Right.BlockKind != BK_Block)
1759 return false;
1760 if (Left.is(tok::period) || Right.is(tok::period))
1761 return false;
1762 if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText == "L")
1763 return false;
1764 if (Left.is(TT_TemplateCloser) && Left.MatchingParen &&
1765 Left.MatchingParen->Previous &&
1766 Left.MatchingParen->Previous->is(tok::period))
1767 // A.<B>DoSomething();
1768 return false;
1769 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_square))
1770 return false;
1771 return true;
1772 }
1773
spaceRequiredBefore(const AnnotatedLine & Line,const FormatToken & Right)1774 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
1775 const FormatToken &Right) {
1776 const FormatToken &Left = *Right.Previous;
1777 if (Style.Language == FormatStyle::LK_Proto) {
1778 if (Right.is(tok::period) &&
1779 Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
1780 Keywords.kw_repeated))
1781 return true;
1782 if (Right.is(tok::l_paren) &&
1783 Left.isOneOf(Keywords.kw_returns, Keywords.kw_option))
1784 return true;
1785 } else if (Style.Language == FormatStyle::LK_JavaScript) {
1786 if (Left.is(Keywords.kw_var))
1787 return true;
1788 if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
1789 return false;
1790 if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
1791 Line.First->isOneOf(Keywords.kw_import, tok::kw_export))
1792 return false;
1793 if (Left.is(TT_TemplateCloser) &&
1794 !Right.isOneOf(tok::l_brace, tok::comma, tok::l_square,
1795 Keywords.kw_implements, Keywords.kw_extends))
1796 // Type assertions ('<type>expr') are not followed by whitespace. Other
1797 // locations that should have whitespace following are identified by the
1798 // above set of follower tokens.
1799 return false;
1800 } else if (Style.Language == FormatStyle::LK_Java) {
1801 if (Left.is(tok::r_square) && Right.is(tok::l_brace))
1802 return true;
1803 if (Left.is(TT_LambdaArrow) || Right.is(TT_LambdaArrow))
1804 return true;
1805 if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren))
1806 return Style.SpaceBeforeParens != FormatStyle::SBPO_Never;
1807 if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
1808 tok::kw_protected) ||
1809 Left.isOneOf(Keywords.kw_final, Keywords.kw_abstract,
1810 Keywords.kw_native)) &&
1811 Right.is(TT_TemplateOpener))
1812 return true;
1813 }
1814 if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
1815 return true; // Never ever merge two identifiers.
1816 if (Left.is(TT_ImplicitStringLiteral))
1817 return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
1818 if (Line.Type == LT_ObjCMethodDecl) {
1819 if (Left.is(TT_ObjCMethodSpecifier))
1820 return true;
1821 if (Left.is(tok::r_paren) && Right.is(tok::identifier))
1822 // Don't space between ')' and <id>
1823 return false;
1824 }
1825 if (Line.Type == LT_ObjCProperty &&
1826 (Right.is(tok::equal) || Left.is(tok::equal)))
1827 return false;
1828
1829 if (Right.is(TT_TrailingReturnArrow) || Left.is(TT_TrailingReturnArrow))
1830 return true;
1831 if (Left.is(tok::comma))
1832 return true;
1833 if (Right.is(tok::comma))
1834 return false;
1835 if (Right.isOneOf(TT_CtorInitializerColon, TT_ObjCBlockLParen))
1836 return true;
1837 if (Left.is(tok::kw_operator))
1838 return Right.is(tok::coloncolon);
1839 if (Right.is(TT_OverloadedOperatorLParen))
1840 return false;
1841 if (Right.is(tok::colon))
1842 return !Line.First->isOneOf(tok::kw_case, tok::kw_default) &&
1843 Right.getNextNonComment() && Right.isNot(TT_ObjCMethodExpr) &&
1844 !Left.is(tok::question) &&
1845 !(Right.is(TT_InlineASMColon) && Left.is(tok::coloncolon)) &&
1846 (Right.isNot(TT_DictLiteral) || Style.SpacesInContainerLiterals);
1847 if (Left.is(TT_UnaryOperator))
1848 return Right.is(TT_BinaryOperator);
1849 if (Left.is(TT_CastRParen))
1850 return Style.SpaceAfterCStyleCast || Right.is(TT_BinaryOperator);
1851 if (Left.is(tok::greater) && Right.is(tok::greater)) {
1852 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
1853 (Style.Standard != FormatStyle::LS_Cpp11 || Style.SpacesInAngles);
1854 }
1855 if (Right.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
1856 Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar))
1857 return false;
1858 if (!Style.SpaceBeforeAssignmentOperators &&
1859 Right.getPrecedence() == prec::Assignment)
1860 return false;
1861 if (Right.is(tok::coloncolon) && Left.isNot(tok::l_brace))
1862 return (Left.is(TT_TemplateOpener) &&
1863 Style.Standard == FormatStyle::LS_Cpp03) ||
1864 !(Left.isOneOf(tok::identifier, tok::l_paren, tok::r_paren) ||
1865 Left.isOneOf(TT_TemplateCloser, TT_TemplateOpener));
1866 if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
1867 return Style.SpacesInAngles;
1868 if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) ||
1869 Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr))
1870 return true;
1871 if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) &&
1872 Right.isNot(TT_FunctionTypeLParen))
1873 return Style.SpaceBeforeParens == FormatStyle::SBPO_Always;
1874 if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
1875 Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen))
1876 return false;
1877 if (Right.is(tok::less) && Left.isNot(tok::l_paren) &&
1878 Line.First->is(tok::hash))
1879 return true;
1880 if (Right.is(TT_TrailingUnaryOperator))
1881 return false;
1882 if (Left.is(TT_RegexLiteral))
1883 return false;
1884 return spaceRequiredBetween(Line, Left, Right);
1885 }
1886
1887 // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
isAllmanBrace(const FormatToken & Tok)1888 static bool isAllmanBrace(const FormatToken &Tok) {
1889 return Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block &&
1890 !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
1891 }
1892
mustBreakBefore(const AnnotatedLine & Line,const FormatToken & Right)1893 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
1894 const FormatToken &Right) {
1895 const FormatToken &Left = *Right.Previous;
1896 if (Right.NewlinesBefore > 1)
1897 return true;
1898
1899 // If the last token before a '}' is a comma or a trailing comment, the
1900 // intention is to insert a line break after it in order to make shuffling
1901 // around entries easier.
1902 const FormatToken *BeforeClosingBrace = nullptr;
1903 if (Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
1904 Left.BlockKind != BK_Block && Left.MatchingParen)
1905 BeforeClosingBrace = Left.MatchingParen->Previous;
1906 else if (Right.MatchingParen &&
1907 Right.MatchingParen->isOneOf(tok::l_brace,
1908 TT_ArrayInitializerLSquare))
1909 BeforeClosingBrace = &Left;
1910 if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
1911 BeforeClosingBrace->isTrailingComment()))
1912 return true;
1913
1914 if (Right.is(tok::comment))
1915 return Left.BlockKind != BK_BracedInit &&
1916 Left.isNot(TT_CtorInitializerColon) &&
1917 (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
1918 if (Right.Previous->isTrailingComment() ||
1919 (Right.isStringLiteral() && Right.Previous->isStringLiteral()))
1920 return true;
1921 if (Right.Previous->IsUnterminatedLiteral)
1922 return true;
1923 if (Right.is(tok::lessless) && Right.Next &&
1924 Right.Previous->is(tok::string_literal) &&
1925 Right.Next->is(tok::string_literal))
1926 return true;
1927 if (Right.Previous->ClosesTemplateDeclaration &&
1928 Right.Previous->MatchingParen &&
1929 Right.Previous->MatchingParen->NestingLevel == 0 &&
1930 Style.AlwaysBreakTemplateDeclarations)
1931 return true;
1932 if ((Right.isOneOf(TT_CtorInitializerComma, TT_CtorInitializerColon)) &&
1933 Style.BreakConstructorInitializersBeforeComma &&
1934 !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
1935 return true;
1936 if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\""))
1937 // Raw string literals are special wrt. line breaks. The author has made a
1938 // deliberate choice and might have aligned the contents of the string
1939 // literal accordingly. Thus, we try keep existing line breaks.
1940 return Right.NewlinesBefore > 0;
1941 if (Right.Previous->is(tok::l_brace) && Right.NestingLevel == 1 &&
1942 Style.Language == FormatStyle::LK_Proto)
1943 // Don't put enums onto single lines in protocol buffers.
1944 return true;
1945 if (Style.Language == FormatStyle::LK_JavaScript && Right.is(tok::r_brace) &&
1946 Left.is(tok::l_brace) && !Left.Children.empty())
1947 // Support AllowShortFunctionsOnASingleLine for JavaScript.
1948 return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
1949 (Left.NestingLevel == 0 && Line.Level == 0 &&
1950 Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline);
1951 if (isAllmanBrace(Left) || isAllmanBrace(Right))
1952 return Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
1953 Style.BreakBeforeBraces == FormatStyle::BS_GNU;
1954 if (Style.Language == FormatStyle::LK_Proto && Left.isNot(tok::l_brace) &&
1955 Right.is(TT_SelectorName))
1956 return true;
1957 if (Left.is(TT_ObjCBlockLBrace) && !Style.AllowShortBlocksOnASingleLine)
1958 return true;
1959
1960 if ((Style.Language == FormatStyle::LK_Java ||
1961 Style.Language == FormatStyle::LK_JavaScript) &&
1962 Left.is(TT_LeadingJavaAnnotation) &&
1963 Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
1964 Line.Last->is(tok::l_brace))
1965 return true;
1966
1967 if (Style.Language == FormatStyle::LK_JavaScript) {
1968 // FIXME: This might apply to other languages and token kinds.
1969 if (Right.is(tok::char_constant) && Left.is(tok::plus) && Left.Previous &&
1970 Left.Previous->is(tok::char_constant))
1971 return true;
1972 if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace) &&
1973 Left.NestingLevel == 0 && Left.Previous &&
1974 Left.Previous->is(tok::equal) &&
1975 Line.First->isOneOf(tok::identifier, Keywords.kw_import,
1976 tok::kw_export) &&
1977 // kw_var is a pseudo-token that's a tok::identifier, so matches above.
1978 !Line.First->is(Keywords.kw_var))
1979 // Enum style object literal.
1980 return true;
1981 } else if (Style.Language == FormatStyle::LK_Java) {
1982 if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&
1983 Right.Next->is(tok::string_literal))
1984 return true;
1985 }
1986
1987 return false;
1988 }
1989
canBreakBefore(const AnnotatedLine & Line,const FormatToken & Right)1990 bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
1991 const FormatToken &Right) {
1992 const FormatToken &Left = *Right.Previous;
1993
1994 if (Style.Language == FormatStyle::LK_Java) {
1995 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
1996 Keywords.kw_implements))
1997 return false;
1998 if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
1999 Keywords.kw_implements))
2000 return true;
2001 }
2002
2003 if (Left.is(tok::at))
2004 return false;
2005 if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
2006 return false;
2007 if (Left.isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
2008 return !Right.is(tok::l_paren);
2009 if (Right.is(TT_PointerOrReference))
2010 return Line.IsMultiVariableDeclStmt ||
2011 (Style.PointerAlignment == FormatStyle::PAS_Right &&
2012 (!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
2013 if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2014 Right.is(tok::kw_operator))
2015 return true;
2016 if (Left.is(TT_PointerOrReference))
2017 return false;
2018 if (Right.isTrailingComment())
2019 // We rely on MustBreakBefore being set correctly here as we should not
2020 // change the "binding" behavior of a comment.
2021 // The first comment in a braced lists is always interpreted as belonging to
2022 // the first list element. Otherwise, it should be placed outside of the
2023 // list.
2024 return Left.BlockKind == BK_BracedInit;
2025 if (Left.is(tok::question) && Right.is(tok::colon))
2026 return false;
2027 if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
2028 return Style.BreakBeforeTernaryOperators;
2029 if (Left.is(TT_ConditionalExpr) || Left.is(tok::question))
2030 return !Style.BreakBeforeTernaryOperators;
2031 if (Right.is(TT_InheritanceColon))
2032 return true;
2033 if (Right.is(tok::colon) &&
2034 !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
2035 return false;
2036 if (Left.is(tok::colon) && (Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))
2037 return true;
2038 if (Right.is(TT_SelectorName))
2039 return true;
2040 if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty)
2041 return true;
2042 if (Left.ClosesTemplateDeclaration)
2043 return true;
2044 if (Right.isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
2045 TT_OverloadedOperator))
2046 return false;
2047 if (Left.is(TT_RangeBasedForLoopColon))
2048 return true;
2049 if (Right.is(TT_RangeBasedForLoopColon))
2050 return false;
2051 if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
2052 Left.is(tok::kw_operator))
2053 return false;
2054 if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl)
2055 return false;
2056 if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen))
2057 return false;
2058 if (Left.is(tok::l_paren) && Left.Previous &&
2059 (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen)))
2060 return false;
2061 if (Right.is(TT_ImplicitStringLiteral))
2062 return false;
2063
2064 if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser))
2065 return false;
2066
2067 // We only break before r_brace if there was a corresponding break before
2068 // the l_brace, which is tracked by BreakBeforeClosingBrace.
2069 if (Right.is(tok::r_brace))
2070 return Right.MatchingParen && Right.MatchingParen->BlockKind == BK_Block;
2071
2072 // Allow breaking after a trailing annotation, e.g. after a method
2073 // declaration.
2074 if (Left.is(TT_TrailingAnnotation))
2075 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
2076 tok::less, tok::coloncolon);
2077
2078 if (Right.is(tok::kw___attribute))
2079 return true;
2080
2081 if (Left.is(tok::identifier) && Right.is(tok::string_literal))
2082 return true;
2083
2084 if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
2085 return true;
2086
2087 if (Left.is(TT_CtorInitializerComma) &&
2088 Style.BreakConstructorInitializersBeforeComma)
2089 return false;
2090 if (Right.is(TT_CtorInitializerComma) &&
2091 Style.BreakConstructorInitializersBeforeComma)
2092 return true;
2093 if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
2094 (Left.is(tok::less) && Right.is(tok::less)))
2095 return false;
2096 if (Right.is(TT_BinaryOperator) &&
2097 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None &&
2098 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
2099 Right.getPrecedence() != prec::Assignment))
2100 return true;
2101 if (Left.is(TT_ArrayInitializerLSquare))
2102 return true;
2103 if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
2104 return true;
2105 if (Left.isBinaryOperator() && !Left.isOneOf(tok::arrowstar, tok::lessless) &&
2106 Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
2107 (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
2108 Left.getPrecedence() == prec::Assignment))
2109 return true;
2110 return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
2111 tok::kw_class, tok::kw_struct) ||
2112 Right.isMemberAccess() ||
2113 Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
2114 tok::colon, tok::l_square, tok::at) ||
2115 (Left.is(tok::r_paren) &&
2116 Right.isOneOf(tok::identifier, tok::kw_const)) ||
2117 (Left.is(tok::l_paren) && !Right.is(tok::r_paren));
2118 }
2119
printDebugInfo(const AnnotatedLine & Line)2120 void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) {
2121 llvm::errs() << "AnnotatedTokens:\n";
2122 const FormatToken *Tok = Line.First;
2123 while (Tok) {
2124 llvm::errs() << " M=" << Tok->MustBreakBefore
2125 << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type
2126 << " S=" << Tok->SpacesRequiredBefore
2127 << " B=" << Tok->BlockParameterCount
2128 << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName()
2129 << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind
2130 << " FakeLParens=";
2131 for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
2132 llvm::errs() << Tok->FakeLParens[i] << "/";
2133 llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n";
2134 if (!Tok->Next)
2135 assert(Tok == Line.Last);
2136 Tok = Tok->Next;
2137 }
2138 llvm::errs() << "----\n";
2139 }
2140
2141 } // namespace format
2142 } // namespace clang
2143