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