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