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