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