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