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