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 && 641 LeftOfParens->Type != TT_ObjCMethodExpr && Current.Next && 642 (Current.Next->is(tok::identifier))) 643 IsCast = true; 644 if (IsCast && !ParensAreEmpty) 645 Current.Type = TT_CastRParen; 646 } else if (Current.is(tok::at) && Current.Next) { 647 switch (Current.Next->Tok.getObjCKeywordID()) { 648 case tok::objc_interface: 649 case tok::objc_implementation: 650 case tok::objc_protocol: 651 Current.Type = TT_ObjCDecl; 652 break; 653 case tok::objc_property: 654 Current.Type = TT_ObjCProperty; 655 break; 656 default: 657 break; 658 } 659 } else if (Current.is(tok::period)) { 660 FormatToken *PreviousNoComment = Current.getPreviousNoneComment(); 661 if (PreviousNoComment && 662 PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) 663 Current.Type = TT_DesignatedInitializerPeriod; 664 } 665 } 666 } 667 668 /// \brief Return the type of the given token assuming it is * or &. 669 TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression) { 670 const FormatToken *PrevToken = Tok.getPreviousNoneComment(); 671 if (PrevToken == NULL) 672 return TT_UnaryOperator; 673 674 const FormatToken *NextToken = Tok.getNextNoneComment(); 675 if (NextToken == NULL) 676 return TT_Unknown; 677 678 if (PrevToken->is(tok::coloncolon) || 679 (PrevToken->is(tok::l_paren) && !IsExpression)) 680 return TT_PointerOrReference; 681 682 if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace, 683 tok::comma, tok::semi, tok::kw_return, tok::colon, 684 tok::equal, tok::kw_delete) || 685 PrevToken->Type == TT_BinaryOperator || 686 PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen) 687 return TT_UnaryOperator; 688 689 if (NextToken->is(tok::l_square)) 690 return TT_PointerOrReference; 691 692 if (PrevToken->Tok.isLiteral() || 693 PrevToken->isOneOf(tok::r_paren, tok::r_square) || 694 NextToken->Tok.isLiteral() || NextToken->isUnaryOperator()) 695 return TT_BinaryOperator; 696 697 // It is very unlikely that we are going to find a pointer or reference type 698 // definition on the RHS of an assignment. 699 if (IsExpression) 700 return TT_BinaryOperator; 701 702 return TT_PointerOrReference; 703 } 704 705 TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) { 706 const FormatToken *PrevToken = Tok.getPreviousNoneComment(); 707 if (PrevToken == NULL || PrevToken->Type == TT_CastRParen) 708 return TT_UnaryOperator; 709 710 // Use heuristics to recognize unary operators. 711 if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square, 712 tok::question, tok::colon, tok::kw_return, 713 tok::kw_case, tok::at, tok::l_brace)) 714 return TT_UnaryOperator; 715 716 // There can't be two consecutive binary operators. 717 if (PrevToken->Type == TT_BinaryOperator) 718 return TT_UnaryOperator; 719 720 // Fall back to marking the token as binary operator. 721 return TT_BinaryOperator; 722 } 723 724 /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 725 TokenType determineIncrementUsage(const FormatToken &Tok) { 726 const FormatToken *PrevToken = Tok.getPreviousNoneComment(); 727 if (PrevToken == NULL || PrevToken->Type == TT_CastRParen) 728 return TT_UnaryOperator; 729 if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier)) 730 return TT_TrailingUnaryOperator; 731 732 return TT_UnaryOperator; 733 } 734 735 // FIXME: This is copy&pasted from Sema. Put it in a common place and remove 736 // duplication. 737 /// \brief Determine whether the token kind starts a simple-type-specifier. 738 bool isSimpleTypeSpecifier(const FormatToken &Tok) const { 739 switch (Tok.Tok.getKind()) { 740 case tok::kw_short: 741 case tok::kw_long: 742 case tok::kw___int64: 743 case tok::kw___int128: 744 case tok::kw_signed: 745 case tok::kw_unsigned: 746 case tok::kw_void: 747 case tok::kw_char: 748 case tok::kw_int: 749 case tok::kw_half: 750 case tok::kw_float: 751 case tok::kw_double: 752 case tok::kw_wchar_t: 753 case tok::kw_bool: 754 case tok::kw___underlying_type: 755 case tok::annot_typename: 756 case tok::kw_char16_t: 757 case tok::kw_char32_t: 758 case tok::kw_typeof: 759 case tok::kw_decltype: 760 return true; 761 default: 762 return false; 763 } 764 } 765 766 SmallVector<Context, 8> Contexts; 767 768 AnnotatedLine &Line; 769 FormatToken *CurrentToken; 770 bool KeywordVirtualFound; 771 bool NameFound; 772 IdentifierInfo &Ident_in; 773 }; 774 775 /// \brief Parses binary expressions by inserting fake parenthesis based on 776 /// operator precedence. 777 class ExpressionParser { 778 public: 779 ExpressionParser(AnnotatedLine &Line) : Current(Line.First) { 780 // Skip leading "}", e.g. in "} else if (...) {". 781 if (Current->is(tok::r_brace)) 782 next(); 783 } 784 785 /// \brief Parse expressions with the given operatore precedence. 786 void parse(int Precedence = 0) { 787 // Conditional expressions need to be parsed separately for proper nesting. 788 if (Precedence == prec::Conditional + 1) { 789 parseConditionalExpr(); 790 return; 791 } 792 if (Precedence > prec::PointerToMember || Current == NULL) 793 return; 794 795 FormatToken *Start = Current; 796 bool OperatorFound = false; 797 798 while (Current) { 799 // Consume operators with higher precedence. 800 parse(Precedence + 1); 801 802 int CurrentPrecedence = 0; 803 if (Current) { 804 if (Current->Type == TT_ConditionalExpr) 805 CurrentPrecedence = 1 + (int)prec::Conditional; 806 else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon) 807 CurrentPrecedence = 1; 808 else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma)) 809 CurrentPrecedence = 1 + (int)Current->getPrecedence(); 810 } 811 812 // At the end of the line or when an operator with higher precedence is 813 // found, insert fake parenthesis and return. 814 if (Current == NULL || Current->closesScope() || 815 (CurrentPrecedence != 0 && CurrentPrecedence < Precedence)) { 816 if (OperatorFound) 817 addFakeParenthesis(Start, prec::Level(Precedence - 1)); 818 return; 819 } 820 821 // Consume scopes: (), [], <> and {} 822 if (Current->opensScope()) { 823 while (Current && !Current->closesScope()) { 824 next(); 825 parse(); 826 } 827 next(); 828 } else { 829 // Operator found. 830 if (CurrentPrecedence == Precedence) 831 OperatorFound = true; 832 833 next(); 834 } 835 } 836 } 837 838 private: 839 void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) { 840 Start->FakeLParens.push_back(Precedence); 841 if (Current) 842 ++Current->Previous->FakeRParens; 843 } 844 845 void parseConditionalExpr() { 846 FormatToken *Start = Current; 847 parse(prec::LogicalOr + 1); 848 if (!Current || !Current->is(tok::question)) 849 return; 850 next(); 851 parse(prec::LogicalOr + 1); 852 if (!Current || Current->Type != TT_ConditionalExpr) 853 return; 854 next(); 855 parseConditionalExpr(); 856 addFakeParenthesis(Start, prec::Conditional); 857 } 858 859 void next() { 860 if (Current) 861 Current = Current->Next; 862 while (Current && Current->isTrailingComment()) 863 Current = Current->Next; 864 } 865 866 FormatToken *Current; 867 }; 868 869 void TokenAnnotator::annotate(AnnotatedLine &Line) { 870 AnnotatingParser Parser(Line, Ident_in); 871 Line.Type = Parser.parseLine(); 872 if (Line.Type == LT_Invalid) 873 return; 874 875 ExpressionParser ExprParser(Line); 876 ExprParser.parse(); 877 878 if (Line.First->Type == TT_ObjCMethodSpecifier) 879 Line.Type = LT_ObjCMethodDecl; 880 else if (Line.First->Type == TT_ObjCDecl) 881 Line.Type = LT_ObjCDecl; 882 else if (Line.First->Type == TT_ObjCProperty) 883 Line.Type = LT_ObjCProperty; 884 885 Line.First->SpacesRequiredBefore = 1; 886 Line.First->CanBreakBefore = Line.First->MustBreakBefore; 887 } 888 889 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { 890 Line.First->TotalLength = Line.First->CodePointCount; 891 if (!Line.First->Next) 892 return; 893 FormatToken *Current = Line.First->Next; 894 while (Current != NULL) { 895 if (Current->Type == TT_LineComment) 896 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments; 897 else 898 Current->SpacesRequiredBefore = 899 spaceRequiredBefore(Line, *Current) ? 1 : 0; 900 901 if (Current->MustBreakBefore) { 902 } else if (Current->is(tok::comment)) { 903 Current->MustBreakBefore = Current->NewlinesBefore > 0; 904 } else if (Current->Previous->isTrailingComment() || 905 (Current->is(tok::string_literal) && 906 Current->Previous->is(tok::string_literal))) { 907 Current->MustBreakBefore = true; 908 } else if (Current->is(tok::lessless) && Current->Next && 909 Current->Previous->is(tok::string_literal) && 910 Current->Next->is(tok::string_literal)) { 911 Current->MustBreakBefore = true; 912 } else if (Current->Previous->ClosesTemplateDeclaration && 913 Style.AlwaysBreakTemplateDeclarations) { 914 Current->MustBreakBefore = true; 915 } else { 916 Current->MustBreakBefore = false; 917 } 918 Current->CanBreakBefore = 919 Current->MustBreakBefore || canBreakBefore(Line, *Current); 920 if (Current->MustBreakBefore) 921 Current->TotalLength = Current->Previous->TotalLength + Style.ColumnLimit; 922 else 923 Current->TotalLength = 924 Current->Previous->TotalLength + Current->CodePointCount + 925 Current->SpacesRequiredBefore; 926 // FIXME: Only calculate this if CanBreakBefore is true once static 927 // initializers etc. are sorted out. 928 // FIXME: Move magic numbers to a better place. 929 Current->SplitPenalty = 930 20 * Current->BindingStrength + splitPenalty(Line, *Current); 931 932 Current = Current->Next; 933 } 934 935 calculateUnbreakableTailLengths(Line); 936 DEBUG({ 937 printDebugInfo(Line); 938 }); 939 } 940 941 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) { 942 unsigned UnbreakableTailLength = 0; 943 FormatToken *Current = Line.Last; 944 while (Current != NULL) { 945 Current->UnbreakableTailLength = UnbreakableTailLength; 946 if (Current->CanBreakBefore || 947 Current->isOneOf(tok::comment, tok::string_literal)) { 948 UnbreakableTailLength = 0; 949 } else { 950 UnbreakableTailLength += 951 Current->CodePointCount + Current->SpacesRequiredBefore; 952 } 953 Current = Current->Previous; 954 } 955 } 956 957 unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, 958 const FormatToken &Tok) { 959 const FormatToken &Left = *Tok.Previous; 960 const FormatToken &Right = Tok; 961 962 if (Left.is(tok::semi)) 963 return 0; 964 if (Left.is(tok::comma)) 965 return 1; 966 967 if (Right.Type == TT_StartOfName) { 968 if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt) 969 return 3; 970 else if (Line.MightBeFunctionDecl && Right.BindingStrength == 1) 971 // FIXME: Clean up hack of using BindingStrength to find top-level names. 972 return Style.PenaltyReturnTypeOnItsOwnLine; 973 else 974 return 200; 975 } 976 if (Left.is(tok::equal) && Right.is(tok::l_brace)) 977 return 150; 978 if (Left.is(tok::coloncolon)) 979 return 500; 980 if (Left.isOneOf(tok::kw_class, tok::kw_struct)) 981 return 5000; 982 983 if (Left.Type == TT_RangeBasedForLoopColon || 984 Left.Type == TT_InheritanceColon) 985 return 2; 986 987 if (Right.isOneOf(tok::arrow, tok::period) && 988 Right.Type != TT_DesignatedInitializerPeriod) { 989 if (Line.Type == LT_BuilderTypeCall) 990 return prec::PointerToMember; 991 if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen && 992 Left.MatchingParen->ParameterCount > 0) 993 return 20; // Should be smaller than breaking at a nested comma. 994 return 150; 995 } 996 997 // Breaking before a trailing 'const' is bad. 998 if (Left.is(tok::r_paren) && Right.is(tok::kw_const)) 999 return 150; 1000 1001 // In for-loops, prefer breaking at ',' and ';'. 1002 if (Line.First->is(tok::kw_for) && Left.is(tok::equal)) 1003 return 4; 1004 1005 // In Objective-C method expressions, prefer breaking before "param:" over 1006 // breaking after it. 1007 if (Right.Type == TT_ObjCSelectorName) 1008 return 0; 1009 if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr) 1010 return 20; 1011 1012 if (Left.is(tok::l_paren) && Line.MightBeFunctionDecl) 1013 return 100; 1014 if (Left.opensScope()) 1015 return Left.ParameterCount > 1 ? prec::Comma : 20; 1016 1017 if (Right.is(tok::lessless)) { 1018 if (Left.is(tok::string_literal)) { 1019 StringRef Content = Left.TokenText; 1020 Content = Content.drop_back(1).drop_front(1).trim(); 1021 if (Content.size() > 1 && 1022 (Content.back() == ':' || Content.back() == '=')) 1023 return 20; 1024 } 1025 return prec::Shift; 1026 } 1027 if (Left.Type == TT_ConditionalExpr) 1028 return prec::Conditional; 1029 prec::Level Level = Left.getPrecedence(); 1030 1031 if (Level != prec::Unknown) 1032 return Level; 1033 1034 return 3; 1035 } 1036 1037 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 1038 const FormatToken &Left, 1039 const FormatToken &Right) { 1040 if (Right.is(tok::hashhash)) 1041 return Left.is(tok::hash); 1042 if (Left.isOneOf(tok::hashhash, tok::hash)) 1043 return Right.is(tok::hash); 1044 if (Right.isOneOf(tok::r_paren, tok::semi, tok::comma)) 1045 return false; 1046 if (Right.is(tok::less) && 1047 (Left.is(tok::kw_template) || 1048 (Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList))) 1049 return true; 1050 if (Left.is(tok::arrow) || Right.is(tok::arrow)) 1051 return false; 1052 if (Left.isOneOf(tok::exclaim, tok::tilde)) 1053 return false; 1054 if (Left.is(tok::at) && 1055 Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant, 1056 tok::numeric_constant, tok::l_paren, tok::l_brace, 1057 tok::kw_true, tok::kw_false)) 1058 return false; 1059 if (Left.is(tok::coloncolon)) 1060 return false; 1061 if (Right.is(tok::coloncolon)) 1062 return !Left.isOneOf(tok::identifier, tok::greater, tok::l_paren); 1063 if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) 1064 return false; 1065 if (Right.Type == TT_PointerOrReference) 1066 return Left.Tok.isLiteral() || 1067 ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) && 1068 !Style.PointerBindsToType); 1069 if (Right.Type == TT_FunctionTypeLParen && Left.isNot(tok::l_paren) && 1070 (Left.Type != TT_PointerOrReference || Style.PointerBindsToType)) 1071 return true; 1072 if (Left.Type == TT_PointerOrReference) 1073 return Right.Tok.isLiteral() || 1074 ((Right.Type != TT_PointerOrReference) && 1075 Right.isNot(tok::l_paren) && Style.PointerBindsToType && 1076 Left.Previous && 1077 !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon)); 1078 if (Right.is(tok::star) && Left.is(tok::l_paren)) 1079 return false; 1080 if (Left.is(tok::l_square)) 1081 return Left.Type == TT_ObjCArrayLiteral && Right.isNot(tok::r_square); 1082 if (Right.is(tok::r_square)) 1083 return Right.Type == TT_ObjCArrayLiteral; 1084 if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr) 1085 return false; 1086 if (Left.is(tok::colon)) 1087 return Left.Type != TT_ObjCMethodExpr; 1088 if (Right.is(tok::colon)) 1089 return Right.Type != TT_ObjCMethodExpr; 1090 if (Left.is(tok::l_paren)) 1091 return false; 1092 if (Right.is(tok::l_paren)) { 1093 return Line.Type == LT_ObjCDecl || 1094 Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch, 1095 tok::kw_return, tok::kw_catch, tok::kw_new, 1096 tok::kw_delete, tok::semi); 1097 } 1098 if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword) 1099 return false; 1100 if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) 1101 return false; // No spaces in "{}". 1102 if (Left.is(tok::l_brace) || Right.is(tok::r_brace)) 1103 return Style.SpacesInBracedLists; 1104 if (Right.Type == TT_UnaryOperator) 1105 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) && 1106 (Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr); 1107 if (Left.isOneOf(tok::identifier, tok::greater, tok::r_square) && 1108 Right.is(tok::l_brace) && Right.getNextNoneComment()) 1109 return false; 1110 if (Right.is(tok::ellipsis)) 1111 return false; 1112 if (Left.is(tok::period) || Right.is(tok::period)) 1113 return false; 1114 return true; 1115 } 1116 1117 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, 1118 const FormatToken &Tok) { 1119 if (Tok.Tok.getIdentifierInfo() && Tok.Previous->Tok.getIdentifierInfo()) 1120 return true; // Never ever merge two identifiers. 1121 if (Line.Type == LT_ObjCMethodDecl) { 1122 if (Tok.Previous->Type == TT_ObjCMethodSpecifier) 1123 return true; 1124 if (Tok.Previous->is(tok::r_paren) && Tok.is(tok::identifier)) 1125 // Don't space between ')' and <id> 1126 return false; 1127 } 1128 if (Line.Type == LT_ObjCProperty && 1129 (Tok.is(tok::equal) || Tok.Previous->is(tok::equal))) 1130 return false; 1131 1132 if (Tok.Previous->is(tok::comma)) 1133 return true; 1134 if (Tok.is(tok::comma)) 1135 return false; 1136 if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen) 1137 return true; 1138 if (Tok.Previous->Tok.is(tok::kw_operator)) 1139 return false; 1140 if (Tok.Type == TT_OverloadedOperatorLParen) 1141 return false; 1142 if (Tok.is(tok::colon)) 1143 return !Line.First->isOneOf(tok::kw_case, tok::kw_default) && 1144 Tok.getNextNoneComment() != NULL && Tok.Type != TT_ObjCMethodExpr; 1145 if (Tok.Previous->Type == TT_UnaryOperator || 1146 Tok.Previous->Type == TT_CastRParen) 1147 return false; 1148 if (Tok.Previous->is(tok::greater) && Tok.is(tok::greater)) { 1149 return Tok.Type == TT_TemplateCloser && 1150 Tok.Previous->Type == TT_TemplateCloser && 1151 Style.Standard != FormatStyle::LS_Cpp11; 1152 } 1153 if (Tok.isOneOf(tok::arrowstar, tok::periodstar) || 1154 Tok.Previous->isOneOf(tok::arrowstar, tok::periodstar)) 1155 return false; 1156 if (Tok.Type == TT_BinaryOperator || Tok.Previous->Type == TT_BinaryOperator) 1157 return true; 1158 if (Tok.Previous->Type == TT_TemplateCloser && Tok.is(tok::l_paren)) 1159 return false; 1160 if (Tok.is(tok::less) && Line.First->is(tok::hash)) 1161 return true; 1162 if (Tok.Type == TT_TrailingUnaryOperator) 1163 return false; 1164 return spaceRequiredBetween(Line, *Tok.Previous, Tok); 1165 } 1166 1167 bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 1168 const FormatToken &Right) { 1169 const FormatToken &Left = *Right.Previous; 1170 if (Right.Type == TT_StartOfName) 1171 return true; 1172 if (Right.is(tok::colon) && 1173 (Right.Type == TT_ObjCDictLiteral || Right.Type == TT_ObjCMethodExpr)) 1174 return false; 1175 if (Left.is(tok::colon) && 1176 (Left.Type == TT_ObjCDictLiteral || Left.Type == TT_ObjCMethodExpr)) 1177 return true; 1178 if (Right.Type == TT_ObjCSelectorName) 1179 return true; 1180 if (Left.ClosesTemplateDeclaration) 1181 return true; 1182 if (Right.Type == TT_ConditionalExpr || Right.is(tok::question)) 1183 return true; 1184 if (Right.Type == TT_RangeBasedForLoopColon || 1185 Right.Type == TT_OverloadedOperatorLParen) 1186 return false; 1187 if (Left.Type == TT_RangeBasedForLoopColon) 1188 return true; 1189 if (Right.Type == TT_RangeBasedForLoopColon) 1190 return false; 1191 if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser || 1192 Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr || 1193 Left.isOneOf(tok::question, tok::kw_operator)) 1194 return false; 1195 if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl) 1196 return false; 1197 if (Left.is(tok::l_paren) && Right.is(tok::l_paren) && Left.Previous && 1198 Left.Previous->is(tok::kw___attribute)) 1199 return false; 1200 1201 if (Right.isTrailingComment()) 1202 // We rely on MustBreakBefore being set correctly here as we should not 1203 // change the "binding" behavior of a comment. 1204 return false; 1205 1206 // We only break before r_brace if there was a corresponding break before 1207 // the l_brace, which is tracked by BreakBeforeClosingBrace. 1208 if (Right.isOneOf(tok::r_brace, tok::r_paren, tok::greater)) 1209 return false; 1210 1211 // Allow breaking after a trailing 'const', e.g. after a method declaration, 1212 // unless it is follow by ';', '{' or '='. 1213 if (Left.is(tok::kw_const) && Left.Previous != NULL && 1214 Left.Previous->is(tok::r_paren)) 1215 return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal); 1216 1217 if (Right.is(tok::kw___attribute)) 1218 return true; 1219 1220 if (Left.is(tok::identifier) && Right.is(tok::string_literal)) 1221 return true; 1222 return (Left.isBinaryOperator() && Left.isNot(tok::lessless)) || 1223 Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace, 1224 tok::kw_class, tok::kw_struct) || 1225 Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) || 1226 (Left.is(tok::r_paren) && Left.Type != TT_CastRParen && 1227 Right.isOneOf(tok::identifier, tok::kw_const, tok::kw___attribute)) || 1228 (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) || 1229 (Left.is(tok::l_square) && !Right.is(tok::r_square)); 1230 } 1231 1232 void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { 1233 llvm::errs() << "AnnotatedTokens:\n"; 1234 const FormatToken *Tok = Line.First; 1235 while (Tok) { 1236 llvm::errs() << " M=" << Tok->MustBreakBefore 1237 << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type << " S=" 1238 << Tok->SpacesRequiredBefore << " P=" << Tok->SplitPenalty 1239 << " Name=" << Tok->Tok.getName() << " FakeLParens="; 1240 for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i) 1241 llvm::errs() << Tok->FakeLParens[i] << "/"; 1242 llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n"; 1243 Tok = Tok->Next; 1244 } 1245 llvm::errs() << "----\n"; 1246 } 1247 1248 } // namespace format 1249 } // namespace clang 1250