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