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