18 #include "llvm/ADT/SmallPtrSet.h" 19 #include "llvm/Support/Debug.h" 21 #define DEBUG_TYPE "format-token-annotator" 33 class AnnotatingParser {
35 AnnotatingParser(
const FormatStyle &
Style, AnnotatedLine &
Line,
36 const AdditionalKeywords &Keywords)
37 :
Style(Style),
Line(Line), CurrentToken(Line.First), AutoFound(
false),
39 Contexts.push_back(Context(tok::unknown, 1,
false));
40 resetTokenMetadata(CurrentToken);
45 if (!CurrentToken || !CurrentToken->Previous)
47 if (NonTemplateLess.count(CurrentToken->Previous))
50 const FormatToken &
Previous = *CurrentToken->Previous;
51 if (Previous.Previous) {
52 if (Previous.Previous->Tok.isLiteral())
54 if (Previous.Previous->is(tok::r_paren) && Contexts.size() > 1 &&
55 (!Previous.Previous->MatchingParen ||
56 !Previous.Previous->MatchingParen->is(TT_OverloadedOperatorLParen)))
60 FormatToken *Left = CurrentToken->Previous;
61 Left->ParentBracket = Contexts.back().ContextKind;
62 ScopedContextCreator ContextCreator(*
this, tok::less, 12);
66 bool InExprContext = Contexts.back().IsExpression;
68 Contexts.back().IsExpression =
false;
71 Contexts.back().InTemplateArgument =
72 Left->Previous && Left->Previous->Tok.isNot(tok::kw_template);
75 CurrentToken->is(tok::question))
78 while (CurrentToken) {
79 if (CurrentToken->is(tok::greater)) {
80 Left->MatchingParen = CurrentToken;
81 CurrentToken->MatchingParen = Left;
82 CurrentToken->Type = TT_TemplateCloser;
86 if (CurrentToken->is(tok::question) &&
91 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
92 (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
102 if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
103 CurrentToken->Previous->is(TT_BinaryOperator) &&
104 Contexts[Contexts.size() - 2].IsExpression &&
105 !Line.startsWith(tok::kw_template))
107 updateParameterCount(Left, CurrentToken);
109 if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
110 if (CurrentToken->is(tok::colon) ||
111 (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
112 Previous->isNot(tok::colon)))
113 Previous->Type = TT_SelectorName;
122 bool parseParens(
bool LookForDecls =
false) {
125 FormatToken *Left = CurrentToken->Previous;
126 Left->ParentBracket = Contexts.back().ContextKind;
127 ScopedContextCreator ContextCreator(*
this, tok::l_paren, 1);
130 Contexts.back().ColonIsForRangeExpr =
131 Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
133 bool StartsObjCMethodExpr =
false;
134 if (CurrentToken->is(tok::caret)) {
136 Left->Type = TT_ObjCBlockLParen;
137 }
else if (FormatToken *MaybeSel = Left->Previous) {
139 if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
140 MaybeSel->Previous->is(tok::at)) {
141 StartsObjCMethodExpr =
true;
145 if (Left->is(TT_OverloadedOperatorLParen)) {
146 Contexts.back().IsExpression =
false;
148 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
149 Line.startsWith(tok::kw_export, Keywords.kw_type,
153 Contexts.back().IsExpression =
false;
154 }
else if (Left->Previous &&
155 (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype,
156 tok::kw_if, tok::kw_while, tok::l_paren,
158 Left->Previous->endsSequence(tok::kw_constexpr, tok::kw_if) ||
159 Left->Previous->is(TT_BinaryOperator))) {
161 Contexts.back().IsExpression =
true;
163 (Left->Previous->is(Keywords.kw_function) ||
164 (Left->Previous->endsSequence(tok::identifier,
165 Keywords.kw_function)))) {
167 Contexts.back().IsExpression =
false;
169 Left->Previous->is(TT_JsTypeColon)) {
171 Contexts.back().IsExpression =
false;
172 }
else if (Left->Previous && Left->Previous->is(tok::r_square) &&
173 Left->Previous->MatchingParen &&
174 Left->Previous->MatchingParen->is(TT_LambdaLSquare)) {
176 Contexts.back().IsExpression =
false;
177 }
else if (Line.InPPDirective &&
178 (!Left->Previous || !Left->Previous->is(tok::identifier))) {
179 Contexts.back().IsExpression =
true;
180 }
else if (Contexts[Contexts.size() - 2].CaretFound) {
182 Contexts.back().IsExpression =
false;
183 }
else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) {
184 Left->Type = TT_AttributeParen;
185 }
else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) {
187 Contexts.back().IsForEachMacro =
true;
188 Contexts.back().IsExpression =
false;
189 }
else if (Left->Previous && Left->Previous->MatchingParen &&
190 Left->Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
191 Contexts.back().IsExpression =
false;
192 }
else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
194 Left->Previous && Left->Previous->isOneOf(tok::kw_for, tok::kw_catch);
195 Contexts.back().IsExpression = !IsForOrCatch;
198 if (StartsObjCMethodExpr) {
199 Contexts.back().ColonIsObjCMethodExpr =
true;
200 Left->Type = TT_ObjCMethodExpr;
203 bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
204 bool ProbablyFunctionType = CurrentToken->isOneOf(tok::star, tok::amp);
205 bool HasMultipleLines =
false;
206 bool HasMultipleParametersOnALine =
false;
207 bool MightBeObjCForRangeLoop =
208 Left->Previous && Left->Previous->is(tok::kw_for);
209 while (CurrentToken) {
214 if (LookForDecls && CurrentToken->Next) {
215 FormatToken *Prev = CurrentToken->getPreviousNonComment();
217 FormatToken *PrevPrev = Prev->getPreviousNonComment();
218 FormatToken *Next = CurrentToken->Next;
219 if (PrevPrev && PrevPrev->is(tok::identifier) &&
220 Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
221 CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
222 Prev->Type = TT_BinaryOperator;
223 LookForDecls =
false;
228 if (CurrentToken->Previous->is(TT_PointerOrReference) &&
229 CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
231 ProbablyFunctionType =
true;
232 if (CurrentToken->is(tok::comma))
233 MightBeFunctionType =
false;
234 if (CurrentToken->Previous->is(TT_BinaryOperator))
235 Contexts.back().IsExpression =
true;
236 if (CurrentToken->is(tok::r_paren)) {
237 if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next &&
238 (CurrentToken->Next->is(tok::l_paren) ||
239 (CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration)))
240 Left->Type = TT_FunctionTypeLParen;
241 Left->MatchingParen = CurrentToken;
242 CurrentToken->MatchingParen = Left;
244 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_brace) &&
245 Left->Previous && Left->Previous->is(tok::l_paren)) {
250 if (
Tok->
is(TT_BinaryOperator) &&
251 Tok->
isOneOf(tok::star, tok::amp, tok::ampamp))
252 Tok->
Type = TT_PointerOrReference;
256 if (StartsObjCMethodExpr) {
257 CurrentToken->Type = TT_ObjCMethodExpr;
258 if (Contexts.back().FirstObjCSelectorName) {
259 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
260 Contexts.back().LongestObjCSelectorName;
264 if (Left->is(TT_AttributeParen))
265 CurrentToken->Type = TT_AttributeParen;
266 if (Left->Previous && Left->Previous->is(TT_JavaAnnotation))
267 CurrentToken->Type = TT_JavaAnnotation;
268 if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
269 CurrentToken->Type = TT_LeadingJavaAnnotation;
271 if (!HasMultipleLines)
273 else if (HasMultipleParametersOnALine)
281 if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
284 if (CurrentToken->is(tok::l_brace))
285 Left->Type = TT_Unknown;
286 if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
287 !CurrentToken->Next->HasUnescapedNewline &&
288 !CurrentToken->Next->isTrailingComment())
289 HasMultipleParametersOnALine =
true;
290 if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
291 CurrentToken->Previous->isSimpleTypeSpecifier()) &&
292 !CurrentToken->is(tok::l_brace))
293 Contexts.back().IsExpression =
false;
294 if (CurrentToken->isOneOf(tok::semi, tok::colon))
295 MightBeObjCForRangeLoop =
false;
296 if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in))
297 CurrentToken->Type = TT_ObjCForIn;
300 if (CurrentToken->is(tok::comma))
301 Contexts.back().CanBeExpression =
true;
303 FormatToken *
Tok = CurrentToken;
306 updateParameterCount(Left, Tok);
307 if (CurrentToken && CurrentToken->HasUnescapedNewline)
308 HasMultipleLines =
true;
320 FormatToken *Left = CurrentToken->Previous;
321 Left->ParentBracket = Contexts.back().ContextKind;
322 FormatToken *
Parent = Left->getPreviousNonComment();
327 bool CppArrayTemplates =
328 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
329 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
330 Contexts.back().InTemplateArgument);
332 bool StartsObjCMethodExpr =
333 !CppArrayTemplates && Style.isCpp() &&
334 Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
335 CurrentToken->isNot(tok::l_brace) &&
337 Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
338 tok::kw_return, tok::kw_throw) ||
339 Parent->isUnaryOperator() ||
340 Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
342 bool ColonFound =
false;
344 unsigned BindingIncrease = 1;
345 if (Left->isCppStructuredBinding(Style)) {
346 Left->Type = TT_StructuredBindingLSquare;
347 }
else if (Left->is(TT_Unknown)) {
348 if (StartsObjCMethodExpr) {
349 Left->Type = TT_ObjCMethodExpr;
351 Contexts.back().ContextKind == tok::l_brace &&
352 Parent->isOneOf(tok::l_brace, tok::comma)) {
353 Left->Type = TT_JsComputedPropertyName;
354 }
else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace &&
355 Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
356 Left->Type = TT_DesignatedInitializerLSquare;
357 }
else if (CurrentToken->is(tok::r_square) && Parent &&
358 Parent->is(TT_TemplateCloser)) {
359 Left->Type = TT_ArraySubscriptLSquare;
361 (!CppArrayTemplates && Parent &&
362 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
363 tok::comma, tok::l_paren, tok::l_square,
364 tok::question, tok::colon, tok::kw_return,
367 Left->Type = TT_ArrayInitializerLSquare;
369 BindingIncrease = 10;
370 Left->Type = TT_ArraySubscriptLSquare;
374 ScopedContextCreator ContextCreator(*
this, tok::l_square, BindingIncrease);
375 Contexts.back().IsExpression =
true;
377 Parent->is(TT_JsTypeColon))
378 Contexts.back().IsExpression =
false;
380 Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
382 while (CurrentToken) {
383 if (CurrentToken->is(tok::r_square)) {
384 if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) &&
385 Left->is(TT_ObjCMethodExpr)) {
388 StartsObjCMethodExpr =
false;
389 Left->Type = TT_Unknown;
391 if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
392 CurrentToken->Type = TT_ObjCMethodExpr;
396 if (Parent && Parent->is(TT_PointerOrReference))
397 Parent->Type = TT_BinaryOperator;
399 Left->MatchingParen = CurrentToken;
400 CurrentToken->MatchingParen = Left;
401 if (Contexts.back().FirstObjCSelectorName) {
402 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
403 Contexts.back().LongestObjCSelectorName;
404 if (Left->BlockParameterCount > 1)
405 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
410 if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
412 if (CurrentToken->is(tok::colon)) {
413 if (Left->isOneOf(TT_ArraySubscriptLSquare,
414 TT_DesignatedInitializerLSquare)) {
415 Left->Type = TT_ObjCMethodExpr;
416 StartsObjCMethodExpr =
true;
417 Contexts.back().ColonIsObjCMethodExpr =
true;
418 if (Parent && Parent->is(tok::r_paren))
419 Parent->Type = TT_CastRParen;
423 if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
425 Left->Type = TT_ArrayInitializerLSquare;
426 FormatToken *
Tok = CurrentToken;
429 updateParameterCount(Left,
Tok);
436 FormatToken *Left = CurrentToken->Previous;
437 Left->ParentBracket = Contexts.back().ContextKind;
439 if (Contexts.back().CaretFound)
440 Left->Type = TT_ObjCBlockLBrace;
441 Contexts.back().CaretFound =
false;
443 ScopedContextCreator ContextCreator(*
this, tok::l_brace, 1);
444 Contexts.back().ColonIsDictLiteral =
true;
446 Contexts.back().IsExpression =
true;
448 Left->Previous->is(TT_JsTypeColon))
449 Contexts.back().IsExpression =
false;
451 while (CurrentToken) {
452 if (CurrentToken->is(tok::r_brace)) {
453 Left->MatchingParen = CurrentToken;
454 CurrentToken->MatchingParen = Left;
458 if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
460 updateParameterCount(Left, CurrentToken);
461 if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
462 FormatToken *
Previous = CurrentToken->getPreviousNonComment();
463 if (Previous->is(TT_JsTypeOptionalQuestion))
464 Previous = Previous->getPreviousNonComment();
465 if (((CurrentToken->is(tok::colon) &&
466 (!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
469 (Previous->Tok.getIdentifierInfo() ||
470 Previous->is(tok::string_literal)))
471 Previous->Type = TT_SelectorName;
472 if (CurrentToken->is(tok::colon) ||
474 Left->Type = TT_DictLiteral;
476 if (CurrentToken->is(tok::comma) &&
478 Left->Type = TT_DictLiteral;
486 void updateParameterCount(FormatToken *Left, FormatToken *Current) {
487 if (Current->is(tok::l_brace) && Current->BlockKind ==
BK_Block)
488 ++Left->BlockParameterCount;
489 if (Current->is(tok::comma)) {
490 ++Left->ParameterCount;
492 Left->Role.reset(
new CommaSeparatedList(Style));
493 Left->Role->CommaFound(Current);
494 }
else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) {
495 Left->ParameterCount = 1;
499 bool parseConditional() {
500 while (CurrentToken) {
501 if (CurrentToken->is(tok::colon)) {
502 CurrentToken->Type = TT_ConditionalExpr;
512 bool parseTemplateDeclaration() {
513 if (CurrentToken && CurrentToken->is(tok::less)) {
514 CurrentToken->Type = TT_TemplateOpener;
519 CurrentToken->Previous->ClosesTemplateDeclaration =
true;
525 bool consumeToken() {
526 FormatToken *
Tok = CurrentToken;
528 switch (Tok->Tok.getKind()) {
531 if (!Tok->Previous && Line.MustBeDeclaration)
532 Tok->Type = TT_ObjCMethodSpecifier;
539 if (Contexts.back().ColonIsForRangeExpr ||
540 (Contexts.size() == 1 &&
541 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
542 Contexts.back().ContextKind == tok::l_paren ||
543 Contexts.back().ContextKind == tok::l_square ||
544 (!Contexts.back().IsExpression &&
545 Contexts.back().ContextKind == tok::l_brace) ||
546 (Contexts.size() == 1 &&
547 Line.MustBeDeclaration)) {
548 Contexts.back().IsExpression =
false;
549 Tok->Type = TT_JsTypeColon;
553 if (Contexts.back().ColonIsDictLiteral ||
556 Tok->Type = TT_DictLiteral;
558 if (FormatToken *
Previous = Tok->getPreviousNonComment())
561 }
else if (Contexts.back().ColonIsObjCMethodExpr ||
562 Line.startsWith(TT_ObjCMethodSpecifier)) {
563 Tok->Type = TT_ObjCMethodExpr;
564 const FormatToken *BeforePrevious = Tok->Previous->Previous;
565 if (!BeforePrevious ||
566 !(BeforePrevious->is(TT_CastRParen) ||
567 (BeforePrevious->is(TT_ObjCMethodExpr) &&
568 BeforePrevious->is(tok::colon))) ||
569 BeforePrevious->is(tok::r_square) ||
570 Contexts.back().LongestObjCSelectorName == 0) {
571 Tok->Previous->Type = TT_SelectorName;
572 if (Tok->Previous->ColumnWidth >
573 Contexts.back().LongestObjCSelectorName)
574 Contexts.back().LongestObjCSelectorName =
575 Tok->Previous->ColumnWidth;
576 if (!Contexts.back().FirstObjCSelectorName)
577 Contexts.back().FirstObjCSelectorName = Tok->Previous;
579 }
else if (Contexts.back().ColonIsForRangeExpr) {
580 Tok->Type = TT_RangeBasedForLoopColon;
581 }
else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
582 Tok->Type = TT_BitFieldColon;
583 }
else if (Contexts.size() == 1 &&
584 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
585 if (Tok->getPreviousNonComment()->isOneOf(tok::r_paren,
587 Tok->Type = TT_CtorInitializerColon;
589 Tok->Type = TT_InheritanceColon;
590 }
else if (Tok->Previous->is(tok::identifier) && Tok->Next &&
591 Tok->Next->isOneOf(tok::r_paren, tok::comma)) {
594 Tok->Type = TT_ObjCMethodExpr;
595 }
else if (Contexts.back().ContextKind == tok::l_paren) {
596 Tok->Type = TT_InlineASMColon;
604 !Contexts.back().IsExpression)
605 Tok->Type = TT_JsTypeOperator;
609 if (Tok->is(tok::kw_if) && CurrentToken &&
610 CurrentToken->is(tok::kw_constexpr))
612 if (CurrentToken && CurrentToken->is(tok::l_paren)) {
614 if (!parseParens(
true))
621 if ((Tok->Previous && Tok->Previous->is(tok::period)) ||
622 (Tok->Next && Tok->Next->is(tok::colon)))
625 if (CurrentToken && CurrentToken->is(Keywords.kw_await))
628 Contexts.back().ColonIsForRangeExpr =
true;
638 if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
639 Tok->Previous->MatchingParen &&
640 Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
641 Tok->Previous->Type = TT_OverloadedOperator;
642 Tok->Previous->MatchingParen->Type = TT_OverloadedOperator;
643 Tok->Type = TT_OverloadedOperatorLParen;
648 if (Line.MustBeDeclaration && Contexts.size() == 1 &&
649 !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
651 !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute,
652 TT_LeadingJavaAnnotation)))
653 Line.MightBeFunctionDecl =
true;
661 FormatToken *
Previous = Tok->getPreviousNonComment();
662 if (Previous && Previous->Type != TT_DictLiteral)
663 Previous->Type = TT_SelectorName;
670 Tok->Type = TT_TemplateOpener;
672 FormatToken *
Previous = Tok->getPreviousNonComment();
673 if (Previous && Previous->Type != TT_DictLiteral)
674 Previous->Type = TT_SelectorName;
677 Tok->Type = TT_BinaryOperator;
678 NonTemplateLess.insert(Tok);
692 Tok->Type = TT_BinaryOperator;
694 case tok::kw_operator:
695 while (CurrentToken &&
696 !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
697 if (CurrentToken->isOneOf(tok::star, tok::amp))
698 CurrentToken->Type = TT_PointerOrReference;
701 CurrentToken->Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator,
703 CurrentToken->Previous->Type = TT_OverloadedOperator;
706 CurrentToken->Type = TT_OverloadedOperatorLParen;
707 if (CurrentToken->Previous->is(TT_BinaryOperator))
708 CurrentToken->Previous->Type = TT_OverloadedOperator;
713 Tok->Next->isOneOf(tok::semi, tok::comma, tok::colon, tok::r_paren,
719 Tok->Type = TT_JsTypeOptionalQuestion;
724 if (Line.MustBeDeclaration && !Contexts.back().IsExpression &&
729 case tok::kw_template:
730 parseTemplateDeclaration();
733 if (Contexts.back().InCtorInitializer)
734 Tok->Type = TT_CtorInitializerComma;
735 else if (Contexts.back().InInheritanceList)
736 Tok->Type = TT_InheritanceComma;
737 else if (Contexts.back().FirstStartOfName &&
738 (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
739 Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt =
true;
740 Line.IsMultiVariableDeclStmt =
true;
742 if (Contexts.back().IsForEachMacro)
743 Contexts.back().IsExpression =
true;
745 case tok::identifier:
746 if (Tok->isOneOf(Keywords.kw___has_include,
747 Keywords.kw___has_include_next)) {
757 void parseIncludeDirective() {
758 if (CurrentToken && CurrentToken->is(tok::less)) {
760 while (CurrentToken) {
763 if (CurrentToken->isNot(tok::comment) &&
764 !CurrentToken->TokenText.startswith(
"//"))
765 CurrentToken->Type = TT_ImplicitStringLiteral;
771 void parseWarningOrError() {
776 while (CurrentToken) {
777 CurrentToken->Type = TT_ImplicitStringLiteral;
785 CurrentToken->isOneOf(Keywords.kw_mark, Keywords.kw_option)) {
786 bool IsMark = CurrentToken->is(Keywords.kw_mark);
789 while (CurrentToken) {
790 if (IsMark || CurrentToken->Previous->is(TT_BinaryOperator))
791 CurrentToken->Type = TT_ImplicitStringLiteral;
797 void parseHasInclude() {
798 if (!CurrentToken || !CurrentToken->is(tok::l_paren))
801 parseIncludeDirective();
805 LineType parsePreprocessorDirective() {
806 bool IsFirstToken = CurrentToken->IsFirst;
816 while (CurrentToken) {
818 CurrentToken->Type = TT_ImplicitStringLiteral;
824 if (CurrentToken->Tok.is(tok::numeric_constant)) {
825 CurrentToken->SpacesRequiredBefore = 1;
830 if (!CurrentToken->Tok.getIdentifierInfo())
832 switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
833 case tok::pp_include:
834 case tok::pp_include_next:
837 parseIncludeDirective();
841 case tok::pp_warning:
842 parseWarningOrError();
849 Contexts.back().IsExpression =
true;
855 while (CurrentToken) {
856 FormatToken *
Tok = CurrentToken;
858 if (Tok->is(tok::l_paren))
860 else if (Tok->isOneOf(Keywords.kw___has_include,
861 Keywords.kw___has_include_next))
869 NonTemplateLess.clear();
870 if (CurrentToken->is(tok::hash))
871 return parsePreprocessorDirective();
876 IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
878 CurrentToken->is(Keywords.kw_package)) ||
879 (Info && Info->getPPKeywordID() == tok::pp_import &&
880 CurrentToken->Next &&
881 CurrentToken->Next->isOneOf(tok::string_literal, tok::identifier,
884 parseIncludeDirective();
890 if (CurrentToken->is(tok::less) && Line.Last->is(tok::greater)) {
891 parseIncludeDirective();
898 CurrentToken->is(Keywords.kw_option)) {
900 if (CurrentToken && CurrentToken->is(tok::identifier))
904 bool KeywordVirtualFound =
false;
905 bool ImportStatement =
false;
909 CurrentToken->is(Keywords.kw_import))
910 ImportStatement =
true;
912 while (CurrentToken) {
913 if (CurrentToken->is(tok::kw_virtual))
914 KeywordVirtualFound =
true;
922 if (Line.First->is(tok::kw_export) &&
923 CurrentToken->is(Keywords.kw_from) && CurrentToken->Next &&
924 CurrentToken->Next->isStringLiteral())
925 ImportStatement =
true;
926 if (isClosureImportStatement(*CurrentToken))
927 ImportStatement =
true;
932 if (KeywordVirtualFound)
937 if (Line.startsWith(TT_ObjCMethodSpecifier)) {
938 if (Contexts.back().FirstObjCSelectorName)
939 Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
940 Contexts.back().LongestObjCSelectorName;
948 bool isClosureImportStatement(
const FormatToken &
Tok) {
951 return Tok.TokenText ==
"goog" && Tok.Next && Tok.Next->is(tok::period) &&
953 (Tok.Next->Next->TokenText ==
"module" ||
954 Tok.Next->Next->TokenText ==
"provide" ||
955 Tok.Next->Next->TokenText ==
"require" ||
956 Tok.Next->Next->TokenText ==
"forwardDeclare") &&
957 Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
960 void resetTokenMetadata(FormatToken *Token) {
966 if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro,
967 TT_FunctionLBrace, TT_ImplicitStringLiteral,
968 TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
969 TT_OverloadedOperator, TT_RegexLiteral,
970 TT_TemplateString, TT_ObjCStringLiteral))
971 CurrentToken->Type = TT_Unknown;
972 CurrentToken->Role.reset();
973 CurrentToken->MatchingParen =
nullptr;
974 CurrentToken->FakeLParens.clear();
975 CurrentToken->FakeRParens = 0;
980 CurrentToken->NestingLevel = Contexts.size() - 1;
981 CurrentToken->BindingStrength = Contexts.back().BindingStrength;
982 modifyContext(*CurrentToken);
983 determineTokenType(*CurrentToken);
984 CurrentToken = CurrentToken->Next;
987 resetTokenMetadata(CurrentToken);
1017 struct ScopedContextCreator {
1018 AnnotatingParser &
P;
1023 P.Contexts.push_back(Context(ContextKind,
1024 P.Contexts.back().BindingStrength + Increase,
1025 P.Contexts.back().IsExpression));
1028 ~ScopedContextCreator() { P.Contexts.pop_back(); }
1031 void modifyContext(
const FormatToken &Current) {
1033 !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) &&
1037 (Line.startsWith(Keywords.kw_type, tok::identifier) ||
1038 Line.startsWith(tok::kw_export, Keywords.kw_type,
1039 tok::identifier))) &&
1040 (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) {
1041 Contexts.back().IsExpression =
true;
1042 if (!Line.startsWith(TT_UnaryOperator)) {
1043 for (FormatToken *
Previous = Current.Previous;
1045 !
Previous->Previous->isOneOf(tok::comma, tok::semi);
1047 if (
Previous->isOneOf(tok::r_square, tok::r_paren)) {
1054 if (
Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
1055 Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
1057 Previous->Type = TT_PointerOrReference;
1060 }
else if (Current.is(tok::lessless) &&
1061 (!Current.Previous || !Current.Previous->is(tok::kw_operator))) {
1062 Contexts.back().IsExpression =
true;
1063 }
else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
1064 Contexts.back().IsExpression =
true;
1065 }
else if (Current.is(TT_TrailingReturnArrow)) {
1066 Contexts.back().IsExpression =
false;
1067 }
else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) {
1069 }
else if (Current.Previous &&
1070 Current.Previous->is(TT_CtorInitializerColon)) {
1071 Contexts.back().IsExpression =
true;
1072 Contexts.back().InCtorInitializer =
true;
1073 }
else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
1074 Contexts.back().InInheritanceList =
true;
1075 }
else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
1076 for (FormatToken *
Previous = Current.Previous;
1079 Previous->Type = TT_PointerOrReference;
1080 if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer)
1081 Contexts.back().IsExpression =
false;
1082 }
else if (Current.is(tok::kw_new)) {
1083 Contexts.back().CanBeExpression =
false;
1084 }
else if (Current.isOneOf(tok::semi, tok::exclaim)) {
1086 Contexts.back().IsExpression =
true;
1090 void determineTokenType(FormatToken &Current) {
1091 if (!Current.is(TT_Unknown))
1096 if (Current.is(tok::exclaim)) {
1097 if (Current.Previous &&
1098 (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace,
1099 tok::r_paren, tok::r_square,
1101 Current.Previous->Tok.isLiteral())) {
1102 Current.Type = TT_JsNonNullAssertion;
1106 Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
1107 Current.Type = TT_JsNonNullAssertion;
1116 if (Current.is(Keywords.kw_instanceof)) {
1117 Current.Type = TT_BinaryOperator;
1118 }
else if (isStartOfName(Current) &&
1119 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0)) {
1120 Contexts.back().FirstStartOfName = &Current;
1121 Current.Type = TT_StartOfName;
1122 }
else if (Current.is(tok::semi)) {
1126 Contexts.back().FirstStartOfName =
nullptr;
1127 }
else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
1129 }
else if (Current.is(tok::arrow) &&
1131 Current.Type = TT_LambdaArrow;
1132 }
else if (Current.is(tok::arrow) && AutoFound && Line.MustBeDeclaration &&
1133 Current.NestingLevel == 0) {
1134 Current.Type = TT_TrailingReturnArrow;
1135 }
else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
1136 Current.Type = determineStarAmpUsage(Current,
1137 Contexts.back().CanBeExpression &&
1138 Contexts.back().IsExpression,
1139 Contexts.back().InTemplateArgument);
1140 }
else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
1141 Current.Type = determinePlusMinusCaretUsage(Current);
1142 if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
1143 Contexts.back().CaretFound =
true;
1144 }
else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
1145 Current.Type = determineIncrementUsage(Current);
1146 }
else if (Current.isOneOf(tok::exclaim, tok::tilde)) {
1147 Current.Type = TT_UnaryOperator;
1148 }
else if (Current.is(tok::question)) {
1150 Line.MustBeDeclaration && !Contexts.back().IsExpression) {
1153 Current.Type = TT_JsTypeOptionalQuestion;
1155 Current.Type = TT_ConditionalExpr;
1157 }
else if (Current.isBinaryOperator() &&
1158 (!Current.Previous || Current.Previous->isNot(tok::l_square))) {
1159 Current.Type = TT_BinaryOperator;
1160 }
else if (Current.is(tok::comment)) {
1161 if (Current.TokenText.startswith(
"/*")) {
1162 if (Current.TokenText.endswith(
"*/"))
1163 Current.Type = TT_BlockComment;
1167 Current.Tok.setKind(tok::unknown);
1169 Current.Type = TT_LineComment;
1171 }
else if (Current.is(tok::r_paren)) {
1172 if (rParenEndsCast(Current))
1173 Current.Type = TT_CastRParen;
1174 if (Current.MatchingParen && Current.Next &&
1175 !Current.Next->isBinaryOperator() &&
1176 !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
1177 tok::comma, tok::period, tok::arrow,
1179 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
1181 if (AfterParen->Tok.isNot(tok::caret)) {
1182 if (FormatToken *BeforeParen = Current.MatchingParen->Previous)
1183 if (BeforeParen->is(tok::identifier) &&
1184 BeforeParen->TokenText == BeforeParen->TokenText.upper() &&
1185 (!BeforeParen->Previous ||
1186 BeforeParen->Previous->ClosesTemplateDeclaration))
1187 Current.Type = TT_FunctionAnnotationRParen;
1190 }
else if (Current.is(tok::at) && Current.Next &&
1195 switch (Current.Next->Tok.getObjCKeywordID()) {
1196 case tok::objc_interface:
1197 case tok::objc_implementation:
1198 case tok::objc_protocol:
1199 Current.Type = TT_ObjCDecl;
1201 case tok::objc_property:
1202 Current.Type = TT_ObjCProperty;
1207 }
else if (Current.is(tok::period)) {
1208 FormatToken *PreviousNoComment = Current.getPreviousNonComment();
1209 if (PreviousNoComment &&
1210 PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
1211 Current.Type = TT_DesignatedInitializerPeriod;
1213 Current.Previous->isOneOf(TT_JavaAnnotation,
1214 TT_LeadingJavaAnnotation)) {
1215 Current.Type = Current.Previous->Type;
1217 }
else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
1219 !Current.Previous->isOneOf(tok::equal, tok::at) &&
1220 Line.MightBeFunctionDecl && Contexts.size() == 1) {
1223 Current.Type = TT_TrailingAnnotation;
1227 if (Current.Previous->is(tok::at) &&
1228 Current.isNot(Keywords.kw_interface)) {
1229 const FormatToken &AtToken = *Current.Previous;
1230 const FormatToken *
Previous = AtToken.getPreviousNonComment();
1231 if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
1232 Current.Type = TT_LeadingJavaAnnotation;
1234 Current.Type = TT_JavaAnnotation;
1235 }
else if (Current.Previous->is(tok::period) &&
1236 Current.Previous->isOneOf(TT_JavaAnnotation,
1237 TT_LeadingJavaAnnotation)) {
1238 Current.Type = Current.Previous->Type;
1248 bool isStartOfName(
const FormatToken &Tok) {
1249 if (Tok.isNot(tok::identifier) || !Tok.Previous)
1252 if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
1256 Tok.Previous->is(Keywords.kw_in))
1260 FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
1261 while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
1262 PreviousNotConst = PreviousNotConst->getPreviousNonComment();
1264 if (!PreviousNotConst)
1267 bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
1268 PreviousNotConst->Previous &&
1269 PreviousNotConst->Previous->is(tok::hash);
1271 if (PreviousNotConst->is(TT_TemplateCloser))
1272 return PreviousNotConst && PreviousNotConst->MatchingParen &&
1273 PreviousNotConst->MatchingParen->Previous &&
1274 PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
1275 PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
1277 if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
1278 PreviousNotConst->MatchingParen->Previous &&
1279 PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
1282 return (!IsPPKeyword &&
1283 PreviousNotConst->isOneOf(tok::identifier, tok::kw_auto)) ||
1284 PreviousNotConst->is(TT_PointerOrReference) ||
1285 PreviousNotConst->isSimpleTypeSpecifier();
1289 bool rParenEndsCast(
const FormatToken &Tok) {
1295 if (Tok.Previous == Tok.MatchingParen || !Tok.Next || !Tok.MatchingParen)
1298 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
1302 if (LeftOfParens->is(tok::r_paren)) {
1303 if (!LeftOfParens->MatchingParen ||
1304 !LeftOfParens->MatchingParen->Previous)
1306 LeftOfParens = LeftOfParens->MatchingParen->Previous;
1311 if (LeftOfParens->Tok.getIdentifierInfo() &&
1312 !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
1318 if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator,
1319 TT_TemplateCloser, tok::ellipsis))
1323 if (Tok.Next->is(tok::question))
1332 if (Tok.Next->isNot(tok::string_literal) &&
1333 (Tok.Next->Tok.isLiteral() ||
1334 Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
1338 bool ParensAreType =
1340 Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) ||
1341 Tok.Previous->isSimpleTypeSpecifier();
1342 bool ParensCouldEndDecl =
1343 Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
1344 if (ParensAreType && !ParensCouldEndDecl)
1355 for (
const FormatToken *Token = Tok.MatchingParen->Next; Token != &Tok;
1356 Token = Token->Next)
1357 if (Token->is(TT_BinaryOperator))
1362 if (Tok.Next->isOneOf(tok::identifier, tok::kw_this))
1365 if (!Tok.Next->Next)
1372 Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star);
1373 if (!NextIsUnary || Tok.Next->is(tok::plus) ||
1374 !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant))
1377 for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen;
1378 Prev = Prev->Previous) {
1379 if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
1389 return TT_BinaryOperator;
1391 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1393 return TT_UnaryOperator;
1395 const FormatToken *NextToken = Tok.getNextNonComment();
1397 NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const) ||
1398 (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
1399 return TT_PointerOrReference;
1401 if (PrevToken->is(tok::coloncolon))
1402 return TT_PointerOrReference;
1404 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
1405 tok::comma, tok::semi, tok::kw_return, tok::colon,
1406 tok::equal, tok::kw_delete, tok::kw_sizeof,
1408 PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
1409 TT_UnaryOperator, TT_CastRParen))
1410 return TT_UnaryOperator;
1412 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
1413 return TT_PointerOrReference;
1415 return TT_PointerOrReference;
1416 if (NextToken->isOneOf(tok::comma, tok::semi))
1417 return TT_PointerOrReference;
1419 if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) {
1420 FormatToken *TokenBeforeMatchingParen =
1421 PrevToken->MatchingParen->getPreviousNonComment();
1422 if (TokenBeforeMatchingParen &&
1423 TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype))
1424 return TT_PointerOrReference;
1427 if (PrevToken->Tok.isLiteral() ||
1428 PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
1429 tok::kw_false, tok::r_brace) ||
1430 NextToken->Tok.isLiteral() ||
1431 NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
1432 NextToken->isUnaryOperator() ||
1436 (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
1437 return TT_BinaryOperator;
1440 if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
1441 return TT_BinaryOperator;
1445 const FormatToken *NextNextToken = NextToken->getNextNonComment();
1446 if (NextNextToken && NextNextToken->is(tok::arrow))
1447 return TT_BinaryOperator;
1451 if (IsExpression && !Contexts.back().CaretFound)
1452 return TT_BinaryOperator;
1454 return TT_PointerOrReference;
1457 TokenType determinePlusMinusCaretUsage(
const FormatToken &Tok) {
1458 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1460 return TT_UnaryOperator;
1462 if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator) &&
1463 !PrevToken->is(tok::exclaim))
1466 return TT_UnaryOperator;
1469 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
1470 tok::question, tok::colon, tok::kw_return,
1471 tok::kw_case, tok::at, tok::l_brace))
1472 return TT_UnaryOperator;
1475 if (PrevToken->is(TT_BinaryOperator))
1476 return TT_UnaryOperator;
1479 return TT_BinaryOperator;
1483 TokenType determineIncrementUsage(
const FormatToken &Tok) {
1484 const FormatToken *PrevToken = Tok.getPreviousNonComment();
1485 if (!PrevToken || PrevToken->is(TT_CastRParen))
1486 return TT_UnaryOperator;
1487 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
1488 return TT_TrailingUnaryOperator;
1490 return TT_UnaryOperator;
1493 SmallVector<Context, 8> Contexts;
1495 const FormatStyle &
Style;
1496 AnnotatedLine &
Line;
1497 FormatToken *CurrentToken;
1499 const AdditionalKeywords &Keywords;
1505 llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
1513 class ExpressionParser {
1515 ExpressionParser(
const FormatStyle &
Style,
const AdditionalKeywords &Keywords,
1516 AnnotatedLine &
Line)
1517 :
Style(Style), Keywords(Keywords), Current(Line.First) {}
1520 void parse(
int Precedence = 0) {
1523 while (Current && (Current->is(tok::kw_return) ||
1524 (Current->is(tok::colon) &&
1525 Current->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))))
1528 if (!Current || Precedence > PrecedenceArrowAndPeriod)
1533 parseConditionalExpr();
1539 if (Precedence == PrecedenceUnaryOperator) {
1540 parseUnaryOperator();
1544 FormatToken *Start = Current;
1545 FormatToken *LatestOperator =
nullptr;
1546 unsigned OperatorIndex = 0;
1550 parse(Precedence + 1);
1552 int CurrentPrecedence = getCurrentPrecedence();
1554 if (Current && Current->is(TT_SelectorName) &&
1555 Precedence == CurrentPrecedence) {
1557 addFakeParenthesis(Start,
prec::Level(Precedence));
1564 (Current->closesScope() &&
1565 (Current->MatchingParen || Current->is(TT_TemplateString))) ||
1566 (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
1573 if (Current->opensScope()) {
1576 while (Current && (!Current->closesScope() || Current->opensScope())) {
1583 if (CurrentPrecedence == Precedence) {
1585 LatestOperator->NextOperator = Current;
1586 LatestOperator = Current;
1587 Current->OperatorIndex = OperatorIndex;
1590 next(Precedence > 0);
1594 if (LatestOperator && (Current || Precedence > 0)) {
1596 if (Precedence == PrecedenceArrowAndPeriod) {
1600 addFakeParenthesis(Start,
prec::Level(Precedence));
1608 int getCurrentPrecedence() {
1610 const FormatToken *NextNonComment = Current->getNextNonComment();
1611 if (Current->is(TT_ConditionalExpr))
1613 if (NextNonComment && Current->is(TT_SelectorName) &&
1614 (NextNonComment->isOneOf(TT_DictLiteral, TT_JsTypeColon) ||
1617 NextNonComment->is(tok::less))))
1619 if (Current->is(TT_JsComputedPropertyName))
1621 if (Current->is(TT_LambdaArrow))
1623 if (Current->is(TT_JsFatArrow))
1625 if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
1626 (Current->is(tok::comment) && NextNonComment &&
1627 NextNonComment->is(TT_SelectorName)))
1629 if (Current->is(TT_RangeBasedForLoopColon))
1633 Current->is(Keywords.kw_instanceof))
1636 Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
1638 if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
1639 return Current->getPrecedence();
1640 if (Current->isOneOf(tok::period, tok::arrow))
1641 return PrecedenceArrowAndPeriod;
1644 Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
1645 Keywords.kw_throws))
1651 void addFakeParenthesis(FormatToken *Start,
prec::Level Precedence) {
1652 Start->FakeLParens.push_back(Precedence);
1654 Start->StartsBinaryExpression =
true;
1656 FormatToken *
Previous = Current->Previous;
1657 while (Previous->is(tok::comment) && Previous->Previous)
1658 Previous = Previous->Previous;
1659 ++Previous->FakeRParens;
1661 Previous->EndsBinaryExpression =
true;
1667 void parseUnaryOperator() {
1669 while (Current && Current->is(TT_UnaryOperator)) {
1670 Tokens.push_back(Current);
1673 parse(PrecedenceArrowAndPeriod);
1674 for (FormatToken *Token : llvm::reverse(Tokens))
1679 void parseConditionalExpr() {
1680 while (Current && Current->isTrailingComment()) {
1683 FormatToken *Start = Current;
1685 if (!Current || !Current->is(tok::question))
1689 if (!Current || Current->isNot(TT_ConditionalExpr))
1696 void next(
bool SkipPastLeadingComments =
true) {
1698 Current = Current->Next;
1700 (Current->NewlinesBefore == 0 || SkipPastLeadingComments) &&
1701 Current->isTrailingComment())
1702 Current = Current->Next;
1705 const FormatStyle &
Style;
1706 const AdditionalKeywords &Keywords;
1707 FormatToken *Current;
1718 bool CommentLine =
true;
1720 if (!
Tok->
is(tok::comment)) {
1721 CommentLine =
false;
1728 if (NextNonCommentLine && CommentLine &&
1731 (*I)->First->OriginalColumn) {
1737 : NextNonCommentLine->
Level;
1739 NextNonCommentLine = (*I)->
First->
isNot(tok::r_brace) ? (*I) :
nullptr;
1742 setCommentLineLevels((*I)->Children);
1747 unsigned Result = 0;
1760 Line.
Type = Parser.parseLine();
1772 ExpressionParser ExprParser(
Style, Keywords, Line);
1791 for (; Next; Next = Next->Next) {
1792 if (Next->is(TT_OverloadedOperatorLParen))
1794 if (Next->is(TT_OverloadedOperator))
1796 if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
1798 if (Next->Next && Next->Next->is(tok::l_square) && Next->Next->Next &&
1799 Next->Next->Next->is(tok::r_square))
1800 Next = Next->Next->Next;
1811 if (Current.
is(tok::kw_operator)) {
1814 Next = skipOperatorName(Next);
1818 for (; Next; Next = Next->
Next) {
1819 if (Next->
is(TT_TemplateOpener)) {
1821 }
else if (Next->
is(tok::coloncolon)) {
1825 if (Next->
is(tok::kw_operator)) {
1826 Next = skipOperatorName(Next->
Next);
1829 if (!Next->
is(tok::identifier))
1831 }
else if (Next->
is(tok::l_paren)) {
1843 if (Line.
Last->
is(tok::l_brace))
1858 Tok->
isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
1860 if (
Tok->
isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) ||
1894 calculateFormattingInformation(**I);
1904 Current->
Type = TT_FunctionDeclarationName;
1905 if (Current->
is(TT_LineComment)) {
1922 if (
Parameter->isOneOf(tok::comment, tok::r_brace))
1925 if (!
Parameter->Previous->is(TT_CtorInitializerComma) &&
1933 spaceRequiredBefore(Line, *Current)) {
1941 Current->
is(TT_FunctionDeclarationName))
1946 unsigned ChildSize = 0;
1955 Prev->
Children[0]->First->MustBreakBefore) ||
1962 if (Current->
is(TT_CtorInitializerColon))
1963 InFunctionDecl =
false;
1969 splitPenalty(Line, *Current, InFunctionDecl);
1971 Current = Current->
Next;
1974 calculateUnbreakableTailLengths(Line);
1975 unsigned IndentLevel = Line.
Level;
1976 for (Current = Line.
First; Current !=
nullptr; Current = Current->
Next) {
1978 Current->
Role->precomputeFormattingInfos(Current);
1981 assert(IndentLevel > 0);
1992 void TokenAnnotator::calculateUnbreakableTailLengths(
AnnotatedLine &Line) {
1993 unsigned UnbreakableTailLength = 0;
1998 Current->
isOneOf(tok::comment, tok::string_literal)) {
1999 UnbreakableTailLength = 0;
2001 UnbreakableTailLength +=
2008 unsigned TokenAnnotator::splitPenalty(
const AnnotatedLine &Line,
2010 bool InFunctionDecl) {
2014 if (Left.
is(tok::semi))
2018 if (Right.
isOneOf(Keywords.kw_extends, Keywords.kw_throws))
2020 if (Right.
is(Keywords.kw_implements))
2025 if (Right.
is(Keywords.kw_function) && Left.
isNot(tok::comma))
2027 if (Left.
is(TT_JsTypeColon))
2029 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2030 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2037 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
2039 if (Right.
is(tok::l_square)) {
2042 if (Left.
is(tok::r_square))
2045 if (Right.
is(TT_LambdaLSquare) && Left.
is(tok::equal))
2047 if (!Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2048 TT_ArrayInitializerLSquare,
2049 TT_DesignatedInitializerLSquare))
2053 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2054 Right.
is(tok::kw_operator)) {
2057 if (Left.
is(TT_StartOfName))
2063 if (Right.
is(TT_PointerOrReference))
2065 if (Right.
is(TT_LambdaArrow))
2067 if (Left.
is(tok::equal) && Right.
is(tok::l_brace))
2069 if (Left.
is(TT_CastRParen))
2071 if (Left.
is(tok::coloncolon) ||
2074 if (Left.
isOneOf(tok::kw_class, tok::kw_struct))
2076 if (Left.
is(tok::comment))
2079 if (Left.
isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
2080 TT_CtorInitializerColon))
2108 if (Right.
is(TT_TrailingAnnotation) &&
2119 bool is_short_annotation = Right.
TokenText.size() < 10;
2120 return (Left.
is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
2124 if (Line.
startsWith(tok::kw_for) && Left.
is(tok::equal))
2129 if (Right.
is(TT_SelectorName))
2131 if (Left.
is(tok::colon) && Left.
is(TT_ObjCMethodExpr))
2134 if (Left.
is(tok::l_paren) && InFunctionDecl &&
2137 if (Left.
is(tok::l_paren) && Left.
Previous &&
2141 if (Left.
is(tok::equal) && InFunctionDecl)
2143 if (Right.
is(tok::r_brace))
2145 if (Left.
is(TT_TemplateOpener))
2153 if (Left.
is(TT_JavaAnnotation))
2163 if (Left.
is(tok::comma))
2168 if (Right.
is(tok::lessless)) {
2175 if (Left.
is(TT_ConditionalExpr))
2188 bool TokenAnnotator::spaceRequiredBetween(
const AnnotatedLine &Line,
2191 if (Left.
is(tok::kw_return) && Right.
isNot(tok::semi))
2198 if (Right.
is(tok::hashhash))
2199 return Left.
is(tok::hash);
2200 if (Left.
isOneOf(tok::hashhash, tok::hash))
2201 return Right.
is(tok::hash);
2202 if (Left.
is(tok::l_paren) && Right.
is(tok::r_paren))
2204 if (Left.
is(tok::l_paren) || Right.
is(tok::r_paren))
2205 return (Right.
is(TT_CastRParen) ||
2209 if (Right.
isOneOf(tok::semi, tok::comma))
2214 if (Right.
is(tok::less) && Left.
is(tok::kw_template))
2216 if (Left.
isOneOf(tok::exclaim, tok::tilde))
2218 if (Left.
is(tok::at) &&
2219 Right.
isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
2220 tok::numeric_constant, tok::l_paren, tok::l_brace,
2221 tok::kw_true, tok::kw_false))
2223 if (Left.
is(tok::colon))
2224 return !Left.
is(TT_ObjCMethodExpr);
2225 if (Left.
is(tok::coloncolon))
2227 if (Left.
is(tok::less) || Right.
isOneOf(tok::greater, tok::less))
2229 if (Right.
is(tok::ellipsis))
2232 if (Left.
is(tok::l_square) && Right.
is(tok::amp))
2234 if (Right.
is(TT_PointerOrReference)) {
2240 if (!TokenBeforeMatchingParen ||
2241 !TokenBeforeMatchingParen->
isOneOf(tok::kw_typeof, tok::kw_decltype))
2245 (!Left.
isOneOf(TT_PointerOrReference, tok::l_paren) &&
2251 if (Right.
is(TT_FunctionTypeLParen) && Left.
isNot(tok::l_paren) &&
2252 (!Left.
is(TT_PointerOrReference) ||
2256 if (Left.
is(TT_PointerOrReference))
2258 (Right.
isOneOf(Keywords.kw_override, Keywords.kw_final) &&
2259 !Right.
is(TT_StartOfName)) ||
2261 (!Right.
isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
2267 if (Right.
is(tok::star) && Left.
is(tok::l_paren))
2269 if (Left.
is(tok::l_square))
2270 return (Left.
is(TT_ArrayInitializerLSquare) &&
2272 (Left.
isOneOf(TT_ArraySubscriptLSquare,
2273 TT_StructuredBindingLSquare) &&
2275 if (Right.
is(tok::r_square))
2281 TT_StructuredBindingLSquare)));
2282 if (Right.
is(tok::l_square) &&
2283 !Right.
isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
2284 TT_DesignatedInitializerLSquare,
2285 TT_StructuredBindingLSquare) &&
2286 !Left.
isOneOf(tok::numeric_constant, TT_DictLiteral))
2288 if (Left.
is(tok::l_brace) && Right.
is(tok::r_brace))
2294 if (Left.
is(TT_BlockComment))
2296 if (Right.
is(tok::l_paren)) {
2297 if (Left.
is(tok::r_paren) && Left.
is(TT_AttributeParen))
2301 (Left.
isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while,
2302 tok::kw_switch, tok::kw_case, TT_ForEachMacro,
2305 (Left.
isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
2306 tok::kw_new, tok::kw_delete) &&
2310 Left.
is(tok::r_paren)) &&
2315 if (Right.
is(TT_UnaryOperator))
2316 return !Left.
isOneOf(tok::l_paren, tok::l_square, tok::at) &&
2317 (Left.
isNot(tok::colon) || Left.
isNot(TT_ObjCMethodExpr));
2318 if ((Left.
isOneOf(tok::identifier, tok::greater, tok::r_square,
2324 if (Left.
is(tok::period) || Right.
is(tok::period))
2326 if (Right.
is(tok::hash) && Left.
is(tok::identifier) && Left.
TokenText ==
"L")
2333 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_square))
2338 bool TokenAnnotator::spaceRequiredBefore(
const AnnotatedLine &Line,
2344 if (Left.
is(tok::kw_operator))
2345 return Right.
is(tok::coloncolon);
2348 if (Right.
is(tok::period) &&
2349 Left.
isOneOf(Keywords.kw_optional, Keywords.kw_required,
2350 Keywords.kw_repeated, Keywords.kw_extend))
2352 if (Right.
is(tok::l_paren) &&
2353 Left.
isOneOf(Keywords.kw_returns, Keywords.kw_option))
2355 if (Right.
isOneOf(tok::l_brace, tok::less) && Left.
is(TT_SelectorName))
2358 if (Left.
is(TT_JsFatArrow))
2361 if (Right.
is(tok::l_paren) && Left.
is(Keywords.kw_await) && Left.
Previous &&
2364 if (Left.
is(Keywords.kw_async) && Right.
is(tok::l_paren) &&
2369 if (Next && Next->
is(TT_JsFatArrow))
2372 if ((Left.
is(TT_TemplateString) && Left.
TokenText.endswith(
"${")) ||
2373 (Right.
is(TT_TemplateString) && Right.
TokenText.startswith(
"}")))
2378 if (Left.
is(tok::identifier) && Keywords.IsJavaScriptIdentifier(Left) &&
2379 Right.
is(TT_TemplateString))
2381 if (Right.
is(tok::star) &&
2382 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield))
2384 if (Right.
isOneOf(tok::l_brace, tok::l_square) &&
2385 Left.
isOneOf(Keywords.kw_function, Keywords.kw_yield,
2386 Keywords.kw_extends, Keywords.kw_implements))
2388 if (Right.
is(tok::l_paren)) {
2398 if (Left.
isOneOf(tok::kw_throw, Keywords.kw_await, Keywords.kw_typeof,
2402 if ((Left.
isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in,
2413 Left.
Previous->
is(tok::period) && Right.
is(tok::l_paren))
2415 if (Left.
is(Keywords.kw_as) &&
2416 Right.
isOneOf(tok::l_square, tok::l_brace, tok::l_paren))
2418 if (Left.
is(tok::kw_default) && Left.
Previous &&
2421 if (Left.
is(Keywords.kw_is) && Right.
is(tok::l_brace))
2423 if (Right.
isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
2425 if (Left.
is(TT_JsTypeOperator) || Right.
is(TT_JsTypeOperator))
2427 if ((Left.
is(tok::l_brace) || Right.
is(tok::r_brace)) &&
2428 Line.
First->
isOneOf(Keywords.kw_import, tok::kw_export))
2430 if (Left.
is(tok::ellipsis))
2432 if (Left.
is(TT_TemplateCloser) &&
2433 !Right.
isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
2434 Keywords.kw_implements, Keywords.kw_extends))
2439 if (Right.
is(TT_JsNonNullAssertion))
2441 if (Left.
is(TT_JsNonNullAssertion) &&
2442 Right.
isOneOf(Keywords.kw_as, Keywords.kw_in))
2445 if (Left.
is(tok::r_square) && Right.
is(tok::l_brace))
2447 if (Left.
is(Keywords.kw_synchronized) && Right.
is(tok::l_paren))
2449 if ((Left.
isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
2450 tok::kw_protected) ||
2451 Left.
isOneOf(Keywords.kw_final, Keywords.kw_abstract,
2452 Keywords.kw_native)) &&
2453 Right.
is(TT_TemplateOpener))
2456 if (Left.
is(TT_ImplicitStringLiteral))
2459 if (Left.
is(TT_ObjCMethodSpecifier))
2461 if (Left.
is(tok::r_paren) && Right.
is(tok::identifier))
2466 (Right.
is(tok::equal) || Left.
is(tok::equal)))
2469 if (Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
2470 Left.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
2472 if (Right.
is(TT_OverloadedOperatorLParen))
2474 if (Left.
is(tok::comma))
2476 if (Right.
is(tok::comma))
2478 if (Right.
isOneOf(TT_CtorInitializerColon, TT_ObjCBlockLParen))
2480 if (Right.
is(tok::colon)) {
2481 if (Line.
First->
isOneOf(tok::kw_case, tok::kw_default) ||
2484 if (Right.
is(TT_ObjCMethodExpr))
2486 if (Left.
is(tok::question))
2488 if (Right.
is(TT_InlineASMColon) && Left.
is(tok::coloncolon))
2490 if (Right.
is(TT_DictLiteral))
2494 if (Left.
is(TT_UnaryOperator))
2495 return Right.
is(TT_BinaryOperator);
2499 if (Left.
is(TT_CastRParen))
2501 Right.
isOneOf(TT_BinaryOperator, TT_SelectorName);
2503 if (Left.
is(tok::greater) && Right.
is(tok::greater))
2504 return Right.
is(TT_TemplateCloser) && Left.
is(TT_TemplateCloser) &&
2506 if (Right.
isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
2507 Left.
isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
2508 (Right.
is(tok::period) && Right.
isNot(TT_DesignatedInitializerPeriod)))
2513 if (Right.
is(tok::coloncolon) && Left.
is(tok::identifier))
2518 if (Right.
is(tok::coloncolon) && !Left.
isOneOf(tok::l_brace, tok::comment))
2519 return (Left.
is(TT_TemplateOpener) &&
2521 !(Left.
isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
2522 tok::kw___super, TT_TemplateCloser,
2523 TT_TemplateOpener));
2524 if ((Left.
is(TT_TemplateOpener)) != (Right.
is(TT_TemplateCloser)))
2527 if (Right.
is(TT_StructuredBindingLSquare))
2528 return !Left.
isOneOf(tok::amp, tok::ampamp) ||
2531 if (Right.
Next && Right.
Next->
is(TT_StructuredBindingLSquare) &&
2532 Right.
isOneOf(tok::amp, tok::ampamp))
2534 if ((Right.
is(TT_BinaryOperator) && !Left.
is(tok::l_paren)) ||
2535 (Left.
isOneOf(TT_BinaryOperator, TT_ConditionalExpr) &&
2536 !Right.
is(tok::r_paren)))
2538 if (Left.
is(TT_TemplateCloser) && Right.
is(tok::l_paren) &&
2539 Right.
isNot(TT_FunctionTypeLParen))
2541 if (Right.
is(TT_TemplateOpener) && Left.
is(tok::r_paren) &&
2544 if (Right.
is(tok::less) && Left.
isNot(tok::l_paren) &&
2547 if (Right.
is(TT_TrailingUnaryOperator))
2549 if (Left.
is(TT_RegexLiteral))
2551 return spaceRequiredBetween(Line, Left, Right);
2557 !Tok.
isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
2560 bool TokenAnnotator::mustBreakBefore(
const AnnotatedLine &Line,
2568 if (Right.
is(tok::string_literal) && Left.
is(tok::plus) && Left.
Previous &&
2571 if (Left.
is(TT_DictLiteral) && Left.
is(tok::l_brace) && Line.
Level == 0 &&
2573 Line.
First->
isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export,
2577 !Line.
First->
isOneOf(Keywords.kw_var, Keywords.kw_let))
2581 if (Left.
is(tok::l_brace) && Line.
Level == 0 &&
2583 Line.
startsWith(tok::kw_const, tok::kw_enum) ||
2584 Line.
startsWith(tok::kw_export, tok::kw_enum) ||
2585 Line.
startsWith(tok::kw_export, tok::kw_const, tok::kw_enum)))
2589 if (Right.
is(tok::r_brace) && Left.
is(tok::l_brace) &&
2598 if (Right.
is(tok::plus) && Left.
is(tok::string_literal) && Right.
Next &&
2599 Right.
Next->
is(tok::string_literal))
2614 if ((Left.
isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
2616 Left.
is(tok::l_paren))) &&
2621 TT_ArrayInitializerLSquare) ||
2624 BeforeClosingBrace = &Left;
2625 if (BeforeClosingBrace && (BeforeClosingBrace->
is(tok::comma) ||
2630 if (Right.
is(tok::comment))
2632 Left.
isNot(TT_CtorInitializerColon) &&
2638 if (Right.
is(tok::lessless) && Right.
Next &&
2640 Right.
Next->
is(tok::string_literal))
2647 if (Right.
is(TT_CtorInitializerComma) &&
2651 if (Right.
is(TT_CtorInitializerColon) &&
2658 if (Right.
is(tok::string_literal) && Right.
TokenText.startswith(
"R\""))
2671 if (Right.
is(TT_InlineASMBrace))
2675 (Line.
startsWith(tok::kw_typedef, tok::kw_enum) &&
2684 Left.
is(TT_LeadingJavaAnnotation) &&
2685 Right.
isNot(TT_LeadingJavaAnnotation) && Right.
isNot(tok::l_paren) &&
2692 bool TokenAnnotator::canBreakBefore(
const AnnotatedLine &Line,
2698 if (Left.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
2699 Keywords.kw_implements))
2701 if (Right.
isOneOf(Keywords.kw_throws, Keywords.kw_extends,
2702 Keywords.kw_implements))
2708 tok::kw_return, Keywords.kw_yield, tok::kw_continue, tok::kw_break,
2709 tok::kw_throw, Keywords.kw_interface, Keywords.kw_type,
2710 tok::kw_static, tok::kw_public, tok::kw_private, tok::kw_protected,
2711 Keywords.kw_readonly, Keywords.kw_abstract, Keywords.kw_get,
2712 Keywords.kw_set, Keywords.kw_async, Keywords.kw_await))
2717 if (Left.
is(TT_JsFatArrow) && Right.
is(tok::l_brace))
2719 if (Left.
is(TT_JsTypeColon))
2723 if (Left.
is(Keywords.kw_in))
2725 if (Right.
is(Keywords.kw_in))
2727 if (Right.
is(Keywords.kw_as))
2729 if (Left.
is(Keywords.kw_as))
2731 if (Left.
is(TT_JsNonNullAssertion))
2733 if (Left.
is(Keywords.kw_declare) &&
2734 Right.
isOneOf(Keywords.kw_module, tok::kw_namespace,
2735 Keywords.kw_function, tok::kw_class, tok::kw_enum,
2736 Keywords.kw_interface, Keywords.kw_type, Keywords.kw_var,
2737 Keywords.kw_let, tok::kw_const))
2741 if (Left.
isOneOf(Keywords.kw_module, tok::kw_namespace) &&
2742 Right.
isOneOf(tok::identifier, tok::string_literal))
2750 if (Left.
is(tok::at))
2754 if (Left.
isOneOf(TT_JavaAnnotation, TT_LeadingJavaAnnotation))
2755 return !Right.
is(tok::l_paren);
2756 if (Right.
is(TT_PointerOrReference))
2759 (!Right.
Next || Right.
Next->
isNot(TT_FunctionDeclarationName)));
2760 if (Right.
isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
2761 Right.
is(tok::kw_operator))
2763 if (Left.
is(TT_PointerOrReference))
2772 (Left.
is(TT_CtorInitializerColon) &&
2774 if (Left.
is(tok::question) && Right.
is(tok::colon))
2776 if (Right.
is(TT_ConditionalExpr) || Right.
is(tok::question))
2778 if (Left.
is(TT_ConditionalExpr) || Left.
is(tok::question))
2780 if (Right.
is(TT_InheritanceColon))
2782 if (Right.
is(TT_ObjCMethodExpr) && !Right.
is(tok::r_square) &&
2783 Left.
isNot(TT_SelectorName))
2785 if (Right.
is(tok::colon) &&
2786 !Right.
isOneOf(TT_CtorInitializerColon, TT_InlineASMColon))
2788 if (Left.
is(tok::colon) && Left.
isOneOf(TT_DictLiteral, TT_ObjCMethodExpr))
2790 if (Right.
is(TT_SelectorName) || (Right.
is(tok::identifier) && Right.
Next &&
2791 Right.
Next->
is(TT_ObjCMethodExpr)))
2792 return Left.
isNot(tok::period);
2797 if (Right.
isOneOf(TT_RangeBasedForLoopColon, TT_OverloadedOperatorLParen,
2798 TT_OverloadedOperator))
2800 if (Left.
is(TT_RangeBasedForLoopColon))
2802 if (Right.
is(TT_RangeBasedForLoopColon))
2804 if (Left.
is(TT_TemplateCloser) && Right.
is(TT_TemplateOpener))
2806 if (Left.
isOneOf(TT_TemplateCloser, TT_UnaryOperator) ||
2807 Left.
is(tok::kw_operator))
2809 if (Left.
is(tok::equal) && !Right.
isOneOf(tok::kw_default, tok::kw_delete) &&
2812 if (Left.
is(tok::l_paren) && Left.
is(TT_AttributeParen))
2814 if (Left.
is(tok::l_paren) && Left.
Previous &&
2817 if (Right.
is(TT_ImplicitStringLiteral))
2820 if (Right.
is(tok::r_paren) || Right.
is(TT_TemplateCloser))
2828 if (Right.
is(tok::r_brace))
2833 if (Left.
is(TT_TrailingAnnotation))
2834 return !Right.
isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
2835 tok::less, tok::coloncolon);
2837 if (Right.
is(tok::kw___attribute))
2840 if (Left.
is(tok::identifier) && Right.
is(tok::string_literal))
2843 if (Right.
is(tok::identifier) && Right.
Next && Right.
Next->
is(TT_DictLiteral))
2846 if (Left.
is(TT_CtorInitializerColon))
2848 if (Right.
is(TT_CtorInitializerColon))
2850 if (Left.
is(TT_CtorInitializerComma) &&
2853 if (Right.
is(TT_CtorInitializerComma) &&
2860 if ((Left.
is(tok::greater) && Right.
is(tok::greater)) ||
2861 (Left.
is(tok::less) && Right.
is(tok::less)))
2863 if (Right.
is(TT_BinaryOperator) &&
2868 if (Left.
is(TT_ArrayInitializerLSquare))
2870 if (Right.
is(tok::kw_typename) && Left.
isNot(tok::kw_const))
2873 !Left.
isOneOf(tok::arrowstar, tok::lessless) &&
2878 return Left.
isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
2879 tok::kw_class, tok::kw_struct, tok::comment) ||
2881 Right.
isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
2882 tok::colon, tok::l_square, tok::at) ||
2883 (Left.
is(tok::r_paren) &&
2884 Right.
isOneOf(tok::identifier, tok::kw_const)) ||
2885 (Left.
is(tok::l_paren) && !Right.
is(tok::r_paren)) ||
2886 (Left.
is(TT_TemplateOpener) && !Right.
is(TT_TemplateCloser));
2889 void TokenAnnotator::printDebugInfo(
const AnnotatedLine &Line) {
2890 llvm::errs() <<
"AnnotatedTokens(L=" << Line.
Level <<
"):\n";
2900 <<
" PPK=" << Tok->
PackingKind <<
" FakeLParens=";
2901 for (
unsigned i = 0, e = Tok->
FakeLParens.size(); i != e; ++i)
2903 llvm::errs() <<
" FakeRParens=" << Tok->
FakeRParens;
2904 llvm::errs() <<
" Text='" << Tok->
TokenText <<
"'\n";
2906 assert(Tok == Line.
Last);
2909 llvm::errs() <<
"----\n";
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
Defines the SourceManager interface.
Parser - This implements a parser for the C family of languages.
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
tok::TokenKind ContextKind
This file implements a token annotator, i.e.
const char * getName() const
const AnnotatedLine * Line
FormatToken * FirstStartOfName
SourceLocation getEnd() const
IdentifierInfo * getIdentifierInfo() const
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
bool ColonIsObjCMethodExpr
Dataflow Directional Tag Classes.
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
FormatToken * FirstObjCSelectorName
The parameter type of a method or function.
unsigned LongestObjCSelectorName
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
SourceLocation getBegin() const