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