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