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: 65234353Sdim 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/// 78234353Sdim/// (if AllowForRangeDecl specified) 79234353Sdim/// for ( for-range-declaration : for-range-initializer ) statement 80234353Sdim/// for-range-declaration: 81234353Sdim/// attribute-specifier-seqopt type-specifier-seq declarator 82234353Sdimbool 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 107243830Sdim bool InvalidAsDeclaration = false; 108243830Sdim TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(), 109243830Sdim &InvalidAsDeclaration); 110193326Sed if (TPR != TPResult::Ambiguous()) 111193326Sed return TPR != TPResult::False(); // Returns true for TPResult::True() or 112193326Sed // TPResult::Error(). 113193326Sed 114243830Sdim // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer, 115243830Sdim // and so gets some cases wrong. We can't carry on if we've already seen 116243830Sdim // something which makes this statement invalid as a declaration in this case, 117243830Sdim // since it can cause us to misparse valid code. Revisit this once 118243830Sdim // TryParseInitDeclaratorList is fixed. 119243830Sdim if (InvalidAsDeclaration) 120243830Sdim return false; 121243830Sdim 122193326Sed // FIXME: Add statistics about the number of ambiguous statements encountered 123193326Sed // and how they were resolved (number of declarations+number of expressions). 124193326Sed 125243830Sdim // Ok, we have a simple-type-specifier/typename-specifier followed by a '(', 126243830Sdim // or an identifier which doesn't resolve as anything. We need tentative 127243830Sdim // parsing... 128193326Sed 129193326Sed TentativeParsingAction PA(*this); 130234353Sdim 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 145193326Sed/// simple-declaration: 146193326Sed/// decl-specifier-seq init-declarator-list[opt] ';' 147193326Sed/// 148234353Sdim/// (if AllowForRangeDecl specified) 149234353Sdim/// for ( for-range-declaration : for-range-initializer ) statement 150234353Sdim/// for-range-declaration: 151234353Sdim/// attribute-specifier-seqopt type-specifier-seq declarator 152234353Sdim/// 153234353SdimParser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { 154193326Sed if (Tok.is(tok::kw_typeof)) 155193326Sed TryParseTypeofSpecifier(); 156218893Sdim else { 157243830Sdim if (Tok.is(tok::annot_cxxscope)) 158243830Sdim ConsumeToken(); 159193326Sed ConsumeToken(); 160243830Sdim 161234353Sdim if (getLangOpts().ObjC1 && Tok.is(tok::less)) 162218893Sdim TryParseProtocolQualifiers(); 163218893Sdim } 164193326Sed 165243830Sdim // Two decl-specifiers in a row conclusively disambiguate this as being a 166243830Sdim // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the 167243830Sdim // overwhelmingly common case that the next token is a '('. 168243830Sdim if (Tok.isNot(tok::l_paren)) { 169243830Sdim TPResult TPR = isCXXDeclarationSpecifier(); 170243830Sdim if (TPR == TPResult::Ambiguous()) 171243830Sdim return TPResult::True(); 172243830Sdim if (TPR == TPResult::True() || TPR == TPResult::Error()) 173243830Sdim return TPR; 174243830Sdim assert(TPR == TPResult::False()); 175243830Sdim } 176243830Sdim 177193326Sed TPResult TPR = TryParseInitDeclaratorList(); 178193326Sed if (TPR != TPResult::Ambiguous()) 179193326Sed return TPR; 180193326Sed 181234353Sdim if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon))) 182193326Sed return TPResult::False(); 183193326Sed 184193326Sed return TPResult::Ambiguous(); 185193326Sed} 186193326Sed 187249423Sdim/// Tentatively parse an init-declarator-list in order to disambiguate it from 188249423Sdim/// an expression. 189249423Sdim/// 190193326Sed/// init-declarator-list: 191193326Sed/// init-declarator 192193326Sed/// init-declarator-list ',' init-declarator 193193326Sed/// 194193326Sed/// init-declarator: 195193326Sed/// declarator initializer[opt] 196193326Sed/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 197193326Sed/// 198249423Sdim/// initializer: 199249423Sdim/// brace-or-equal-initializer 200249423Sdim/// '(' expression-list ')' 201193326Sed/// 202249423Sdim/// brace-or-equal-initializer: 203249423Sdim/// '=' initializer-clause 204249423Sdim/// [C++11] braced-init-list 205193326Sed/// 206249423Sdim/// initializer-clause: 207249423Sdim/// assignment-expression 208249423Sdim/// braced-init-list 209249423Sdim/// 210249423Sdim/// braced-init-list: 211249423Sdim/// '{' initializer-list ','[opt] '}' 212249423Sdim/// '{' '}' 213249423Sdim/// 214193326SedParser::TPResult Parser::TryParseInitDeclaratorList() { 215193326Sed while (1) { 216193326Sed // declarator 217193326Sed TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 218193326Sed if (TPR != TPResult::Ambiguous()) 219193326Sed return TPR; 220193326Sed 221193326Sed // [GNU] simple-asm-expr[opt] attributes[opt] 222193326Sed if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 223193326Sed return TPResult::True(); 224193326Sed 225193326Sed // initializer[opt] 226193326Sed if (Tok.is(tok::l_paren)) { 227193326Sed // Parse through the parens. 228193326Sed ConsumeParen(); 229193326Sed if (!SkipUntil(tok::r_paren)) 230193326Sed return TPResult::Error(); 231249423Sdim } else if (Tok.is(tok::l_brace)) { 232249423Sdim // A left-brace here is sufficient to disambiguate the parse; an 233249423Sdim // expression can never be followed directly by a braced-init-list. 234249423Sdim return TPResult::True(); 235212904Sdim } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { 236212904Sdim // MSVC and g++ won't examine the rest of declarators if '=' is 237212904Sdim // encountered; they just conclude that we have a declaration. 238212904Sdim // EDG parses the initializer completely, which is the proper behavior 239212904Sdim // for this case. 240193326Sed // 241212904Sdim // At present, Clang follows MSVC and g++, since the parser does not have 242212904Sdim // the ability to parse an expression fully without recording the 243212904Sdim // results of that parse. 244212904Sdim // Also allow 'in' after on objective-c declaration as in: 245212904Sdim // for (int (^b)(void) in array). Ideally this should be done in the 246212904Sdim // context of parsing for-init-statement of a foreach statement only. But, 247212904Sdim // in any other context 'in' is invalid after a declaration and parser 248212904Sdim // issues the error regardless of outcome of this decision. 249212904Sdim // FIXME. Change if above assumption does not hold. 250212904Sdim return TPResult::True(); 251193326Sed } 252193326Sed 253193326Sed if (Tok.isNot(tok::comma)) 254193326Sed break; 255193326Sed ConsumeToken(); // the comma. 256193326Sed } 257193326Sed 258193326Sed return TPResult::Ambiguous(); 259193326Sed} 260193326Sed 261193326Sed/// isCXXConditionDeclaration - Disambiguates between a declaration or an 262193326Sed/// expression for a condition of a if/switch/while/for statement. 263193326Sed/// If during the disambiguation process a parsing error is encountered, 264193326Sed/// the function returns true to let the declaration parsing code handle it. 265193326Sed/// 266193326Sed/// condition: 267193326Sed/// expression 268193326Sed/// type-specifier-seq declarator '=' assignment-expression 269234353Sdim/// [C++11] type-specifier-seq declarator '=' initializer-clause 270234353Sdim/// [C++11] type-specifier-seq declarator braced-init-list 271193326Sed/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 272193326Sed/// '=' assignment-expression 273193326Sed/// 274193326Sedbool Parser::isCXXConditionDeclaration() { 275193326Sed TPResult TPR = isCXXDeclarationSpecifier(); 276193326Sed if (TPR != TPResult::Ambiguous()) 277193326Sed return TPR != TPResult::False(); // Returns true for TPResult::True() or 278193326Sed // TPResult::Error(). 279193326Sed 280193326Sed // FIXME: Add statistics about the number of ambiguous statements encountered 281193326Sed // and how they were resolved (number of declarations+number of expressions). 282193326Sed 283193326Sed // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 284193326Sed // We need tentative parsing... 285193326Sed 286193326Sed TentativeParsingAction PA(*this); 287193326Sed 288193326Sed // type-specifier-seq 289193326Sed if (Tok.is(tok::kw_typeof)) 290193326Sed TryParseTypeofSpecifier(); 291218893Sdim else { 292193326Sed ConsumeToken(); 293218893Sdim 294234353Sdim if (getLangOpts().ObjC1 && Tok.is(tok::less)) 295218893Sdim TryParseProtocolQualifiers(); 296218893Sdim } 297193326Sed assert(Tok.is(tok::l_paren) && "Expected '('"); 298193326Sed 299193326Sed // declarator 300193326Sed TPR = TryParseDeclarator(false/*mayBeAbstract*/); 301193326Sed 302193326Sed // In case of an error, let the declaration parsing code handle it. 303193326Sed if (TPR == TPResult::Error()) 304193326Sed TPR = TPResult::True(); 305193326Sed 306193326Sed if (TPR == TPResult::Ambiguous()) { 307193326Sed // '=' 308193326Sed // [GNU] simple-asm-expr[opt] attributes[opt] 309193326Sed if (Tok.is(tok::equal) || 310193326Sed Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 311193326Sed TPR = TPResult::True(); 312249423Sdim else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) 313234353Sdim TPR = TPResult::True(); 314193326Sed else 315193326Sed TPR = TPResult::False(); 316193326Sed } 317193326Sed 318193326Sed PA.Revert(); 319193326Sed 320193326Sed assert(TPR == TPResult::True() || TPR == TPResult::False()); 321193326Sed return TPR == TPResult::True(); 322193326Sed} 323193326Sed 324198092Srdivacky /// \brief Determine whether the next set of tokens contains a type-id. 325193326Sed /// 326193326Sed /// The context parameter states what context we're parsing right 327193326Sed /// now, which affects how this routine copes with the token 328193326Sed /// following the type-id. If the context is TypeIdInParens, we have 329193326Sed /// already parsed the '(' and we will cease lookahead when we hit 330193326Sed /// the corresponding ')'. If the context is 331193326Sed /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 332193326Sed /// before this template argument, and will cease lookahead when we 333193326Sed /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 334193326Sed /// and false for an expression. If during the disambiguation 335193326Sed /// process a parsing error is encountered, the function returns 336193326Sed /// true to let the declaration parsing code handle it. 337193326Sed /// 338193326Sed /// type-id: 339193326Sed /// type-specifier-seq abstract-declarator[opt] 340193326Sed /// 341193326Sedbool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 342198092Srdivacky 343193326Sed isAmbiguous = false; 344193326Sed 345193326Sed // C++ 8.2p2: 346193326Sed // The ambiguity arising from the similarity between a function-style cast and 347193326Sed // a type-id can occur in different contexts. The ambiguity appears as a 348193326Sed // choice between a function-style cast expression and a declaration of a 349193326Sed // type. The resolution is that any construct that could possibly be a type-id 350193326Sed // in its syntactic context shall be considered a type-id. 351193326Sed 352193326Sed TPResult TPR = isCXXDeclarationSpecifier(); 353193326Sed if (TPR != TPResult::Ambiguous()) 354193326Sed return TPR != TPResult::False(); // Returns true for TPResult::True() or 355193326Sed // TPResult::Error(). 356193326Sed 357193326Sed // FIXME: Add statistics about the number of ambiguous statements encountered 358193326Sed // and how they were resolved (number of declarations+number of expressions). 359193326Sed 360193326Sed // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 361193326Sed // We need tentative parsing... 362193326Sed 363193326Sed TentativeParsingAction PA(*this); 364193326Sed 365193326Sed // type-specifier-seq 366193326Sed if (Tok.is(tok::kw_typeof)) 367193326Sed TryParseTypeofSpecifier(); 368218893Sdim else { 369193326Sed ConsumeToken(); 370218893Sdim 371234353Sdim if (getLangOpts().ObjC1 && Tok.is(tok::less)) 372218893Sdim TryParseProtocolQualifiers(); 373218893Sdim } 374218893Sdim 375193326Sed assert(Tok.is(tok::l_paren) && "Expected '('"); 376193326Sed 377193326Sed // declarator 378193326Sed TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 379193326Sed 380193326Sed // In case of an error, let the declaration parsing code handle it. 381193326Sed if (TPR == TPResult::Error()) 382193326Sed TPR = TPResult::True(); 383193326Sed 384193326Sed if (TPR == TPResult::Ambiguous()) { 385193326Sed // We are supposed to be inside parens, so if after the abstract declarator 386193326Sed // we encounter a ')' this is a type-id, otherwise it's an expression. 387193326Sed if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 388193326Sed TPR = TPResult::True(); 389193326Sed isAmbiguous = true; 390193326Sed 391193326Sed // We are supposed to be inside a template argument, so if after 392193326Sed // the abstract declarator we encounter a '>', '>>' (in C++0x), or 393193326Sed // ',', this is a type-id. Otherwise, it's an expression. 394193326Sed } else if (Context == TypeIdAsTemplateArgument && 395193326Sed (Tok.is(tok::greater) || Tok.is(tok::comma) || 396249423Sdim (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater)))) { 397193326Sed TPR = TPResult::True(); 398193326Sed isAmbiguous = true; 399193326Sed 400193326Sed } else 401193326Sed TPR = TPResult::False(); 402193326Sed } 403193326Sed 404193326Sed PA.Revert(); 405193326Sed 406193326Sed assert(TPR == TPResult::True() || TPR == TPResult::False()); 407193326Sed return TPR == TPResult::True(); 408193326Sed} 409193326Sed 410234353Sdim/// \brief Returns true if this is a C++11 attribute-specifier. Per 411234353Sdim/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens 412234353Sdim/// always introduce an attribute. In Objective-C++11, this rule does not 413234353Sdim/// apply if either '[' begins a message-send. 414199990Srdivacky/// 415234353Sdim/// If Disambiguate is true, we try harder to determine whether a '[[' starts 416234353Sdim/// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not. 417199990Srdivacky/// 418234353Sdim/// If OuterMightBeMessageSend is true, we assume the outer '[' is either an 419234353Sdim/// Obj-C message send or the start of an attribute. Otherwise, we assume it 420234353Sdim/// is not an Obj-C message send. 421199990Srdivacky/// 422234353Sdim/// C++11 [dcl.attr.grammar]: 423234353Sdim/// 424234353Sdim/// attribute-specifier: 425199990Srdivacky/// '[' '[' attribute-list ']' ']' 426226633Sdim/// alignment-specifier 427199990Srdivacky/// 428234353Sdim/// attribute-list: 429199990Srdivacky/// attribute[opt] 430199990Srdivacky/// attribute-list ',' attribute[opt] 431234353Sdim/// attribute '...' 432234353Sdim/// attribute-list ',' attribute '...' 433199990Srdivacky/// 434234353Sdim/// attribute: 435199990Srdivacky/// attribute-token attribute-argument-clause[opt] 436199990Srdivacky/// 437234353Sdim/// attribute-token: 438199990Srdivacky/// identifier 439234353Sdim/// identifier '::' identifier 440199990Srdivacky/// 441234353Sdim/// attribute-argument-clause: 442199990Srdivacky/// '(' balanced-token-seq ')' 443234353SdimParser::CXX11AttributeKind 444234353SdimParser::isCXX11AttributeSpecifier(bool Disambiguate, 445234353Sdim bool OuterMightBeMessageSend) { 446226633Sdim if (Tok.is(tok::kw_alignas)) 447234353Sdim return CAK_AttributeSpecifier; 448226633Sdim 449199990Srdivacky if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) 450234353Sdim return CAK_NotAttributeSpecifier; 451199990Srdivacky 452234353Sdim // No tentative parsing if we don't need to look for ']]' or a lambda. 453234353Sdim if (!Disambiguate && !getLangOpts().ObjC1) 454234353Sdim return CAK_AttributeSpecifier; 455199990Srdivacky 456234353Sdim TentativeParsingAction PA(*this); 457234353Sdim 458199990Srdivacky // Opening brackets were checked for above. 459199990Srdivacky ConsumeBracket(); 460199990Srdivacky 461234353Sdim // Outside Obj-C++11, treat anything with a matching ']]' as an attribute. 462234353Sdim if (!getLangOpts().ObjC1) { 463234353Sdim ConsumeBracket(); 464199990Srdivacky 465234353Sdim bool IsAttribute = SkipUntil(tok::r_square, false); 466234353Sdim IsAttribute &= Tok.is(tok::r_square); 467234353Sdim 468234353Sdim PA.Revert(); 469234353Sdim 470234353Sdim return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier; 471234353Sdim } 472234353Sdim 473234353Sdim // In Obj-C++11, we need to distinguish four situations: 474234353Sdim // 1a) int x[[attr]]; C++11 attribute. 475234353Sdim // 1b) [[attr]]; C++11 statement attribute. 476234353Sdim // 2) int x[[obj](){ return 1; }()]; Lambda in array size/index. 477234353Sdim // 3a) int x[[obj get]]; Message send in array size/index. 478234353Sdim // 3b) [[Class alloc] init]; Message send in message send. 479234353Sdim // 4) [[obj]{ return self; }() doStuff]; Lambda in message send. 480234353Sdim // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted. 481234353Sdim 482234353Sdim // If we have a lambda-introducer, then this is definitely not a message send. 483234353Sdim // FIXME: If this disambiguation is too slow, fold the tentative lambda parse 484234353Sdim // into the tentative attribute parse below. 485234353Sdim LambdaIntroducer Intro; 486234353Sdim if (!TryParseLambdaIntroducer(Intro)) { 487234353Sdim // A lambda cannot end with ']]', and an attribute must. 488234353Sdim bool IsAttribute = Tok.is(tok::r_square); 489234353Sdim 490234353Sdim PA.Revert(); 491234353Sdim 492234353Sdim if (IsAttribute) 493234353Sdim // Case 1: C++11 attribute. 494234353Sdim return CAK_AttributeSpecifier; 495234353Sdim 496234353Sdim if (OuterMightBeMessageSend) 497234353Sdim // Case 4: Lambda in message send. 498234353Sdim return CAK_NotAttributeSpecifier; 499234353Sdim 500234353Sdim // Case 2: Lambda in array size / index. 501234353Sdim return CAK_InvalidAttributeSpecifier; 502234353Sdim } 503234353Sdim 504199990Srdivacky ConsumeBracket(); 505199990Srdivacky 506234353Sdim // If we don't have a lambda-introducer, then we have an attribute or a 507234353Sdim // message-send. 508234353Sdim bool IsAttribute = true; 509234353Sdim while (Tok.isNot(tok::r_square)) { 510234353Sdim if (Tok.is(tok::comma)) { 511234353Sdim // Case 1: Stray commas can only occur in attributes. 512234353Sdim PA.Revert(); 513234353Sdim return CAK_AttributeSpecifier; 514234353Sdim } 515199990Srdivacky 516234353Sdim // Parse the attribute-token, if present. 517234353Sdim // C++11 [dcl.attr.grammar]: 518234353Sdim // If a keyword or an alternative token that satisfies the syntactic 519234353Sdim // requirements of an identifier is contained in an attribute-token, 520234353Sdim // it is considered an identifier. 521234353Sdim SourceLocation Loc; 522234353Sdim if (!TryParseCXX11AttributeIdentifier(Loc)) { 523234353Sdim IsAttribute = false; 524234353Sdim break; 525234353Sdim } 526234353Sdim if (Tok.is(tok::coloncolon)) { 527234353Sdim ConsumeToken(); 528234353Sdim if (!TryParseCXX11AttributeIdentifier(Loc)) { 529234353Sdim IsAttribute = false; 530234353Sdim break; 531234353Sdim } 532234353Sdim } 533234353Sdim 534234353Sdim // Parse the attribute-argument-clause, if present. 535234353Sdim if (Tok.is(tok::l_paren)) { 536234353Sdim ConsumeParen(); 537234353Sdim if (!SkipUntil(tok::r_paren, false)) { 538234353Sdim IsAttribute = false; 539234353Sdim break; 540234353Sdim } 541234353Sdim } 542234353Sdim 543234353Sdim if (Tok.is(tok::ellipsis)) 544234353Sdim ConsumeToken(); 545234353Sdim 546234353Sdim if (Tok.isNot(tok::comma)) 547234353Sdim break; 548234353Sdim 549234353Sdim ConsumeToken(); 550234353Sdim } 551234353Sdim 552234353Sdim // An attribute must end ']]'. 553234353Sdim if (IsAttribute) { 554234353Sdim if (Tok.is(tok::r_square)) { 555234353Sdim ConsumeBracket(); 556234353Sdim IsAttribute = Tok.is(tok::r_square); 557234353Sdim } else { 558234353Sdim IsAttribute = false; 559234353Sdim } 560234353Sdim } 561234353Sdim 562234353Sdim PA.Revert(); 563234353Sdim 564234353Sdim if (IsAttribute) 565234353Sdim // Case 1: C++11 statement attribute. 566234353Sdim return CAK_AttributeSpecifier; 567234353Sdim 568234353Sdim // Case 3: Message send. 569234353Sdim return CAK_NotAttributeSpecifier; 570199990Srdivacky} 571199990Srdivacky 572193326Sed/// declarator: 573193326Sed/// direct-declarator 574193326Sed/// ptr-operator declarator 575193326Sed/// 576193326Sed/// direct-declarator: 577193326Sed/// declarator-id 578193326Sed/// direct-declarator '(' parameter-declaration-clause ')' 579193326Sed/// cv-qualifier-seq[opt] exception-specification[opt] 580193326Sed/// direct-declarator '[' constant-expression[opt] ']' 581193326Sed/// '(' declarator ')' 582193326Sed/// [GNU] '(' attributes declarator ')' 583193326Sed/// 584193326Sed/// abstract-declarator: 585193326Sed/// ptr-operator abstract-declarator[opt] 586193326Sed/// direct-abstract-declarator 587218893Sdim/// ... 588193326Sed/// 589193326Sed/// direct-abstract-declarator: 590193326Sed/// direct-abstract-declarator[opt] 591193326Sed/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 592193326Sed/// exception-specification[opt] 593193326Sed/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 594193326Sed/// '(' abstract-declarator ')' 595193326Sed/// 596193326Sed/// ptr-operator: 597193326Sed/// '*' cv-qualifier-seq[opt] 598193326Sed/// '&' 599193326Sed/// [C++0x] '&&' [TODO] 600193326Sed/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 601193326Sed/// 602193326Sed/// cv-qualifier-seq: 603193326Sed/// cv-qualifier cv-qualifier-seq[opt] 604193326Sed/// 605193326Sed/// cv-qualifier: 606193326Sed/// 'const' 607193326Sed/// 'volatile' 608193326Sed/// 609193326Sed/// declarator-id: 610218893Sdim/// '...'[opt] id-expression 611193326Sed/// 612193326Sed/// id-expression: 613193326Sed/// unqualified-id 614193326Sed/// qualified-id [TODO] 615193326Sed/// 616193326Sed/// unqualified-id: 617193326Sed/// identifier 618193326Sed/// operator-function-id [TODO] 619193326Sed/// conversion-function-id [TODO] 620193326Sed/// '~' class-name [TODO] 621193326Sed/// template-id [TODO] 622193326Sed/// 623193326SedParser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 624193326Sed bool mayHaveIdentifier) { 625193326Sed // declarator: 626193326Sed // direct-declarator 627193326Sed // ptr-operator declarator 628193326Sed 629193326Sed while (1) { 630193326Sed if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 631204643Srdivacky if (TryAnnotateCXXScopeToken(true)) 632204643Srdivacky return TPResult::Error(); 633193326Sed 634193326Sed if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 635218893Sdim Tok.is(tok::ampamp) || 636193326Sed (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 637193326Sed // ptr-operator 638193326Sed ConsumeToken(); 639193326Sed while (Tok.is(tok::kw_const) || 640193326Sed Tok.is(tok::kw_volatile) || 641193326Sed Tok.is(tok::kw_restrict)) 642193326Sed ConsumeToken(); 643193326Sed } else { 644193326Sed break; 645193326Sed } 646193326Sed } 647193326Sed 648193326Sed // direct-declarator: 649193326Sed // direct-abstract-declarator: 650218893Sdim if (Tok.is(tok::ellipsis)) 651218893Sdim ConsumeToken(); 652218893Sdim 653198092Srdivacky if ((Tok.is(tok::identifier) || 654198092Srdivacky (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) && 655198092Srdivacky mayHaveIdentifier) { 656193326Sed // declarator-id 657198092Srdivacky if (Tok.is(tok::annot_cxxscope)) 658198092Srdivacky ConsumeToken(); 659243830Sdim else 660243830Sdim TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo()); 661193326Sed ConsumeToken(); 662193326Sed } else if (Tok.is(tok::l_paren)) { 663193326Sed ConsumeParen(); 664193326Sed if (mayBeAbstract && 665193326Sed (Tok.is(tok::r_paren) || // 'int()' is a function. 666234353Sdim // 'int(...)' is a function. 667234353Sdim (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) || 668193326Sed isDeclarationSpecifier())) { // 'int(int)' is a function. 669193326Sed // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 670193326Sed // exception-specification[opt] 671193326Sed TPResult TPR = TryParseFunctionDeclarator(); 672193326Sed if (TPR != TPResult::Ambiguous()) 673193326Sed return TPR; 674193326Sed } else { 675193326Sed // '(' declarator ')' 676193326Sed // '(' attributes declarator ')' 677193326Sed // '(' abstract-declarator ')' 678218893Sdim if (Tok.is(tok::kw___attribute) || 679218893Sdim Tok.is(tok::kw___declspec) || 680218893Sdim Tok.is(tok::kw___cdecl) || 681218893Sdim Tok.is(tok::kw___stdcall) || 682218893Sdim Tok.is(tok::kw___fastcall) || 683226633Sdim Tok.is(tok::kw___thiscall) || 684226633Sdim Tok.is(tok::kw___unaligned)) 685193326Sed return TPResult::True(); // attributes indicate declaration 686193326Sed TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 687193326Sed if (TPR != TPResult::Ambiguous()) 688193326Sed return TPR; 689193326Sed if (Tok.isNot(tok::r_paren)) 690193326Sed return TPResult::False(); 691193326Sed ConsumeParen(); 692193326Sed } 693193326Sed } else if (!mayBeAbstract) { 694193326Sed return TPResult::False(); 695193326Sed } 696193326Sed 697193326Sed while (1) { 698193326Sed TPResult TPR(TPResult::Ambiguous()); 699193326Sed 700218893Sdim // abstract-declarator: ... 701218893Sdim if (Tok.is(tok::ellipsis)) 702218893Sdim ConsumeToken(); 703218893Sdim 704193326Sed if (Tok.is(tok::l_paren)) { 705193326Sed // Check whether we have a function declarator or a possible ctor-style 706193326Sed // initializer that follows the declarator. Note that ctor-style 707193326Sed // initializers are not possible in contexts where abstract declarators 708193326Sed // are allowed. 709239462Sdim if (!mayBeAbstract && !isCXXFunctionDeclarator()) 710193326Sed break; 711193326Sed 712193326Sed // direct-declarator '(' parameter-declaration-clause ')' 713193326Sed // cv-qualifier-seq[opt] exception-specification[opt] 714193326Sed ConsumeParen(); 715193326Sed TPR = TryParseFunctionDeclarator(); 716193326Sed } else if (Tok.is(tok::l_square)) { 717193326Sed // direct-declarator '[' constant-expression[opt] ']' 718193326Sed // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 719193326Sed TPR = TryParseBracketDeclarator(); 720193326Sed } else { 721193326Sed break; 722193326Sed } 723193326Sed 724193326Sed if (TPR != TPResult::Ambiguous()) 725193326Sed return TPR; 726193326Sed } 727193326Sed 728193326Sed return TPResult::Ambiguous(); 729193326Sed} 730193326Sed 731218893SdimParser::TPResult 732218893SdimParser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { 733218893Sdim switch (Kind) { 734218893Sdim // Obviously starts an expression. 735218893Sdim case tok::numeric_constant: 736218893Sdim case tok::char_constant: 737226633Sdim case tok::wide_char_constant: 738226633Sdim case tok::utf16_char_constant: 739226633Sdim case tok::utf32_char_constant: 740218893Sdim case tok::string_literal: 741218893Sdim case tok::wide_string_literal: 742226633Sdim case tok::utf8_string_literal: 743226633Sdim case tok::utf16_string_literal: 744226633Sdim case tok::utf32_string_literal: 745218893Sdim case tok::l_square: 746218893Sdim case tok::l_paren: 747218893Sdim case tok::amp: 748218893Sdim case tok::ampamp: 749218893Sdim case tok::star: 750218893Sdim case tok::plus: 751218893Sdim case tok::plusplus: 752218893Sdim case tok::minus: 753218893Sdim case tok::minusminus: 754218893Sdim case tok::tilde: 755218893Sdim case tok::exclaim: 756218893Sdim case tok::kw_sizeof: 757218893Sdim case tok::kw___func__: 758218893Sdim case tok::kw_const_cast: 759218893Sdim case tok::kw_delete: 760218893Sdim case tok::kw_dynamic_cast: 761218893Sdim case tok::kw_false: 762218893Sdim case tok::kw_new: 763218893Sdim case tok::kw_operator: 764218893Sdim case tok::kw_reinterpret_cast: 765218893Sdim case tok::kw_static_cast: 766218893Sdim case tok::kw_this: 767218893Sdim case tok::kw_throw: 768218893Sdim case tok::kw_true: 769218893Sdim case tok::kw_typeid: 770218893Sdim case tok::kw_alignof: 771218893Sdim case tok::kw_noexcept: 772218893Sdim case tok::kw_nullptr: 773239462Sdim case tok::kw__Alignof: 774218893Sdim case tok::kw___null: 775218893Sdim case tok::kw___alignof: 776218893Sdim case tok::kw___builtin_choose_expr: 777218893Sdim case tok::kw___builtin_offsetof: 778218893Sdim case tok::kw___builtin_types_compatible_p: 779218893Sdim case tok::kw___builtin_va_arg: 780218893Sdim case tok::kw___imag: 781218893Sdim case tok::kw___real: 782218893Sdim case tok::kw___FUNCTION__: 783239462Sdim case tok::kw_L__FUNCTION__: 784218893Sdim case tok::kw___PRETTY_FUNCTION__: 785218893Sdim case tok::kw___has_nothrow_assign: 786218893Sdim case tok::kw___has_nothrow_copy: 787218893Sdim case tok::kw___has_nothrow_constructor: 788218893Sdim case tok::kw___has_trivial_assign: 789218893Sdim case tok::kw___has_trivial_copy: 790218893Sdim case tok::kw___has_trivial_constructor: 791218893Sdim case tok::kw___has_trivial_destructor: 792218893Sdim case tok::kw___has_virtual_destructor: 793218893Sdim case tok::kw___is_abstract: 794218893Sdim case tok::kw___is_base_of: 795218893Sdim case tok::kw___is_class: 796218893Sdim case tok::kw___is_convertible_to: 797218893Sdim case tok::kw___is_empty: 798218893Sdim case tok::kw___is_enum: 799243830Sdim case tok::kw___is_interface_class: 800234353Sdim case tok::kw___is_final: 801221345Sdim case tok::kw___is_literal: 802221345Sdim case tok::kw___is_literal_type: 803218893Sdim case tok::kw___is_pod: 804218893Sdim case tok::kw___is_polymorphic: 805221345Sdim case tok::kw___is_trivial: 806234353Sdim case tok::kw___is_trivially_assignable: 807234353Sdim case tok::kw___is_trivially_constructible: 808223017Sdim case tok::kw___is_trivially_copyable: 809218893Sdim case tok::kw___is_union: 810218893Sdim case tok::kw___uuidof: 811218893Sdim return TPResult::True(); 812218893Sdim 813218893Sdim // Obviously starts a type-specifier-seq: 814218893Sdim case tok::kw_char: 815218893Sdim case tok::kw_const: 816218893Sdim case tok::kw_double: 817218893Sdim case tok::kw_enum: 818226633Sdim case tok::kw_half: 819218893Sdim case tok::kw_float: 820218893Sdim case tok::kw_int: 821218893Sdim case tok::kw_long: 822221345Sdim case tok::kw___int64: 823234353Sdim case tok::kw___int128: 824218893Sdim case tok::kw_restrict: 825218893Sdim case tok::kw_short: 826218893Sdim case tok::kw_signed: 827218893Sdim case tok::kw_struct: 828218893Sdim case tok::kw_union: 829218893Sdim case tok::kw_unsigned: 830218893Sdim case tok::kw_void: 831218893Sdim case tok::kw_volatile: 832218893Sdim case tok::kw__Bool: 833218893Sdim case tok::kw__Complex: 834218893Sdim case tok::kw_class: 835218893Sdim case tok::kw_typename: 836218893Sdim case tok::kw_wchar_t: 837218893Sdim case tok::kw_char16_t: 838218893Sdim case tok::kw_char32_t: 839223017Sdim case tok::kw___underlying_type: 840218893Sdim case tok::kw__Decimal32: 841218893Sdim case tok::kw__Decimal64: 842218893Sdim case tok::kw__Decimal128: 843218893Sdim case tok::kw___thread: 844251662Sdim case tok::kw_thread_local: 845251662Sdim case tok::kw__Thread_local: 846218893Sdim case tok::kw_typeof: 847218893Sdim case tok::kw___cdecl: 848218893Sdim case tok::kw___stdcall: 849218893Sdim case tok::kw___fastcall: 850218893Sdim case tok::kw___thiscall: 851226633Sdim case tok::kw___unaligned: 852218893Sdim case tok::kw___vector: 853218893Sdim case tok::kw___pixel: 854226633Sdim case tok::kw__Atomic: 855249423Sdim case tok::kw_image1d_t: 856249423Sdim case tok::kw_image1d_array_t: 857249423Sdim case tok::kw_image1d_buffer_t: 858249423Sdim case tok::kw_image2d_t: 859249423Sdim case tok::kw_image2d_array_t: 860249423Sdim case tok::kw_image3d_t: 861249423Sdim case tok::kw_sampler_t: 862249423Sdim case tok::kw_event_t: 863249423Sdim case tok::kw___unknown_anytype: 864218893Sdim return TPResult::False(); 865218893Sdim 866218893Sdim default: 867218893Sdim break; 868218893Sdim } 869218893Sdim 870218893Sdim return TPResult::Ambiguous(); 871218893Sdim} 872218893Sdim 873243830Sdimbool Parser::isTentativelyDeclared(IdentifierInfo *II) { 874243830Sdim return std::find(TentativelyDeclaredIdentifiers.begin(), 875243830Sdim TentativelyDeclaredIdentifiers.end(), II) 876243830Sdim != TentativelyDeclaredIdentifiers.end(); 877243830Sdim} 878243830Sdim 879193326Sed/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 880193326Sed/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 881193326Sed/// be either a decl-specifier or a function-style cast, and TPResult::Error() 882193326Sed/// if a parsing error was found and reported. 883193326Sed/// 884239462Sdim/// If HasMissingTypename is provided, a name with a dependent scope specifier 885239462Sdim/// will be treated as ambiguous if the 'typename' keyword is missing. If this 886243830Sdim/// happens, *HasMissingTypename will be set to 'true'. This will also be used 887243830Sdim/// as an indicator that undeclared identifiers (which will trigger a later 888243830Sdim/// parse error) should be treated as types. Returns TPResult::Ambiguous() in 889243830Sdim/// such cases. 890239462Sdim/// 891193326Sed/// decl-specifier: 892193326Sed/// storage-class-specifier 893193326Sed/// type-specifier 894193326Sed/// function-specifier 895193326Sed/// 'friend' 896193326Sed/// 'typedef' 897251662Sdim/// [C++11] 'constexpr' 898193326Sed/// [GNU] attributes declaration-specifiers[opt] 899193326Sed/// 900193326Sed/// storage-class-specifier: 901193326Sed/// 'register' 902193326Sed/// 'static' 903193326Sed/// 'extern' 904193326Sed/// 'mutable' 905193326Sed/// 'auto' 906193326Sed/// [GNU] '__thread' 907251662Sdim/// [C++11] 'thread_local' 908251662Sdim/// [C11] '_Thread_local' 909193326Sed/// 910193326Sed/// function-specifier: 911193326Sed/// 'inline' 912193326Sed/// 'virtual' 913193326Sed/// 'explicit' 914193326Sed/// 915193326Sed/// typedef-name: 916193326Sed/// identifier 917193326Sed/// 918193326Sed/// type-specifier: 919193326Sed/// simple-type-specifier 920193326Sed/// class-specifier 921193326Sed/// enum-specifier 922193326Sed/// elaborated-type-specifier 923193326Sed/// typename-specifier 924193326Sed/// cv-qualifier 925193326Sed/// 926193326Sed/// simple-type-specifier: 927193326Sed/// '::'[opt] nested-name-specifier[opt] type-name 928193326Sed/// '::'[opt] nested-name-specifier 'template' 929193326Sed/// simple-template-id [TODO] 930193326Sed/// 'char' 931193326Sed/// 'wchar_t' 932193326Sed/// 'bool' 933193326Sed/// 'short' 934193326Sed/// 'int' 935193326Sed/// 'long' 936193326Sed/// 'signed' 937193326Sed/// 'unsigned' 938193326Sed/// 'float' 939193326Sed/// 'double' 940193326Sed/// 'void' 941193326Sed/// [GNU] typeof-specifier 942193326Sed/// [GNU] '_Complex' 943251662Sdim/// [C++11] 'auto' 944251662Sdim/// [C++11] 'decltype' ( expression ) 945251662Sdim/// [C++1y] 'decltype' ( 'auto' ) 946193326Sed/// 947193326Sed/// type-name: 948193326Sed/// class-name 949193326Sed/// enum-name 950193326Sed/// typedef-name 951193326Sed/// 952193326Sed/// elaborated-type-specifier: 953193326Sed/// class-key '::'[opt] nested-name-specifier[opt] identifier 954193326Sed/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 955193326Sed/// simple-template-id 956193326Sed/// 'enum' '::'[opt] nested-name-specifier[opt] identifier 957193326Sed/// 958193326Sed/// enum-name: 959193326Sed/// identifier 960193326Sed/// 961193326Sed/// enum-specifier: 962193326Sed/// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 963193326Sed/// 'enum' identifier[opt] '{' enumerator-list ',' '}' 964193326Sed/// 965193326Sed/// class-specifier: 966193326Sed/// class-head '{' member-specification[opt] '}' 967193326Sed/// 968193326Sed/// class-head: 969193326Sed/// class-key identifier[opt] base-clause[opt] 970193326Sed/// class-key nested-name-specifier identifier base-clause[opt] 971193326Sed/// class-key nested-name-specifier[opt] simple-template-id 972193326Sed/// base-clause[opt] 973193326Sed/// 974193326Sed/// class-key: 975193326Sed/// 'class' 976193326Sed/// 'struct' 977193326Sed/// 'union' 978193326Sed/// 979193326Sed/// cv-qualifier: 980193326Sed/// 'const' 981193326Sed/// 'volatile' 982193326Sed/// [GNU] restrict 983193326Sed/// 984234353SdimParser::TPResult 985239462SdimParser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, 986239462Sdim bool *HasMissingTypename) { 987193326Sed switch (Tok.getKind()) { 988243830Sdim case tok::identifier: { 989203955Srdivacky // Check for need to substitute AltiVec __vector keyword 990203955Srdivacky // for "vector" identifier. 991203955Srdivacky if (TryAltiVecVectorToken()) 992203955Srdivacky return TPResult::True(); 993243830Sdim 994243830Sdim const Token &Next = NextToken(); 995243830Sdim // In 'foo bar', 'foo' is always a type name outside of Objective-C. 996243830Sdim if (!getLangOpts().ObjC1 && Next.is(tok::identifier)) 997243830Sdim return TPResult::True(); 998243830Sdim 999243830Sdim if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) { 1000243830Sdim // Determine whether this is a valid expression. If not, we will hit 1001243830Sdim // a parse error one way or another. In that case, tell the caller that 1002243830Sdim // this is ambiguous. Typo-correct to type and expression keywords and 1003243830Sdim // to types and identifiers, in order to try to recover from errors. 1004243830Sdim CorrectionCandidateCallback TypoCorrection; 1005243830Sdim TypoCorrection.WantRemainingKeywords = false; 1006249423Sdim TypoCorrection.WantTypeSpecifiers = Next.isNot(tok::arrow); 1007243830Sdim switch (TryAnnotateName(false /* no nested name specifier */, 1008243830Sdim &TypoCorrection)) { 1009243830Sdim case ANK_Error: 1010243830Sdim return TPResult::Error(); 1011243830Sdim case ANK_TentativeDecl: 1012243830Sdim return TPResult::False(); 1013243830Sdim case ANK_TemplateName: 1014243830Sdim // A bare type template-name which can't be a template template 1015243830Sdim // argument is an error, and was probably intended to be a type. 1016243830Sdim return GreaterThanIsOperator ? TPResult::True() : TPResult::False(); 1017243830Sdim case ANK_Unresolved: 1018243830Sdim return HasMissingTypename ? TPResult::Ambiguous() : TPResult::False(); 1019243830Sdim case ANK_Success: 1020243830Sdim break; 1021243830Sdim } 1022243830Sdim assert(Tok.isNot(tok::identifier) && 1023243830Sdim "TryAnnotateName succeeded without producing an annotation"); 1024243830Sdim } else { 1025243830Sdim // This might possibly be a type with a dependent scope specifier and 1026243830Sdim // a missing 'typename' keyword. Don't use TryAnnotateName in this case, 1027243830Sdim // since it will annotate as a primary expression, and we want to use the 1028243830Sdim // "missing 'typename'" logic. 1029243830Sdim if (TryAnnotateTypeOrScopeToken()) 1030243830Sdim return TPResult::Error(); 1031243830Sdim // If annotation failed, assume it's a non-type. 1032243830Sdim // FIXME: If this happens due to an undeclared identifier, treat it as 1033243830Sdim // ambiguous. 1034243830Sdim if (Tok.is(tok::identifier)) 1035243830Sdim return TPResult::False(); 1036243830Sdim } 1037243830Sdim 1038243830Sdim // We annotated this token as something. Recurse to handle whatever we got. 1039243830Sdim return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1040243830Sdim } 1041243830Sdim 1042193326Sed case tok::kw_typename: // typename T::type 1043193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 1044193326Sed // recurse to handle whatever we get. 1045193326Sed if (TryAnnotateTypeOrScopeToken()) 1046204643Srdivacky return TPResult::Error(); 1047239462Sdim return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1048193326Sed 1049201361Srdivacky case tok::coloncolon: { // ::foo::bar 1050201361Srdivacky const Token &Next = NextToken(); 1051201361Srdivacky if (Next.is(tok::kw_new) || // ::new 1052201361Srdivacky Next.is(tok::kw_delete)) // ::delete 1053201361Srdivacky return TPResult::False(); 1054234353Sdim } 1055234353Sdim // Fall through. 1056234353Sdim case tok::kw_decltype: 1057193326Sed // Annotate typenames and C++ scope specifiers. If we get one, just 1058193326Sed // recurse to handle whatever we get. 1059193326Sed if (TryAnnotateTypeOrScopeToken()) 1060204643Srdivacky return TPResult::Error(); 1061239462Sdim return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 1062234353Sdim 1063193326Sed // decl-specifier: 1064193326Sed // storage-class-specifier 1065193326Sed // type-specifier 1066193326Sed // function-specifier 1067193326Sed // 'friend' 1068193326Sed // 'typedef' 1069198954Srdivacky // 'constexpr' 1070193326Sed case tok::kw_friend: 1071193326Sed case tok::kw_typedef: 1072198954Srdivacky case tok::kw_constexpr: 1073193326Sed // storage-class-specifier 1074193326Sed case tok::kw_register: 1075193326Sed case tok::kw_static: 1076193326Sed case tok::kw_extern: 1077193326Sed case tok::kw_mutable: 1078193326Sed case tok::kw_auto: 1079193326Sed case tok::kw___thread: 1080251662Sdim case tok::kw_thread_local: 1081251662Sdim case tok::kw__Thread_local: 1082193326Sed // function-specifier 1083193326Sed case tok::kw_inline: 1084193326Sed case tok::kw_virtual: 1085193326Sed case tok::kw_explicit: 1086193326Sed 1087226633Sdim // Modules 1088226633Sdim case tok::kw___module_private__: 1089249423Sdim 1090249423Sdim // Debugger support 1091249423Sdim case tok::kw___unknown_anytype: 1092226633Sdim 1093193326Sed // type-specifier: 1094193326Sed // simple-type-specifier 1095193326Sed // class-specifier 1096193326Sed // enum-specifier 1097193326Sed // elaborated-type-specifier 1098193326Sed // typename-specifier 1099193326Sed // cv-qualifier 1100193326Sed 1101193326Sed // class-specifier 1102193326Sed // elaborated-type-specifier 1103193326Sed case tok::kw_class: 1104193326Sed case tok::kw_struct: 1105193326Sed case tok::kw_union: 1106193326Sed // enum-specifier 1107193326Sed case tok::kw_enum: 1108193326Sed // cv-qualifier 1109193326Sed case tok::kw_const: 1110193326Sed case tok::kw_volatile: 1111193326Sed 1112193326Sed // GNU 1113193326Sed case tok::kw_restrict: 1114193326Sed case tok::kw__Complex: 1115193326Sed case tok::kw___attribute: 1116193326Sed return TPResult::True(); 1117198092Srdivacky 1118193326Sed // Microsoft 1119193326Sed case tok::kw___declspec: 1120193326Sed case tok::kw___cdecl: 1121193326Sed case tok::kw___stdcall: 1122193326Sed case tok::kw___fastcall: 1123208600Srdivacky case tok::kw___thiscall: 1124194179Sed case tok::kw___w64: 1125194179Sed case tok::kw___ptr64: 1126226633Sdim case tok::kw___ptr32: 1127194179Sed case tok::kw___forceinline: 1128226633Sdim case tok::kw___unaligned: 1129194179Sed return TPResult::True(); 1130212904Sdim 1131212904Sdim // Borland 1132212904Sdim case tok::kw___pascal: 1133212904Sdim return TPResult::True(); 1134203955Srdivacky 1135203955Srdivacky // AltiVec 1136203955Srdivacky case tok::kw___vector: 1137203955Srdivacky return TPResult::True(); 1138193326Sed 1139207619Srdivacky case tok::annot_template_id: { 1140224145Sdim TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 1141207619Srdivacky if (TemplateId->Kind != TNK_Type_template) 1142207619Srdivacky return TPResult::False(); 1143207619Srdivacky CXXScopeSpec SS; 1144221345Sdim AnnotateTemplateIdTokenAsType(); 1145207619Srdivacky assert(Tok.is(tok::annot_typename)); 1146207619Srdivacky goto case_typename; 1147207619Srdivacky } 1148207619Srdivacky 1149201361Srdivacky case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed 1150201361Srdivacky // We've already annotated a scope; try to annotate a type. 1151204643Srdivacky if (TryAnnotateTypeOrScopeToken()) 1152204643Srdivacky return TPResult::Error(); 1153234353Sdim if (!Tok.is(tok::annot_typename)) { 1154234353Sdim // If the next token is an identifier or a type qualifier, then this 1155234353Sdim // can't possibly be a valid expression either. 1156234353Sdim if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) { 1157234353Sdim CXXScopeSpec SS; 1158234353Sdim Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 1159234353Sdim Tok.getAnnotationRange(), 1160234353Sdim SS); 1161234353Sdim if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) { 1162234353Sdim TentativeParsingAction PA(*this); 1163234353Sdim ConsumeToken(); 1164234353Sdim ConsumeToken(); 1165234353Sdim bool isIdentifier = Tok.is(tok::identifier); 1166234353Sdim TPResult TPR = TPResult::False(); 1167234353Sdim if (!isIdentifier) 1168239462Sdim TPR = isCXXDeclarationSpecifier(BracedCastResult, 1169239462Sdim HasMissingTypename); 1170234353Sdim PA.Revert(); 1171234353Sdim 1172234353Sdim if (isIdentifier || 1173234353Sdim TPR == TPResult::True() || TPR == TPResult::Error()) 1174234353Sdim return TPResult::Error(); 1175239462Sdim 1176239462Sdim if (HasMissingTypename) { 1177239462Sdim // We can't tell whether this is a missing 'typename' or a valid 1178239462Sdim // expression. 1179239462Sdim *HasMissingTypename = true; 1180239462Sdim return TPResult::Ambiguous(); 1181239462Sdim } 1182243830Sdim } else { 1183243830Sdim // Try to resolve the name. If it doesn't exist, assume it was 1184243830Sdim // intended to name a type and keep disambiguating. 1185243830Sdim switch (TryAnnotateName(false /* SS is not dependent */)) { 1186243830Sdim case ANK_Error: 1187243830Sdim return TPResult::Error(); 1188243830Sdim case ANK_TentativeDecl: 1189243830Sdim return TPResult::False(); 1190243830Sdim case ANK_TemplateName: 1191243830Sdim // A bare type template-name which can't be a template template 1192243830Sdim // argument is an error, and was probably intended to be a type. 1193243830Sdim return GreaterThanIsOperator ? TPResult::True() : TPResult::False(); 1194243830Sdim case ANK_Unresolved: 1195243830Sdim return HasMissingTypename ? TPResult::Ambiguous() 1196243830Sdim : TPResult::False(); 1197243830Sdim case ANK_Success: 1198243830Sdim // Annotated it, check again. 1199243830Sdim assert(Tok.isNot(tok::annot_cxxscope) || 1200243830Sdim NextToken().isNot(tok::identifier)); 1201243830Sdim return isCXXDeclarationSpecifier(BracedCastResult, 1202243830Sdim HasMissingTypename); 1203243830Sdim } 1204234353Sdim } 1205234353Sdim } 1206201361Srdivacky return TPResult::False(); 1207234353Sdim } 1208201361Srdivacky // If that succeeded, fallthrough into the generic simple-type-id case. 1209201361Srdivacky 1210193326Sed // The ambiguity resides in a simple-type-specifier/typename-specifier 1211193326Sed // followed by a '('. The '(' could either be the start of: 1212193326Sed // 1213193326Sed // direct-declarator: 1214193326Sed // '(' declarator ')' 1215193326Sed // 1216193326Sed // direct-abstract-declarator: 1217193326Sed // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1218193326Sed // exception-specification[opt] 1219193326Sed // '(' abstract-declarator ')' 1220193326Sed // 1221193326Sed // or part of a function-style cast expression: 1222193326Sed // 1223193326Sed // simple-type-specifier '(' expression-list[opt] ')' 1224193326Sed // 1225193326Sed 1226193326Sed // simple-type-specifier: 1227193326Sed 1228218893Sdim case tok::annot_typename: 1229218893Sdim case_typename: 1230218893Sdim // In Objective-C, we might have a protocol-qualified type. 1231234353Sdim if (getLangOpts().ObjC1 && NextToken().is(tok::less)) { 1232218893Sdim // Tentatively parse the 1233218893Sdim TentativeParsingAction PA(*this); 1234218893Sdim ConsumeToken(); // The type token 1235218893Sdim 1236218893Sdim TPResult TPR = TryParseProtocolQualifiers(); 1237218893Sdim bool isFollowedByParen = Tok.is(tok::l_paren); 1238234353Sdim bool isFollowedByBrace = Tok.is(tok::l_brace); 1239218893Sdim 1240218893Sdim PA.Revert(); 1241218893Sdim 1242218893Sdim if (TPR == TPResult::Error()) 1243218893Sdim return TPResult::Error(); 1244218893Sdim 1245218893Sdim if (isFollowedByParen) 1246218893Sdim return TPResult::Ambiguous(); 1247234353Sdim 1248249423Sdim if (getLangOpts().CPlusPlus11 && isFollowedByBrace) 1249234353Sdim return BracedCastResult; 1250218893Sdim 1251218893Sdim return TPResult::True(); 1252218893Sdim } 1253218893Sdim 1254193326Sed case tok::kw_char: 1255193326Sed case tok::kw_wchar_t: 1256198092Srdivacky case tok::kw_char16_t: 1257198092Srdivacky case tok::kw_char32_t: 1258193326Sed case tok::kw_bool: 1259193326Sed case tok::kw_short: 1260193326Sed case tok::kw_int: 1261193326Sed case tok::kw_long: 1262221345Sdim case tok::kw___int64: 1263234353Sdim case tok::kw___int128: 1264193326Sed case tok::kw_signed: 1265193326Sed case tok::kw_unsigned: 1266226633Sdim case tok::kw_half: 1267193326Sed case tok::kw_float: 1268193326Sed case tok::kw_double: 1269193326Sed case tok::kw_void: 1270234353Sdim case tok::annot_decltype: 1271193326Sed if (NextToken().is(tok::l_paren)) 1272193326Sed return TPResult::Ambiguous(); 1273193326Sed 1274234353Sdim // This is a function-style cast in all cases we disambiguate other than 1275234353Sdim // one: 1276234353Sdim // struct S { 1277234353Sdim // enum E : int { a = 4 }; // enum 1278234353Sdim // enum E : int { 4 }; // bit-field 1279234353Sdim // }; 1280249423Sdim if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace)) 1281234353Sdim return BracedCastResult; 1282234353Sdim 1283218893Sdim if (isStartOfObjCClassMessageMissingOpenBracket()) 1284218893Sdim return TPResult::False(); 1285218893Sdim 1286193326Sed return TPResult::True(); 1287193326Sed 1288195099Sed // GNU typeof support. 1289193326Sed case tok::kw_typeof: { 1290193326Sed if (NextToken().isNot(tok::l_paren)) 1291193326Sed return TPResult::True(); 1292193326Sed 1293193326Sed TentativeParsingAction PA(*this); 1294193326Sed 1295193326Sed TPResult TPR = TryParseTypeofSpecifier(); 1296193326Sed bool isFollowedByParen = Tok.is(tok::l_paren); 1297234353Sdim bool isFollowedByBrace = Tok.is(tok::l_brace); 1298193326Sed 1299193326Sed PA.Revert(); 1300193326Sed 1301193326Sed if (TPR == TPResult::Error()) 1302193326Sed return TPResult::Error(); 1303193326Sed 1304193326Sed if (isFollowedByParen) 1305193326Sed return TPResult::Ambiguous(); 1306193326Sed 1307249423Sdim if (getLangOpts().CPlusPlus11 && isFollowedByBrace) 1308234353Sdim return BracedCastResult; 1309234353Sdim 1310193326Sed return TPResult::True(); 1311193326Sed } 1312193326Sed 1313223017Sdim // C++0x type traits support 1314223017Sdim case tok::kw___underlying_type: 1315223017Sdim return TPResult::True(); 1316223017Sdim 1317234353Sdim // C11 _Atomic 1318226633Sdim case tok::kw__Atomic: 1319226633Sdim return TPResult::True(); 1320226633Sdim 1321193326Sed default: 1322193326Sed return TPResult::False(); 1323193326Sed } 1324193326Sed} 1325193326Sed 1326193326Sed/// [GNU] typeof-specifier: 1327193326Sed/// 'typeof' '(' expressions ')' 1328193326Sed/// 'typeof' '(' type-name ')' 1329193326Sed/// 1330193326SedParser::TPResult Parser::TryParseTypeofSpecifier() { 1331193326Sed assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 1332193326Sed ConsumeToken(); 1333193326Sed 1334193326Sed assert(Tok.is(tok::l_paren) && "Expected '('"); 1335193326Sed // Parse through the parens after 'typeof'. 1336193326Sed ConsumeParen(); 1337193326Sed if (!SkipUntil(tok::r_paren)) 1338193326Sed return TPResult::Error(); 1339193326Sed 1340193326Sed return TPResult::Ambiguous(); 1341193326Sed} 1342193326Sed 1343218893Sdim/// [ObjC] protocol-qualifiers: 1344218893Sdim//// '<' identifier-list '>' 1345218893SdimParser::TPResult Parser::TryParseProtocolQualifiers() { 1346218893Sdim assert(Tok.is(tok::less) && "Expected '<' for qualifier list"); 1347218893Sdim ConsumeToken(); 1348218893Sdim do { 1349218893Sdim if (Tok.isNot(tok::identifier)) 1350218893Sdim return TPResult::Error(); 1351218893Sdim ConsumeToken(); 1352218893Sdim 1353218893Sdim if (Tok.is(tok::comma)) { 1354218893Sdim ConsumeToken(); 1355218893Sdim continue; 1356218893Sdim } 1357218893Sdim 1358218893Sdim if (Tok.is(tok::greater)) { 1359218893Sdim ConsumeToken(); 1360218893Sdim return TPResult::Ambiguous(); 1361218893Sdim } 1362218893Sdim } while (false); 1363218893Sdim 1364218893Sdim return TPResult::Error(); 1365218893Sdim} 1366218893Sdim 1367239462SdimParser::TPResult 1368239462SdimParser::TryParseDeclarationSpecifier(bool *HasMissingTypename) { 1369239462Sdim TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(), 1370239462Sdim HasMissingTypename); 1371193326Sed if (TPR != TPResult::Ambiguous()) 1372193326Sed return TPR; 1373193326Sed 1374193326Sed if (Tok.is(tok::kw_typeof)) 1375193326Sed TryParseTypeofSpecifier(); 1376218893Sdim else { 1377239462Sdim if (Tok.is(tok::annot_cxxscope)) 1378239462Sdim ConsumeToken(); 1379193326Sed ConsumeToken(); 1380218893Sdim 1381234353Sdim if (getLangOpts().ObjC1 && Tok.is(tok::less)) 1382218893Sdim TryParseProtocolQualifiers(); 1383218893Sdim } 1384198092Srdivacky 1385193326Sed return TPResult::Ambiguous(); 1386193326Sed} 1387193326Sed 1388193326Sed/// isCXXFunctionDeclarator - Disambiguates between a function declarator or 1389193326Sed/// a constructor-style initializer, when parsing declaration statements. 1390193326Sed/// Returns true for function declarator and false for constructor-style 1391193326Sed/// initializer. 1392193326Sed/// If during the disambiguation process a parsing error is encountered, 1393193326Sed/// the function returns true to let the declaration parsing code handle it. 1394193326Sed/// 1395193326Sed/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1396193326Sed/// exception-specification[opt] 1397193326Sed/// 1398239462Sdimbool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) { 1399193326Sed 1400193326Sed // C++ 8.2p1: 1401193326Sed // The ambiguity arising from the similarity between a function-style cast and 1402193326Sed // a declaration mentioned in 6.8 can also occur in the context of a 1403193326Sed // declaration. In that context, the choice is between a function declaration 1404193326Sed // with a redundant set of parentheses around a parameter name and an object 1405193326Sed // declaration with a function-style cast as the initializer. Just as for the 1406193326Sed // ambiguities mentioned in 6.8, the resolution is to consider any construct 1407193326Sed // that could possibly be a declaration a declaration. 1408193326Sed 1409193326Sed TentativeParsingAction PA(*this); 1410193326Sed 1411193326Sed ConsumeParen(); 1412239462Sdim bool InvalidAsDeclaration = false; 1413239462Sdim TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration); 1414239462Sdim if (TPR == TPResult::Ambiguous()) { 1415239462Sdim if (Tok.isNot(tok::r_paren)) 1416239462Sdim TPR = TPResult::False(); 1417239462Sdim else { 1418239462Sdim const Token &Next = NextToken(); 1419239462Sdim if (Next.is(tok::amp) || Next.is(tok::ampamp) || 1420239462Sdim Next.is(tok::kw_const) || Next.is(tok::kw_volatile) || 1421239462Sdim Next.is(tok::kw_throw) || Next.is(tok::kw_noexcept) || 1422249423Sdim Next.is(tok::l_square) || isCXX11VirtSpecifier(Next) || 1423239462Sdim Next.is(tok::l_brace) || Next.is(tok::kw_try) || 1424239462Sdim Next.is(tok::equal) || Next.is(tok::arrow)) 1425239462Sdim // The next token cannot appear after a constructor-style initializer, 1426239462Sdim // and can appear next in a function definition. This must be a function 1427239462Sdim // declarator. 1428239462Sdim TPR = TPResult::True(); 1429239462Sdim else if (InvalidAsDeclaration) 1430239462Sdim // Use the absence of 'typename' as a tie-breaker. 1431239462Sdim TPR = TPResult::False(); 1432239462Sdim } 1433239462Sdim } 1434193326Sed 1435193326Sed PA.Revert(); 1436193326Sed 1437239462Sdim if (IsAmbiguous && TPR == TPResult::Ambiguous()) 1438239462Sdim *IsAmbiguous = true; 1439239462Sdim 1440193326Sed // In case of an error, let the declaration parsing code handle it. 1441239462Sdim return TPR != TPResult::False(); 1442193326Sed} 1443193326Sed 1444193326Sed/// parameter-declaration-clause: 1445193326Sed/// parameter-declaration-list[opt] '...'[opt] 1446193326Sed/// parameter-declaration-list ',' '...' 1447193326Sed/// 1448193326Sed/// parameter-declaration-list: 1449193326Sed/// parameter-declaration 1450193326Sed/// parameter-declaration-list ',' parameter-declaration 1451193326Sed/// 1452193326Sed/// parameter-declaration: 1453234353Sdim/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] 1454234353Sdim/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] 1455218893Sdim/// '=' assignment-expression 1456234353Sdim/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] 1457234353Sdim/// attributes[opt] 1458234353Sdim/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] 1459234353Sdim/// attributes[opt] '=' assignment-expression 1460193326Sed/// 1461239462SdimParser::TPResult 1462239462SdimParser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration) { 1463193326Sed 1464193326Sed if (Tok.is(tok::r_paren)) 1465239462Sdim return TPResult::Ambiguous(); 1466193326Sed 1467193326Sed // parameter-declaration-list[opt] '...'[opt] 1468193326Sed // parameter-declaration-list ',' '...' 1469193326Sed // 1470193326Sed // parameter-declaration-list: 1471193326Sed // parameter-declaration 1472193326Sed // parameter-declaration-list ',' parameter-declaration 1473193326Sed // 1474193326Sed while (1) { 1475193326Sed // '...'[opt] 1476193326Sed if (Tok.is(tok::ellipsis)) { 1477193326Sed ConsumeToken(); 1478234353Sdim if (Tok.is(tok::r_paren)) 1479234353Sdim return TPResult::True(); // '...)' is a sign of a function declarator. 1480234353Sdim else 1481234353Sdim return TPResult::False(); 1482193326Sed } 1483193326Sed 1484234353Sdim // An attribute-specifier-seq here is a sign of a function declarator. 1485234353Sdim if (isCXX11AttributeSpecifier(/*Disambiguate*/false, 1486234353Sdim /*OuterMightBeMessageSend*/true)) 1487234353Sdim return TPResult::True(); 1488234353Sdim 1489221345Sdim ParsedAttributes attrs(AttrFactory); 1490218893Sdim MaybeParseMicrosoftAttributes(attrs); 1491218893Sdim 1492193326Sed // decl-specifier-seq 1493234353Sdim // A parameter-declaration's initializer must be preceded by an '=', so 1494234353Sdim // decl-specifier-seq '{' is not a parameter in C++11. 1495239462Sdim TPResult TPR = TryParseDeclarationSpecifier(InvalidAsDeclaration); 1496193326Sed if (TPR != TPResult::Ambiguous()) 1497193326Sed return TPR; 1498193326Sed 1499193326Sed // declarator 1500193326Sed // abstract-declarator[opt] 1501193326Sed TPR = TryParseDeclarator(true/*mayBeAbstract*/); 1502193326Sed if (TPR != TPResult::Ambiguous()) 1503193326Sed return TPR; 1504193326Sed 1505218893Sdim // [GNU] attributes[opt] 1506218893Sdim if (Tok.is(tok::kw___attribute)) 1507218893Sdim return TPResult::True(); 1508218893Sdim 1509193326Sed if (Tok.is(tok::equal)) { 1510193326Sed // '=' assignment-expression 1511193326Sed // Parse through assignment-expression. 1512234353Sdim if (!SkipUntil(tok::comma, tok::r_paren, true/*StopAtSemi*/, 1513234353Sdim true/*DontConsume*/)) 1514193326Sed return TPResult::Error(); 1515193326Sed } 1516193326Sed 1517193326Sed if (Tok.is(tok::ellipsis)) { 1518193326Sed ConsumeToken(); 1519234353Sdim if (Tok.is(tok::r_paren)) 1520234353Sdim return TPResult::True(); // '...)' is a sign of a function declarator. 1521234353Sdim else 1522234353Sdim return TPResult::False(); 1523193326Sed } 1524193326Sed 1525193326Sed if (Tok.isNot(tok::comma)) 1526193326Sed break; 1527193326Sed ConsumeToken(); // the comma. 1528193326Sed } 1529193326Sed 1530193326Sed return TPResult::Ambiguous(); 1531193326Sed} 1532193326Sed 1533193326Sed/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 1534193326Sed/// parsing as a function declarator. 1535193326Sed/// If TryParseFunctionDeclarator fully parsed the function declarator, it will 1536193326Sed/// return TPResult::Ambiguous(), otherwise it will return either False() or 1537193326Sed/// Error(). 1538198092Srdivacky/// 1539193326Sed/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 1540193326Sed/// exception-specification[opt] 1541193326Sed/// 1542193326Sed/// exception-specification: 1543193326Sed/// 'throw' '(' type-id-list[opt] ')' 1544193326Sed/// 1545193326SedParser::TPResult Parser::TryParseFunctionDeclarator() { 1546193326Sed 1547193326Sed // The '(' is already parsed. 1548193326Sed 1549193326Sed TPResult TPR = TryParseParameterDeclarationClause(); 1550193326Sed if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1551193326Sed TPR = TPResult::False(); 1552193326Sed 1553193326Sed if (TPR == TPResult::False() || TPR == TPResult::Error()) 1554193326Sed return TPR; 1555193326Sed 1556193326Sed // Parse through the parens. 1557193326Sed if (!SkipUntil(tok::r_paren)) 1558193326Sed return TPResult::Error(); 1559193326Sed 1560193326Sed // cv-qualifier-seq 1561193326Sed while (Tok.is(tok::kw_const) || 1562193326Sed Tok.is(tok::kw_volatile) || 1563193326Sed Tok.is(tok::kw_restrict) ) 1564193326Sed ConsumeToken(); 1565193326Sed 1566218893Sdim // ref-qualifier[opt] 1567218893Sdim if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) 1568218893Sdim ConsumeToken(); 1569218893Sdim 1570193326Sed // exception-specification 1571193326Sed if (Tok.is(tok::kw_throw)) { 1572193326Sed ConsumeToken(); 1573193326Sed if (Tok.isNot(tok::l_paren)) 1574193326Sed return TPResult::Error(); 1575193326Sed 1576193326Sed // Parse through the parens after 'throw'. 1577193326Sed ConsumeParen(); 1578193326Sed if (!SkipUntil(tok::r_paren)) 1579193326Sed return TPResult::Error(); 1580193326Sed } 1581221345Sdim if (Tok.is(tok::kw_noexcept)) { 1582221345Sdim ConsumeToken(); 1583221345Sdim // Possibly an expression as well. 1584221345Sdim if (Tok.is(tok::l_paren)) { 1585221345Sdim // Find the matching rparen. 1586221345Sdim ConsumeParen(); 1587221345Sdim if (!SkipUntil(tok::r_paren)) 1588221345Sdim return TPResult::Error(); 1589221345Sdim } 1590221345Sdim } 1591193326Sed 1592193326Sed return TPResult::Ambiguous(); 1593193326Sed} 1594193326Sed 1595193326Sed/// '[' constant-expression[opt] ']' 1596193326Sed/// 1597193326SedParser::TPResult Parser::TryParseBracketDeclarator() { 1598193326Sed ConsumeBracket(); 1599193326Sed if (!SkipUntil(tok::r_square)) 1600193326Sed return TPResult::Error(); 1601193326Sed 1602193326Sed return TPResult::Ambiguous(); 1603193326Sed} 1604