1193326Sed//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the tentative parsing portions of the Parser 11193326Sed// interfaces, for ambiguity resolution. 12193326Sed// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed 15193326Sed#include "clang/Parse/Parser.h" 16193326Sed#include "clang/Parse/ParseDiagnostic.h" 17212904Sdim#include "clang/Sema/ParsedTemplate.h" 18193326Sedusing namespace clang; 19193326Sed 20193326Sed/// isCXXDeclarationStatement - C++-specialized function that disambiguates 21193326Sed/// between a declaration or an expression statement, when parsing function 22193326Sed/// bodies. Returns true for declaration, false for expression. 23193326Sed/// 24193326Sed/// declaration-statement: 25193326Sed/// block-declaration 26193326Sed/// 27193326Sed/// block-declaration: 28193326Sed/// simple-declaration 29193326Sed/// asm-definition 30193326Sed/// namespace-alias-definition 31193326Sed/// using-declaration 32193326Sed/// using-directive 33193326Sed/// [C++0x] static_assert-declaration 34193326Sed/// 35193326Sed/// asm-definition: 36193326Sed/// 'asm' '(' string-literal ')' ';' 37193326Sed/// 38193326Sed/// namespace-alias-definition: 39193326Sed/// 'namespace' identifier = qualified-namespace-specifier ';' 40193326Sed/// 41193326Sed/// using-declaration: 42193326Sed/// 'using' typename[opt] '::'[opt] nested-name-specifier 43193326Sed/// unqualified-id ';' 44193326Sed/// 'using' '::' unqualified-id ; 45193326Sed/// 46193326Sed/// using-directive: 47193326Sed/// 'using' 'namespace' '::'[opt] nested-name-specifier[opt] 48193326Sed/// namespace-name ';' 49193326Sed/// 50193326Sedbool Parser::isCXXDeclarationStatement() { 51193326Sed switch (Tok.getKind()) { 52193326Sed // asm-definition 53193326Sed case tok::kw_asm: 54193326Sed // namespace-alias-definition 55193326Sed case tok::kw_namespace: 56193326Sed // using-declaration 57193326Sed // using-directive 58193326Sed case tok::kw_using: 59199990Srdivacky // static_assert-declaration 60193326Sed case tok::kw_static_assert: 61221345Sdim case tok::kw__Static_assert: 62193326Sed return true; 63199990Srdivacky // simple-declaration 64193326Sed default: 65235633Sdim return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false); 66193326Sed } 67193326Sed} 68193326Sed 69193326Sed/// isCXXSimpleDeclaration - C++-specialized function that disambiguates 70193326Sed/// between a simple-declaration or an expression-statement. 71193326Sed/// If during the disambiguation process a parsing error is encountered, 72193326Sed/// the function returns true to let the declaration parsing code handle it. 73193326Sed/// Returns false if the statement is disambiguated as expression. 74193326Sed/// 75193326Sed/// simple-declaration: 76193326Sed/// decl-specifier-seq init-declarator-list[opt] ';' 77193326Sed/// 78235633Sdim/// (if AllowForRangeDecl specified) 79235633Sdim/// for ( for-range-declaration : for-range-initializer ) statement 80235633Sdim/// for-range-declaration: 81235633Sdim/// attribute-specifier-seqopt type-specifier-seq declarator 82235633Sdimbool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) { 83193326Sed // C++ 6.8p1: 84193326Sed // There is an ambiguity in the grammar involving expression-statements and 85193326Sed // declarations: An expression-statement with a function-style explicit type 86193326Sed // conversion (5.2.3) as its leftmost subexpression can be indistinguishable 87193326Sed // from a declaration where the first declarator starts with a '('. In those 88193326Sed // cases the statement is a declaration. [Note: To disambiguate, the whole 89193326Sed // statement might have to be examined to determine if it is an 90193326Sed // expression-statement or a declaration]. 91193326Sed 92193326Sed // C++ 6.8p3: 93193326Sed // The disambiguation is purely syntactic; that is, the meaning of the names 94193326Sed // occurring in such a statement, beyond whether they are type-names or not, 95193326Sed // is not generally used in or changed by the disambiguation. Class 96193326Sed // templates are instantiated as necessary to determine if a qualified name 97193326Sed // is a type-name. Disambiguation precedes parsing, and a statement 98193326Sed // disambiguated as a declaration may be an ill-formed declaration. 99193326Sed 100193326Sed // We don't have to parse all of the decl-specifier-seq part. There's only 101193326Sed // an ambiguity if the first decl-specifier is 102193326Sed // simple-type-specifier/typename-specifier followed by a '(', which may 103193326Sed // indicate a function-style cast expression. 104193326Sed // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such 105193326Sed // a case. 106193326Sed 107245431Sdim bool InvalidAsDeclaration = false; 108245431Sdim TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(), 109245431Sdim &InvalidAsDeclaration); 110193326Sed if (TPR != TPResult::Ambiguous()) 111193326Sed return TPR != TPResult::False(); // Returns true for TPResult::True() or 112193326Sed // TPResult::Error(). 113193326Sed 114245431Sdim // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer, 115245431Sdim // and so gets some cases wrong. We can't carry on if we've already seen 116245431Sdim // something which makes this statement invalid as a declaration in this case, 117245431Sdim // since it can cause us to misparse valid code. Revisit this once 118245431Sdim // TryParseInitDeclaratorList is fixed. 119245431Sdim if (InvalidAsDeclaration) 120245431Sdim return false; 121245431Sdim 122193326Sed // FIXME: Add statistics about the number of ambiguous statements encountered 123193326Sed // and how they were resolved (number of declarations+number of expressions). 124193326Sed 125245431Sdim // Ok, we have a simple-type-specifier/typename-specifier followed by a '(', 126245431Sdim // or an identifier which doesn't resolve as anything. We need tentative 127245431Sdim // parsing... 128193326Sed 129193326Sed TentativeParsingAction PA(*this); 130235633Sdim TPR = TryParseSimpleDeclaration(AllowForRangeDecl); 131193326Sed PA.Revert(); 132193326Sed 133193326Sed // In case of an error, let the declaration parsing code handle it. 134193326Sed if (TPR == TPResult::Error()) 135193326Sed return true; 136193326Sed 137193326Sed // Declarations take precedence over expressions. 138193326Sed if (TPR == TPResult::Ambiguous()) 139193326Sed TPR = TPResult::True(); 140193326Sed 141193326Sed assert(TPR == TPResult::True() || TPR == TPResult::False()); 142193326Sed return TPR == TPResult::True(); 143193326Sed} 144193326Sed 145263509Sdim/// Try to consume a token sequence that we've already identified as 146263509Sdim/// (potentially) starting a decl-specifier. 147263509SdimParser::TPResult Parser::TryConsumeDeclarationSpecifier() { 148263509Sdim switch (Tok.getKind()) { 149263509Sdim case tok::kw__Atomic: 150263509Sdim if (NextToken().isNot(tok::l_paren)) { 151263509Sdim ConsumeToken(); 152263509Sdim break; 153263509Sdim } 154263509Sdim // Fall through. 155263509Sdim case tok::kw_typeof: 156263509Sdim case tok::kw___attribute: 157263509Sdim case tok::kw___underlying_type: { 158263509Sdim ConsumeToken(); 159263509Sdim if (Tok.isNot(tok::l_paren)) 160263509Sdim return TPResult::Error(); 161263509Sdim ConsumeParen(); 162263509Sdim if (!SkipUntil(tok::r_paren)) 163263509Sdim return TPResult::Error(); 164263509Sdim break; 165263509Sdim } 166263509Sdim 167263509Sdim case tok::kw_class: 168263509Sdim case tok::kw_struct: 169263509Sdim case tok::kw_union: 170263509Sdim case tok::kw___interface: 171263509Sdim case tok::kw_enum: 172263509Sdim // elaborated-type-specifier: 173263509Sdim // class-key attribute-specifier-seq[opt] 174263509Sdim // nested-name-specifier[opt] identifier 175263509Sdim // class-key nested-name-specifier[opt] template[opt] simple-template-id 176263509Sdim // enum nested-name-specifier[opt] identifier 177263509Sdim // 178263509Sdim // FIXME: We don't support class-specifiers nor enum-specifiers here. 179263509Sdim ConsumeToken(); 180263509Sdim 181263509Sdim // Skip attributes. 182263509Sdim while (Tok.is(tok::l_square) || Tok.is(tok::kw___attribute) || 183263509Sdim Tok.is(tok::kw___declspec) || Tok.is(tok::kw_alignas)) { 184263509Sdim if (Tok.is(tok::l_square)) { 185263509Sdim ConsumeBracket(); 186263509Sdim if (!SkipUntil(tok::r_square)) 187263509Sdim return TPResult::Error(); 188263509Sdim } else { 189263509Sdim ConsumeToken(); 190263509Sdim if (Tok.isNot(tok::l_paren)) 191263509Sdim return TPResult::Error(); 192263509Sdim ConsumeParen(); 193263509Sdim if (!SkipUntil(tok::r_paren)) 194263509Sdim return TPResult::Error(); 195263509Sdim } 196263509Sdim } 197263509Sdim 198263509Sdim if (TryAnnotateCXXScopeToken()) 199263509Sdim return TPResult::Error(); 200263509Sdim if (Tok.is(tok::annot_cxxscope)) 201263509Sdim ConsumeToken(); 202263509Sdim if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) 203263509Sdim return TPResult::Error(); 204263509Sdim ConsumeToken(); 205263509Sdim break; 206263509Sdim 207263509Sdim case tok::annot_cxxscope: 208263509Sdim ConsumeToken(); 209263509Sdim // Fall through. 210263509Sdim default: 211263509Sdim ConsumeToken(); 212263509Sdim 213263509Sdim if (getLangOpts().ObjC1 && Tok.is(tok::less)) 214263509Sdim return TryParseProtocolQualifiers(); 215263509Sdim break; 216263509Sdim } 217263509Sdim 218263509Sdim return TPResult::Ambiguous(); 219263509Sdim} 220263509Sdim 221193326Sed/// simple-declaration: 222193326Sed/// decl-specifier-seq init-declarator-list[opt] ';' 223193326Sed/// 224235633Sdim/// (if AllowForRangeDecl specified) 225235633Sdim/// for ( for-range-declaration : for-range-initializer ) statement 226235633Sdim/// for-range-declaration: 227235633Sdim/// attribute-specifier-seqopt type-specifier-seq declarator 228235633Sdim/// 229235633SdimParser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { 230263509Sdim if (TryConsumeDeclarationSpecifier() == TPResult::Error()) 231263509Sdim return TPResult::Error(); 232245431Sdim 233245431Sdim // Two decl-specifiers in a row conclusively disambiguate this as being a 234245431Sdim // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the 235245431Sdim // overwhelmingly common case that the next token is a '('. 236245431Sdim if (Tok.isNot(tok::l_paren)) { 237245431Sdim TPResult TPR = isCXXDeclarationSpecifier(); 238245431Sdim if (TPR == TPResult::Ambiguous()) 239245431Sdim return TPResult::True(); 240245431Sdim if (TPR == TPResult::True() || TPR == TPResult::Error()) 241245431Sdim return TPR; 242245431Sdim assert(TPR == TPResult::False()); 243245431Sdim } 244245431Sdim 245193326Sed TPResult TPR = TryParseInitDeclaratorList(); 246193326Sed if (TPR != TPResult::Ambiguous()) 247193326Sed return TPR; 248193326Sed 249235633Sdim if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon))) 250193326Sed return TPResult::False(); 251193326Sed 252193326Sed return TPResult::Ambiguous(); 253193326Sed} 254193326Sed 255252723Sdim/// Tentatively parse an init-declarator-list in order to disambiguate it from 256252723Sdim/// an expression. 257252723Sdim/// 258193326Sed/// init-declarator-list: 259193326Sed/// init-declarator 260193326Sed/// init-declarator-list ',' init-declarator 261193326Sed/// 262193326Sed/// init-declarator: 263193326Sed/// declarator initializer[opt] 264193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 265193326Sed/// 266252723Sdim/// initializer: 267252723Sdim/// brace-or-equal-initializer 268252723Sdim/// '(' expression-list ')' 269193326Sed/// 270252723Sdim/// brace-or-equal-initializer: 271252723Sdim/// '=' initializer-clause 272252723Sdim/// [C++11] braced-init-list 273193326Sed/// 274252723Sdim/// initializer-clause: 275252723Sdim/// assignment-expression 276252723Sdim/// braced-init-list 277252723Sdim/// 278252723Sdim/// braced-init-list: 279252723Sdim/// '{' initializer-list ','[opt] '}' 280252723Sdim/// '{' '}' 281252723Sdim/// 282193326SedParser::TPResult Parser::TryParseInitDeclaratorList() { 283193326Sed while (1) { 284193326Sed // declarator 285193326Sed TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 286193326Sed if (TPR != TPResult::Ambiguous()) 287193326Sed return TPR; 288193326Sed 289193326Sed // [GNU] simple-asm-expr[opt] attributes[opt] 290193326Sed if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 291193326Sed return TPResult::True(); 292193326Sed 293193326Sed // initializer[opt] 294193326Sed if (Tok.is(tok::l_paren)) { 295193326Sed // Parse through the parens. 296193326Sed ConsumeParen(); 297263509Sdim if (!SkipUntil(tok::r_paren, StopAtSemi)) 298193326Sed return TPResult::Error(); 299252723Sdim } else if (Tok.is(tok::l_brace)) { 300252723Sdim // A left-brace here is sufficient to disambiguate the parse; an 301252723Sdim // expression can never be followed directly by a braced-init-list. 302252723Sdim return TPResult::True(); 303212904Sdim } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { 304263509Sdim // MSVC and g++ won't examine the rest of declarators if '=' is 305212904Sdim // encountered; they just conclude that we have a declaration. 306212904Sdim // EDG parses the initializer completely, which is the proper behavior 307212904Sdim // for this case. 308193326Sed // 309212904Sdim // At present, Clang follows MSVC and g++, since the parser does not have 310212904Sdim // the ability to parse an expression fully without recording the 311212904Sdim // results of that parse. 312263509Sdim // FIXME: Handle this case correctly. 313263509Sdim // 314263509Sdim // Also allow 'in' after an Objective-C declaration as in: 315263509Sdim // for (int (^b)(void) in array). Ideally this should be done in the 316212904Sdim // context of parsing for-init-statement of a foreach statement only. But, 317212904Sdim // in any other context 'in' is invalid after a declaration and parser 318212904Sdim // issues the error regardless of outcome of this decision. 319263509Sdim // FIXME: Change if above assumption does not hold. 320212904Sdim return TPResult::True(); 321193326Sed } 322193326Sed 323193326Sed if (Tok.isNot(tok::comma)) 324193326Sed break; 325193326Sed ConsumeToken(); // the comma. 326193326Sed } 327193326Sed 328193326Sed return TPResult::Ambiguous(); 329193326Sed} 330193326Sed 331193326Sed/// isCXXConditionDeclaration - Disambiguates between a declaration or an 332193326Sed/// expression for a condition of a if/switch/while/for statement. 333193326Sed/// If during the disambiguation process a parsing error is encountered, 334193326Sed/// the function returns true to let the declaration parsing code handle it. 335193326Sed/// 336193326Sed/// condition: 337193326Sed/// expression 338193326Sed/// type-specifier-seq declarator '=' assignment-expression 339235633Sdim/// [C++11] type-specifier-seq declarator '=' initializer-clause 340235633Sdim/// [C++11] type-specifier-seq declarator braced-init-list 341193326Sed/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 342193326Sed/// '=' assignment-expression 343193326Sed/// 344193326Sedbool Parser::isCXXConditionDeclaration() { 345193326Sed TPResult TPR = isCXXDeclarationSpecifier(); 346193326Sed if (TPR != TPResult::Ambiguous()) 347193326Sed return TPR != TPResult::False(); // Returns true for TPResult::True() or 348193326Sed // TPResult::Error(). 349193326Sed 350193326Sed // FIXME: Add statistics about the number of ambiguous statements encountered 351193326Sed // and how they were resolved (number of declarations+number of expressions). 352193326Sed 353193326Sed // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 354193326Sed // We need tentative parsing... 355193326Sed 356193326Sed TentativeParsingAction PA(*this); 357193326Sed 358193326Sed // type-specifier-seq 359263509Sdim TryConsumeDeclarationSpecifier(); 360193326Sed assert(Tok.is(tok::l_paren) && "Expected '('"); 361193326Sed 362193326Sed // declarator 363193326Sed TPR = TryParseDeclarator(false/*mayBeAbstract*/); 364193326Sed 365193326Sed // In case of an error, let the declaration parsing code handle it. 366193326Sed if (TPR == TPResult::Error()) 367193326Sed TPR = TPResult::True(); 368193326Sed 369193326Sed if (TPR == TPResult::Ambiguous()) { 370193326Sed // '=' 371193326Sed // [GNU] simple-asm-expr[opt] attributes[opt] 372193326Sed if (Tok.is(tok::equal) || 373193326Sed Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 374193326Sed TPR = TPResult::True(); 375252723Sdim else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) 376235633Sdim TPR = TPResult::True(); 377193326Sed else 378193326Sed TPR = TPResult::False(); 379193326Sed } 380193326Sed 381193326Sed PA.Revert(); 382193326Sed 383193326Sed assert(TPR == TPResult::True() || TPR == TPResult::False()); 384193326Sed return TPR == TPResult::True(); 385193326Sed} 386193326Sed 387198092Srdivacky /// \brief Determine whether the next set of tokens contains a type-id. 388193326Sed /// 389193326Sed /// The context parameter states what context we're parsing right 390193326Sed /// now, which affects how this routine copes with the token 391193326Sed /// following the type-id. If the context is TypeIdInParens, we have 392193326Sed /// already parsed the '(' and we will cease lookahead when we hit 393193326Sed /// the corresponding ')'. If the context is 394193326Sed /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 395193326Sed /// before this template argument, and will cease lookahead when we 396193326Sed /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 397193326Sed /// and false for an expression. If during the disambiguation 398193326Sed /// process a parsing error is encountered, the function returns 399193326Sed /// true to let the declaration parsing code handle it. 400193326Sed /// 401193326Sed /// type-id: 402193326Sed /// type-specifier-seq abstract-declarator[opt] 403193326Sed /// 404193326Sedbool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 405198092Srdivacky 406193326Sed isAmbiguous = false; 407193326Sed 408193326Sed // C++ 8.2p2: 409193326Sed // The ambiguity arising from the similarity between a function-style cast and 410193326Sed // a type-id can occur in different contexts. The ambiguity appears as a 411193326Sed // choice between a function-style cast expression and a declaration of a 412193326Sed // type. The resolution is that any construct that could possibly be a type-id 413193326Sed // in its syntactic context shall be considered a type-id. 414193326Sed 415193326Sed TPResult TPR = isCXXDeclarationSpecifier(); 416193326Sed if (TPR != TPResult::Ambiguous()) 417193326Sed return TPR != TPResult::False(); // Returns true for TPResult::True() or 418193326Sed // TPResult::Error(). 419193326Sed 420193326Sed // FIXME: Add statistics about the number of ambiguous statements encountered 421193326Sed // and how they were resolved (number of declarations+number of expressions). 422193326Sed 423193326Sed // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 424193326Sed // We need tentative parsing... 425193326Sed 426193326Sed TentativeParsingAction PA(*this); 427193326Sed 428193326Sed // type-specifier-seq 429263509Sdim TryConsumeDeclarationSpecifier(); 430193326Sed assert(Tok.is(tok::l_paren) && "Expected '('"); 431193326Sed 432193326Sed // declarator 433193326Sed TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 434193326Sed 435193326Sed // In case of an error, let the declaration parsing code handle it. 436193326Sed if (TPR == TPResult::Error()) 437193326Sed TPR = TPResult::True(); 438193326Sed 439193326Sed if (TPR == TPResult::Ambiguous()) { 440193326Sed // We are supposed to be inside parens, so if after the abstract declarator 441193326Sed // we encounter a ')' this is a type-id, otherwise it's an expression. 442193326Sed if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 443193326Sed TPR = TPResult::True(); 444193326Sed isAmbiguous = true; 445193326Sed 446193326Sed // We are supposed to be inside a template argument, so if after 447193326Sed // the abstract declarator we encounter a '>', '>>' (in C++0x), or 448193326Sed // ',', this is a type-id. Otherwise, it's an expression. 449193326Sed } else if (Context == TypeIdAsTemplateArgument && 450193326Sed (Tok.is(tok::greater) || Tok.is(tok::comma) || 451252723Sdim (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater)))) { 452193326Sed TPR = TPResult::True(); 453193326Sed isAmbiguous = true; 454193326Sed 455193326Sed } else 456193326Sed TPR = TPResult::False(); 457193326Sed } 458193326Sed 459193326Sed PA.Revert(); 460193326Sed 461193326Sed assert(TPR == TPResult::True() || TPR == TPResult::False()); 462193326Sed return TPR == TPResult::True(); 463193326Sed} 464193326Sed 465235633Sdim/// \brief Returns true if this is a C++11 attribute-specifier. Per 466235633Sdim/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens 467235633Sdim/// always introduce an attribute. In Objective-C++11, this rule does not 468235633Sdim/// apply if either '[' begins a message-send. 469199990Srdivacky/// 470235633Sdim/// If Disambiguate is true, we try harder to determine whether a '[[' starts 471235633Sdim/// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not. 472199990Srdivacky/// 473235633Sdim/// If OuterMightBeMessageSend is true, we assume the outer '[' is either an 474235633Sdim/// Obj-C message send or the start of an attribute. Otherwise, we assume it 475235633Sdim/// is not an Obj-C message send. 476199990Srdivacky/// 477235633Sdim/// C++11 [dcl.attr.grammar]: 478235633Sdim/// 479235633Sdim/// attribute-specifier: 480199990Srdivacky/// '[' '[' attribute-list ']' ']' 481226890Sdim/// alignment-specifier 482199990Srdivacky/// 483235633Sdim/// attribute-list: 484199990Srdivacky/// attribute[opt] 485199990Srdivacky/// attribute-list ',' attribute[opt] 486235633Sdim/// attribute '...' 487235633Sdim/// attribute-list ',' attribute '...' 488199990Srdivacky/// 489235633Sdim/// attribute: 490199990Srdivacky/// attribute-token attribute-argument-clause[opt] 491199990Srdivacky/// 492235633Sdim/// attribute-token: 493199990Srdivacky/// identifier 494235633Sdim/// identifier '::' identifier 495199990Srdivacky/// 496235633Sdim/// attribute-argument-clause: 497199990Srdivacky/// '(' balanced-token-seq ')' 498235633SdimParser::CXX11AttributeKind 499235633SdimParser::isCXX11AttributeSpecifier(bool Disambiguate, 500235633Sdim bool OuterMightBeMessageSend) { 501226890Sdim if (Tok.is(tok::kw_alignas)) 502235633Sdim return CAK_AttributeSpecifier; 503226890Sdim 504199990Srdivacky if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) 505235633Sdim return CAK_NotAttributeSpecifier; 506199990Srdivacky 507235633Sdim // No tentative parsing if we don't need to look for ']]' or a lambda. 508235633Sdim if (!Disambiguate && !getLangOpts().ObjC1) 509235633Sdim return CAK_AttributeSpecifier; 510199990Srdivacky 511235633Sdim TentativeParsingAction PA(*this); 512235633Sdim 513199990Srdivacky // Opening brackets were checked for above. 514199990Srdivacky ConsumeBracket(); 515199990Srdivacky 516235633Sdim // Outside Obj-C++11, treat anything with a matching ']]' as an attribute. 517235633Sdim if (!getLangOpts().ObjC1) { 518235633Sdim ConsumeBracket(); 519199990Srdivacky 520263509Sdim bool IsAttribute = SkipUntil(tok::r_square); 521235633Sdim IsAttribute &= Tok.is(tok::r_square); 522235633Sdim 523235633Sdim PA.Revert(); 524235633Sdim 525235633Sdim return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier; 526235633Sdim } 527235633Sdim 528235633Sdim // In Obj-C++11, we need to distinguish four situations: 529235633Sdim // 1a) int x[[attr]]; C++11 attribute. 530235633Sdim // 1b) [[attr]]; C++11 statement attribute. 531235633Sdim // 2) int x[[obj](){ return 1; }()]; Lambda in array size/index. 532235633Sdim // 3a) int x[[obj get]]; Message send in array size/index. 533235633Sdim // 3b) [[Class alloc] init]; Message send in message send. 534235633Sdim // 4) [[obj]{ return self; }() doStuff]; Lambda in message send. 535235633Sdim // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted. 536235633Sdim 537235633Sdim // If we have a lambda-introducer, then this is definitely not a message send. 538235633Sdim // FIXME: If this disambiguation is too slow, fold the tentative lambda parse 539235633Sdim // into the tentative attribute parse below. 540235633Sdim LambdaIntroducer Intro; 541235633Sdim if (!TryParseLambdaIntroducer(Intro)) { 542235633Sdim // A lambda cannot end with ']]', and an attribute must. 543235633Sdim bool IsAttribute = Tok.is(tok::r_square); 544235633Sdim 545235633Sdim PA.Revert(); 546235633Sdim 547235633Sdim if (IsAttribute) 548235633Sdim // Case 1: C++11 attribute. 549235633Sdim return CAK_AttributeSpecifier; 550235633Sdim 551235633Sdim if (OuterMightBeMessageSend) 552235633Sdim // Case 4: Lambda in message send. 553235633Sdim return CAK_NotAttributeSpecifier; 554235633Sdim 555235633Sdim // Case 2: Lambda in array size / index. 556235633Sdim return CAK_InvalidAttributeSpecifier; 557235633Sdim } 558235633Sdim 559199990Srdivacky ConsumeBracket(); 560199990Srdivacky 561235633Sdim // If we don't have a lambda-introducer, then we have an attribute or a 562235633Sdim // message-send. 563235633Sdim bool IsAttribute = true; 564235633Sdim while (Tok.isNot(tok::r_square)) { 565235633Sdim if (Tok.is(tok::comma)) { 566235633Sdim // Case 1: Stray commas can only occur in attributes. 567235633Sdim PA.Revert(); 568235633Sdim return CAK_AttributeSpecifier; 569235633Sdim } 570199990Srdivacky 571235633Sdim // Parse the attribute-token, if present. 572235633Sdim // C++11 [dcl.attr.grammar]: 573235633Sdim // If a keyword or an alternative token that satisfies the syntactic 574235633Sdim // requirements of an identifier is contained in an attribute-token, 575235633Sdim // it is considered an identifier. 576235633Sdim SourceLocation Loc; 577235633Sdim if (!TryParseCXX11AttributeIdentifier(Loc)) { 578235633Sdim IsAttribute = false; 579235633Sdim break; 580235633Sdim } 581235633Sdim if (Tok.is(tok::coloncolon)) { 582235633Sdim ConsumeToken(); 583235633Sdim if (!TryParseCXX11AttributeIdentifier(Loc)) { 584235633Sdim IsAttribute = false; 585235633Sdim break; 586235633Sdim } 587235633Sdim } 588235633Sdim 589235633Sdim // Parse the attribute-argument-clause, if present. 590235633Sdim if (Tok.is(tok::l_paren)) { 591235633Sdim ConsumeParen(); 592263509Sdim if (!SkipUntil(tok::r_paren)) { 593235633Sdim IsAttribute = false; 594235633Sdim break; 595235633Sdim } 596235633Sdim } 597235633Sdim 598235633Sdim if (Tok.is(tok::ellipsis)) 599235633Sdim ConsumeToken(); 600235633Sdim 601235633Sdim if (Tok.isNot(tok::comma)) 602235633Sdim break; 603235633Sdim 604235633Sdim ConsumeToken(); 605235633Sdim } 606235633Sdim 607235633Sdim // An attribute must end ']]'. 608235633Sdim if (IsAttribute) { 609235633Sdim if (Tok.is(tok::r_square)) { 610235633Sdim ConsumeBracket(); 611235633Sdim IsAttribute = Tok.is(tok::r_square); 612235633Sdim } else { 613235633Sdim IsAttribute = false; 614235633Sdim } 615235633Sdim } 616235633Sdim 617235633Sdim PA.Revert(); 618235633Sdim 619235633Sdim if (IsAttribute) 620235633Sdim // Case 1: C++11 statement attribute. 621235633Sdim return CAK_AttributeSpecifier; 622235633Sdim 623235633Sdim // Case 3: Message send. 624235633Sdim return CAK_NotAttributeSpecifier; 625199990Srdivacky} 626199990Srdivacky 627263509SdimParser::TPResult Parser::TryParsePtrOperatorSeq() { 628263509Sdim while (true) { 629263509Sdim if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 630263509Sdim if (TryAnnotateCXXScopeToken(true)) 631263509Sdim return TPResult::Error(); 632263509Sdim 633263509Sdim if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 634263509Sdim Tok.is(tok::ampamp) || 635263509Sdim (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 636263509Sdim // ptr-operator 637263509Sdim ConsumeToken(); 638263509Sdim while (Tok.is(tok::kw_const) || 639263509Sdim Tok.is(tok::kw_volatile) || 640263509Sdim Tok.is(tok::kw_restrict)) 641263509Sdim ConsumeToken(); 642263509Sdim } else { 643263509Sdim return TPResult::True(); 644263509Sdim } 645263509Sdim } 646263509Sdim} 647263509Sdim 648263509Sdim/// operator-function-id: 649263509Sdim/// 'operator' operator 650263509Sdim/// 651263509Sdim/// operator: one of 652263509Sdim/// new delete new[] delete[] + - * / % ^ [...] 653263509Sdim/// 654263509Sdim/// conversion-function-id: 655263509Sdim/// 'operator' conversion-type-id 656263509Sdim/// 657263509Sdim/// conversion-type-id: 658263509Sdim/// type-specifier-seq conversion-declarator[opt] 659263509Sdim/// 660263509Sdim/// conversion-declarator: 661263509Sdim/// ptr-operator conversion-declarator[opt] 662263509Sdim/// 663263509Sdim/// literal-operator-id: 664263509Sdim/// 'operator' string-literal identifier 665263509Sdim/// 'operator' user-defined-string-literal 666263509SdimParser::TPResult Parser::TryParseOperatorId() { 667263509Sdim assert(Tok.is(tok::kw_operator)); 668263509Sdim ConsumeToken(); 669263509Sdim 670263509Sdim // Maybe this is an operator-function-id. 671263509Sdim switch (Tok.getKind()) { 672263509Sdim case tok::kw_new: case tok::kw_delete: 673263509Sdim ConsumeToken(); 674263509Sdim if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) { 675263509Sdim ConsumeBracket(); 676263509Sdim ConsumeBracket(); 677263509Sdim } 678263509Sdim return TPResult::True(); 679263509Sdim 680263509Sdim#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \ 681263509Sdim case tok::Token: 682263509Sdim#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly) 683263509Sdim#include "clang/Basic/OperatorKinds.def" 684263509Sdim ConsumeToken(); 685263509Sdim return TPResult::True(); 686263509Sdim 687263509Sdim case tok::l_square: 688263509Sdim if (NextToken().is(tok::r_square)) { 689263509Sdim ConsumeBracket(); 690263509Sdim ConsumeBracket(); 691263509Sdim return TPResult::True(); 692263509Sdim } 693263509Sdim break; 694263509Sdim 695263509Sdim case tok::l_paren: 696263509Sdim if (NextToken().is(tok::r_paren)) { 697263509Sdim ConsumeParen(); 698263509Sdim ConsumeParen(); 699263509Sdim return TPResult::True(); 700263509Sdim } 701263509Sdim break; 702263509Sdim 703263509Sdim default: 704263509Sdim break; 705263509Sdim } 706263509Sdim 707263509Sdim // Maybe this is a literal-operator-id. 708263509Sdim if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) { 709263509Sdim bool FoundUDSuffix = false; 710263509Sdim do { 711263509Sdim FoundUDSuffix |= Tok.hasUDSuffix(); 712263509Sdim ConsumeStringToken(); 713263509Sdim } while (isTokenStringLiteral()); 714263509Sdim 715263509Sdim if (!FoundUDSuffix) { 716263509Sdim if (Tok.is(tok::identifier)) 717263509Sdim ConsumeToken(); 718263509Sdim else 719263509Sdim return TPResult::Error(); 720263509Sdim } 721263509Sdim return TPResult::True(); 722263509Sdim } 723263509Sdim 724263509Sdim // Maybe this is a conversion-function-id. 725263509Sdim bool AnyDeclSpecifiers = false; 726263509Sdim while (true) { 727263509Sdim TPResult TPR = isCXXDeclarationSpecifier(); 728263509Sdim if (TPR == TPResult::Error()) 729263509Sdim return TPR; 730263509Sdim if (TPR == TPResult::False()) { 731263509Sdim if (!AnyDeclSpecifiers) 732263509Sdim return TPResult::Error(); 733263509Sdim break; 734263509Sdim } 735263509Sdim if (TryConsumeDeclarationSpecifier() == TPResult::Error()) 736263509Sdim return TPResult::Error(); 737263509Sdim AnyDeclSpecifiers = true; 738263509Sdim } 739263509Sdim return TryParsePtrOperatorSeq(); 740263509Sdim} 741263509Sdim 742193326Sed/// declarator: 743193326Sed/// direct-declarator 744193326Sed/// ptr-operator declarator 745193326Sed/// 746193326Sed/// direct-declarator: 747193326Sed/// declarator-id 748193326Sed/// direct-declarator '(' parameter-declaration-clause ')' 749193326Sed/// cv-qualifier-seq[opt] exception-specification[opt] 750193326Sed/// direct-declarator '[' constant-expression[opt] ']' 751193326Sed/// '(' declarator ')' 752193326Sed/// [GNU] '(' attributes declarator ')' 753193326Sed/// 754193326Sed/// abstract-declarator: 755193326Sed/// ptr-operator abstract-declarator[opt] 756193326Sed/// direct-abstract-declarator 757218893Sdim/// ... 758193326Sed/// 759193326Sed/// direct-abstract-declarator: 760193326Sed/// direct-abstract-declarator[opt] 761193326Sed/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 762193326Sed/// exception-specification[opt] 763193326Sed/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 764193326Sed/// '(' abstract-declarator ')' 765193326Sed/// 766193326Sed/// ptr-operator: 767193326Sed/// '*' cv-qualifier-seq[opt] 768193326Sed/// '&' 769193326Sed/// [C++0x] '&&' [TODO] 770193326Sed/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 771193326Sed/// 772193326Sed/// cv-qualifier-seq: 773193326Sed/// cv-qualifier cv-qualifier-seq[opt] 774193326Sed/// 775193326Sed/// cv-qualifier: 776193326Sed/// 'const' 777193326Sed/// 'volatile' 778193326Sed/// 779193326Sed/// declarator-id: 780218893Sdim/// '...'[opt] id-expression 781193326Sed/// 782193326Sed/// id-expression: 783193326Sed/// unqualified-id 784193326Sed/// qualified-id [TODO] 785193326Sed/// 786193326Sed/// unqualified-id: 787193326Sed/// identifier 788263509Sdim/// operator-function-id 789263509Sdim/// conversion-function-id 790263509Sdim/// literal-operator-id 791193326Sed/// '~' class-name [TODO] 792263509Sdim/// '~' decltype-specifier [TODO] 793193326Sed/// template-id [TODO] 794193326Sed/// 795193326SedParser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 796193326Sed bool mayHaveIdentifier) { 797193326Sed // declarator: 798193326Sed // direct-declarator 799193326Sed // ptr-operator declarator 800263509Sdim if (TryParsePtrOperatorSeq() == TPResult::Error()) 801263509Sdim return TPResult::Error(); 802193326Sed 803193326Sed // direct-declarator: 804193326Sed // direct-abstract-declarator: 805218893Sdim if (Tok.is(tok::ellipsis)) 806218893Sdim ConsumeToken(); 807263509Sdim 808263509Sdim if ((Tok.is(tok::identifier) || Tok.is(tok::kw_operator) || 809263509Sdim (Tok.is(tok::annot_cxxscope) && (NextToken().is(tok::identifier) || 810263509Sdim NextToken().is(tok::kw_operator)))) && 811198092Srdivacky mayHaveIdentifier) { 812193326Sed // declarator-id 813198092Srdivacky if (Tok.is(tok::annot_cxxscope)) 814198092Srdivacky ConsumeToken(); 815263509Sdim else if (Tok.is(tok::identifier)) 816245431Sdim TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo()); 817263509Sdim if (Tok.is(tok::kw_operator)) { 818263509Sdim if (TryParseOperatorId() == TPResult::Error()) 819263509Sdim return TPResult::Error(); 820263509Sdim } else 821263509Sdim ConsumeToken(); 822193326Sed } else if (Tok.is(tok::l_paren)) { 823193326Sed ConsumeParen(); 824193326Sed if (mayBeAbstract && 825193326Sed (Tok.is(tok::r_paren) || // 'int()' is a function. 826235633Sdim // 'int(...)' is a function. 827235633Sdim (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) || 828193326Sed isDeclarationSpecifier())) { // 'int(int)' is a function. 829193326Sed // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 830193326Sed // exception-specification[opt] 831193326Sed TPResult TPR = TryParseFunctionDeclarator(); 832193326Sed if (TPR != TPResult::Ambiguous()) 833193326Sed return TPR; 834193326Sed } else { 835193326Sed // '(' declarator ')' 836193326Sed // '(' attributes declarator ')' 837193326Sed // '(' abstract-declarator ')' 838218893Sdim if (Tok.is(tok::kw___attribute) || 839218893Sdim Tok.is(tok::kw___declspec) || 840218893Sdim Tok.is(tok::kw___cdecl) || 841218893Sdim Tok.is(tok::kw___stdcall) || 842218893Sdim Tok.is(tok::kw___fastcall) || 843226890Sdim Tok.is(tok::kw___thiscall) || 844226890Sdim Tok.is(tok::kw___unaligned)) 845193326Sed return TPResult::True(); // attributes indicate declaration 846193326Sed TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 847193326Sed if (TPR != TPResult::Ambiguous()) 848193326Sed return TPR; 849193326Sed if (Tok.isNot(tok::r_paren)) 850193326Sed return TPResult::False(); 851193326Sed ConsumeParen(); 852193326Sed } 853193326Sed } else if (!mayBeAbstract) { 854193326Sed return TPResult::False(); 855193326Sed } 856193326Sed 857193326Sed while (1) { 858193326Sed TPResult TPR(TPResult::Ambiguous()); 859193326Sed 860218893Sdim // abstract-declarator: ... 861218893Sdim if (Tok.is(tok::ellipsis)) 862218893Sdim ConsumeToken(); 863218893Sdim 864193326Sed if (Tok.is(tok::l_paren)) { 865193326Sed // Check whether we have a function declarator or a possible ctor-style 866193326Sed // initializer that follows the declarator. Note that ctor-style 867193326Sed // initializers are not possible in contexts where abstract declarators 868193326Sed // are allowed. 869245431Sdim if (!mayBeAbstract && !isCXXFunctionDeclarator()) 870193326Sed break; 871193326Sed 872193326Sed // direct-declarator '(' parameter-declaration-clause ')' 873193326Sed // cv-qualifier-seq[opt] exception-specification[opt] 874193326Sed ConsumeParen(); 875193326Sed TPR = TryParseFunctionDeclarator(); 876193326Sed } else if (Tok.is(tok::l_square)) { 877193326Sed // direct-declarator '[' constant-expression[opt] ']' 878193326Sed // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 879193326Sed TPR = TryParseBracketDeclarator(); 880193326Sed } else { 881193326Sed break; 882193326Sed } 883193326Sed 884193326Sed if (TPR != TPResult::Ambiguous()) 885193326Sed return TPR; 886193326Sed } 887193326Sed 888193326Sed return TPResult::Ambiguous(); 889193326Sed} 890193326Sed 891218893SdimParser::TPResult 892218893SdimParser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { 893218893Sdim switch (Kind) { 894218893Sdim // Obviously starts an expression. 895218893Sdim case tok::numeric_constant: 896218893Sdim case tok::char_constant: 897226890Sdim case tok::wide_char_constant: 898226890Sdim case tok::utf16_char_constant: 899226890Sdim case tok::utf32_char_constant: 900218893Sdim case tok::string_literal: 901218893Sdim case tok::wide_string_literal: 902226890Sdim case tok::utf8_string_literal: 903226890Sdim case tok::utf16_string_literal: 904226890Sdim case tok::utf32_string_literal: 905218893Sdim case tok::l_square: 906218893Sdim case tok::l_paren: 907218893Sdim case tok::amp: 908218893Sdim case tok::ampamp: 909218893Sdim case tok::star: 910218893Sdim case tok::plus: 911218893Sdim case tok::plusplus: 912218893Sdim case tok::minus: 913218893Sdim case tok::minusminus: 914218893Sdim case tok::tilde: 915218893Sdim case tok::exclaim: 916218893Sdim case tok::kw_sizeof: 917218893Sdim case tok::kw___func__: 918218893Sdim case tok::kw_const_cast: 919218893Sdim case tok::kw_delete: 920218893Sdim case tok::kw_dynamic_cast: 921218893Sdim case tok::kw_false: 922218893Sdim case tok::kw_new: 923218893Sdim case tok::kw_operator: 924218893Sdim case tok::kw_reinterpret_cast: 925218893Sdim case tok::kw_static_cast: 926218893Sdim case tok::kw_this: 927218893Sdim case tok::kw_throw: 928218893Sdim case tok::kw_true: 929218893Sdim case tok::kw_typeid: 930218893Sdim case tok::kw_alignof: 931218893Sdim case tok::kw_noexcept: 932218893Sdim case tok::kw_nullptr: 933245431Sdim case tok::kw__Alignof: 934218893Sdim case tok::kw___null: 935218893Sdim case tok::kw___alignof: 936218893Sdim case tok::kw___builtin_choose_expr: 937218893Sdim case tok::kw___builtin_offsetof: 938218893Sdim case tok::kw___builtin_types_compatible_p: 939218893Sdim case tok::kw___builtin_va_arg: 940218893Sdim case tok::kw___imag: 941218893Sdim case tok::kw___real: 942218893Sdim case tok::kw___FUNCTION__: 943263509Sdim case tok::kw___FUNCDNAME__: 944245431Sdim case tok::kw_L__FUNCTION__: 945218893Sdim case tok::kw___PRETTY_FUNCTION__: 946218893Sdim case tok::kw___has_nothrow_assign: 947218893Sdim case tok::kw___has_nothrow_copy: 948218893Sdim case tok::kw___has_nothrow_constructor: 949218893Sdim case tok::kw___has_trivial_assign: 950218893Sdim case tok::kw___has_trivial_copy: 951218893Sdim case tok::kw___has_trivial_constructor: 952218893Sdim case tok::kw___has_trivial_destructor: 953218893Sdim case tok::kw___has_virtual_destructor: 954218893Sdim case tok::kw___is_abstract: 955218893Sdim case tok::kw___is_base_of: 956218893Sdim case tok::kw___is_class: 957218893Sdim case tok::kw___is_convertible_to: 958218893Sdim case tok::kw___is_empty: 959218893Sdim case tok::kw___is_enum: 960245431Sdim case tok::kw___is_interface_class: 961235633Sdim case tok::kw___is_final: 962221345Sdim case tok::kw___is_literal: 963221345Sdim case tok::kw___is_literal_type: 964218893Sdim case tok::kw___is_pod: 965218893Sdim case tok::kw___is_polymorphic: 966263509Sdim case tok::kw___is_sealed: 967221345Sdim case tok::kw___is_trivial: 968235633Sdim case tok::kw___is_trivially_assignable: 969235633Sdim case tok::kw___is_trivially_constructible: 970223017Sdim case tok::kw___is_trivially_copyable: 971218893Sdim case tok::kw___is_union: 972218893Sdim case tok::kw___uuidof: 973218893Sdim return TPResult::True(); 974218893Sdim 975218893Sdim // Obviously starts a type-specifier-seq: 976218893Sdim case tok::kw_char: 977218893Sdim case tok::kw_const: 978218893Sdim case tok::kw_double: 979218893Sdim case tok::kw_enum: 980226890Sdim case tok::kw_half: 981218893Sdim case tok::kw_float: 982218893Sdim case tok::kw_int: 983218893Sdim case tok::kw_long: 984221345Sdim case tok::kw___int64: 985235633Sdim case tok::kw___int128: 986218893Sdim case tok::kw_restrict: 987218893Sdim case tok::kw_short: 988218893Sdim case tok::kw_signed: 989218893Sdim case tok::kw_struct: 990218893Sdim case tok::kw_union: 991218893Sdim case tok::kw_unsigned: 992218893Sdim case tok::kw_void: 993218893Sdim case tok::kw_volatile: 994218893Sdim case tok::kw__Bool: 995218893Sdim case tok::kw__Complex: 996218893Sdim case tok::kw_class: 997218893Sdim case tok::kw_typename: 998218893Sdim case tok::kw_wchar_t: 999218893Sdim case tok::kw_char16_t: 1000218893Sdim case tok::kw_char32_t: 1001218893Sdim case tok::kw__Decimal32: 1002218893Sdim case tok::kw__Decimal64: 1003218893Sdim case tok::kw__Decimal128: 1004263509Sdim case tok::kw___interface: 1005218893Sdim case tok::kw___thread: 1006252723Sdim case tok::kw_thread_local: 1007252723Sdim case tok::kw__Thread_local: 1008218893Sdim case tok::kw_typeof: 1009263509Sdim case tok::kw___underlying_type: 1010218893Sdim case tok::kw___cdecl: 1011218893Sdim case tok::kw___stdcall: 1012218893Sdim case tok::kw___fastcall: 1013218893Sdim case tok::kw___thiscall: 1014226890Sdim case tok::kw___unaligned: 1015218893Sdim case tok::kw___vector: 1016218893Sdim case tok::kw___pixel: 1017226890Sdim case tok::kw__Atomic: 1018252723Sdim case tok::kw_image1d_t: 1019252723Sdim case tok::kw_image1d_array_t: 1020252723Sdim case tok::kw_image1d_buffer_t: 1021252723Sdim case tok::kw_image2d_t: 1022252723Sdim case tok::kw_image2d_array_t: 1023252723Sdim case tok::kw_image3d_t: 1024252723Sdim case tok::kw_sampler_t: 1025252723Sdim case tok::kw_event_t: 1026252723Sdim case tok::kw___unknown_anytype: 1027218893Sdim return TPResult::False(); 1028218893Sdim 1029218893Sdim default: 1030218893Sdim break; 1031218893Sdim } 1032218893Sdim 1033218893Sdim return TPResult::Ambiguous(); 1034218893Sdim} 1035218893Sdim 1036245431Sdimbool Parser::isTentativelyDeclared(IdentifierInfo *II) { 1037245431Sdim return std::find(TentativelyDeclaredIdentifiers.begin(), 1038245431Sdim TentativelyDeclaredIdentifiers.end(), II) 1039245431Sdim != TentativelyDeclaredIdentifiers.end(); 1040245431Sdim} 1041245431Sdim 1042193326Sed/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 1043193326Sed/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 1044193326Sed/// be either a decl-specifier or a function-style cast, and TPResult::Error() 1045193326Sed/// if a parsing error was found and reported. 1046193326Sed/// 1047245431Sdim/// If HasMissingTypename is provided, a name with a dependent scope specifier 1048245431Sdim/// will be treated as ambiguous if the 'typename' keyword is missing. If this 1049245431Sdim/// happens, *HasMissingTypename will be set to 'true'. This will also be used 1050245431Sdim/// as an indicator that undeclared identifiers (which will trigger a later 1051245431Sdim/// parse error) should be treated as types. Returns TPResult::Ambiguous() in 1052245431Sdim/// such cases. 1053245431Sdim/// 1054193326Sed/// decl-specifier: 1055193326Sed/// storage-class-specifier 1056193326Sed/// type-specifier 1057193326Sed/// function-specifier 1058193326Sed/// 'friend' 1059193326Sed/// 'typedef' 1060252723Sdim/// [C++11] 'constexpr' 1061193326Sed/// [GNU] attributes declaration-specifiers[opt] 1062193326Sed/// 1063193326Sed/// storage-class-specifier: 1064193326Sed/// 'register' 1065193326Sed/// 'static' 1066193326Sed/// 'extern' 1067193326Sed/// 'mutable' 1068193326Sed/// 'auto' 1069193326Sed/// [GNU] '__thread' 1070252723Sdim/// [C++11] 'thread_local' 1071252723Sdim/// [C11] '_Thread_local' 1072193326Sed/// 1073193326Sed/// function-specifier: 1074193326Sed/// 'inline' 1075193326Sed/// 'virtual' 1076193326Sed/// 'explicit' 1077193326Sed/// 1078193326Sed/// typedef-name: 1079193326Sed/// identifier 1080193326Sed/// 1081193326Sed/// type-specifier: 1082193326Sed/// simple-type-specifier 1083193326Sed/// class-specifier 1084193326Sed/// enum-specifier 1085193326Sed/// elaborated-type-specifier 1086193326Sed/// typename-specifier 1087193326Sed/// cv-qualifier 1088193326Sed/// 1089193326Sed/// simple-type-specifier: 1090193326Sed/// '::'[opt] nested-name-specifier[opt] type-name 1091193326Sed/// '::'[opt] nested-name-specifier 'template' 1092193326Sed/// simple-template-id [TODO] 1093193326Sed/// 'char' 1094193326Sed/// 'wchar_t' 1095193326Sed/// 'bool' 1096193326Sed/// 'short' 1097193326Sed/// 'int' 1098193326Sed/// 'long' 1099193326Sed/// 'signed' 1100193326Sed/// 'unsigned' 1101193326Sed/// 'float' 1102193326Sed/// 'double' 1103193326Sed/// 'void' 1104193326Sed/// [GNU] typeof-specifier 1105193326Sed/// [GNU] '_Complex' 1106252723Sdim/// [C++11] 'auto' 1107252723Sdim/// [C++11] 'decltype' ( expression ) 1108252723Sdim/// [C++1y] 'decltype' ( 'auto' ) 1109193326Sed/// 1110193326Sed/// type-name: 1111193326Sed/// class-name 1112193326Sed/// enum-name 1113193326Sed/// typedef-name 1114193326Sed/// 1115193326Sed/// elaborated-type-specifier: 1116193326Sed/// class-key '::'[opt] nested-name-specifier[opt] identifier 1117193326Sed/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 1118193326Sed/// simple-template-id 1119193326Sed/// 'enum' '::'[opt] nested-name-specifier[opt] identifier 1120193326Sed/// 1121193326Sed/// enum-name: 1122193326Sed/// identifier 1123193326Sed/// 1124193326Sed/// enum-specifier: 1125193326Sed/// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 1126193326Sed/// 'enum' identifier[opt] '{' enumerator-list ',' '}' 1127193326Sed/// 1128193326Sed/// class-specifier: 1129193326Sed/// class-head '{' member-specification[opt] '}' 1130193326Sed/// 1131193326Sed/// class-head: 1132193326Sed/// class-key identifier[opt] base-clause[opt] 1133193326Sed/// class-key nested-name-specifier identifier base-clause[opt] 1134193326Sed/// class-key nested-name-specifier[opt] simple-template-id 1135193326Sed/// base-clause[opt] 1136193326Sed/// 1137193326Sed/// class-key: 1138193326Sed/// 'class' 1139193326Sed/// 'struct' 1140193326Sed/// 'union' 1141193326Sed/// 1142193326Sed/// cv-qualifier: 1143193326Sed/// 'const' 1144193326Sed/// 'volatile' 1145193326Sed/// [GNU] restrict 1146193326Sed/// 1147235633SdimParser::TPResult 1148245431SdimParser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, 1149245431Sdim bool *HasMissingTypename) { 1150193326Sed switch (Tok.getKind()) { 1151245431Sdim case tok::identifier: { 1152203955Srdivacky // Check for need to substitute AltiVec __vector keyword 1153203955Srdivacky // for "vector" identifier. 1154203955Srdivacky if (TryAltiVecVectorToken()) 1155203955Srdivacky return TPResult::True(); 1156245431Sdim 1157245431Sdim const Token &Next = NextToken(); 1158245431Sdim // In 'foo bar', 'foo' is always a type name outside of Objective-C. 1159245431Sdim if (!getLangOpts().ObjC1 && Next.is(tok::identifier)) 1160245431Sdim return TPResult::True(); 1161245431Sdim 1162245431Sdim if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) { 1163245431Sdim // Determine whether this is a valid expression. If not, we will hit 1164245431Sdim // a parse error one way or another. In that case, tell the caller that 1165245431Sdim // this is ambiguous. Typo-correct to type and expression keywords and 1166245431Sdim // to types and identifiers, in order to try to recover from errors. 1167245431Sdim CorrectionCandidateCallback TypoCorrection; 1168245431Sdim TypoCorrection.WantRemainingKeywords = false; 1169252723Sdim TypoCorrection.WantTypeSpecifiers = Next.isNot(tok::arrow); 1170245431Sdim switch (TryAnnotateName(false /* no nested name specifier */, 1171245431Sdim &TypoCorrection)) { 1172245431Sdim case ANK_Error: 1173245431Sdim return TPResult::Error(); 1174245431Sdim case ANK_TentativeDecl: 1175245431Sdim return TPResult::False(); 1176245431Sdim case ANK_TemplateName: 1177245431Sdim // A bare type template-name which can't be a template template 1178245431Sdim // argument is an error, and was probably intended to be a type. 1179245431Sdim return GreaterThanIsOperator ? TPResult::True() : TPResult::False(); 1180245431Sdim case ANK_Unresolved: 1181245431Sdim return HasMissingTypename ? TPResult::Ambiguous() : TPResult::False(); 1182245431Sdim case ANK_Success: 1183245431Sdim break; 1184245431Sdim } 1185245431Sdim assert(Tok.isNot(tok::identifier) && 1186245431Sdim "TryAnnotateName succeeded without producing an annotation"); 1187245431Sdim } else { 1188245431Sdim // This might possibly be a type with a dependent scope specifier and 1189245431Sdim // a missing 'typename' keyword. Don't use TryAnnotateName in this case, 1190245431Sdim // since it will annotate as a primary expression, and we want to use the 1191245431Sdim // "missing 'typename'" logic. 1192245431Sdim if (TryAnnotateTypeOrScopeToken()) 1193245431Sdim return TPResult::Error(); 1194245431Sdim // If annotation failed, assume it's a non-type. 1195245431Sdim // FIXME: If this happens due to an undeclared identifier, treat it as 1196245431Sdim // ambiguous. 1197245431Sdim if (Tok.is(tok::identifier)) 1198245431Sdim return TPResult::False(); 1199245431Sdim } 1200245431Sdim 1201245431Sdim // We annotated this token as something. Recurse to handle whatever we got. 1202245431Sdim return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1203245431Sdim } 1204245431Sdim 1205193326Sed case tok::kw_typename: // typename T::type 1206193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 1207193326Sed // recurse to handle whatever we get. 1208193326Sed if (TryAnnotateTypeOrScopeToken()) 1209204643Srdivacky return TPResult::Error(); 1210245431Sdim return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1211193326Sed 1212201361Srdivacky case tok::coloncolon: { // ::foo::bar 1213201361Srdivacky const Token &Next = NextToken(); 1214201361Srdivacky if (Next.is(tok::kw_new) || // ::new 1215201361Srdivacky Next.is(tok::kw_delete)) // ::delete 1216201361Srdivacky return TPResult::False(); 1217235633Sdim } 1218235633Sdim // Fall through. 1219235633Sdim case tok::kw_decltype: 1220193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 1221193326Sed // recurse to handle whatever we get. 1222193326Sed if (TryAnnotateTypeOrScopeToken()) 1223204643Srdivacky return TPResult::Error(); 1224245431Sdim return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1225235633Sdim 1226193326Sed // decl-specifier: 1227193326Sed // storage-class-specifier 1228193326Sed // type-specifier 1229193326Sed // function-specifier 1230193326Sed // 'friend' 1231193326Sed // 'typedef' 1232198954Srdivacky // 'constexpr' 1233193326Sed case tok::kw_friend: 1234193326Sed case tok::kw_typedef: 1235198954Srdivacky case tok::kw_constexpr: 1236193326Sed // storage-class-specifier 1237193326Sed case tok::kw_register: 1238193326Sed case tok::kw_static: 1239193326Sed case tok::kw_extern: 1240193326Sed case tok::kw_mutable: 1241193326Sed case tok::kw_auto: 1242193326Sed case tok::kw___thread: 1243252723Sdim case tok::kw_thread_local: 1244252723Sdim case tok::kw__Thread_local: 1245193326Sed // function-specifier 1246193326Sed case tok::kw_inline: 1247193326Sed case tok::kw_virtual: 1248193326Sed case tok::kw_explicit: 1249193326Sed 1250226890Sdim // Modules 1251226890Sdim case tok::kw___module_private__: 1252252723Sdim 1253252723Sdim // Debugger support 1254252723Sdim case tok::kw___unknown_anytype: 1255226890Sdim 1256193326Sed // type-specifier: 1257193326Sed // simple-type-specifier 1258193326Sed // class-specifier 1259193326Sed // enum-specifier 1260193326Sed // elaborated-type-specifier 1261193326Sed // typename-specifier 1262193326Sed // cv-qualifier 1263193326Sed 1264193326Sed // class-specifier 1265193326Sed // elaborated-type-specifier 1266193326Sed case tok::kw_class: 1267193326Sed case tok::kw_struct: 1268193326Sed case tok::kw_union: 1269263509Sdim case tok::kw___interface: 1270193326Sed // enum-specifier 1271193326Sed case tok::kw_enum: 1272193326Sed // cv-qualifier 1273193326Sed case tok::kw_const: 1274193326Sed case tok::kw_volatile: 1275193326Sed 1276193326Sed // GNU 1277193326Sed case tok::kw_restrict: 1278193326Sed case tok::kw__Complex: 1279193326Sed case tok::kw___attribute: 1280193326Sed return TPResult::True(); 1281198092Srdivacky 1282193326Sed // Microsoft 1283193326Sed case tok::kw___declspec: 1284193326Sed case tok::kw___cdecl: 1285193326Sed case tok::kw___stdcall: 1286193326Sed case tok::kw___fastcall: 1287208600Srdivacky case tok::kw___thiscall: 1288194179Sed case tok::kw___w64: 1289263509Sdim case tok::kw___sptr: 1290263509Sdim case tok::kw___uptr: 1291194179Sed case tok::kw___ptr64: 1292226890Sdim case tok::kw___ptr32: 1293194179Sed case tok::kw___forceinline: 1294226890Sdim case tok::kw___unaligned: 1295194179Sed return TPResult::True(); 1296212904Sdim 1297212904Sdim // Borland 1298212904Sdim case tok::kw___pascal: 1299212904Sdim return TPResult::True(); 1300203955Srdivacky 1301203955Srdivacky // AltiVec 1302203955Srdivacky case tok::kw___vector: 1303203955Srdivacky return TPResult::True(); 1304193326Sed 1305207619Srdivacky case tok::annot_template_id: { 1306224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 1307207619Srdivacky if (TemplateId->Kind != TNK_Type_template) 1308207619Srdivacky return TPResult::False(); 1309207619Srdivacky CXXScopeSpec SS; 1310221345Sdim AnnotateTemplateIdTokenAsType(); 1311207619Srdivacky assert(Tok.is(tok::annot_typename)); 1312207619Srdivacky goto case_typename; 1313207619Srdivacky } 1314207619Srdivacky 1315201361Srdivacky case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed 1316201361Srdivacky // We've already annotated a scope; try to annotate a type. 1317204643Srdivacky if (TryAnnotateTypeOrScopeToken()) 1318204643Srdivacky return TPResult::Error(); 1319235633Sdim if (!Tok.is(tok::annot_typename)) { 1320235633Sdim // If the next token is an identifier or a type qualifier, then this 1321235633Sdim // can't possibly be a valid expression either. 1322235633Sdim if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) { 1323235633Sdim CXXScopeSpec SS; 1324235633Sdim Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 1325235633Sdim Tok.getAnnotationRange(), 1326235633Sdim SS); 1327235633Sdim if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) { 1328235633Sdim TentativeParsingAction PA(*this); 1329235633Sdim ConsumeToken(); 1330235633Sdim ConsumeToken(); 1331235633Sdim bool isIdentifier = Tok.is(tok::identifier); 1332235633Sdim TPResult TPR = TPResult::False(); 1333235633Sdim if (!isIdentifier) 1334245431Sdim TPR = isCXXDeclarationSpecifier(BracedCastResult, 1335245431Sdim HasMissingTypename); 1336235633Sdim PA.Revert(); 1337235633Sdim 1338235633Sdim if (isIdentifier || 1339235633Sdim TPR == TPResult::True() || TPR == TPResult::Error()) 1340235633Sdim return TPResult::Error(); 1341245431Sdim 1342245431Sdim if (HasMissingTypename) { 1343245431Sdim // We can't tell whether this is a missing 'typename' or a valid 1344245431Sdim // expression. 1345245431Sdim *HasMissingTypename = true; 1346245431Sdim return TPResult::Ambiguous(); 1347245431Sdim } 1348245431Sdim } else { 1349245431Sdim // Try to resolve the name. If it doesn't exist, assume it was 1350245431Sdim // intended to name a type and keep disambiguating. 1351245431Sdim switch (TryAnnotateName(false /* SS is not dependent */)) { 1352245431Sdim case ANK_Error: 1353245431Sdim return TPResult::Error(); 1354245431Sdim case ANK_TentativeDecl: 1355245431Sdim return TPResult::False(); 1356245431Sdim case ANK_TemplateName: 1357245431Sdim // A bare type template-name which can't be a template template 1358245431Sdim // argument is an error, and was probably intended to be a type. 1359245431Sdim return GreaterThanIsOperator ? TPResult::True() : TPResult::False(); 1360245431Sdim case ANK_Unresolved: 1361245431Sdim return HasMissingTypename ? TPResult::Ambiguous() 1362245431Sdim : TPResult::False(); 1363245431Sdim case ANK_Success: 1364245431Sdim // Annotated it, check again. 1365245431Sdim assert(Tok.isNot(tok::annot_cxxscope) || 1366245431Sdim NextToken().isNot(tok::identifier)); 1367245431Sdim return isCXXDeclarationSpecifier(BracedCastResult, 1368245431Sdim HasMissingTypename); 1369245431Sdim } 1370235633Sdim } 1371235633Sdim } 1372201361Srdivacky return TPResult::False(); 1373235633Sdim } 1374201361Srdivacky // If that succeeded, fallthrough into the generic simple-type-id case. 1375201361Srdivacky 1376193326Sed // The ambiguity resides in a simple-type-specifier/typename-specifier 1377193326Sed // followed by a '('. The '(' could either be the start of: 1378193326Sed // 1379193326Sed // direct-declarator: 1380193326Sed // '(' declarator ')' 1381193326Sed // 1382193326Sed // direct-abstract-declarator: 1383193326Sed // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1384193326Sed // exception-specification[opt] 1385193326Sed // '(' abstract-declarator ')' 1386193326Sed // 1387193326Sed // or part of a function-style cast expression: 1388193326Sed // 1389193326Sed // simple-type-specifier '(' expression-list[opt] ')' 1390193326Sed // 1391193326Sed 1392193326Sed // simple-type-specifier: 1393193326Sed 1394218893Sdim case tok::annot_typename: 1395218893Sdim case_typename: 1396218893Sdim // In Objective-C, we might have a protocol-qualified type. 1397235633Sdim if (getLangOpts().ObjC1 && NextToken().is(tok::less)) { 1398218893Sdim // Tentatively parse the 1399218893Sdim TentativeParsingAction PA(*this); 1400218893Sdim ConsumeToken(); // The type token 1401218893Sdim 1402218893Sdim TPResult TPR = TryParseProtocolQualifiers(); 1403218893Sdim bool isFollowedByParen = Tok.is(tok::l_paren); 1404235633Sdim bool isFollowedByBrace = Tok.is(tok::l_brace); 1405218893Sdim 1406218893Sdim PA.Revert(); 1407218893Sdim 1408218893Sdim if (TPR == TPResult::Error()) 1409218893Sdim return TPResult::Error(); 1410218893Sdim 1411218893Sdim if (isFollowedByParen) 1412218893Sdim return TPResult::Ambiguous(); 1413235633Sdim 1414252723Sdim if (getLangOpts().CPlusPlus11 && isFollowedByBrace) 1415235633Sdim return BracedCastResult; 1416218893Sdim 1417218893Sdim return TPResult::True(); 1418218893Sdim } 1419218893Sdim 1420193326Sed case tok::kw_char: 1421193326Sed case tok::kw_wchar_t: 1422198092Srdivacky case tok::kw_char16_t: 1423198092Srdivacky case tok::kw_char32_t: 1424193326Sed case tok::kw_bool: 1425193326Sed case tok::kw_short: 1426193326Sed case tok::kw_int: 1427193326Sed case tok::kw_long: 1428221345Sdim case tok::kw___int64: 1429235633Sdim case tok::kw___int128: 1430193326Sed case tok::kw_signed: 1431193326Sed case tok::kw_unsigned: 1432226890Sdim case tok::kw_half: 1433193326Sed case tok::kw_float: 1434193326Sed case tok::kw_double: 1435193326Sed case tok::kw_void: 1436235633Sdim case tok::annot_decltype: 1437193326Sed if (NextToken().is(tok::l_paren)) 1438193326Sed return TPResult::Ambiguous(); 1439193326Sed 1440235633Sdim // This is a function-style cast in all cases we disambiguate other than 1441235633Sdim // one: 1442235633Sdim // struct S { 1443235633Sdim // enum E : int { a = 4 }; // enum 1444235633Sdim // enum E : int { 4 }; // bit-field 1445235633Sdim // }; 1446252723Sdim if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace)) 1447235633Sdim return BracedCastResult; 1448235633Sdim 1449218893Sdim if (isStartOfObjCClassMessageMissingOpenBracket()) 1450218893Sdim return TPResult::False(); 1451218893Sdim 1452193326Sed return TPResult::True(); 1453193326Sed 1454195099Sed // GNU typeof support. 1455193326Sed case tok::kw_typeof: { 1456193326Sed if (NextToken().isNot(tok::l_paren)) 1457193326Sed return TPResult::True(); 1458193326Sed 1459193326Sed TentativeParsingAction PA(*this); 1460193326Sed 1461193326Sed TPResult TPR = TryParseTypeofSpecifier(); 1462193326Sed bool isFollowedByParen = Tok.is(tok::l_paren); 1463235633Sdim bool isFollowedByBrace = Tok.is(tok::l_brace); 1464193326Sed 1465193326Sed PA.Revert(); 1466193326Sed 1467193326Sed if (TPR == TPResult::Error()) 1468193326Sed return TPResult::Error(); 1469193326Sed 1470193326Sed if (isFollowedByParen) 1471193326Sed return TPResult::Ambiguous(); 1472193326Sed 1473252723Sdim if (getLangOpts().CPlusPlus11 && isFollowedByBrace) 1474235633Sdim return BracedCastResult; 1475235633Sdim 1476193326Sed return TPResult::True(); 1477193326Sed } 1478193326Sed 1479223017Sdim // C++0x type traits support 1480223017Sdim case tok::kw___underlying_type: 1481223017Sdim return TPResult::True(); 1482223017Sdim 1483235633Sdim // C11 _Atomic 1484226890Sdim case tok::kw__Atomic: 1485226890Sdim return TPResult::True(); 1486226890Sdim 1487193326Sed default: 1488193326Sed return TPResult::False(); 1489193326Sed } 1490193326Sed} 1491193326Sed 1492263509Sdimbool Parser::isCXXDeclarationSpecifierAType() { 1493263509Sdim switch (Tok.getKind()) { 1494263509Sdim // typename-specifier 1495263509Sdim case tok::annot_decltype: 1496263509Sdim case tok::annot_template_id: 1497263509Sdim case tok::annot_typename: 1498263509Sdim case tok::kw_typeof: 1499263509Sdim case tok::kw___underlying_type: 1500263509Sdim return true; 1501263509Sdim 1502263509Sdim // elaborated-type-specifier 1503263509Sdim case tok::kw_class: 1504263509Sdim case tok::kw_struct: 1505263509Sdim case tok::kw_union: 1506263509Sdim case tok::kw___interface: 1507263509Sdim case tok::kw_enum: 1508263509Sdim return true; 1509263509Sdim 1510263509Sdim // simple-type-specifier 1511263509Sdim case tok::kw_char: 1512263509Sdim case tok::kw_wchar_t: 1513263509Sdim case tok::kw_char16_t: 1514263509Sdim case tok::kw_char32_t: 1515263509Sdim case tok::kw_bool: 1516263509Sdim case tok::kw_short: 1517263509Sdim case tok::kw_int: 1518263509Sdim case tok::kw_long: 1519263509Sdim case tok::kw___int64: 1520263509Sdim case tok::kw___int128: 1521263509Sdim case tok::kw_signed: 1522263509Sdim case tok::kw_unsigned: 1523263509Sdim case tok::kw_half: 1524263509Sdim case tok::kw_float: 1525263509Sdim case tok::kw_double: 1526263509Sdim case tok::kw_void: 1527263509Sdim case tok::kw___unknown_anytype: 1528263509Sdim return true; 1529263509Sdim 1530263509Sdim case tok::kw_auto: 1531263509Sdim return getLangOpts().CPlusPlus11; 1532263509Sdim 1533263509Sdim case tok::kw__Atomic: 1534263509Sdim // "_Atomic foo" 1535263509Sdim return NextToken().is(tok::l_paren); 1536263509Sdim 1537263509Sdim default: 1538263509Sdim return false; 1539263509Sdim } 1540263509Sdim} 1541263509Sdim 1542193326Sed/// [GNU] typeof-specifier: 1543193326Sed/// 'typeof' '(' expressions ')' 1544193326Sed/// 'typeof' '(' type-name ')' 1545193326Sed/// 1546193326SedParser::TPResult Parser::TryParseTypeofSpecifier() { 1547193326Sed assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 1548193326Sed ConsumeToken(); 1549193326Sed 1550193326Sed assert(Tok.is(tok::l_paren) && "Expected '('"); 1551193326Sed // Parse through the parens after 'typeof'. 1552193326Sed ConsumeParen(); 1553263509Sdim if (!SkipUntil(tok::r_paren, StopAtSemi)) 1554193326Sed return TPResult::Error(); 1555193326Sed 1556193326Sed return TPResult::Ambiguous(); 1557193326Sed} 1558193326Sed 1559218893Sdim/// [ObjC] protocol-qualifiers: 1560218893Sdim//// '<' identifier-list '>' 1561218893SdimParser::TPResult Parser::TryParseProtocolQualifiers() { 1562218893Sdim assert(Tok.is(tok::less) && "Expected '<' for qualifier list"); 1563218893Sdim ConsumeToken(); 1564218893Sdim do { 1565218893Sdim if (Tok.isNot(tok::identifier)) 1566218893Sdim return TPResult::Error(); 1567218893Sdim ConsumeToken(); 1568218893Sdim 1569218893Sdim if (Tok.is(tok::comma)) { 1570218893Sdim ConsumeToken(); 1571218893Sdim continue; 1572218893Sdim } 1573218893Sdim 1574218893Sdim if (Tok.is(tok::greater)) { 1575218893Sdim ConsumeToken(); 1576218893Sdim return TPResult::Ambiguous(); 1577218893Sdim } 1578218893Sdim } while (false); 1579218893Sdim 1580218893Sdim return TPResult::Error(); 1581218893Sdim} 1582218893Sdim 1583193326Sed/// isCXXFunctionDeclarator - Disambiguates between a function declarator or 1584193326Sed/// a constructor-style initializer, when parsing declaration statements. 1585193326Sed/// Returns true for function declarator and false for constructor-style 1586193326Sed/// initializer. 1587193326Sed/// If during the disambiguation process a parsing error is encountered, 1588193326Sed/// the function returns true to let the declaration parsing code handle it. 1589193326Sed/// 1590193326Sed/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1591193326Sed/// exception-specification[opt] 1592193326Sed/// 1593245431Sdimbool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) { 1594193326Sed 1595193326Sed // C++ 8.2p1: 1596193326Sed // The ambiguity arising from the similarity between a function-style cast and 1597193326Sed // a declaration mentioned in 6.8 can also occur in the context of a 1598193326Sed // declaration. In that context, the choice is between a function declaration 1599193326Sed // with a redundant set of parentheses around a parameter name and an object 1600193326Sed // declaration with a function-style cast as the initializer. Just as for the 1601193326Sed // ambiguities mentioned in 6.8, the resolution is to consider any construct 1602193326Sed // that could possibly be a declaration a declaration. 1603193326Sed 1604193326Sed TentativeParsingAction PA(*this); 1605193326Sed 1606193326Sed ConsumeParen(); 1607245431Sdim bool InvalidAsDeclaration = false; 1608245431Sdim TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration); 1609245431Sdim if (TPR == TPResult::Ambiguous()) { 1610245431Sdim if (Tok.isNot(tok::r_paren)) 1611245431Sdim TPR = TPResult::False(); 1612245431Sdim else { 1613245431Sdim const Token &Next = NextToken(); 1614245431Sdim if (Next.is(tok::amp) || Next.is(tok::ampamp) || 1615245431Sdim Next.is(tok::kw_const) || Next.is(tok::kw_volatile) || 1616245431Sdim Next.is(tok::kw_throw) || Next.is(tok::kw_noexcept) || 1617252723Sdim Next.is(tok::l_square) || isCXX11VirtSpecifier(Next) || 1618245431Sdim Next.is(tok::l_brace) || Next.is(tok::kw_try) || 1619245431Sdim Next.is(tok::equal) || Next.is(tok::arrow)) 1620245431Sdim // The next token cannot appear after a constructor-style initializer, 1621245431Sdim // and can appear next in a function definition. This must be a function 1622245431Sdim // declarator. 1623245431Sdim TPR = TPResult::True(); 1624245431Sdim else if (InvalidAsDeclaration) 1625245431Sdim // Use the absence of 'typename' as a tie-breaker. 1626245431Sdim TPR = TPResult::False(); 1627245431Sdim } 1628245431Sdim } 1629193326Sed 1630193326Sed PA.Revert(); 1631193326Sed 1632245431Sdim if (IsAmbiguous && TPR == TPResult::Ambiguous()) 1633245431Sdim *IsAmbiguous = true; 1634245431Sdim 1635193326Sed // In case of an error, let the declaration parsing code handle it. 1636245431Sdim return TPR != TPResult::False(); 1637193326Sed} 1638193326Sed 1639193326Sed/// parameter-declaration-clause: 1640193326Sed/// parameter-declaration-list[opt] '...'[opt] 1641193326Sed/// parameter-declaration-list ',' '...' 1642193326Sed/// 1643193326Sed/// parameter-declaration-list: 1644193326Sed/// parameter-declaration 1645193326Sed/// parameter-declaration-list ',' parameter-declaration 1646193326Sed/// 1647193326Sed/// parameter-declaration: 1648235633Sdim/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] 1649235633Sdim/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] 1650218893Sdim/// '=' assignment-expression 1651235633Sdim/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] 1652235633Sdim/// attributes[opt] 1653235633Sdim/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] 1654235633Sdim/// attributes[opt] '=' assignment-expression 1655193326Sed/// 1656245431SdimParser::TPResult 1657263509SdimParser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration, 1658263509Sdim bool VersusTemplateArgument) { 1659193326Sed 1660193326Sed if (Tok.is(tok::r_paren)) 1661245431Sdim return TPResult::Ambiguous(); 1662193326Sed 1663193326Sed // parameter-declaration-list[opt] '...'[opt] 1664193326Sed // parameter-declaration-list ',' '...' 1665193326Sed // 1666193326Sed // parameter-declaration-list: 1667193326Sed // parameter-declaration 1668193326Sed // parameter-declaration-list ',' parameter-declaration 1669193326Sed // 1670193326Sed while (1) { 1671193326Sed // '...'[opt] 1672193326Sed if (Tok.is(tok::ellipsis)) { 1673193326Sed ConsumeToken(); 1674235633Sdim if (Tok.is(tok::r_paren)) 1675235633Sdim return TPResult::True(); // '...)' is a sign of a function declarator. 1676235633Sdim else 1677235633Sdim return TPResult::False(); 1678193326Sed } 1679193326Sed 1680235633Sdim // An attribute-specifier-seq here is a sign of a function declarator. 1681235633Sdim if (isCXX11AttributeSpecifier(/*Disambiguate*/false, 1682235633Sdim /*OuterMightBeMessageSend*/true)) 1683235633Sdim return TPResult::True(); 1684235633Sdim 1685221345Sdim ParsedAttributes attrs(AttrFactory); 1686218893Sdim MaybeParseMicrosoftAttributes(attrs); 1687218893Sdim 1688193326Sed // decl-specifier-seq 1689235633Sdim // A parameter-declaration's initializer must be preceded by an '=', so 1690235633Sdim // decl-specifier-seq '{' is not a parameter in C++11. 1691263509Sdim TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(), 1692263509Sdim InvalidAsDeclaration); 1693263509Sdim 1694263509Sdim if (VersusTemplateArgument && TPR == TPResult::True()) { 1695263509Sdim // Consume the decl-specifier-seq. We have to look past it, since a 1696263509Sdim // type-id might appear here in a template argument. 1697263509Sdim bool SeenType = false; 1698263509Sdim do { 1699263509Sdim SeenType |= isCXXDeclarationSpecifierAType(); 1700263509Sdim if (TryConsumeDeclarationSpecifier() == TPResult::Error()) 1701263509Sdim return TPResult::Error(); 1702263509Sdim 1703263509Sdim // If we see a parameter name, this can't be a template argument. 1704263509Sdim if (SeenType && Tok.is(tok::identifier)) 1705263509Sdim return TPResult::True(); 1706263509Sdim 1707263509Sdim TPR = isCXXDeclarationSpecifier(TPResult::False(), 1708263509Sdim InvalidAsDeclaration); 1709263509Sdim if (TPR == TPResult::Error()) 1710263509Sdim return TPR; 1711263509Sdim } while (TPR != TPResult::False()); 1712263509Sdim } else if (TPR == TPResult::Ambiguous()) { 1713263509Sdim // Disambiguate what follows the decl-specifier. 1714263509Sdim if (TryConsumeDeclarationSpecifier() == TPResult::Error()) 1715263509Sdim return TPResult::Error(); 1716263509Sdim } else 1717193326Sed return TPR; 1718193326Sed 1719193326Sed // declarator 1720193326Sed // abstract-declarator[opt] 1721193326Sed TPR = TryParseDeclarator(true/*mayBeAbstract*/); 1722193326Sed if (TPR != TPResult::Ambiguous()) 1723193326Sed return TPR; 1724193326Sed 1725218893Sdim // [GNU] attributes[opt] 1726218893Sdim if (Tok.is(tok::kw___attribute)) 1727218893Sdim return TPResult::True(); 1728218893Sdim 1729263509Sdim // If we're disambiguating a template argument in a default argument in 1730263509Sdim // a class definition versus a parameter declaration, an '=' here 1731263509Sdim // disambiguates the parse one way or the other. 1732263509Sdim // If this is a parameter, it must have a default argument because 1733263509Sdim // (a) the previous parameter did, and 1734263509Sdim // (b) this must be the first declaration of the function, so we can't 1735263509Sdim // inherit any default arguments from elsewhere. 1736263509Sdim // If we see an ')', then we've reached the end of a 1737263509Sdim // parameter-declaration-clause, and the last param is missing its default 1738263509Sdim // argument. 1739263509Sdim if (VersusTemplateArgument) 1740263509Sdim return (Tok.is(tok::equal) || Tok.is(tok::r_paren)) ? TPResult::True() 1741263509Sdim : TPResult::False(); 1742263509Sdim 1743193326Sed if (Tok.is(tok::equal)) { 1744193326Sed // '=' assignment-expression 1745193326Sed // Parse through assignment-expression. 1746263509Sdim // FIXME: assignment-expression may contain an unparenthesized comma. 1747263509Sdim if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch)) 1748193326Sed return TPResult::Error(); 1749193326Sed } 1750193326Sed 1751193326Sed if (Tok.is(tok::ellipsis)) { 1752193326Sed ConsumeToken(); 1753235633Sdim if (Tok.is(tok::r_paren)) 1754235633Sdim return TPResult::True(); // '...)' is a sign of a function declarator. 1755235633Sdim else 1756235633Sdim return TPResult::False(); 1757193326Sed } 1758193326Sed 1759193326Sed if (Tok.isNot(tok::comma)) 1760193326Sed break; 1761193326Sed ConsumeToken(); // the comma. 1762193326Sed } 1763193326Sed 1764193326Sed return TPResult::Ambiguous(); 1765193326Sed} 1766193326Sed 1767193326Sed/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 1768193326Sed/// parsing as a function declarator. 1769193326Sed/// If TryParseFunctionDeclarator fully parsed the function declarator, it will 1770193326Sed/// return TPResult::Ambiguous(), otherwise it will return either False() or 1771193326Sed/// Error(). 1772198092Srdivacky/// 1773193326Sed/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1774193326Sed/// exception-specification[opt] 1775193326Sed/// 1776193326Sed/// exception-specification: 1777193326Sed/// 'throw' '(' type-id-list[opt] ')' 1778193326Sed/// 1779193326SedParser::TPResult Parser::TryParseFunctionDeclarator() { 1780193326Sed 1781193326Sed // The '(' is already parsed. 1782193326Sed 1783193326Sed TPResult TPR = TryParseParameterDeclarationClause(); 1784193326Sed if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1785193326Sed TPR = TPResult::False(); 1786193326Sed 1787193326Sed if (TPR == TPResult::False() || TPR == TPResult::Error()) 1788193326Sed return TPR; 1789193326Sed 1790193326Sed // Parse through the parens. 1791263509Sdim if (!SkipUntil(tok::r_paren, StopAtSemi)) 1792193326Sed return TPResult::Error(); 1793193326Sed 1794193326Sed // cv-qualifier-seq 1795193326Sed while (Tok.is(tok::kw_const) || 1796193326Sed Tok.is(tok::kw_volatile) || 1797193326Sed Tok.is(tok::kw_restrict) ) 1798193326Sed ConsumeToken(); 1799193326Sed 1800218893Sdim // ref-qualifier[opt] 1801218893Sdim if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) 1802218893Sdim ConsumeToken(); 1803218893Sdim 1804193326Sed // exception-specification 1805193326Sed if (Tok.is(tok::kw_throw)) { 1806193326Sed ConsumeToken(); 1807193326Sed if (Tok.isNot(tok::l_paren)) 1808193326Sed return TPResult::Error(); 1809193326Sed 1810193326Sed // Parse through the parens after 'throw'. 1811193326Sed ConsumeParen(); 1812263509Sdim if (!SkipUntil(tok::r_paren, StopAtSemi)) 1813193326Sed return TPResult::Error(); 1814193326Sed } 1815221345Sdim if (Tok.is(tok::kw_noexcept)) { 1816221345Sdim ConsumeToken(); 1817221345Sdim // Possibly an expression as well. 1818221345Sdim if (Tok.is(tok::l_paren)) { 1819221345Sdim // Find the matching rparen. 1820221345Sdim ConsumeParen(); 1821263509Sdim if (!SkipUntil(tok::r_paren, StopAtSemi)) 1822221345Sdim return TPResult::Error(); 1823221345Sdim } 1824221345Sdim } 1825193326Sed 1826193326Sed return TPResult::Ambiguous(); 1827193326Sed} 1828193326Sed 1829193326Sed/// '[' constant-expression[opt] ']' 1830193326Sed/// 1831193326SedParser::TPResult Parser::TryParseBracketDeclarator() { 1832193326Sed ConsumeBracket(); 1833263509Sdim if (!SkipUntil(tok::r_square, StopAtSemi)) 1834193326Sed return TPResult::Error(); 1835193326Sed 1836193326Sed return TPResult::Ambiguous(); 1837193326Sed} 1838