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