ParseTentative.cpp revision 212904
1//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===// 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// This file implements the tentative parsing portions of the Parser 11// interfaces, for ambiguity resolution. 12// 13//===----------------------------------------------------------------------===// 14 15#include "clang/Parse/Parser.h" 16#include "clang/Parse/ParseDiagnostic.h" 17#include "clang/Sema/ParsedTemplate.h" 18using namespace clang; 19 20/// isCXXDeclarationStatement - C++-specialized function that disambiguates 21/// between a declaration or an expression statement, when parsing function 22/// bodies. Returns true for declaration, false for expression. 23/// 24/// declaration-statement: 25/// block-declaration 26/// 27/// block-declaration: 28/// simple-declaration 29/// asm-definition 30/// namespace-alias-definition 31/// using-declaration 32/// using-directive 33/// [C++0x] static_assert-declaration 34/// 35/// asm-definition: 36/// 'asm' '(' string-literal ')' ';' 37/// 38/// namespace-alias-definition: 39/// 'namespace' identifier = qualified-namespace-specifier ';' 40/// 41/// using-declaration: 42/// 'using' typename[opt] '::'[opt] nested-name-specifier 43/// unqualified-id ';' 44/// 'using' '::' unqualified-id ; 45/// 46/// using-directive: 47/// 'using' 'namespace' '::'[opt] nested-name-specifier[opt] 48/// namespace-name ';' 49/// 50bool Parser::isCXXDeclarationStatement() { 51 switch (Tok.getKind()) { 52 // asm-definition 53 case tok::kw_asm: 54 // namespace-alias-definition 55 case tok::kw_namespace: 56 // using-declaration 57 // using-directive 58 case tok::kw_using: 59 // static_assert-declaration 60 case tok::kw_static_assert: 61 return true; 62 // simple-declaration 63 default: 64 return isCXXSimpleDeclaration(); 65 } 66} 67 68/// isCXXSimpleDeclaration - C++-specialized function that disambiguates 69/// between a simple-declaration or an expression-statement. 70/// If during the disambiguation process a parsing error is encountered, 71/// the function returns true to let the declaration parsing code handle it. 72/// Returns false if the statement is disambiguated as expression. 73/// 74/// simple-declaration: 75/// decl-specifier-seq init-declarator-list[opt] ';' 76/// 77bool Parser::isCXXSimpleDeclaration() { 78 // C++ 6.8p1: 79 // There is an ambiguity in the grammar involving expression-statements and 80 // declarations: An expression-statement with a function-style explicit type 81 // conversion (5.2.3) as its leftmost subexpression can be indistinguishable 82 // from a declaration where the first declarator starts with a '('. In those 83 // cases the statement is a declaration. [Note: To disambiguate, the whole 84 // statement might have to be examined to determine if it is an 85 // expression-statement or a declaration]. 86 87 // C++ 6.8p3: 88 // The disambiguation is purely syntactic; that is, the meaning of the names 89 // occurring in such a statement, beyond whether they are type-names or not, 90 // is not generally used in or changed by the disambiguation. Class 91 // templates are instantiated as necessary to determine if a qualified name 92 // is a type-name. Disambiguation precedes parsing, and a statement 93 // disambiguated as a declaration may be an ill-formed declaration. 94 95 // We don't have to parse all of the decl-specifier-seq part. There's only 96 // an ambiguity if the first decl-specifier is 97 // simple-type-specifier/typename-specifier followed by a '(', which may 98 // indicate a function-style cast expression. 99 // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such 100 // a case. 101 102 TPResult TPR = isCXXDeclarationSpecifier(); 103 if (TPR != TPResult::Ambiguous()) 104 return TPR != TPResult::False(); // Returns true for TPResult::True() or 105 // TPResult::Error(). 106 107 // FIXME: Add statistics about the number of ambiguous statements encountered 108 // and how they were resolved (number of declarations+number of expressions). 109 110 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 111 // We need tentative parsing... 112 113 TentativeParsingAction PA(*this); 114 115 TPR = TryParseSimpleDeclaration(); 116 SourceLocation TentativeParseLoc = Tok.getLocation(); 117 118 PA.Revert(); 119 120 // In case of an error, let the declaration parsing code handle it. 121 if (TPR == TPResult::Error()) 122 return true; 123 124 // Declarations take precedence over expressions. 125 if (TPR == TPResult::Ambiguous()) 126 TPR = TPResult::True(); 127 128 assert(TPR == TPResult::True() || TPR == TPResult::False()); 129 return TPR == TPResult::True(); 130} 131 132/// simple-declaration: 133/// decl-specifier-seq init-declarator-list[opt] ';' 134/// 135Parser::TPResult Parser::TryParseSimpleDeclaration() { 136 // We know that we have a simple-type-specifier/typename-specifier followed 137 // by a '('. 138 assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous()); 139 140 if (Tok.is(tok::kw_typeof)) 141 TryParseTypeofSpecifier(); 142 else 143 ConsumeToken(); 144 145 assert(Tok.is(tok::l_paren) && "Expected '('"); 146 147 TPResult TPR = TryParseInitDeclaratorList(); 148 if (TPR != TPResult::Ambiguous()) 149 return TPR; 150 151 if (Tok.isNot(tok::semi)) 152 return TPResult::False(); 153 154 return TPResult::Ambiguous(); 155} 156 157/// init-declarator-list: 158/// init-declarator 159/// init-declarator-list ',' init-declarator 160/// 161/// init-declarator: 162/// declarator initializer[opt] 163/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 164/// 165/// initializer: 166/// '=' initializer-clause 167/// '(' expression-list ')' 168/// 169/// initializer-clause: 170/// assignment-expression 171/// '{' initializer-list ','[opt] '}' 172/// '{' '}' 173/// 174Parser::TPResult Parser::TryParseInitDeclaratorList() { 175 while (1) { 176 // declarator 177 TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 178 if (TPR != TPResult::Ambiguous()) 179 return TPR; 180 181 // [GNU] simple-asm-expr[opt] attributes[opt] 182 if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 183 return TPResult::True(); 184 185 // initializer[opt] 186 if (Tok.is(tok::l_paren)) { 187 // Parse through the parens. 188 ConsumeParen(); 189 if (!SkipUntil(tok::r_paren)) 190 return TPResult::Error(); 191 } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { 192 // MSVC and g++ won't examine the rest of declarators if '=' is 193 // encountered; they just conclude that we have a declaration. 194 // EDG parses the initializer completely, which is the proper behavior 195 // for this case. 196 // 197 // At present, Clang follows MSVC and g++, since the parser does not have 198 // the ability to parse an expression fully without recording the 199 // results of that parse. 200 // Also allow 'in' after on objective-c declaration as in: 201 // for (int (^b)(void) in array). Ideally this should be done in the 202 // context of parsing for-init-statement of a foreach statement only. But, 203 // in any other context 'in' is invalid after a declaration and parser 204 // issues the error regardless of outcome of this decision. 205 // FIXME. Change if above assumption does not hold. 206 return TPResult::True(); 207 } 208 209 if (Tok.isNot(tok::comma)) 210 break; 211 ConsumeToken(); // the comma. 212 } 213 214 return TPResult::Ambiguous(); 215} 216 217/// isCXXConditionDeclaration - Disambiguates between a declaration or an 218/// expression for a condition of a if/switch/while/for statement. 219/// If during the disambiguation process a parsing error is encountered, 220/// the function returns true to let the declaration parsing code handle it. 221/// 222/// condition: 223/// expression 224/// type-specifier-seq declarator '=' assignment-expression 225/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 226/// '=' assignment-expression 227/// 228bool Parser::isCXXConditionDeclaration() { 229 TPResult TPR = isCXXDeclarationSpecifier(); 230 if (TPR != TPResult::Ambiguous()) 231 return TPR != TPResult::False(); // Returns true for TPResult::True() or 232 // TPResult::Error(). 233 234 // FIXME: Add statistics about the number of ambiguous statements encountered 235 // and how they were resolved (number of declarations+number of expressions). 236 237 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 238 // We need tentative parsing... 239 240 TentativeParsingAction PA(*this); 241 242 // type-specifier-seq 243 if (Tok.is(tok::kw_typeof)) 244 TryParseTypeofSpecifier(); 245 else 246 ConsumeToken(); 247 assert(Tok.is(tok::l_paren) && "Expected '('"); 248 249 // declarator 250 TPR = TryParseDeclarator(false/*mayBeAbstract*/); 251 252 // In case of an error, let the declaration parsing code handle it. 253 if (TPR == TPResult::Error()) 254 TPR = TPResult::True(); 255 256 if (TPR == TPResult::Ambiguous()) { 257 // '=' 258 // [GNU] simple-asm-expr[opt] attributes[opt] 259 if (Tok.is(tok::equal) || 260 Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 261 TPR = TPResult::True(); 262 else 263 TPR = TPResult::False(); 264 } 265 266 PA.Revert(); 267 268 assert(TPR == TPResult::True() || TPR == TPResult::False()); 269 return TPR == TPResult::True(); 270} 271 272 /// \brief Determine whether the next set of tokens contains a type-id. 273 /// 274 /// The context parameter states what context we're parsing right 275 /// now, which affects how this routine copes with the token 276 /// following the type-id. If the context is TypeIdInParens, we have 277 /// already parsed the '(' and we will cease lookahead when we hit 278 /// the corresponding ')'. If the context is 279 /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 280 /// before this template argument, and will cease lookahead when we 281 /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 282 /// and false for an expression. If during the disambiguation 283 /// process a parsing error is encountered, the function returns 284 /// true to let the declaration parsing code handle it. 285 /// 286 /// type-id: 287 /// type-specifier-seq abstract-declarator[opt] 288 /// 289bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 290 291 isAmbiguous = false; 292 293 // C++ 8.2p2: 294 // The ambiguity arising from the similarity between a function-style cast and 295 // a type-id can occur in different contexts. The ambiguity appears as a 296 // choice between a function-style cast expression and a declaration of a 297 // type. The resolution is that any construct that could possibly be a type-id 298 // in its syntactic context shall be considered a type-id. 299 300 TPResult TPR = isCXXDeclarationSpecifier(); 301 if (TPR != TPResult::Ambiguous()) 302 return TPR != TPResult::False(); // Returns true for TPResult::True() or 303 // TPResult::Error(). 304 305 // FIXME: Add statistics about the number of ambiguous statements encountered 306 // and how they were resolved (number of declarations+number of expressions). 307 308 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 309 // We need tentative parsing... 310 311 TentativeParsingAction PA(*this); 312 313 // type-specifier-seq 314 if (Tok.is(tok::kw_typeof)) 315 TryParseTypeofSpecifier(); 316 else 317 ConsumeToken(); 318 assert(Tok.is(tok::l_paren) && "Expected '('"); 319 320 // declarator 321 TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 322 323 // In case of an error, let the declaration parsing code handle it. 324 if (TPR == TPResult::Error()) 325 TPR = TPResult::True(); 326 327 if (TPR == TPResult::Ambiguous()) { 328 // We are supposed to be inside parens, so if after the abstract declarator 329 // we encounter a ')' this is a type-id, otherwise it's an expression. 330 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 331 TPR = TPResult::True(); 332 isAmbiguous = true; 333 334 // We are supposed to be inside a template argument, so if after 335 // the abstract declarator we encounter a '>', '>>' (in C++0x), or 336 // ',', this is a type-id. Otherwise, it's an expression. 337 } else if (Context == TypeIdAsTemplateArgument && 338 (Tok.is(tok::greater) || Tok.is(tok::comma) || 339 (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) { 340 TPR = TPResult::True(); 341 isAmbiguous = true; 342 343 } else 344 TPR = TPResult::False(); 345 } 346 347 PA.Revert(); 348 349 assert(TPR == TPResult::True() || TPR == TPResult::False()); 350 return TPR == TPResult::True(); 351} 352 353/// isCXX0XAttributeSpecifier - returns true if this is a C++0x 354/// attribute-specifier. By default, unless in Obj-C++, only a cursory check is 355/// performed that will simply return true if a [[ is seen. Currently C++ has no 356/// syntactical ambiguities from this check, but it may inhibit error recovery. 357/// If CheckClosing is true, a check is made for closing ]] brackets. 358/// 359/// If given, After is set to the token after the attribute-specifier so that 360/// appropriate parsing decisions can be made; it is left untouched if false is 361/// returned. 362/// 363/// FIXME: If an error is in the closing ]] brackets, the program assumes 364/// the absence of an attribute-specifier, which can cause very yucky errors 365/// to occur. 366/// 367/// [C++0x] attribute-specifier: 368/// '[' '[' attribute-list ']' ']' 369/// 370/// [C++0x] attribute-list: 371/// attribute[opt] 372/// attribute-list ',' attribute[opt] 373/// 374/// [C++0x] attribute: 375/// attribute-token attribute-argument-clause[opt] 376/// 377/// [C++0x] attribute-token: 378/// identifier 379/// attribute-scoped-token 380/// 381/// [C++0x] attribute-scoped-token: 382/// attribute-namespace '::' identifier 383/// 384/// [C++0x] attribute-namespace: 385/// identifier 386/// 387/// [C++0x] attribute-argument-clause: 388/// '(' balanced-token-seq ')' 389/// 390/// [C++0x] balanced-token-seq: 391/// balanced-token 392/// balanced-token-seq balanced-token 393/// 394/// [C++0x] balanced-token: 395/// '(' balanced-token-seq ')' 396/// '[' balanced-token-seq ']' 397/// '{' balanced-token-seq '}' 398/// any token but '(', ')', '[', ']', '{', or '}' 399bool Parser::isCXX0XAttributeSpecifier (bool CheckClosing, 400 tok::TokenKind *After) { 401 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) 402 return false; 403 404 // No tentative parsing if we don't need to look for ]] 405 if (!CheckClosing && !getLang().ObjC1) 406 return true; 407 408 struct TentativeReverter { 409 TentativeParsingAction PA; 410 411 TentativeReverter (Parser& P) 412 : PA(P) 413 {} 414 ~TentativeReverter () { 415 PA.Revert(); 416 } 417 } R(*this); 418 419 // Opening brackets were checked for above. 420 ConsumeBracket(); 421 ConsumeBracket(); 422 423 // SkipUntil will handle balanced tokens, which are guaranteed in attributes. 424 SkipUntil(tok::r_square, false); 425 426 if (Tok.isNot(tok::r_square)) 427 return false; 428 ConsumeBracket(); 429 430 if (After) 431 *After = Tok.getKind(); 432 433 return true; 434} 435 436/// declarator: 437/// direct-declarator 438/// ptr-operator declarator 439/// 440/// direct-declarator: 441/// declarator-id 442/// direct-declarator '(' parameter-declaration-clause ')' 443/// cv-qualifier-seq[opt] exception-specification[opt] 444/// direct-declarator '[' constant-expression[opt] ']' 445/// '(' declarator ')' 446/// [GNU] '(' attributes declarator ')' 447/// 448/// abstract-declarator: 449/// ptr-operator abstract-declarator[opt] 450/// direct-abstract-declarator 451/// 452/// direct-abstract-declarator: 453/// direct-abstract-declarator[opt] 454/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 455/// exception-specification[opt] 456/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 457/// '(' abstract-declarator ')' 458/// 459/// ptr-operator: 460/// '*' cv-qualifier-seq[opt] 461/// '&' 462/// [C++0x] '&&' [TODO] 463/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 464/// 465/// cv-qualifier-seq: 466/// cv-qualifier cv-qualifier-seq[opt] 467/// 468/// cv-qualifier: 469/// 'const' 470/// 'volatile' 471/// 472/// declarator-id: 473/// id-expression 474/// 475/// id-expression: 476/// unqualified-id 477/// qualified-id [TODO] 478/// 479/// unqualified-id: 480/// identifier 481/// operator-function-id [TODO] 482/// conversion-function-id [TODO] 483/// '~' class-name [TODO] 484/// template-id [TODO] 485/// 486Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 487 bool mayHaveIdentifier) { 488 // declarator: 489 // direct-declarator 490 // ptr-operator declarator 491 492 while (1) { 493 if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 494 if (TryAnnotateCXXScopeToken(true)) 495 return TPResult::Error(); 496 497 if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 498 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 499 // ptr-operator 500 ConsumeToken(); 501 while (Tok.is(tok::kw_const) || 502 Tok.is(tok::kw_volatile) || 503 Tok.is(tok::kw_restrict)) 504 ConsumeToken(); 505 } else { 506 break; 507 } 508 } 509 510 // direct-declarator: 511 // direct-abstract-declarator: 512 513 if ((Tok.is(tok::identifier) || 514 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) && 515 mayHaveIdentifier) { 516 // declarator-id 517 if (Tok.is(tok::annot_cxxscope)) 518 ConsumeToken(); 519 ConsumeToken(); 520 } else if (Tok.is(tok::l_paren)) { 521 ConsumeParen(); 522 if (mayBeAbstract && 523 (Tok.is(tok::r_paren) || // 'int()' is a function. 524 Tok.is(tok::ellipsis) || // 'int(...)' is a function. 525 isDeclarationSpecifier())) { // 'int(int)' is a function. 526 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 527 // exception-specification[opt] 528 TPResult TPR = TryParseFunctionDeclarator(); 529 if (TPR != TPResult::Ambiguous()) 530 return TPR; 531 } else { 532 // '(' declarator ')' 533 // '(' attributes declarator ')' 534 // '(' abstract-declarator ')' 535 if (Tok.is(tok::kw___attribute)) 536 return TPResult::True(); // attributes indicate declaration 537 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 538 if (TPR != TPResult::Ambiguous()) 539 return TPR; 540 if (Tok.isNot(tok::r_paren)) 541 return TPResult::False(); 542 ConsumeParen(); 543 } 544 } else if (!mayBeAbstract) { 545 return TPResult::False(); 546 } 547 548 while (1) { 549 TPResult TPR(TPResult::Ambiguous()); 550 551 if (Tok.is(tok::l_paren)) { 552 // Check whether we have a function declarator or a possible ctor-style 553 // initializer that follows the declarator. Note that ctor-style 554 // initializers are not possible in contexts where abstract declarators 555 // are allowed. 556 if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/)) 557 break; 558 559 // direct-declarator '(' parameter-declaration-clause ')' 560 // cv-qualifier-seq[opt] exception-specification[opt] 561 ConsumeParen(); 562 TPR = TryParseFunctionDeclarator(); 563 } else if (Tok.is(tok::l_square)) { 564 // direct-declarator '[' constant-expression[opt] ']' 565 // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 566 TPR = TryParseBracketDeclarator(); 567 } else { 568 break; 569 } 570 571 if (TPR != TPResult::Ambiguous()) 572 return TPR; 573 } 574 575 return TPResult::Ambiguous(); 576} 577 578/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 579/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 580/// be either a decl-specifier or a function-style cast, and TPResult::Error() 581/// if a parsing error was found and reported. 582/// 583/// decl-specifier: 584/// storage-class-specifier 585/// type-specifier 586/// function-specifier 587/// 'friend' 588/// 'typedef' 589/// [C++0x] 'constexpr' 590/// [GNU] attributes declaration-specifiers[opt] 591/// 592/// storage-class-specifier: 593/// 'register' 594/// 'static' 595/// 'extern' 596/// 'mutable' 597/// 'auto' 598/// [GNU] '__thread' 599/// 600/// function-specifier: 601/// 'inline' 602/// 'virtual' 603/// 'explicit' 604/// 605/// typedef-name: 606/// identifier 607/// 608/// type-specifier: 609/// simple-type-specifier 610/// class-specifier 611/// enum-specifier 612/// elaborated-type-specifier 613/// typename-specifier 614/// cv-qualifier 615/// 616/// simple-type-specifier: 617/// '::'[opt] nested-name-specifier[opt] type-name 618/// '::'[opt] nested-name-specifier 'template' 619/// simple-template-id [TODO] 620/// 'char' 621/// 'wchar_t' 622/// 'bool' 623/// 'short' 624/// 'int' 625/// 'long' 626/// 'signed' 627/// 'unsigned' 628/// 'float' 629/// 'double' 630/// 'void' 631/// [GNU] typeof-specifier 632/// [GNU] '_Complex' 633/// [C++0x] 'auto' [TODO] 634/// [C++0x] 'decltype' ( expression ) 635/// 636/// type-name: 637/// class-name 638/// enum-name 639/// typedef-name 640/// 641/// elaborated-type-specifier: 642/// class-key '::'[opt] nested-name-specifier[opt] identifier 643/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 644/// simple-template-id 645/// 'enum' '::'[opt] nested-name-specifier[opt] identifier 646/// 647/// enum-name: 648/// identifier 649/// 650/// enum-specifier: 651/// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 652/// 'enum' identifier[opt] '{' enumerator-list ',' '}' 653/// 654/// class-specifier: 655/// class-head '{' member-specification[opt] '}' 656/// 657/// class-head: 658/// class-key identifier[opt] base-clause[opt] 659/// class-key nested-name-specifier identifier base-clause[opt] 660/// class-key nested-name-specifier[opt] simple-template-id 661/// base-clause[opt] 662/// 663/// class-key: 664/// 'class' 665/// 'struct' 666/// 'union' 667/// 668/// cv-qualifier: 669/// 'const' 670/// 'volatile' 671/// [GNU] restrict 672/// 673Parser::TPResult Parser::isCXXDeclarationSpecifier() { 674 switch (Tok.getKind()) { 675 case tok::identifier: // foo::bar 676 // Check for need to substitute AltiVec __vector keyword 677 // for "vector" identifier. 678 if (TryAltiVecVectorToken()) 679 return TPResult::True(); 680 // Fall through. 681 case tok::kw_typename: // typename T::type 682 // Annotate typenames and C++ scope specifiers. If we get one, just 683 // recurse to handle whatever we get. 684 if (TryAnnotateTypeOrScopeToken()) 685 return TPResult::Error(); 686 if (Tok.is(tok::identifier)) 687 return TPResult::False(); 688 return isCXXDeclarationSpecifier(); 689 690 case tok::coloncolon: { // ::foo::bar 691 const Token &Next = NextToken(); 692 if (Next.is(tok::kw_new) || // ::new 693 Next.is(tok::kw_delete)) // ::delete 694 return TPResult::False(); 695 696 // Annotate typenames and C++ scope specifiers. If we get one, just 697 // recurse to handle whatever we get. 698 if (TryAnnotateTypeOrScopeToken()) 699 return TPResult::Error(); 700 return isCXXDeclarationSpecifier(); 701 } 702 703 // decl-specifier: 704 // storage-class-specifier 705 // type-specifier 706 // function-specifier 707 // 'friend' 708 // 'typedef' 709 // 'constexpr' 710 case tok::kw_friend: 711 case tok::kw_typedef: 712 case tok::kw_constexpr: 713 // storage-class-specifier 714 case tok::kw_register: 715 case tok::kw_static: 716 case tok::kw_extern: 717 case tok::kw_mutable: 718 case tok::kw_auto: 719 case tok::kw___thread: 720 // function-specifier 721 case tok::kw_inline: 722 case tok::kw_virtual: 723 case tok::kw_explicit: 724 725 // type-specifier: 726 // simple-type-specifier 727 // class-specifier 728 // enum-specifier 729 // elaborated-type-specifier 730 // typename-specifier 731 // cv-qualifier 732 733 // class-specifier 734 // elaborated-type-specifier 735 case tok::kw_class: 736 case tok::kw_struct: 737 case tok::kw_union: 738 // enum-specifier 739 case tok::kw_enum: 740 // cv-qualifier 741 case tok::kw_const: 742 case tok::kw_volatile: 743 744 // GNU 745 case tok::kw_restrict: 746 case tok::kw__Complex: 747 case tok::kw___attribute: 748 return TPResult::True(); 749 750 // Microsoft 751 case tok::kw___declspec: 752 case tok::kw___cdecl: 753 case tok::kw___stdcall: 754 case tok::kw___fastcall: 755 case tok::kw___thiscall: 756 case tok::kw___w64: 757 case tok::kw___ptr64: 758 case tok::kw___forceinline: 759 return TPResult::True(); 760 761 // Borland 762 case tok::kw___pascal: 763 return TPResult::True(); 764 765 // AltiVec 766 case tok::kw___vector: 767 return TPResult::True(); 768 769 case tok::annot_template_id: { 770 TemplateIdAnnotation *TemplateId 771 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 772 if (TemplateId->Kind != TNK_Type_template) 773 return TPResult::False(); 774 CXXScopeSpec SS; 775 AnnotateTemplateIdTokenAsType(&SS); 776 assert(Tok.is(tok::annot_typename)); 777 goto case_typename; 778 } 779 780 case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed 781 // We've already annotated a scope; try to annotate a type. 782 if (TryAnnotateTypeOrScopeToken()) 783 return TPResult::Error(); 784 if (!Tok.is(tok::annot_typename)) 785 return TPResult::False(); 786 // If that succeeded, fallthrough into the generic simple-type-id case. 787 788 // The ambiguity resides in a simple-type-specifier/typename-specifier 789 // followed by a '('. The '(' could either be the start of: 790 // 791 // direct-declarator: 792 // '(' declarator ')' 793 // 794 // direct-abstract-declarator: 795 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 796 // exception-specification[opt] 797 // '(' abstract-declarator ')' 798 // 799 // or part of a function-style cast expression: 800 // 801 // simple-type-specifier '(' expression-list[opt] ')' 802 // 803 804 // simple-type-specifier: 805 806 case tok::kw_char: 807 case tok::kw_wchar_t: 808 case tok::kw_char16_t: 809 case tok::kw_char32_t: 810 case tok::kw_bool: 811 case tok::kw_short: 812 case tok::kw_int: 813 case tok::kw_long: 814 case tok::kw_signed: 815 case tok::kw_unsigned: 816 case tok::kw_float: 817 case tok::kw_double: 818 case tok::kw_void: 819 case tok::annot_typename: 820 case_typename: 821 if (NextToken().is(tok::l_paren)) 822 return TPResult::Ambiguous(); 823 824 return TPResult::True(); 825 826 // GNU typeof support. 827 case tok::kw_typeof: { 828 if (NextToken().isNot(tok::l_paren)) 829 return TPResult::True(); 830 831 TentativeParsingAction PA(*this); 832 833 TPResult TPR = TryParseTypeofSpecifier(); 834 bool isFollowedByParen = Tok.is(tok::l_paren); 835 836 PA.Revert(); 837 838 if (TPR == TPResult::Error()) 839 return TPResult::Error(); 840 841 if (isFollowedByParen) 842 return TPResult::Ambiguous(); 843 844 return TPResult::True(); 845 } 846 847 // C++0x decltype support. 848 case tok::kw_decltype: 849 return TPResult::True(); 850 851 default: 852 return TPResult::False(); 853 } 854} 855 856/// [GNU] typeof-specifier: 857/// 'typeof' '(' expressions ')' 858/// 'typeof' '(' type-name ')' 859/// 860Parser::TPResult Parser::TryParseTypeofSpecifier() { 861 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 862 ConsumeToken(); 863 864 assert(Tok.is(tok::l_paren) && "Expected '('"); 865 // Parse through the parens after 'typeof'. 866 ConsumeParen(); 867 if (!SkipUntil(tok::r_paren)) 868 return TPResult::Error(); 869 870 return TPResult::Ambiguous(); 871} 872 873Parser::TPResult Parser::TryParseDeclarationSpecifier() { 874 TPResult TPR = isCXXDeclarationSpecifier(); 875 if (TPR != TPResult::Ambiguous()) 876 return TPR; 877 878 if (Tok.is(tok::kw_typeof)) 879 TryParseTypeofSpecifier(); 880 else 881 ConsumeToken(); 882 883 assert(Tok.is(tok::l_paren) && "Expected '('!"); 884 return TPResult::Ambiguous(); 885} 886 887/// isCXXFunctionDeclarator - Disambiguates between a function declarator or 888/// a constructor-style initializer, when parsing declaration statements. 889/// Returns true for function declarator and false for constructor-style 890/// initializer. 891/// If during the disambiguation process a parsing error is encountered, 892/// the function returns true to let the declaration parsing code handle it. 893/// 894/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 895/// exception-specification[opt] 896/// 897bool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) { 898 899 // C++ 8.2p1: 900 // The ambiguity arising from the similarity between a function-style cast and 901 // a declaration mentioned in 6.8 can also occur in the context of a 902 // declaration. In that context, the choice is between a function declaration 903 // with a redundant set of parentheses around a parameter name and an object 904 // declaration with a function-style cast as the initializer. Just as for the 905 // ambiguities mentioned in 6.8, the resolution is to consider any construct 906 // that could possibly be a declaration a declaration. 907 908 TentativeParsingAction PA(*this); 909 910 ConsumeParen(); 911 TPResult TPR = TryParseParameterDeclarationClause(); 912 if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 913 TPR = TPResult::False(); 914 915 SourceLocation TPLoc = Tok.getLocation(); 916 PA.Revert(); 917 918 // In case of an error, let the declaration parsing code handle it. 919 if (TPR == TPResult::Error()) 920 return true; 921 922 if (TPR == TPResult::Ambiguous()) { 923 // Function declarator has precedence over constructor-style initializer. 924 // Emit a warning just in case the author intended a variable definition. 925 if (warnIfAmbiguous) 926 Diag(Tok, diag::warn_parens_disambiguated_as_function_decl) 927 << SourceRange(Tok.getLocation(), TPLoc); 928 return true; 929 } 930 931 return TPR == TPResult::True(); 932} 933 934/// parameter-declaration-clause: 935/// parameter-declaration-list[opt] '...'[opt] 936/// parameter-declaration-list ',' '...' 937/// 938/// parameter-declaration-list: 939/// parameter-declaration 940/// parameter-declaration-list ',' parameter-declaration 941/// 942/// parameter-declaration: 943/// decl-specifier-seq declarator 944/// decl-specifier-seq declarator '=' assignment-expression 945/// decl-specifier-seq abstract-declarator[opt] 946/// decl-specifier-seq abstract-declarator[opt] '=' assignment-expression 947/// 948Parser::TPResult Parser::TryParseParameterDeclarationClause() { 949 950 if (Tok.is(tok::r_paren)) 951 return TPResult::True(); 952 953 // parameter-declaration-list[opt] '...'[opt] 954 // parameter-declaration-list ',' '...' 955 // 956 // parameter-declaration-list: 957 // parameter-declaration 958 // parameter-declaration-list ',' parameter-declaration 959 // 960 while (1) { 961 // '...'[opt] 962 if (Tok.is(tok::ellipsis)) { 963 ConsumeToken(); 964 return TPResult::True(); // '...' is a sign of a function declarator. 965 } 966 967 // decl-specifier-seq 968 TPResult TPR = TryParseDeclarationSpecifier(); 969 if (TPR != TPResult::Ambiguous()) 970 return TPR; 971 972 // declarator 973 // abstract-declarator[opt] 974 TPR = TryParseDeclarator(true/*mayBeAbstract*/); 975 if (TPR != TPResult::Ambiguous()) 976 return TPR; 977 978 if (Tok.is(tok::equal)) { 979 // '=' assignment-expression 980 // Parse through assignment-expression. 981 tok::TokenKind StopToks[3] ={ tok::comma, tok::ellipsis, tok::r_paren }; 982 if (!SkipUntil(StopToks, 3, true/*StopAtSemi*/, true/*DontConsume*/)) 983 return TPResult::Error(); 984 } 985 986 if (Tok.is(tok::ellipsis)) { 987 ConsumeToken(); 988 return TPResult::True(); // '...' is a sign of a function declarator. 989 } 990 991 if (Tok.isNot(tok::comma)) 992 break; 993 ConsumeToken(); // the comma. 994 } 995 996 return TPResult::Ambiguous(); 997} 998 999/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 1000/// parsing as a function declarator. 1001/// If TryParseFunctionDeclarator fully parsed the function declarator, it will 1002/// return TPResult::Ambiguous(), otherwise it will return either False() or 1003/// Error(). 1004/// 1005/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1006/// exception-specification[opt] 1007/// 1008/// exception-specification: 1009/// 'throw' '(' type-id-list[opt] ')' 1010/// 1011Parser::TPResult Parser::TryParseFunctionDeclarator() { 1012 1013 // The '(' is already parsed. 1014 1015 TPResult TPR = TryParseParameterDeclarationClause(); 1016 if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1017 TPR = TPResult::False(); 1018 1019 if (TPR == TPResult::False() || TPR == TPResult::Error()) 1020 return TPR; 1021 1022 // Parse through the parens. 1023 if (!SkipUntil(tok::r_paren)) 1024 return TPResult::Error(); 1025 1026 // cv-qualifier-seq 1027 while (Tok.is(tok::kw_const) || 1028 Tok.is(tok::kw_volatile) || 1029 Tok.is(tok::kw_restrict) ) 1030 ConsumeToken(); 1031 1032 // exception-specification 1033 if (Tok.is(tok::kw_throw)) { 1034 ConsumeToken(); 1035 if (Tok.isNot(tok::l_paren)) 1036 return TPResult::Error(); 1037 1038 // Parse through the parens after 'throw'. 1039 ConsumeParen(); 1040 if (!SkipUntil(tok::r_paren)) 1041 return TPResult::Error(); 1042 } 1043 1044 return TPResult::Ambiguous(); 1045} 1046 1047/// '[' constant-expression[opt] ']' 1048/// 1049Parser::TPResult Parser::TryParseBracketDeclarator() { 1050 ConsumeBracket(); 1051 if (!SkipUntil(tok::r_square)) 1052 return TPResult::Error(); 1053 1054 return TPResult::Ambiguous(); 1055} 1056