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