ParseTentative.cpp revision 9490ab433deef70105d817616928d700f87642d9
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 case tok::kw__Static_assert: 62 return true; 63 // simple-declaration 64 default: 65 return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false); 66 } 67} 68 69/// isCXXSimpleDeclaration - C++-specialized function that disambiguates 70/// between a simple-declaration or an expression-statement. 71/// If during the disambiguation process a parsing error is encountered, 72/// the function returns true to let the declaration parsing code handle it. 73/// Returns false if the statement is disambiguated as expression. 74/// 75/// simple-declaration: 76/// decl-specifier-seq init-declarator-list[opt] ';' 77/// 78/// (if AllowForRangeDecl specified) 79/// for ( for-range-declaration : for-range-initializer ) statement 80/// for-range-declaration: 81/// attribute-specifier-seqopt type-specifier-seq declarator 82bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) { 83 // C++ 6.8p1: 84 // There is an ambiguity in the grammar involving expression-statements and 85 // declarations: An expression-statement with a function-style explicit type 86 // conversion (5.2.3) as its leftmost subexpression can be indistinguishable 87 // from a declaration where the first declarator starts with a '('. In those 88 // cases the statement is a declaration. [Note: To disambiguate, the whole 89 // statement might have to be examined to determine if it is an 90 // expression-statement or a declaration]. 91 92 // C++ 6.8p3: 93 // The disambiguation is purely syntactic; that is, the meaning of the names 94 // occurring in such a statement, beyond whether they are type-names or not, 95 // is not generally used in or changed by the disambiguation. Class 96 // templates are instantiated as necessary to determine if a qualified name 97 // is a type-name. Disambiguation precedes parsing, and a statement 98 // disambiguated as a declaration may be an ill-formed declaration. 99 100 // We don't have to parse all of the decl-specifier-seq part. There's only 101 // an ambiguity if the first decl-specifier is 102 // simple-type-specifier/typename-specifier followed by a '(', which may 103 // indicate a function-style cast expression. 104 // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such 105 // a case. 106 107 TPResult TPR = isCXXDeclarationSpecifier(); 108 if (TPR != TPResult::Ambiguous()) 109 return TPR != TPResult::False(); // Returns true for TPResult::True() or 110 // TPResult::Error(). 111 112 // FIXME: Add statistics about the number of ambiguous statements encountered 113 // and how they were resolved (number of declarations+number of expressions). 114 115 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 116 // We need tentative parsing... 117 118 TentativeParsingAction PA(*this); 119 TPR = TryParseSimpleDeclaration(AllowForRangeDecl); 120 PA.Revert(); 121 122 // In case of an error, let the declaration parsing code handle it. 123 if (TPR == TPResult::Error()) 124 return true; 125 126 // Declarations take precedence over expressions. 127 if (TPR == TPResult::Ambiguous()) 128 TPR = TPResult::True(); 129 130 assert(TPR == TPResult::True() || TPR == TPResult::False()); 131 return TPR == TPResult::True(); 132} 133 134/// simple-declaration: 135/// decl-specifier-seq init-declarator-list[opt] ';' 136/// 137/// (if AllowForRangeDecl specified) 138/// for ( for-range-declaration : for-range-initializer ) statement 139/// for-range-declaration: 140/// attribute-specifier-seqopt type-specifier-seq declarator 141/// 142Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { 143 // We know that we have a simple-type-specifier/typename-specifier followed 144 // by a '('. 145 assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous()); 146 147 if (Tok.is(tok::kw_typeof)) 148 TryParseTypeofSpecifier(); 149 else { 150 ConsumeToken(); 151 152 if (getLang().ObjC1 && Tok.is(tok::less)) 153 TryParseProtocolQualifiers(); 154 } 155 156 assert(Tok.is(tok::l_paren) && "Expected '('"); 157 158 TPResult TPR = TryParseInitDeclaratorList(); 159 if (TPR != TPResult::Ambiguous()) 160 return TPR; 161 162 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon))) 163 return TPResult::False(); 164 165 return TPResult::Ambiguous(); 166} 167 168/// init-declarator-list: 169/// init-declarator 170/// init-declarator-list ',' init-declarator 171/// 172/// init-declarator: 173/// declarator initializer[opt] 174/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 175/// 176/// initializer: 177/// '=' initializer-clause 178/// '(' expression-list ')' 179/// 180/// initializer-clause: 181/// assignment-expression 182/// '{' initializer-list ','[opt] '}' 183/// '{' '}' 184/// 185Parser::TPResult Parser::TryParseInitDeclaratorList() { 186 while (1) { 187 // declarator 188 TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 189 if (TPR != TPResult::Ambiguous()) 190 return TPR; 191 192 // [GNU] simple-asm-expr[opt] attributes[opt] 193 if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 194 return TPResult::True(); 195 196 // initializer[opt] 197 if (Tok.is(tok::l_paren)) { 198 // Parse through the parens. 199 ConsumeParen(); 200 if (!SkipUntil(tok::r_paren)) 201 return TPResult::Error(); 202 } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { 203 // MSVC and g++ won't examine the rest of declarators if '=' is 204 // encountered; they just conclude that we have a declaration. 205 // EDG parses the initializer completely, which is the proper behavior 206 // for this case. 207 // 208 // At present, Clang follows MSVC and g++, since the parser does not have 209 // the ability to parse an expression fully without recording the 210 // results of that parse. 211 // Also allow 'in' after on objective-c declaration as in: 212 // for (int (^b)(void) in array). Ideally this should be done in the 213 // context of parsing for-init-statement of a foreach statement only. But, 214 // in any other context 'in' is invalid after a declaration and parser 215 // issues the error regardless of outcome of this decision. 216 // FIXME. Change if above assumption does not hold. 217 return TPResult::True(); 218 } 219 220 if (Tok.isNot(tok::comma)) 221 break; 222 ConsumeToken(); // the comma. 223 } 224 225 return TPResult::Ambiguous(); 226} 227 228/// isCXXConditionDeclaration - Disambiguates between a declaration or an 229/// expression for a condition of a if/switch/while/for statement. 230/// If during the disambiguation process a parsing error is encountered, 231/// the function returns true to let the declaration parsing code handle it. 232/// 233/// condition: 234/// expression 235/// type-specifier-seq declarator '=' assignment-expression 236/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 237/// '=' assignment-expression 238/// 239bool Parser::isCXXConditionDeclaration() { 240 TPResult TPR = isCXXDeclarationSpecifier(); 241 if (TPR != TPResult::Ambiguous()) 242 return TPR != TPResult::False(); // Returns true for TPResult::True() or 243 // TPResult::Error(). 244 245 // FIXME: Add statistics about the number of ambiguous statements encountered 246 // and how they were resolved (number of declarations+number of expressions). 247 248 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 249 // We need tentative parsing... 250 251 TentativeParsingAction PA(*this); 252 253 // type-specifier-seq 254 if (Tok.is(tok::kw_typeof)) 255 TryParseTypeofSpecifier(); 256 else { 257 ConsumeToken(); 258 259 if (getLang().ObjC1 && Tok.is(tok::less)) 260 TryParseProtocolQualifiers(); 261 } 262 assert(Tok.is(tok::l_paren) && "Expected '('"); 263 264 // declarator 265 TPR = TryParseDeclarator(false/*mayBeAbstract*/); 266 267 // In case of an error, let the declaration parsing code handle it. 268 if (TPR == TPResult::Error()) 269 TPR = TPResult::True(); 270 271 if (TPR == TPResult::Ambiguous()) { 272 // '=' 273 // [GNU] simple-asm-expr[opt] attributes[opt] 274 if (Tok.is(tok::equal) || 275 Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 276 TPR = TPResult::True(); 277 else 278 TPR = TPResult::False(); 279 } 280 281 PA.Revert(); 282 283 assert(TPR == TPResult::True() || TPR == TPResult::False()); 284 return TPR == TPResult::True(); 285} 286 287 /// \brief Determine whether the next set of tokens contains a type-id. 288 /// 289 /// The context parameter states what context we're parsing right 290 /// now, which affects how this routine copes with the token 291 /// following the type-id. If the context is TypeIdInParens, we have 292 /// already parsed the '(' and we will cease lookahead when we hit 293 /// the corresponding ')'. If the context is 294 /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 295 /// before this template argument, and will cease lookahead when we 296 /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 297 /// and false for an expression. If during the disambiguation 298 /// process a parsing error is encountered, the function returns 299 /// true to let the declaration parsing code handle it. 300 /// 301 /// type-id: 302 /// type-specifier-seq abstract-declarator[opt] 303 /// 304bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 305 306 isAmbiguous = false; 307 308 // C++ 8.2p2: 309 // The ambiguity arising from the similarity between a function-style cast and 310 // a type-id can occur in different contexts. The ambiguity appears as a 311 // choice between a function-style cast expression and a declaration of a 312 // type. The resolution is that any construct that could possibly be a type-id 313 // in its syntactic context shall be considered a type-id. 314 315 TPResult TPR = isCXXDeclarationSpecifier(); 316 if (TPR != TPResult::Ambiguous()) 317 return TPR != TPResult::False(); // Returns true for TPResult::True() or 318 // TPResult::Error(). 319 320 // FIXME: Add statistics about the number of ambiguous statements encountered 321 // and how they were resolved (number of declarations+number of expressions). 322 323 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 324 // We need tentative parsing... 325 326 TentativeParsingAction PA(*this); 327 328 // type-specifier-seq 329 if (Tok.is(tok::kw_typeof)) 330 TryParseTypeofSpecifier(); 331 else { 332 ConsumeToken(); 333 334 if (getLang().ObjC1 && Tok.is(tok::less)) 335 TryParseProtocolQualifiers(); 336 } 337 338 assert(Tok.is(tok::l_paren) && "Expected '('"); 339 340 // declarator 341 TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 342 343 // In case of an error, let the declaration parsing code handle it. 344 if (TPR == TPResult::Error()) 345 TPR = TPResult::True(); 346 347 if (TPR == TPResult::Ambiguous()) { 348 // We are supposed to be inside parens, so if after the abstract declarator 349 // we encounter a ')' this is a type-id, otherwise it's an expression. 350 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 351 TPR = TPResult::True(); 352 isAmbiguous = true; 353 354 // We are supposed to be inside a template argument, so if after 355 // the abstract declarator we encounter a '>', '>>' (in C++0x), or 356 // ',', this is a type-id. Otherwise, it's an expression. 357 } else if (Context == TypeIdAsTemplateArgument && 358 (Tok.is(tok::greater) || Tok.is(tok::comma) || 359 (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) { 360 TPR = TPResult::True(); 361 isAmbiguous = true; 362 363 } else 364 TPR = TPResult::False(); 365 } 366 367 PA.Revert(); 368 369 assert(TPR == TPResult::True() || TPR == TPResult::False()); 370 return TPR == TPResult::True(); 371} 372 373/// isCXX0XAttributeSpecifier - returns true if this is a C++0x 374/// attribute-specifier. By default, unless in Obj-C++, only a cursory check is 375/// performed that will simply return true if a [[ is seen. Currently C++ has no 376/// syntactical ambiguities from this check, but it may inhibit error recovery. 377/// If CheckClosing is true, a check is made for closing ]] brackets. 378/// 379/// If given, After is set to the token after the attribute-specifier so that 380/// appropriate parsing decisions can be made; it is left untouched if false is 381/// returned. 382/// 383/// FIXME: If an error is in the closing ]] brackets, the program assumes 384/// the absence of an attribute-specifier, which can cause very yucky errors 385/// to occur. 386/// 387/// [C++0x] attribute-specifier: 388/// '[' '[' attribute-list ']' ']' 389/// alignment-specifier 390/// 391/// [C++0x] attribute-list: 392/// attribute[opt] 393/// attribute-list ',' attribute[opt] 394/// 395/// [C++0x] attribute: 396/// attribute-token attribute-argument-clause[opt] 397/// 398/// [C++0x] attribute-token: 399/// identifier 400/// attribute-scoped-token 401/// 402/// [C++0x] attribute-scoped-token: 403/// attribute-namespace '::' identifier 404/// 405/// [C++0x] attribute-namespace: 406/// identifier 407/// 408/// [C++0x] attribute-argument-clause: 409/// '(' balanced-token-seq ')' 410/// 411/// [C++0x] balanced-token-seq: 412/// balanced-token 413/// balanced-token-seq balanced-token 414/// 415/// [C++0x] balanced-token: 416/// '(' balanced-token-seq ')' 417/// '[' balanced-token-seq ']' 418/// '{' balanced-token-seq '}' 419/// any token but '(', ')', '[', ']', '{', or '}' 420bool Parser::isCXX0XAttributeSpecifier (bool CheckClosing, 421 tok::TokenKind *After) { 422 if (Tok.is(tok::kw_alignas)) 423 return true; 424 425 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) 426 return false; 427 428 // No tentative parsing if we don't need to look for ]] 429 if (!CheckClosing && !getLang().ObjC1) 430 return true; 431 432 struct TentativeReverter { 433 TentativeParsingAction PA; 434 435 TentativeReverter (Parser& P) 436 : PA(P) 437 {} 438 ~TentativeReverter () { 439 PA.Revert(); 440 } 441 } R(*this); 442 443 // Opening brackets were checked for above. 444 ConsumeBracket(); 445 ConsumeBracket(); 446 447 // SkipUntil will handle balanced tokens, which are guaranteed in attributes. 448 SkipUntil(tok::r_square, false); 449 450 if (Tok.isNot(tok::r_square)) 451 return false; 452 ConsumeBracket(); 453 454 if (After) 455 *After = Tok.getKind(); 456 457 return true; 458} 459 460/// declarator: 461/// direct-declarator 462/// ptr-operator declarator 463/// 464/// direct-declarator: 465/// declarator-id 466/// direct-declarator '(' parameter-declaration-clause ')' 467/// cv-qualifier-seq[opt] exception-specification[opt] 468/// direct-declarator '[' constant-expression[opt] ']' 469/// '(' declarator ')' 470/// [GNU] '(' attributes declarator ')' 471/// 472/// abstract-declarator: 473/// ptr-operator abstract-declarator[opt] 474/// direct-abstract-declarator 475/// ... 476/// 477/// direct-abstract-declarator: 478/// direct-abstract-declarator[opt] 479/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 480/// exception-specification[opt] 481/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 482/// '(' abstract-declarator ')' 483/// 484/// ptr-operator: 485/// '*' cv-qualifier-seq[opt] 486/// '&' 487/// [C++0x] '&&' [TODO] 488/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 489/// 490/// cv-qualifier-seq: 491/// cv-qualifier cv-qualifier-seq[opt] 492/// 493/// cv-qualifier: 494/// 'const' 495/// 'volatile' 496/// 497/// declarator-id: 498/// '...'[opt] id-expression 499/// 500/// id-expression: 501/// unqualified-id 502/// qualified-id [TODO] 503/// 504/// unqualified-id: 505/// identifier 506/// operator-function-id [TODO] 507/// conversion-function-id [TODO] 508/// '~' class-name [TODO] 509/// template-id [TODO] 510/// 511Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 512 bool mayHaveIdentifier) { 513 // declarator: 514 // direct-declarator 515 // ptr-operator declarator 516 517 while (1) { 518 if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 519 if (TryAnnotateCXXScopeToken(true)) 520 return TPResult::Error(); 521 522 if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 523 Tok.is(tok::ampamp) || 524 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 525 // ptr-operator 526 ConsumeToken(); 527 while (Tok.is(tok::kw_const) || 528 Tok.is(tok::kw_volatile) || 529 Tok.is(tok::kw_restrict)) 530 ConsumeToken(); 531 } else { 532 break; 533 } 534 } 535 536 // direct-declarator: 537 // direct-abstract-declarator: 538 if (Tok.is(tok::ellipsis)) 539 ConsumeToken(); 540 541 if ((Tok.is(tok::identifier) || 542 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) && 543 mayHaveIdentifier) { 544 // declarator-id 545 if (Tok.is(tok::annot_cxxscope)) 546 ConsumeToken(); 547 ConsumeToken(); 548 } else if (Tok.is(tok::l_paren)) { 549 ConsumeParen(); 550 if (mayBeAbstract && 551 (Tok.is(tok::r_paren) || // 'int()' is a function. 552 Tok.is(tok::ellipsis) || // 'int(...)' is a function. 553 isDeclarationSpecifier())) { // 'int(int)' is a function. 554 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 555 // exception-specification[opt] 556 TPResult TPR = TryParseFunctionDeclarator(); 557 if (TPR != TPResult::Ambiguous()) 558 return TPR; 559 } else { 560 // '(' declarator ')' 561 // '(' attributes declarator ')' 562 // '(' abstract-declarator ')' 563 if (Tok.is(tok::kw___attribute) || 564 Tok.is(tok::kw___declspec) || 565 Tok.is(tok::kw___cdecl) || 566 Tok.is(tok::kw___stdcall) || 567 Tok.is(tok::kw___fastcall) || 568 Tok.is(tok::kw___thiscall) || 569 Tok.is(tok::kw___unaligned)) 570 return TPResult::True(); // attributes indicate declaration 571 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 572 if (TPR != TPResult::Ambiguous()) 573 return TPR; 574 if (Tok.isNot(tok::r_paren)) 575 return TPResult::False(); 576 ConsumeParen(); 577 } 578 } else if (!mayBeAbstract) { 579 return TPResult::False(); 580 } 581 582 while (1) { 583 TPResult TPR(TPResult::Ambiguous()); 584 585 // abstract-declarator: ... 586 if (Tok.is(tok::ellipsis)) 587 ConsumeToken(); 588 589 if (Tok.is(tok::l_paren)) { 590 // Check whether we have a function declarator or a possible ctor-style 591 // initializer that follows the declarator. Note that ctor-style 592 // initializers are not possible in contexts where abstract declarators 593 // are allowed. 594 if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/)) 595 break; 596 597 // direct-declarator '(' parameter-declaration-clause ')' 598 // cv-qualifier-seq[opt] exception-specification[opt] 599 ConsumeParen(); 600 TPR = TryParseFunctionDeclarator(); 601 } else if (Tok.is(tok::l_square)) { 602 // direct-declarator '[' constant-expression[opt] ']' 603 // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 604 TPR = TryParseBracketDeclarator(); 605 } else { 606 break; 607 } 608 609 if (TPR != TPResult::Ambiguous()) 610 return TPR; 611 } 612 613 return TPResult::Ambiguous(); 614} 615 616Parser::TPResult 617Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { 618 switch (Kind) { 619 // Obviously starts an expression. 620 case tok::numeric_constant: 621 case tok::char_constant: 622 case tok::wide_char_constant: 623 case tok::utf16_char_constant: 624 case tok::utf32_char_constant: 625 case tok::string_literal: 626 case tok::wide_string_literal: 627 case tok::utf8_string_literal: 628 case tok::utf16_string_literal: 629 case tok::utf32_string_literal: 630 case tok::l_square: 631 case tok::l_paren: 632 case tok::amp: 633 case tok::ampamp: 634 case tok::star: 635 case tok::plus: 636 case tok::plusplus: 637 case tok::minus: 638 case tok::minusminus: 639 case tok::tilde: 640 case tok::exclaim: 641 case tok::kw_sizeof: 642 case tok::kw___func__: 643 case tok::kw_const_cast: 644 case tok::kw_delete: 645 case tok::kw_dynamic_cast: 646 case tok::kw_false: 647 case tok::kw_new: 648 case tok::kw_operator: 649 case tok::kw_reinterpret_cast: 650 case tok::kw_static_cast: 651 case tok::kw_this: 652 case tok::kw_throw: 653 case tok::kw_true: 654 case tok::kw_typeid: 655 case tok::kw_alignof: 656 case tok::kw_noexcept: 657 case tok::kw_nullptr: 658 case tok::kw___null: 659 case tok::kw___alignof: 660 case tok::kw___builtin_choose_expr: 661 case tok::kw___builtin_offsetof: 662 case tok::kw___builtin_types_compatible_p: 663 case tok::kw___builtin_va_arg: 664 case tok::kw___imag: 665 case tok::kw___real: 666 case tok::kw___FUNCTION__: 667 case tok::kw___PRETTY_FUNCTION__: 668 case tok::kw___has_nothrow_assign: 669 case tok::kw___has_nothrow_copy: 670 case tok::kw___has_nothrow_constructor: 671 case tok::kw___has_trivial_assign: 672 case tok::kw___has_trivial_copy: 673 case tok::kw___has_trivial_constructor: 674 case tok::kw___has_trivial_destructor: 675 case tok::kw___has_virtual_destructor: 676 case tok::kw___is_abstract: 677 case tok::kw___is_base_of: 678 case tok::kw___is_class: 679 case tok::kw___is_convertible_to: 680 case tok::kw___is_empty: 681 case tok::kw___is_enum: 682 case tok::kw___is_final: 683 case tok::kw___is_literal: 684 case tok::kw___is_literal_type: 685 case tok::kw___is_pod: 686 case tok::kw___is_polymorphic: 687 case tok::kw___is_trivial: 688 case tok::kw___is_trivially_copyable: 689 case tok::kw___is_union: 690 case tok::kw___uuidof: 691 return TPResult::True(); 692 693 // Obviously starts a type-specifier-seq: 694 case tok::kw_char: 695 case tok::kw_const: 696 case tok::kw_double: 697 case tok::kw_enum: 698 case tok::kw_half: 699 case tok::kw_float: 700 case tok::kw_int: 701 case tok::kw_long: 702 case tok::kw___int64: 703 case tok::kw_restrict: 704 case tok::kw_short: 705 case tok::kw_signed: 706 case tok::kw_struct: 707 case tok::kw_union: 708 case tok::kw_unsigned: 709 case tok::kw_void: 710 case tok::kw_volatile: 711 case tok::kw__Bool: 712 case tok::kw__Complex: 713 case tok::kw_class: 714 case tok::kw_typename: 715 case tok::kw_wchar_t: 716 case tok::kw_char16_t: 717 case tok::kw_char32_t: 718 case tok::kw___underlying_type: 719 case tok::kw_thread_local: 720 case tok::kw__Decimal32: 721 case tok::kw__Decimal64: 722 case tok::kw__Decimal128: 723 case tok::kw___thread: 724 case tok::kw_typeof: 725 case tok::kw___cdecl: 726 case tok::kw___stdcall: 727 case tok::kw___fastcall: 728 case tok::kw___thiscall: 729 case tok::kw___unaligned: 730 case tok::kw___vector: 731 case tok::kw___pixel: 732 case tok::kw__Atomic: 733 return TPResult::False(); 734 735 default: 736 break; 737 } 738 739 return TPResult::Ambiguous(); 740} 741 742/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 743/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 744/// be either a decl-specifier or a function-style cast, and TPResult::Error() 745/// if a parsing error was found and reported. 746/// 747/// decl-specifier: 748/// storage-class-specifier 749/// type-specifier 750/// function-specifier 751/// 'friend' 752/// 'typedef' 753/// [C++0x] 'constexpr' 754/// [GNU] attributes declaration-specifiers[opt] 755/// 756/// storage-class-specifier: 757/// 'register' 758/// 'static' 759/// 'extern' 760/// 'mutable' 761/// 'auto' 762/// [GNU] '__thread' 763/// 764/// function-specifier: 765/// 'inline' 766/// 'virtual' 767/// 'explicit' 768/// 769/// typedef-name: 770/// identifier 771/// 772/// type-specifier: 773/// simple-type-specifier 774/// class-specifier 775/// enum-specifier 776/// elaborated-type-specifier 777/// typename-specifier 778/// cv-qualifier 779/// 780/// simple-type-specifier: 781/// '::'[opt] nested-name-specifier[opt] type-name 782/// '::'[opt] nested-name-specifier 'template' 783/// simple-template-id [TODO] 784/// 'char' 785/// 'wchar_t' 786/// 'bool' 787/// 'short' 788/// 'int' 789/// 'long' 790/// 'signed' 791/// 'unsigned' 792/// 'float' 793/// 'double' 794/// 'void' 795/// [GNU] typeof-specifier 796/// [GNU] '_Complex' 797/// [C++0x] 'auto' [TODO] 798/// [C++0x] 'decltype' ( expression ) 799/// 800/// type-name: 801/// class-name 802/// enum-name 803/// typedef-name 804/// 805/// elaborated-type-specifier: 806/// class-key '::'[opt] nested-name-specifier[opt] identifier 807/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 808/// simple-template-id 809/// 'enum' '::'[opt] nested-name-specifier[opt] identifier 810/// 811/// enum-name: 812/// identifier 813/// 814/// enum-specifier: 815/// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 816/// 'enum' identifier[opt] '{' enumerator-list ',' '}' 817/// 818/// class-specifier: 819/// class-head '{' member-specification[opt] '}' 820/// 821/// class-head: 822/// class-key identifier[opt] base-clause[opt] 823/// class-key nested-name-specifier identifier base-clause[opt] 824/// class-key nested-name-specifier[opt] simple-template-id 825/// base-clause[opt] 826/// 827/// class-key: 828/// 'class' 829/// 'struct' 830/// 'union' 831/// 832/// cv-qualifier: 833/// 'const' 834/// 'volatile' 835/// [GNU] restrict 836/// 837Parser::TPResult Parser::isCXXDeclarationSpecifier() { 838 switch (Tok.getKind()) { 839 case tok::identifier: // foo::bar 840 // Check for need to substitute AltiVec __vector keyword 841 // for "vector" identifier. 842 if (TryAltiVecVectorToken()) 843 return TPResult::True(); 844 // Fall through. 845 case tok::kw_typename: // typename T::type 846 // Annotate typenames and C++ scope specifiers. If we get one, just 847 // recurse to handle whatever we get. 848 if (TryAnnotateTypeOrScopeToken()) 849 return TPResult::Error(); 850 if (Tok.is(tok::identifier)) 851 return TPResult::False(); 852 return isCXXDeclarationSpecifier(); 853 854 case tok::coloncolon: { // ::foo::bar 855 const Token &Next = NextToken(); 856 if (Next.is(tok::kw_new) || // ::new 857 Next.is(tok::kw_delete)) // ::delete 858 return TPResult::False(); 859 } 860 // Fall through. 861 case tok::kw_decltype: 862 // Annotate typenames and C++ scope specifiers. If we get one, just 863 // recurse to handle whatever we get. 864 if (TryAnnotateTypeOrScopeToken()) 865 return TPResult::Error(); 866 return isCXXDeclarationSpecifier(); 867 868 // decl-specifier: 869 // storage-class-specifier 870 // type-specifier 871 // function-specifier 872 // 'friend' 873 // 'typedef' 874 // 'constexpr' 875 case tok::kw_friend: 876 case tok::kw_typedef: 877 case tok::kw_constexpr: 878 // storage-class-specifier 879 case tok::kw_register: 880 case tok::kw_static: 881 case tok::kw_extern: 882 case tok::kw_mutable: 883 case tok::kw_auto: 884 case tok::kw___thread: 885 // function-specifier 886 case tok::kw_inline: 887 case tok::kw_virtual: 888 case tok::kw_explicit: 889 890 // Modules 891 case tok::kw___module_private__: 892 893 // type-specifier: 894 // simple-type-specifier 895 // class-specifier 896 // enum-specifier 897 // elaborated-type-specifier 898 // typename-specifier 899 // cv-qualifier 900 901 // class-specifier 902 // elaborated-type-specifier 903 case tok::kw_class: 904 case tok::kw_struct: 905 case tok::kw_union: 906 // enum-specifier 907 case tok::kw_enum: 908 // cv-qualifier 909 case tok::kw_const: 910 case tok::kw_volatile: 911 912 // GNU 913 case tok::kw_restrict: 914 case tok::kw__Complex: 915 case tok::kw___attribute: 916 return TPResult::True(); 917 918 // Microsoft 919 case tok::kw___declspec: 920 case tok::kw___cdecl: 921 case tok::kw___stdcall: 922 case tok::kw___fastcall: 923 case tok::kw___thiscall: 924 case tok::kw___w64: 925 case tok::kw___ptr64: 926 case tok::kw___ptr32: 927 case tok::kw___forceinline: 928 case tok::kw___unaligned: 929 return TPResult::True(); 930 931 // Borland 932 case tok::kw___pascal: 933 return TPResult::True(); 934 935 // AltiVec 936 case tok::kw___vector: 937 return TPResult::True(); 938 939 case tok::annot_template_id: { 940 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 941 if (TemplateId->Kind != TNK_Type_template) 942 return TPResult::False(); 943 CXXScopeSpec SS; 944 AnnotateTemplateIdTokenAsType(); 945 assert(Tok.is(tok::annot_typename)); 946 goto case_typename; 947 } 948 949 case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed 950 // We've already annotated a scope; try to annotate a type. 951 if (TryAnnotateTypeOrScopeToken()) 952 return TPResult::Error(); 953 if (!Tok.is(tok::annot_typename)) 954 return TPResult::False(); 955 // If that succeeded, fallthrough into the generic simple-type-id case. 956 957 // The ambiguity resides in a simple-type-specifier/typename-specifier 958 // followed by a '('. The '(' could either be the start of: 959 // 960 // direct-declarator: 961 // '(' declarator ')' 962 // 963 // direct-abstract-declarator: 964 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 965 // exception-specification[opt] 966 // '(' abstract-declarator ')' 967 // 968 // or part of a function-style cast expression: 969 // 970 // simple-type-specifier '(' expression-list[opt] ')' 971 // 972 973 // simple-type-specifier: 974 975 case tok::annot_typename: 976 case_typename: 977 // In Objective-C, we might have a protocol-qualified type. 978 if (getLang().ObjC1 && NextToken().is(tok::less)) { 979 // Tentatively parse the 980 TentativeParsingAction PA(*this); 981 ConsumeToken(); // The type token 982 983 TPResult TPR = TryParseProtocolQualifiers(); 984 bool isFollowedByParen = Tok.is(tok::l_paren); 985 986 PA.Revert(); 987 988 if (TPR == TPResult::Error()) 989 return TPResult::Error(); 990 991 if (isFollowedByParen) 992 return TPResult::Ambiguous(); 993 994 return TPResult::True(); 995 } 996 997 case tok::kw_char: 998 case tok::kw_wchar_t: 999 case tok::kw_char16_t: 1000 case tok::kw_char32_t: 1001 case tok::kw_bool: 1002 case tok::kw_short: 1003 case tok::kw_int: 1004 case tok::kw_long: 1005 case tok::kw___int64: 1006 case tok::kw_signed: 1007 case tok::kw_unsigned: 1008 case tok::kw_half: 1009 case tok::kw_float: 1010 case tok::kw_double: 1011 case tok::kw_void: 1012 if (NextToken().is(tok::l_paren)) 1013 return TPResult::Ambiguous(); 1014 1015 if (isStartOfObjCClassMessageMissingOpenBracket()) 1016 return TPResult::False(); 1017 1018 return TPResult::True(); 1019 1020 // GNU typeof support. 1021 case tok::kw_typeof: { 1022 if (NextToken().isNot(tok::l_paren)) 1023 return TPResult::True(); 1024 1025 TentativeParsingAction PA(*this); 1026 1027 TPResult TPR = TryParseTypeofSpecifier(); 1028 bool isFollowedByParen = Tok.is(tok::l_paren); 1029 1030 PA.Revert(); 1031 1032 if (TPR == TPResult::Error()) 1033 return TPResult::Error(); 1034 1035 if (isFollowedByParen) 1036 return TPResult::Ambiguous(); 1037 1038 return TPResult::True(); 1039 } 1040 1041 // C++0x decltype support. 1042 case tok::annot_decltype: 1043 return TPResult::True(); 1044 1045 // C++0x type traits support 1046 case tok::kw___underlying_type: 1047 return TPResult::True(); 1048 1049 // C1x _Atomic 1050 case tok::kw__Atomic: 1051 return TPResult::True(); 1052 1053 default: 1054 return TPResult::False(); 1055 } 1056} 1057 1058/// [GNU] typeof-specifier: 1059/// 'typeof' '(' expressions ')' 1060/// 'typeof' '(' type-name ')' 1061/// 1062Parser::TPResult Parser::TryParseTypeofSpecifier() { 1063 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 1064 ConsumeToken(); 1065 1066 assert(Tok.is(tok::l_paren) && "Expected '('"); 1067 // Parse through the parens after 'typeof'. 1068 ConsumeParen(); 1069 if (!SkipUntil(tok::r_paren)) 1070 return TPResult::Error(); 1071 1072 return TPResult::Ambiguous(); 1073} 1074 1075/// [ObjC] protocol-qualifiers: 1076//// '<' identifier-list '>' 1077Parser::TPResult Parser::TryParseProtocolQualifiers() { 1078 assert(Tok.is(tok::less) && "Expected '<' for qualifier list"); 1079 ConsumeToken(); 1080 do { 1081 if (Tok.isNot(tok::identifier)) 1082 return TPResult::Error(); 1083 ConsumeToken(); 1084 1085 if (Tok.is(tok::comma)) { 1086 ConsumeToken(); 1087 continue; 1088 } 1089 1090 if (Tok.is(tok::greater)) { 1091 ConsumeToken(); 1092 return TPResult::Ambiguous(); 1093 } 1094 } while (false); 1095 1096 return TPResult::Error(); 1097} 1098 1099Parser::TPResult Parser::TryParseDeclarationSpecifier() { 1100 TPResult TPR = isCXXDeclarationSpecifier(); 1101 if (TPR != TPResult::Ambiguous()) 1102 return TPR; 1103 1104 if (Tok.is(tok::kw_typeof)) 1105 TryParseTypeofSpecifier(); 1106 else { 1107 ConsumeToken(); 1108 1109 if (getLang().ObjC1 && Tok.is(tok::less)) 1110 TryParseProtocolQualifiers(); 1111 } 1112 1113 assert(Tok.is(tok::l_paren) && "Expected '('!"); 1114 return TPResult::Ambiguous(); 1115} 1116 1117/// isCXXFunctionDeclarator - Disambiguates between a function declarator or 1118/// a constructor-style initializer, when parsing declaration statements. 1119/// Returns true for function declarator and false for constructor-style 1120/// initializer. 1121/// If during the disambiguation process a parsing error is encountered, 1122/// the function returns true to let the declaration parsing code handle it. 1123/// 1124/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1125/// exception-specification[opt] 1126/// 1127bool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) { 1128 1129 // C++ 8.2p1: 1130 // The ambiguity arising from the similarity between a function-style cast and 1131 // a declaration mentioned in 6.8 can also occur in the context of a 1132 // declaration. In that context, the choice is between a function declaration 1133 // with a redundant set of parentheses around a parameter name and an object 1134 // declaration with a function-style cast as the initializer. Just as for the 1135 // ambiguities mentioned in 6.8, the resolution is to consider any construct 1136 // that could possibly be a declaration a declaration. 1137 1138 TentativeParsingAction PA(*this); 1139 1140 ConsumeParen(); 1141 TPResult TPR = TryParseParameterDeclarationClause(); 1142 if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1143 TPR = TPResult::False(); 1144 1145 SourceLocation TPLoc = Tok.getLocation(); 1146 PA.Revert(); 1147 1148 // In case of an error, let the declaration parsing code handle it. 1149 if (TPR == TPResult::Error()) 1150 return true; 1151 1152 if (TPR == TPResult::Ambiguous()) { 1153 // Function declarator has precedence over constructor-style initializer. 1154 // Emit a warning just in case the author intended a variable definition. 1155 if (warnIfAmbiguous) 1156 Diag(Tok, diag::warn_parens_disambiguated_as_function_decl) 1157 << SourceRange(Tok.getLocation(), TPLoc); 1158 return true; 1159 } 1160 1161 return TPR == TPResult::True(); 1162} 1163 1164/// parameter-declaration-clause: 1165/// parameter-declaration-list[opt] '...'[opt] 1166/// parameter-declaration-list ',' '...' 1167/// 1168/// parameter-declaration-list: 1169/// parameter-declaration 1170/// parameter-declaration-list ',' parameter-declaration 1171/// 1172/// parameter-declaration: 1173/// decl-specifier-seq declarator attributes[opt] 1174/// decl-specifier-seq declarator attributes[opt] '=' assignment-expression 1175/// decl-specifier-seq abstract-declarator[opt] attributes[opt] 1176/// decl-specifier-seq abstract-declarator[opt] attributes[opt] 1177/// '=' assignment-expression 1178/// 1179Parser::TPResult Parser::TryParseParameterDeclarationClause() { 1180 1181 if (Tok.is(tok::r_paren)) 1182 return TPResult::True(); 1183 1184 // parameter-declaration-list[opt] '...'[opt] 1185 // parameter-declaration-list ',' '...' 1186 // 1187 // parameter-declaration-list: 1188 // parameter-declaration 1189 // parameter-declaration-list ',' parameter-declaration 1190 // 1191 while (1) { 1192 // '...'[opt] 1193 if (Tok.is(tok::ellipsis)) { 1194 ConsumeToken(); 1195 return TPResult::True(); // '...' is a sign of a function declarator. 1196 } 1197 1198 ParsedAttributes attrs(AttrFactory); 1199 MaybeParseMicrosoftAttributes(attrs); 1200 1201 // decl-specifier-seq 1202 TPResult TPR = TryParseDeclarationSpecifier(); 1203 if (TPR != TPResult::Ambiguous()) 1204 return TPR; 1205 1206 // declarator 1207 // abstract-declarator[opt] 1208 TPR = TryParseDeclarator(true/*mayBeAbstract*/); 1209 if (TPR != TPResult::Ambiguous()) 1210 return TPR; 1211 1212 // [GNU] attributes[opt] 1213 if (Tok.is(tok::kw___attribute)) 1214 return TPResult::True(); 1215 1216 if (Tok.is(tok::equal)) { 1217 // '=' assignment-expression 1218 // Parse through assignment-expression. 1219 tok::TokenKind StopToks[2] ={ tok::comma, tok::r_paren }; 1220 if (!SkipUntil(StopToks, 2, true/*StopAtSemi*/, true/*DontConsume*/)) 1221 return TPResult::Error(); 1222 } 1223 1224 if (Tok.is(tok::ellipsis)) { 1225 ConsumeToken(); 1226 return TPResult::True(); // '...' is a sign of a function declarator. 1227 } 1228 1229 if (Tok.isNot(tok::comma)) 1230 break; 1231 ConsumeToken(); // the comma. 1232 } 1233 1234 return TPResult::Ambiguous(); 1235} 1236 1237/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 1238/// parsing as a function declarator. 1239/// If TryParseFunctionDeclarator fully parsed the function declarator, it will 1240/// return TPResult::Ambiguous(), otherwise it will return either False() or 1241/// Error(). 1242/// 1243/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1244/// exception-specification[opt] 1245/// 1246/// exception-specification: 1247/// 'throw' '(' type-id-list[opt] ')' 1248/// 1249Parser::TPResult Parser::TryParseFunctionDeclarator() { 1250 1251 // The '(' is already parsed. 1252 1253 TPResult TPR = TryParseParameterDeclarationClause(); 1254 if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1255 TPR = TPResult::False(); 1256 1257 if (TPR == TPResult::False() || TPR == TPResult::Error()) 1258 return TPR; 1259 1260 // Parse through the parens. 1261 if (!SkipUntil(tok::r_paren)) 1262 return TPResult::Error(); 1263 1264 // cv-qualifier-seq 1265 while (Tok.is(tok::kw_const) || 1266 Tok.is(tok::kw_volatile) || 1267 Tok.is(tok::kw_restrict) ) 1268 ConsumeToken(); 1269 1270 // ref-qualifier[opt] 1271 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) 1272 ConsumeToken(); 1273 1274 // exception-specification 1275 if (Tok.is(tok::kw_throw)) { 1276 ConsumeToken(); 1277 if (Tok.isNot(tok::l_paren)) 1278 return TPResult::Error(); 1279 1280 // Parse through the parens after 'throw'. 1281 ConsumeParen(); 1282 if (!SkipUntil(tok::r_paren)) 1283 return TPResult::Error(); 1284 } 1285 if (Tok.is(tok::kw_noexcept)) { 1286 ConsumeToken(); 1287 // Possibly an expression as well. 1288 if (Tok.is(tok::l_paren)) { 1289 // Find the matching rparen. 1290 ConsumeParen(); 1291 if (!SkipUntil(tok::r_paren)) 1292 return TPResult::Error(); 1293 } 1294 } 1295 1296 return TPResult::Ambiguous(); 1297} 1298 1299/// '[' constant-expression[opt] ']' 1300/// 1301Parser::TPResult Parser::TryParseBracketDeclarator() { 1302 ConsumeBracket(); 1303 if (!SkipUntil(tok::r_square)) 1304 return TPResult::Error(); 1305 1306 return TPResult::Ambiguous(); 1307} 1308