ParseTentative.cpp revision 736104a7619c53ef92553780273d7357a3cdde81
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 bool InvalidAsDeclaration = false; 108 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(), 109 &InvalidAsDeclaration); 110 if (TPR != TPResult::Ambiguous()) 111 return TPR != TPResult::False(); // Returns true for TPResult::True() or 112 // TPResult::Error(). 113 114 // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer, 115 // and so gets some cases wrong. We can't carry on if we've already seen 116 // something which makes this statement invalid as a declaration in this case, 117 // since it can cause us to misparse valid code. Revisit this once 118 // TryParseInitDeclaratorList is fixed. 119 if (InvalidAsDeclaration) 120 return false; 121 122 // FIXME: Add statistics about the number of ambiguous statements encountered 123 // and how they were resolved (number of declarations+number of expressions). 124 125 // Ok, we have a simple-type-specifier/typename-specifier followed by a '(', 126 // or an identifier which doesn't resolve as anything. We need tentative 127 // parsing... 128 129 TentativeParsingAction PA(*this); 130 TPR = TryParseSimpleDeclaration(AllowForRangeDecl); 131 PA.Revert(); 132 133 // In case of an error, let the declaration parsing code handle it. 134 if (TPR == TPResult::Error()) 135 return true; 136 137 // Declarations take precedence over expressions. 138 if (TPR == TPResult::Ambiguous()) 139 TPR = TPResult::True(); 140 141 assert(TPR == TPResult::True() || TPR == TPResult::False()); 142 return TPR == TPResult::True(); 143} 144 145/// simple-declaration: 146/// decl-specifier-seq init-declarator-list[opt] ';' 147/// 148/// (if AllowForRangeDecl specified) 149/// for ( for-range-declaration : for-range-initializer ) statement 150/// for-range-declaration: 151/// attribute-specifier-seqopt type-specifier-seq declarator 152/// 153Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { 154 if (Tok.is(tok::kw_typeof)) 155 TryParseTypeofSpecifier(); 156 else { 157 if (Tok.is(tok::annot_cxxscope)) 158 ConsumeToken(); 159 ConsumeToken(); 160 161 if (getLangOpts().ObjC1 && Tok.is(tok::less)) 162 TryParseProtocolQualifiers(); 163 } 164 165 // Two decl-specifiers in a row conclusively disambiguate this as being a 166 // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the 167 // overwhelmingly common case that the next token is a '('. 168 if (Tok.isNot(tok::l_paren)) { 169 TPResult TPR = isCXXDeclarationSpecifier(); 170 if (TPR == TPResult::Ambiguous()) 171 return TPResult::True(); 172 if (TPR == TPResult::True() || TPR == TPResult::Error()) 173 return TPR; 174 assert(TPR == TPResult::False()); 175 } 176 177 TPResult TPR = TryParseInitDeclaratorList(); 178 if (TPR != TPResult::Ambiguous()) 179 return TPR; 180 181 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon))) 182 return TPResult::False(); 183 184 return TPResult::Ambiguous(); 185} 186 187/// init-declarator-list: 188/// init-declarator 189/// init-declarator-list ',' init-declarator 190/// 191/// init-declarator: 192/// declarator initializer[opt] 193/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 194/// 195/// initializer: 196/// '=' initializer-clause 197/// '(' expression-list ')' 198/// 199/// initializer-clause: 200/// assignment-expression 201/// '{' initializer-list ','[opt] '}' 202/// '{' '}' 203/// 204Parser::TPResult Parser::TryParseInitDeclaratorList() { 205 while (1) { 206 // declarator 207 TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 208 if (TPR != TPResult::Ambiguous()) 209 return TPR; 210 211 // [GNU] simple-asm-expr[opt] attributes[opt] 212 if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 213 return TPResult::True(); 214 215 // initializer[opt] 216 if (Tok.is(tok::l_paren)) { 217 // Parse through the parens. 218 ConsumeParen(); 219 if (!SkipUntil(tok::r_paren)) 220 return TPResult::Error(); 221 } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { 222 // MSVC and g++ won't examine the rest of declarators if '=' is 223 // encountered; they just conclude that we have a declaration. 224 // EDG parses the initializer completely, which is the proper behavior 225 // for this case. 226 // 227 // At present, Clang follows MSVC and g++, since the parser does not have 228 // the ability to parse an expression fully without recording the 229 // results of that parse. 230 // Also allow 'in' after on objective-c declaration as in: 231 // for (int (^b)(void) in array). Ideally this should be done in the 232 // context of parsing for-init-statement of a foreach statement only. But, 233 // in any other context 'in' is invalid after a declaration and parser 234 // issues the error regardless of outcome of this decision. 235 // FIXME. Change if above assumption does not hold. 236 return TPResult::True(); 237 } 238 239 if (Tok.isNot(tok::comma)) 240 break; 241 ConsumeToken(); // the comma. 242 } 243 244 return TPResult::Ambiguous(); 245} 246 247/// isCXXConditionDeclaration - Disambiguates between a declaration or an 248/// expression for a condition of a if/switch/while/for statement. 249/// If during the disambiguation process a parsing error is encountered, 250/// the function returns true to let the declaration parsing code handle it. 251/// 252/// condition: 253/// expression 254/// type-specifier-seq declarator '=' assignment-expression 255/// [C++11] type-specifier-seq declarator '=' initializer-clause 256/// [C++11] type-specifier-seq declarator braced-init-list 257/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 258/// '=' assignment-expression 259/// 260bool Parser::isCXXConditionDeclaration() { 261 TPResult TPR = isCXXDeclarationSpecifier(); 262 if (TPR != TPResult::Ambiguous()) 263 return TPR != TPResult::False(); // Returns true for TPResult::True() or 264 // TPResult::Error(). 265 266 // FIXME: Add statistics about the number of ambiguous statements encountered 267 // and how they were resolved (number of declarations+number of expressions). 268 269 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 270 // We need tentative parsing... 271 272 TentativeParsingAction PA(*this); 273 274 // type-specifier-seq 275 if (Tok.is(tok::kw_typeof)) 276 TryParseTypeofSpecifier(); 277 else { 278 ConsumeToken(); 279 280 if (getLangOpts().ObjC1 && Tok.is(tok::less)) 281 TryParseProtocolQualifiers(); 282 } 283 assert(Tok.is(tok::l_paren) && "Expected '('"); 284 285 // declarator 286 TPR = TryParseDeclarator(false/*mayBeAbstract*/); 287 288 // In case of an error, let the declaration parsing code handle it. 289 if (TPR == TPResult::Error()) 290 TPR = TPResult::True(); 291 292 if (TPR == TPResult::Ambiguous()) { 293 // '=' 294 // [GNU] simple-asm-expr[opt] attributes[opt] 295 if (Tok.is(tok::equal) || 296 Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 297 TPR = TPResult::True(); 298 else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) 299 TPR = TPResult::True(); 300 else 301 TPR = TPResult::False(); 302 } 303 304 PA.Revert(); 305 306 assert(TPR == TPResult::True() || TPR == TPResult::False()); 307 return TPR == TPResult::True(); 308} 309 310 /// \brief Determine whether the next set of tokens contains a type-id. 311 /// 312 /// The context parameter states what context we're parsing right 313 /// now, which affects how this routine copes with the token 314 /// following the type-id. If the context is TypeIdInParens, we have 315 /// already parsed the '(' and we will cease lookahead when we hit 316 /// the corresponding ')'. If the context is 317 /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 318 /// before this template argument, and will cease lookahead when we 319 /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 320 /// and false for an expression. If during the disambiguation 321 /// process a parsing error is encountered, the function returns 322 /// true to let the declaration parsing code handle it. 323 /// 324 /// type-id: 325 /// type-specifier-seq abstract-declarator[opt] 326 /// 327bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 328 329 isAmbiguous = false; 330 331 // C++ 8.2p2: 332 // The ambiguity arising from the similarity between a function-style cast and 333 // a type-id can occur in different contexts. The ambiguity appears as a 334 // choice between a function-style cast expression and a declaration of a 335 // type. The resolution is that any construct that could possibly be a type-id 336 // in its syntactic context shall be considered a type-id. 337 338 TPResult TPR = isCXXDeclarationSpecifier(); 339 if (TPR != TPResult::Ambiguous()) 340 return TPR != TPResult::False(); // Returns true for TPResult::True() or 341 // TPResult::Error(). 342 343 // FIXME: Add statistics about the number of ambiguous statements encountered 344 // and how they were resolved (number of declarations+number of expressions). 345 346 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 347 // We need tentative parsing... 348 349 TentativeParsingAction PA(*this); 350 351 // type-specifier-seq 352 if (Tok.is(tok::kw_typeof)) 353 TryParseTypeofSpecifier(); 354 else { 355 ConsumeToken(); 356 357 if (getLangOpts().ObjC1 && Tok.is(tok::less)) 358 TryParseProtocolQualifiers(); 359 } 360 361 assert(Tok.is(tok::l_paren) && "Expected '('"); 362 363 // declarator 364 TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 365 366 // In case of an error, let the declaration parsing code handle it. 367 if (TPR == TPResult::Error()) 368 TPR = TPResult::True(); 369 370 if (TPR == TPResult::Ambiguous()) { 371 // We are supposed to be inside parens, so if after the abstract declarator 372 // we encounter a ')' this is a type-id, otherwise it's an expression. 373 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 374 TPR = TPResult::True(); 375 isAmbiguous = true; 376 377 // We are supposed to be inside a template argument, so if after 378 // the abstract declarator we encounter a '>', '>>' (in C++0x), or 379 // ',', this is a type-id. Otherwise, it's an expression. 380 } else if (Context == TypeIdAsTemplateArgument && 381 (Tok.is(tok::greater) || Tok.is(tok::comma) || 382 (getLangOpts().CPlusPlus0x && Tok.is(tok::greatergreater)))) { 383 TPR = TPResult::True(); 384 isAmbiguous = true; 385 386 } else 387 TPR = TPResult::False(); 388 } 389 390 PA.Revert(); 391 392 assert(TPR == TPResult::True() || TPR == TPResult::False()); 393 return TPR == TPResult::True(); 394} 395 396/// \brief Returns true if this is a C++11 attribute-specifier. Per 397/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens 398/// always introduce an attribute. In Objective-C++11, this rule does not 399/// apply if either '[' begins a message-send. 400/// 401/// If Disambiguate is true, we try harder to determine whether a '[[' starts 402/// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not. 403/// 404/// If OuterMightBeMessageSend is true, we assume the outer '[' is either an 405/// Obj-C message send or the start of an attribute. Otherwise, we assume it 406/// is not an Obj-C message send. 407/// 408/// C++11 [dcl.attr.grammar]: 409/// 410/// attribute-specifier: 411/// '[' '[' attribute-list ']' ']' 412/// alignment-specifier 413/// 414/// attribute-list: 415/// attribute[opt] 416/// attribute-list ',' attribute[opt] 417/// attribute '...' 418/// attribute-list ',' attribute '...' 419/// 420/// attribute: 421/// attribute-token attribute-argument-clause[opt] 422/// 423/// attribute-token: 424/// identifier 425/// identifier '::' identifier 426/// 427/// attribute-argument-clause: 428/// '(' balanced-token-seq ')' 429Parser::CXX11AttributeKind 430Parser::isCXX11AttributeSpecifier(bool Disambiguate, 431 bool OuterMightBeMessageSend) { 432 if (Tok.is(tok::kw_alignas)) 433 return CAK_AttributeSpecifier; 434 435 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) 436 return CAK_NotAttributeSpecifier; 437 438 // No tentative parsing if we don't need to look for ']]' or a lambda. 439 if (!Disambiguate && !getLangOpts().ObjC1) 440 return CAK_AttributeSpecifier; 441 442 TentativeParsingAction PA(*this); 443 444 // Opening brackets were checked for above. 445 ConsumeBracket(); 446 447 // Outside Obj-C++11, treat anything with a matching ']]' as an attribute. 448 if (!getLangOpts().ObjC1) { 449 ConsumeBracket(); 450 451 bool IsAttribute = SkipUntil(tok::r_square, false); 452 IsAttribute &= Tok.is(tok::r_square); 453 454 PA.Revert(); 455 456 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier; 457 } 458 459 // In Obj-C++11, we need to distinguish four situations: 460 // 1a) int x[[attr]]; C++11 attribute. 461 // 1b) [[attr]]; C++11 statement attribute. 462 // 2) int x[[obj](){ return 1; }()]; Lambda in array size/index. 463 // 3a) int x[[obj get]]; Message send in array size/index. 464 // 3b) [[Class alloc] init]; Message send in message send. 465 // 4) [[obj]{ return self; }() doStuff]; Lambda in message send. 466 // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted. 467 468 // If we have a lambda-introducer, then this is definitely not a message send. 469 // FIXME: If this disambiguation is too slow, fold the tentative lambda parse 470 // into the tentative attribute parse below. 471 LambdaIntroducer Intro; 472 if (!TryParseLambdaIntroducer(Intro)) { 473 // A lambda cannot end with ']]', and an attribute must. 474 bool IsAttribute = Tok.is(tok::r_square); 475 476 PA.Revert(); 477 478 if (IsAttribute) 479 // Case 1: C++11 attribute. 480 return CAK_AttributeSpecifier; 481 482 if (OuterMightBeMessageSend) 483 // Case 4: Lambda in message send. 484 return CAK_NotAttributeSpecifier; 485 486 // Case 2: Lambda in array size / index. 487 return CAK_InvalidAttributeSpecifier; 488 } 489 490 ConsumeBracket(); 491 492 // If we don't have a lambda-introducer, then we have an attribute or a 493 // message-send. 494 bool IsAttribute = true; 495 while (Tok.isNot(tok::r_square)) { 496 if (Tok.is(tok::comma)) { 497 // Case 1: Stray commas can only occur in attributes. 498 PA.Revert(); 499 return CAK_AttributeSpecifier; 500 } 501 502 // Parse the attribute-token, if present. 503 // C++11 [dcl.attr.grammar]: 504 // If a keyword or an alternative token that satisfies the syntactic 505 // requirements of an identifier is contained in an attribute-token, 506 // it is considered an identifier. 507 SourceLocation Loc; 508 if (!TryParseCXX11AttributeIdentifier(Loc)) { 509 IsAttribute = false; 510 break; 511 } 512 if (Tok.is(tok::coloncolon)) { 513 ConsumeToken(); 514 if (!TryParseCXX11AttributeIdentifier(Loc)) { 515 IsAttribute = false; 516 break; 517 } 518 } 519 520 // Parse the attribute-argument-clause, if present. 521 if (Tok.is(tok::l_paren)) { 522 ConsumeParen(); 523 if (!SkipUntil(tok::r_paren, false)) { 524 IsAttribute = false; 525 break; 526 } 527 } 528 529 if (Tok.is(tok::ellipsis)) 530 ConsumeToken(); 531 532 if (Tok.isNot(tok::comma)) 533 break; 534 535 ConsumeToken(); 536 } 537 538 // An attribute must end ']]'. 539 if (IsAttribute) { 540 if (Tok.is(tok::r_square)) { 541 ConsumeBracket(); 542 IsAttribute = Tok.is(tok::r_square); 543 } else { 544 IsAttribute = false; 545 } 546 } 547 548 PA.Revert(); 549 550 if (IsAttribute) 551 // Case 1: C++11 statement attribute. 552 return CAK_AttributeSpecifier; 553 554 // Case 3: Message send. 555 return CAK_NotAttributeSpecifier; 556} 557 558/// declarator: 559/// direct-declarator 560/// ptr-operator declarator 561/// 562/// direct-declarator: 563/// declarator-id 564/// direct-declarator '(' parameter-declaration-clause ')' 565/// cv-qualifier-seq[opt] exception-specification[opt] 566/// direct-declarator '[' constant-expression[opt] ']' 567/// '(' declarator ')' 568/// [GNU] '(' attributes declarator ')' 569/// 570/// abstract-declarator: 571/// ptr-operator abstract-declarator[opt] 572/// direct-abstract-declarator 573/// ... 574/// 575/// direct-abstract-declarator: 576/// direct-abstract-declarator[opt] 577/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 578/// exception-specification[opt] 579/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 580/// '(' abstract-declarator ')' 581/// 582/// ptr-operator: 583/// '*' cv-qualifier-seq[opt] 584/// '&' 585/// [C++0x] '&&' [TODO] 586/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 587/// 588/// cv-qualifier-seq: 589/// cv-qualifier cv-qualifier-seq[opt] 590/// 591/// cv-qualifier: 592/// 'const' 593/// 'volatile' 594/// 595/// declarator-id: 596/// '...'[opt] id-expression 597/// 598/// id-expression: 599/// unqualified-id 600/// qualified-id [TODO] 601/// 602/// unqualified-id: 603/// identifier 604/// operator-function-id [TODO] 605/// conversion-function-id [TODO] 606/// '~' class-name [TODO] 607/// template-id [TODO] 608/// 609Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 610 bool mayHaveIdentifier) { 611 // declarator: 612 // direct-declarator 613 // ptr-operator declarator 614 615 while (1) { 616 if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 617 if (TryAnnotateCXXScopeToken(true)) 618 return TPResult::Error(); 619 620 if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 621 Tok.is(tok::ampamp) || 622 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 623 // ptr-operator 624 ConsumeToken(); 625 while (Tok.is(tok::kw_const) || 626 Tok.is(tok::kw_volatile) || 627 Tok.is(tok::kw_restrict)) 628 ConsumeToken(); 629 } else { 630 break; 631 } 632 } 633 634 // direct-declarator: 635 // direct-abstract-declarator: 636 if (Tok.is(tok::ellipsis)) 637 ConsumeToken(); 638 639 if ((Tok.is(tok::identifier) || 640 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) && 641 mayHaveIdentifier) { 642 // declarator-id 643 if (Tok.is(tok::annot_cxxscope)) 644 ConsumeToken(); 645 else 646 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo()); 647 ConsumeToken(); 648 } else if (Tok.is(tok::l_paren)) { 649 ConsumeParen(); 650 if (mayBeAbstract && 651 (Tok.is(tok::r_paren) || // 'int()' is a function. 652 // 'int(...)' is a function. 653 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) || 654 isDeclarationSpecifier())) { // 'int(int)' is a function. 655 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 656 // exception-specification[opt] 657 TPResult TPR = TryParseFunctionDeclarator(); 658 if (TPR != TPResult::Ambiguous()) 659 return TPR; 660 } else { 661 // '(' declarator ')' 662 // '(' attributes declarator ')' 663 // '(' abstract-declarator ')' 664 if (Tok.is(tok::kw___attribute) || 665 Tok.is(tok::kw___declspec) || 666 Tok.is(tok::kw___cdecl) || 667 Tok.is(tok::kw___stdcall) || 668 Tok.is(tok::kw___fastcall) || 669 Tok.is(tok::kw___thiscall) || 670 Tok.is(tok::kw___unaligned)) 671 return TPResult::True(); // attributes indicate declaration 672 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 673 if (TPR != TPResult::Ambiguous()) 674 return TPR; 675 if (Tok.isNot(tok::r_paren)) 676 return TPResult::False(); 677 ConsumeParen(); 678 } 679 } else if (!mayBeAbstract) { 680 return TPResult::False(); 681 } 682 683 while (1) { 684 TPResult TPR(TPResult::Ambiguous()); 685 686 // abstract-declarator: ... 687 if (Tok.is(tok::ellipsis)) 688 ConsumeToken(); 689 690 if (Tok.is(tok::l_paren)) { 691 // Check whether we have a function declarator or a possible ctor-style 692 // initializer that follows the declarator. Note that ctor-style 693 // initializers are not possible in contexts where abstract declarators 694 // are allowed. 695 if (!mayBeAbstract && !isCXXFunctionDeclarator()) 696 break; 697 698 // direct-declarator '(' parameter-declaration-clause ')' 699 // cv-qualifier-seq[opt] exception-specification[opt] 700 ConsumeParen(); 701 TPR = TryParseFunctionDeclarator(); 702 } else if (Tok.is(tok::l_square)) { 703 // direct-declarator '[' constant-expression[opt] ']' 704 // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 705 TPR = TryParseBracketDeclarator(); 706 } else { 707 break; 708 } 709 710 if (TPR != TPResult::Ambiguous()) 711 return TPR; 712 } 713 714 return TPResult::Ambiguous(); 715} 716 717Parser::TPResult 718Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { 719 switch (Kind) { 720 // Obviously starts an expression. 721 case tok::numeric_constant: 722 case tok::char_constant: 723 case tok::wide_char_constant: 724 case tok::utf16_char_constant: 725 case tok::utf32_char_constant: 726 case tok::string_literal: 727 case tok::wide_string_literal: 728 case tok::utf8_string_literal: 729 case tok::utf16_string_literal: 730 case tok::utf32_string_literal: 731 case tok::l_square: 732 case tok::l_paren: 733 case tok::amp: 734 case tok::ampamp: 735 case tok::star: 736 case tok::plus: 737 case tok::plusplus: 738 case tok::minus: 739 case tok::minusminus: 740 case tok::tilde: 741 case tok::exclaim: 742 case tok::kw_sizeof: 743 case tok::kw___func__: 744 case tok::kw_const_cast: 745 case tok::kw_delete: 746 case tok::kw_dynamic_cast: 747 case tok::kw_false: 748 case tok::kw_new: 749 case tok::kw_operator: 750 case tok::kw_reinterpret_cast: 751 case tok::kw_static_cast: 752 case tok::kw_this: 753 case tok::kw_throw: 754 case tok::kw_true: 755 case tok::kw_typeid: 756 case tok::kw_alignof: 757 case tok::kw_noexcept: 758 case tok::kw_nullptr: 759 case tok::kw__Alignof: 760 case tok::kw___null: 761 case tok::kw___alignof: 762 case tok::kw___builtin_choose_expr: 763 case tok::kw___builtin_offsetof: 764 case tok::kw___builtin_types_compatible_p: 765 case tok::kw___builtin_va_arg: 766 case tok::kw___imag: 767 case tok::kw___real: 768 case tok::kw___FUNCTION__: 769 case tok::kw_L__FUNCTION__: 770 case tok::kw___PRETTY_FUNCTION__: 771 case tok::kw___has_nothrow_assign: 772 case tok::kw___has_nothrow_copy: 773 case tok::kw___has_nothrow_constructor: 774 case tok::kw___has_trivial_assign: 775 case tok::kw___has_trivial_copy: 776 case tok::kw___has_trivial_constructor: 777 case tok::kw___has_trivial_destructor: 778 case tok::kw___has_virtual_destructor: 779 case tok::kw___is_abstract: 780 case tok::kw___is_base_of: 781 case tok::kw___is_class: 782 case tok::kw___is_convertible_to: 783 case tok::kw___is_empty: 784 case tok::kw___is_enum: 785 case tok::kw___is_interface_class: 786 case tok::kw___is_final: 787 case tok::kw___is_literal: 788 case tok::kw___is_literal_type: 789 case tok::kw___is_pod: 790 case tok::kw___is_polymorphic: 791 case tok::kw___is_trivial: 792 case tok::kw___is_trivially_assignable: 793 case tok::kw___is_trivially_constructible: 794 case tok::kw___is_trivially_copyable: 795 case tok::kw___is_union: 796 case tok::kw___uuidof: 797 return TPResult::True(); 798 799 // Obviously starts a type-specifier-seq: 800 case tok::kw_char: 801 case tok::kw_const: 802 case tok::kw_double: 803 case tok::kw_enum: 804 case tok::kw_half: 805 case tok::kw_float: 806 case tok::kw_int: 807 case tok::kw_long: 808 case tok::kw___int64: 809 case tok::kw___int128: 810 case tok::kw_restrict: 811 case tok::kw_short: 812 case tok::kw_signed: 813 case tok::kw_struct: 814 case tok::kw_union: 815 case tok::kw_unsigned: 816 case tok::kw_void: 817 case tok::kw_volatile: 818 case tok::kw__Bool: 819 case tok::kw__Complex: 820 case tok::kw_class: 821 case tok::kw_typename: 822 case tok::kw_wchar_t: 823 case tok::kw_char16_t: 824 case tok::kw_char32_t: 825 case tok::kw___underlying_type: 826 case tok::kw_thread_local: 827 case tok::kw__Decimal32: 828 case tok::kw__Decimal64: 829 case tok::kw__Decimal128: 830 case tok::kw___thread: 831 case tok::kw_typeof: 832 case tok::kw___cdecl: 833 case tok::kw___stdcall: 834 case tok::kw___fastcall: 835 case tok::kw___thiscall: 836 case tok::kw___unaligned: 837 case tok::kw___vector: 838 case tok::kw___pixel: 839 case tok::kw__Atomic: 840 case tok::kw_image1d_t: 841 case tok::kw_image1d_array_t: 842 case tok::kw_image1d_buffer_t: 843 case tok::kw_image2d_t: 844 case tok::kw_image2d_array_t: 845 case tok::kw_image3d_t: 846 case tok::kw___unknown_anytype: 847 return TPResult::False(); 848 849 default: 850 break; 851 } 852 853 return TPResult::Ambiguous(); 854} 855 856bool Parser::isTentativelyDeclared(IdentifierInfo *II) { 857 return std::find(TentativelyDeclaredIdentifiers.begin(), 858 TentativelyDeclaredIdentifiers.end(), II) 859 != TentativelyDeclaredIdentifiers.end(); 860} 861 862/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 863/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 864/// be either a decl-specifier or a function-style cast, and TPResult::Error() 865/// if a parsing error was found and reported. 866/// 867/// If HasMissingTypename is provided, a name with a dependent scope specifier 868/// will be treated as ambiguous if the 'typename' keyword is missing. If this 869/// happens, *HasMissingTypename will be set to 'true'. This will also be used 870/// as an indicator that undeclared identifiers (which will trigger a later 871/// parse error) should be treated as types. Returns TPResult::Ambiguous() in 872/// such cases. 873/// 874/// decl-specifier: 875/// storage-class-specifier 876/// type-specifier 877/// function-specifier 878/// 'friend' 879/// 'typedef' 880/// [C++0x] 'constexpr' 881/// [GNU] attributes declaration-specifiers[opt] 882/// 883/// storage-class-specifier: 884/// 'register' 885/// 'static' 886/// 'extern' 887/// 'mutable' 888/// 'auto' 889/// [GNU] '__thread' 890/// 891/// function-specifier: 892/// 'inline' 893/// 'virtual' 894/// 'explicit' 895/// 896/// typedef-name: 897/// identifier 898/// 899/// type-specifier: 900/// simple-type-specifier 901/// class-specifier 902/// enum-specifier 903/// elaborated-type-specifier 904/// typename-specifier 905/// cv-qualifier 906/// 907/// simple-type-specifier: 908/// '::'[opt] nested-name-specifier[opt] type-name 909/// '::'[opt] nested-name-specifier 'template' 910/// simple-template-id [TODO] 911/// 'char' 912/// 'wchar_t' 913/// 'bool' 914/// 'short' 915/// 'int' 916/// 'long' 917/// 'signed' 918/// 'unsigned' 919/// 'float' 920/// 'double' 921/// 'void' 922/// [GNU] typeof-specifier 923/// [GNU] '_Complex' 924/// [C++0x] 'auto' [TODO] 925/// [C++0x] 'decltype' ( expression ) 926/// 927/// type-name: 928/// class-name 929/// enum-name 930/// typedef-name 931/// 932/// elaborated-type-specifier: 933/// class-key '::'[opt] nested-name-specifier[opt] identifier 934/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 935/// simple-template-id 936/// 'enum' '::'[opt] nested-name-specifier[opt] identifier 937/// 938/// enum-name: 939/// identifier 940/// 941/// enum-specifier: 942/// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 943/// 'enum' identifier[opt] '{' enumerator-list ',' '}' 944/// 945/// class-specifier: 946/// class-head '{' member-specification[opt] '}' 947/// 948/// class-head: 949/// class-key identifier[opt] base-clause[opt] 950/// class-key nested-name-specifier identifier base-clause[opt] 951/// class-key nested-name-specifier[opt] simple-template-id 952/// base-clause[opt] 953/// 954/// class-key: 955/// 'class' 956/// 'struct' 957/// 'union' 958/// 959/// cv-qualifier: 960/// 'const' 961/// 'volatile' 962/// [GNU] restrict 963/// 964Parser::TPResult 965Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, 966 bool *HasMissingTypename) { 967 switch (Tok.getKind()) { 968 case tok::identifier: { 969 // Check for need to substitute AltiVec __vector keyword 970 // for "vector" identifier. 971 if (TryAltiVecVectorToken()) 972 return TPResult::True(); 973 974 const Token &Next = NextToken(); 975 // In 'foo bar', 'foo' is always a type name outside of Objective-C. 976 if (!getLangOpts().ObjC1 && Next.is(tok::identifier)) 977 return TPResult::True(); 978 979 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) { 980 // Determine whether this is a valid expression. If not, we will hit 981 // a parse error one way or another. In that case, tell the caller that 982 // this is ambiguous. Typo-correct to type and expression keywords and 983 // to types and identifiers, in order to try to recover from errors. 984 CorrectionCandidateCallback TypoCorrection; 985 TypoCorrection.WantRemainingKeywords = false; 986 switch (TryAnnotateName(false /* no nested name specifier */, 987 &TypoCorrection)) { 988 case ANK_Error: 989 return TPResult::Error(); 990 case ANK_TentativeDecl: 991 return TPResult::False(); 992 case ANK_TemplateName: 993 // A bare type template-name which can't be a template template 994 // argument is an error, and was probably intended to be a type. 995 return GreaterThanIsOperator ? TPResult::True() : TPResult::False(); 996 case ANK_Unresolved: 997 return HasMissingTypename ? TPResult::Ambiguous() : TPResult::False(); 998 case ANK_Success: 999 break; 1000 } 1001 assert(Tok.isNot(tok::identifier) && 1002 "TryAnnotateName succeeded without producing an annotation"); 1003 } else { 1004 // This might possibly be a type with a dependent scope specifier and 1005 // a missing 'typename' keyword. Don't use TryAnnotateName in this case, 1006 // since it will annotate as a primary expression, and we want to use the 1007 // "missing 'typename'" logic. 1008 if (TryAnnotateTypeOrScopeToken()) 1009 return TPResult::Error(); 1010 // If annotation failed, assume it's a non-type. 1011 // FIXME: If this happens due to an undeclared identifier, treat it as 1012 // ambiguous. 1013 if (Tok.is(tok::identifier)) 1014 return TPResult::False(); 1015 } 1016 1017 // We annotated this token as something. Recurse to handle whatever we got. 1018 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1019 } 1020 1021 case tok::kw_typename: // typename T::type 1022 // Annotate typenames and C++ scope specifiers. If we get one, just 1023 // recurse to handle whatever we get. 1024 if (TryAnnotateTypeOrScopeToken()) 1025 return TPResult::Error(); 1026 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1027 1028 case tok::coloncolon: { // ::foo::bar 1029 const Token &Next = NextToken(); 1030 if (Next.is(tok::kw_new) || // ::new 1031 Next.is(tok::kw_delete)) // ::delete 1032 return TPResult::False(); 1033 } 1034 // Fall through. 1035 case tok::kw_decltype: 1036 // Annotate typenames and C++ scope specifiers. If we get one, just 1037 // recurse to handle whatever we get. 1038 if (TryAnnotateTypeOrScopeToken()) 1039 return TPResult::Error(); 1040 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1041 1042 // decl-specifier: 1043 // storage-class-specifier 1044 // type-specifier 1045 // function-specifier 1046 // 'friend' 1047 // 'typedef' 1048 // 'constexpr' 1049 case tok::kw_friend: 1050 case tok::kw_typedef: 1051 case tok::kw_constexpr: 1052 // storage-class-specifier 1053 case tok::kw_register: 1054 case tok::kw_static: 1055 case tok::kw_extern: 1056 case tok::kw_mutable: 1057 case tok::kw_auto: 1058 case tok::kw___thread: 1059 // function-specifier 1060 case tok::kw_inline: 1061 case tok::kw_virtual: 1062 case tok::kw_explicit: 1063 1064 // Modules 1065 case tok::kw___module_private__: 1066 1067 // Debugger support 1068 case tok::kw___unknown_anytype: 1069 1070 // type-specifier: 1071 // simple-type-specifier 1072 // class-specifier 1073 // enum-specifier 1074 // elaborated-type-specifier 1075 // typename-specifier 1076 // cv-qualifier 1077 1078 // class-specifier 1079 // elaborated-type-specifier 1080 case tok::kw_class: 1081 case tok::kw_struct: 1082 case tok::kw_union: 1083 // enum-specifier 1084 case tok::kw_enum: 1085 // cv-qualifier 1086 case tok::kw_const: 1087 case tok::kw_volatile: 1088 1089 // GNU 1090 case tok::kw_restrict: 1091 case tok::kw__Complex: 1092 case tok::kw___attribute: 1093 return TPResult::True(); 1094 1095 // Microsoft 1096 case tok::kw___declspec: 1097 case tok::kw___cdecl: 1098 case tok::kw___stdcall: 1099 case tok::kw___fastcall: 1100 case tok::kw___thiscall: 1101 case tok::kw___w64: 1102 case tok::kw___ptr64: 1103 case tok::kw___ptr32: 1104 case tok::kw___forceinline: 1105 case tok::kw___unaligned: 1106 return TPResult::True(); 1107 1108 // Borland 1109 case tok::kw___pascal: 1110 return TPResult::True(); 1111 1112 // AltiVec 1113 case tok::kw___vector: 1114 return TPResult::True(); 1115 1116 case tok::annot_template_id: { 1117 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 1118 if (TemplateId->Kind != TNK_Type_template) 1119 return TPResult::False(); 1120 CXXScopeSpec SS; 1121 AnnotateTemplateIdTokenAsType(); 1122 assert(Tok.is(tok::annot_typename)); 1123 goto case_typename; 1124 } 1125 1126 case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed 1127 // We've already annotated a scope; try to annotate a type. 1128 if (TryAnnotateTypeOrScopeToken()) 1129 return TPResult::Error(); 1130 if (!Tok.is(tok::annot_typename)) { 1131 // If the next token is an identifier or a type qualifier, then this 1132 // can't possibly be a valid expression either. 1133 if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) { 1134 CXXScopeSpec SS; 1135 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 1136 Tok.getAnnotationRange(), 1137 SS); 1138 if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) { 1139 TentativeParsingAction PA(*this); 1140 ConsumeToken(); 1141 ConsumeToken(); 1142 bool isIdentifier = Tok.is(tok::identifier); 1143 TPResult TPR = TPResult::False(); 1144 if (!isIdentifier) 1145 TPR = isCXXDeclarationSpecifier(BracedCastResult, 1146 HasMissingTypename); 1147 PA.Revert(); 1148 1149 if (isIdentifier || 1150 TPR == TPResult::True() || TPR == TPResult::Error()) 1151 return TPResult::Error(); 1152 1153 if (HasMissingTypename) { 1154 // We can't tell whether this is a missing 'typename' or a valid 1155 // expression. 1156 *HasMissingTypename = true; 1157 return TPResult::Ambiguous(); 1158 } 1159 } else { 1160 // Try to resolve the name. If it doesn't exist, assume it was 1161 // intended to name a type and keep disambiguating. 1162 switch (TryAnnotateName(false /* SS is not dependent */)) { 1163 case ANK_Error: 1164 return TPResult::Error(); 1165 case ANK_TentativeDecl: 1166 return TPResult::False(); 1167 case ANK_TemplateName: 1168 // A bare type template-name which can't be a template template 1169 // argument is an error, and was probably intended to be a type. 1170 return GreaterThanIsOperator ? TPResult::True() : TPResult::False(); 1171 case ANK_Unresolved: 1172 return HasMissingTypename ? TPResult::Ambiguous() 1173 : TPResult::False(); 1174 case ANK_Success: 1175 // Annotated it, check again. 1176 assert(Tok.isNot(tok::annot_cxxscope) || 1177 NextToken().isNot(tok::identifier)); 1178 return isCXXDeclarationSpecifier(BracedCastResult, 1179 HasMissingTypename); 1180 } 1181 } 1182 } 1183 return TPResult::False(); 1184 } 1185 // If that succeeded, fallthrough into the generic simple-type-id case. 1186 1187 // The ambiguity resides in a simple-type-specifier/typename-specifier 1188 // followed by a '('. The '(' could either be the start of: 1189 // 1190 // direct-declarator: 1191 // '(' declarator ')' 1192 // 1193 // direct-abstract-declarator: 1194 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1195 // exception-specification[opt] 1196 // '(' abstract-declarator ')' 1197 // 1198 // or part of a function-style cast expression: 1199 // 1200 // simple-type-specifier '(' expression-list[opt] ')' 1201 // 1202 1203 // simple-type-specifier: 1204 1205 case tok::annot_typename: 1206 case_typename: 1207 // In Objective-C, we might have a protocol-qualified type. 1208 if (getLangOpts().ObjC1 && NextToken().is(tok::less)) { 1209 // Tentatively parse the 1210 TentativeParsingAction PA(*this); 1211 ConsumeToken(); // The type token 1212 1213 TPResult TPR = TryParseProtocolQualifiers(); 1214 bool isFollowedByParen = Tok.is(tok::l_paren); 1215 bool isFollowedByBrace = Tok.is(tok::l_brace); 1216 1217 PA.Revert(); 1218 1219 if (TPR == TPResult::Error()) 1220 return TPResult::Error(); 1221 1222 if (isFollowedByParen) 1223 return TPResult::Ambiguous(); 1224 1225 if (getLangOpts().CPlusPlus0x && isFollowedByBrace) 1226 return BracedCastResult; 1227 1228 return TPResult::True(); 1229 } 1230 1231 case tok::kw_char: 1232 case tok::kw_wchar_t: 1233 case tok::kw_char16_t: 1234 case tok::kw_char32_t: 1235 case tok::kw_bool: 1236 case tok::kw_short: 1237 case tok::kw_int: 1238 case tok::kw_long: 1239 case tok::kw___int64: 1240 case tok::kw___int128: 1241 case tok::kw_signed: 1242 case tok::kw_unsigned: 1243 case tok::kw_half: 1244 case tok::kw_float: 1245 case tok::kw_double: 1246 case tok::kw_void: 1247 case tok::annot_decltype: 1248 if (NextToken().is(tok::l_paren)) 1249 return TPResult::Ambiguous(); 1250 1251 // This is a function-style cast in all cases we disambiguate other than 1252 // one: 1253 // struct S { 1254 // enum E : int { a = 4 }; // enum 1255 // enum E : int { 4 }; // bit-field 1256 // }; 1257 if (getLangOpts().CPlusPlus0x && NextToken().is(tok::l_brace)) 1258 return BracedCastResult; 1259 1260 if (isStartOfObjCClassMessageMissingOpenBracket()) 1261 return TPResult::False(); 1262 1263 return TPResult::True(); 1264 1265 // GNU typeof support. 1266 case tok::kw_typeof: { 1267 if (NextToken().isNot(tok::l_paren)) 1268 return TPResult::True(); 1269 1270 TentativeParsingAction PA(*this); 1271 1272 TPResult TPR = TryParseTypeofSpecifier(); 1273 bool isFollowedByParen = Tok.is(tok::l_paren); 1274 bool isFollowedByBrace = Tok.is(tok::l_brace); 1275 1276 PA.Revert(); 1277 1278 if (TPR == TPResult::Error()) 1279 return TPResult::Error(); 1280 1281 if (isFollowedByParen) 1282 return TPResult::Ambiguous(); 1283 1284 if (getLangOpts().CPlusPlus0x && isFollowedByBrace) 1285 return BracedCastResult; 1286 1287 return TPResult::True(); 1288 } 1289 1290 // C++0x type traits support 1291 case tok::kw___underlying_type: 1292 return TPResult::True(); 1293 1294 // C11 _Atomic 1295 case tok::kw__Atomic: 1296 return TPResult::True(); 1297 1298 default: 1299 return TPResult::False(); 1300 } 1301} 1302 1303/// [GNU] typeof-specifier: 1304/// 'typeof' '(' expressions ')' 1305/// 'typeof' '(' type-name ')' 1306/// 1307Parser::TPResult Parser::TryParseTypeofSpecifier() { 1308 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 1309 ConsumeToken(); 1310 1311 assert(Tok.is(tok::l_paren) && "Expected '('"); 1312 // Parse through the parens after 'typeof'. 1313 ConsumeParen(); 1314 if (!SkipUntil(tok::r_paren)) 1315 return TPResult::Error(); 1316 1317 return TPResult::Ambiguous(); 1318} 1319 1320/// [ObjC] protocol-qualifiers: 1321//// '<' identifier-list '>' 1322Parser::TPResult Parser::TryParseProtocolQualifiers() { 1323 assert(Tok.is(tok::less) && "Expected '<' for qualifier list"); 1324 ConsumeToken(); 1325 do { 1326 if (Tok.isNot(tok::identifier)) 1327 return TPResult::Error(); 1328 ConsumeToken(); 1329 1330 if (Tok.is(tok::comma)) { 1331 ConsumeToken(); 1332 continue; 1333 } 1334 1335 if (Tok.is(tok::greater)) { 1336 ConsumeToken(); 1337 return TPResult::Ambiguous(); 1338 } 1339 } while (false); 1340 1341 return TPResult::Error(); 1342} 1343 1344Parser::TPResult 1345Parser::TryParseDeclarationSpecifier(bool *HasMissingTypename) { 1346 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(), 1347 HasMissingTypename); 1348 if (TPR != TPResult::Ambiguous()) 1349 return TPR; 1350 1351 if (Tok.is(tok::kw_typeof)) 1352 TryParseTypeofSpecifier(); 1353 else { 1354 if (Tok.is(tok::annot_cxxscope)) 1355 ConsumeToken(); 1356 ConsumeToken(); 1357 1358 if (getLangOpts().ObjC1 && Tok.is(tok::less)) 1359 TryParseProtocolQualifiers(); 1360 } 1361 1362 return TPResult::Ambiguous(); 1363} 1364 1365/// isCXXFunctionDeclarator - Disambiguates between a function declarator or 1366/// a constructor-style initializer, when parsing declaration statements. 1367/// Returns true for function declarator and false for constructor-style 1368/// initializer. 1369/// If during the disambiguation process a parsing error is encountered, 1370/// the function returns true to let the declaration parsing code handle it. 1371/// 1372/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1373/// exception-specification[opt] 1374/// 1375bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) { 1376 1377 // C++ 8.2p1: 1378 // The ambiguity arising from the similarity between a function-style cast and 1379 // a declaration mentioned in 6.8 can also occur in the context of a 1380 // declaration. In that context, the choice is between a function declaration 1381 // with a redundant set of parentheses around a parameter name and an object 1382 // declaration with a function-style cast as the initializer. Just as for the 1383 // ambiguities mentioned in 6.8, the resolution is to consider any construct 1384 // that could possibly be a declaration a declaration. 1385 1386 TentativeParsingAction PA(*this); 1387 1388 ConsumeParen(); 1389 bool InvalidAsDeclaration = false; 1390 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration); 1391 if (TPR == TPResult::Ambiguous()) { 1392 if (Tok.isNot(tok::r_paren)) 1393 TPR = TPResult::False(); 1394 else { 1395 const Token &Next = NextToken(); 1396 if (Next.is(tok::amp) || Next.is(tok::ampamp) || 1397 Next.is(tok::kw_const) || Next.is(tok::kw_volatile) || 1398 Next.is(tok::kw_throw) || Next.is(tok::kw_noexcept) || 1399 Next.is(tok::l_square) || isCXX0XVirtSpecifier(Next) || 1400 Next.is(tok::l_brace) || Next.is(tok::kw_try) || 1401 Next.is(tok::equal) || Next.is(tok::arrow)) 1402 // The next token cannot appear after a constructor-style initializer, 1403 // and can appear next in a function definition. This must be a function 1404 // declarator. 1405 TPR = TPResult::True(); 1406 else if (InvalidAsDeclaration) 1407 // Use the absence of 'typename' as a tie-breaker. 1408 TPR = TPResult::False(); 1409 } 1410 } 1411 1412 PA.Revert(); 1413 1414 if (IsAmbiguous && TPR == TPResult::Ambiguous()) 1415 *IsAmbiguous = true; 1416 1417 // In case of an error, let the declaration parsing code handle it. 1418 return TPR != TPResult::False(); 1419} 1420 1421/// parameter-declaration-clause: 1422/// parameter-declaration-list[opt] '...'[opt] 1423/// parameter-declaration-list ',' '...' 1424/// 1425/// parameter-declaration-list: 1426/// parameter-declaration 1427/// parameter-declaration-list ',' parameter-declaration 1428/// 1429/// parameter-declaration: 1430/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] 1431/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] 1432/// '=' assignment-expression 1433/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] 1434/// attributes[opt] 1435/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] 1436/// attributes[opt] '=' assignment-expression 1437/// 1438Parser::TPResult 1439Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration) { 1440 1441 if (Tok.is(tok::r_paren)) 1442 return TPResult::Ambiguous(); 1443 1444 // parameter-declaration-list[opt] '...'[opt] 1445 // parameter-declaration-list ',' '...' 1446 // 1447 // parameter-declaration-list: 1448 // parameter-declaration 1449 // parameter-declaration-list ',' parameter-declaration 1450 // 1451 while (1) { 1452 // '...'[opt] 1453 if (Tok.is(tok::ellipsis)) { 1454 ConsumeToken(); 1455 if (Tok.is(tok::r_paren)) 1456 return TPResult::True(); // '...)' is a sign of a function declarator. 1457 else 1458 return TPResult::False(); 1459 } 1460 1461 // An attribute-specifier-seq here is a sign of a function declarator. 1462 if (isCXX11AttributeSpecifier(/*Disambiguate*/false, 1463 /*OuterMightBeMessageSend*/true)) 1464 return TPResult::True(); 1465 1466 ParsedAttributes attrs(AttrFactory); 1467 MaybeParseMicrosoftAttributes(attrs); 1468 1469 // decl-specifier-seq 1470 // A parameter-declaration's initializer must be preceded by an '=', so 1471 // decl-specifier-seq '{' is not a parameter in C++11. 1472 TPResult TPR = TryParseDeclarationSpecifier(InvalidAsDeclaration); 1473 if (TPR != TPResult::Ambiguous()) 1474 return TPR; 1475 1476 // declarator 1477 // abstract-declarator[opt] 1478 TPR = TryParseDeclarator(true/*mayBeAbstract*/); 1479 if (TPR != TPResult::Ambiguous()) 1480 return TPR; 1481 1482 // [GNU] attributes[opt] 1483 if (Tok.is(tok::kw___attribute)) 1484 return TPResult::True(); 1485 1486 if (Tok.is(tok::equal)) { 1487 // '=' assignment-expression 1488 // Parse through assignment-expression. 1489 if (!SkipUntil(tok::comma, tok::r_paren, true/*StopAtSemi*/, 1490 true/*DontConsume*/)) 1491 return TPResult::Error(); 1492 } 1493 1494 if (Tok.is(tok::ellipsis)) { 1495 ConsumeToken(); 1496 if (Tok.is(tok::r_paren)) 1497 return TPResult::True(); // '...)' is a sign of a function declarator. 1498 else 1499 return TPResult::False(); 1500 } 1501 1502 if (Tok.isNot(tok::comma)) 1503 break; 1504 ConsumeToken(); // the comma. 1505 } 1506 1507 return TPResult::Ambiguous(); 1508} 1509 1510/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 1511/// parsing as a function declarator. 1512/// If TryParseFunctionDeclarator fully parsed the function declarator, it will 1513/// return TPResult::Ambiguous(), otherwise it will return either False() or 1514/// Error(). 1515/// 1516/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1517/// exception-specification[opt] 1518/// 1519/// exception-specification: 1520/// 'throw' '(' type-id-list[opt] ')' 1521/// 1522Parser::TPResult Parser::TryParseFunctionDeclarator() { 1523 1524 // The '(' is already parsed. 1525 1526 TPResult TPR = TryParseParameterDeclarationClause(); 1527 if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1528 TPR = TPResult::False(); 1529 1530 if (TPR == TPResult::False() || TPR == TPResult::Error()) 1531 return TPR; 1532 1533 // Parse through the parens. 1534 if (!SkipUntil(tok::r_paren)) 1535 return TPResult::Error(); 1536 1537 // cv-qualifier-seq 1538 while (Tok.is(tok::kw_const) || 1539 Tok.is(tok::kw_volatile) || 1540 Tok.is(tok::kw_restrict) ) 1541 ConsumeToken(); 1542 1543 // ref-qualifier[opt] 1544 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) 1545 ConsumeToken(); 1546 1547 // exception-specification 1548 if (Tok.is(tok::kw_throw)) { 1549 ConsumeToken(); 1550 if (Tok.isNot(tok::l_paren)) 1551 return TPResult::Error(); 1552 1553 // Parse through the parens after 'throw'. 1554 ConsumeParen(); 1555 if (!SkipUntil(tok::r_paren)) 1556 return TPResult::Error(); 1557 } 1558 if (Tok.is(tok::kw_noexcept)) { 1559 ConsumeToken(); 1560 // Possibly an expression as well. 1561 if (Tok.is(tok::l_paren)) { 1562 // Find the matching rparen. 1563 ConsumeParen(); 1564 if (!SkipUntil(tok::r_paren)) 1565 return TPResult::Error(); 1566 } 1567 } 1568 1569 return TPResult::Ambiguous(); 1570} 1571 1572/// '[' constant-expression[opt] ']' 1573/// 1574Parser::TPResult Parser::TryParseBracketDeclarator() { 1575 ConsumeBracket(); 1576 if (!SkipUntil(tok::r_square)) 1577 return TPResult::Error(); 1578 1579 return TPResult::Ambiguous(); 1580} 1581