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