ParseTentative.cpp revision f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00
15404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===// 25404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// 35404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// The LLVM Compiler Infrastructure 45404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// 55404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 65404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// License. See LICENSE.TXT for details. 75404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// 85404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 95404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// 105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// This file implements the tentative parsing portions of the Parser 115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// interfaces, for ambiguity resolution. 125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis// 135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis#include "clang/Parse/Parser.h" 16500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h" 1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h" 185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidisusing namespace clang; 195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXDeclarationStatement - C++-specialized function that disambiguates 215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// between a declaration or an expression statement, when parsing function 225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// bodies. Returns true for declaration, false for expression. 235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declaration-statement: 255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// block-declaration 265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// block-declaration: 285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-declaration 295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// asm-definition 305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// namespace-alias-definition 315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// using-declaration 325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// using-directive 33511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration 345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// asm-definition: 365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'asm' '(' string-literal ')' ';' 375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// namespace-alias-definition: 395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'namespace' identifier = qualified-namespace-specifier ';' 405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// using-declaration: 425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'using' typename[opt] '::'[opt] nested-name-specifier 435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// unqualified-id ';' 445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'using' '::' unqualified-id ; 455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// using-directive: 475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'using' 'namespace' '::'[opt] nested-name-specifier[opt] 485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// namespace-name ';' 495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidisbool Parser::isCXXDeclarationStatement() { 515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis switch (Tok.getKind()) { 525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // asm-definition 535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_asm: 545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // namespace-alias-definition 555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_namespace: 565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // using-declaration 575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // using-directive 585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_using: 59511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson // static_assert-declaration 60bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case tok::kw_static_assert: 61511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return true; 625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-declaration 63bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt default: 645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return isCXXSimpleDeclaration(); 655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXSimpleDeclaration - C++-specialized function that disambiguates 695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// between a simple-declaration or an expression-statement. 705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// Returns false if the statement is disambiguated as expression. 735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-declaration: 755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq init-declarator-list[opt] ';' 765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidisbool Parser::isCXXSimpleDeclaration() { 785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // C++ 6.8p1: 795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // There is an ambiguity in the grammar involving expression-statements and 805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarations: An expression-statement with a function-style explicit type 815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // conversion (5.2.3) as its leftmost subexpression can be indistinguishable 825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // from a declaration where the first declarator starts with a '('. In those 835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cases the statement is a declaration. [Note: To disambiguate, the whole 845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // statement might have to be examined to determine if it is an 855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // expression-statement or a declaration]. 865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // C++ 6.8p3: 885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // The disambiguation is purely syntactic; that is, the meaning of the names 895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // occurring in such a statement, beyond whether they are type-names or not, 905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // is not generally used in or changed by the disambiguation. Class 915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // templates are instantiated as necessary to determine if a qualified name 925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // is a type-name. Disambiguation precedes parsing, and a statement 935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // disambiguated as a declaration may be an ill-formed declaration. 945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We don't have to parse all of the decl-specifier-seq part. There's only 965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // an ambiguity if the first decl-specifier is 975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier/typename-specifier followed by a '(', which may 985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // indicate a function-style cast expression. 99b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such 100b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // a case. 1015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 102b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 103b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 104b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 105b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // TPResult::Error(). 1065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 1085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 1095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 1115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We need tentative parsing... 1125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 1145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseSimpleDeclaration(); 1165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis SourceLocation TentativeParseLoc = Tok.getLocation(); 1175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 1195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 121b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 1225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return true; 1235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Declarations take precedence over expressions. 125b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) 126b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 1275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 128b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 129b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 1305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 1315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-declaration: 1335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq init-declarator-list[opt] ';' 1345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 135b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseSimpleDeclaration() { 1365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We know that we have a simple-type-specifier/typename-specifier followed 1375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // by a '('. 138b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous()); 1395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 1415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TryParseTypeofSpecifier(); 1425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis else 1435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 1445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 1465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 147b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseInitDeclaratorList(); 148b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 1495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 1505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::semi)) 152b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 1535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 154b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 1555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 1565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1571ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator-list: 1581ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator 1591ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator-list ',' init-declarator 1605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1611ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator: 1621ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// declarator initializer[opt] 1631ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 1645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer: 1665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '=' initializer-clause 1675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' expression-list ')' 1685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer-clause: 1705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// assignment-expression 1715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '{' initializer-list ','[opt] '}' 1725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '{' '}' 1735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 174b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseInitDeclaratorList() { 1755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 1765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator 177b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 178b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 1795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 1805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1811ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis // [GNU] simple-asm-expr[opt] attributes[opt] 1821ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 183b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 1841ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis 1855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // initializer[opt] 1865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::l_paren)) { 1875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens. 1885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 1895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 190b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 191f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { 19206b7080b04ba799379469c03471558e4222921ceDouglas Gregor // MSVC and g++ won't examine the rest of declarators if '=' is 19306b7080b04ba799379469c03471558e4222921ceDouglas Gregor // encountered; they just conclude that we have a declaration. 19406b7080b04ba799379469c03471558e4222921ceDouglas Gregor // EDG parses the initializer completely, which is the proper behavior 19506b7080b04ba799379469c03471558e4222921ceDouglas Gregor // for this case. 1965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 19706b7080b04ba799379469c03471558e4222921ceDouglas Gregor // At present, Clang follows MSVC and g++, since the parser does not have 19806b7080b04ba799379469c03471558e4222921ceDouglas Gregor // the ability to parse an expression fully without recording the 19906b7080b04ba799379469c03471558e4222921ceDouglas Gregor // results of that parse. 200f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // Also allow 'in' after on objective-c declaration as in: 201f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // for (int (^b)(void) in array). Ideally this should be done in the 202f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // context of parsing for-init-statement of a foreach statement only. But, 203f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // in any other context 'in' is invalid after a declaration and parser 204f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // issues the error regardless of outcome of this decision. 205f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // FIXME. Change if above assumption does not hold. 20606b7080b04ba799379469c03471558e4222921ceDouglas Gregor return TPResult::True(); 2075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 2085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 2095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 2105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 2115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); // the comma. 2125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 2135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 214b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 2155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 2165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 217a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// isCXXConditionDeclaration - Disambiguates between a declaration or an 218a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// expression for a condition of a if/switch/while/for statement. 219a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 220a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 221a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// 222a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// condition: 223a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// expression 224a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 225a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 226a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// '=' assignment-expression 227a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// 228a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidisbool Parser::isCXXConditionDeclaration() { 229b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 230b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 231b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 232b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // TPResult::Error(). 233a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 234a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 235a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 236a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 237a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 238a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // We need tentative parsing... 239a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 240a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TentativeParsingAction PA(*this); 241a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 242a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // type-specifier-seq 243a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 244a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TryParseTypeofSpecifier(); 245a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis else 246a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis ConsumeToken(); 247a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 248a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 249a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // declarator 250a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TPR = TryParseDeclarator(false/*mayBeAbstract*/); 251a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 252a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 253b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 254b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 255a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 256b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 257a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // '=' 258a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // [GNU] simple-asm-expr[opt] attributes[opt] 259a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (Tok.is(tok::equal) || 260a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 261b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 262a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis else 263b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::False(); 264a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis } 265a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 266ca35baa788ccba7a213365b9d64d6b2f7bdb9afeArgyrios Kyrtzidis PA.Revert(); 267ca35baa788ccba7a213365b9d64d6b2f7bdb9afeArgyrios Kyrtzidis 268b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 269b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 270a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis} 271a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// \brief Determine whether the next set of tokens contains a type-id. 2738b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 2748b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// The context parameter states what context we're parsing right 2758b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// now, which affects how this routine copes with the token 2768b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// following the type-id. If the context is TypeIdInParens, we have 2778b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// already parsed the '(' and we will cease lookahead when we hit 2788b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// the corresponding ')'. If the context is 2798b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 2808b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// before this template argument, and will cease lookahead when we 2818b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 2828b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// and false for an expression. If during the disambiguation 2838b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// process a parsing error is encountered, the function returns 2848b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// true to let the declaration parsing code handle it. 2858b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 2868b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// type-id: 2878b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// type-specifier-seq abstract-declarator[opt] 2888b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 289f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidisbool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 291f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = false; 292d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 293d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // C++ 8.2p2: 294d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // The ambiguity arising from the similarity between a function-style cast and 295d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // a type-id can occur in different contexts. The ambiguity appears as a 296d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // choice between a function-style cast expression and a declaration of a 297d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // type. The resolution is that any construct that could possibly be a type-id 298d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // in its syntactic context shall be considered a type-id. 299d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 30078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 30178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 30278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 30378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // TPResult::Error(). 30478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 30578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 30678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 30778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 30878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 30978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // We need tentative parsing... 31078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 31178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TentativeParsingAction PA(*this); 31278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 31378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // type-specifier-seq 31478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 31578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TryParseTypeofSpecifier(); 31678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis else 31778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis ConsumeToken(); 31878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 31978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 32078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // declarator 32178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 32278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 32378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 32478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR == TPResult::Error()) 32578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::True(); 32678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 32778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 32878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // We are supposed to be inside parens, so if after the abstract declarator 32978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // we encounter a ')' this is a type-id, otherwise it's an expression. 330f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 3318b642592a35167a3780074e78674e0bece87c40cDouglas Gregor TPR = TPResult::True(); 332f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = true; 333f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 3348b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // We are supposed to be inside a template argument, so if after 3358b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // the abstract declarator we encounter a '>', '>>' (in C++0x), or 3368b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // ',', this is a type-id. Otherwise, it's an expression. 337f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } else if (Context == TypeIdAsTemplateArgument && 338f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis (Tok.is(tok::greater) || Tok.is(tok::comma) || 339f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) { 34078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::True(); 341f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = true; 342f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 343f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } else 34478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::False(); 34578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis } 34678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 34778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis PA.Revert(); 34878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 34978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 35078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis return TPR == TPResult::True(); 35178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis} 35278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 353bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// isCXX0XAttributeSpecifier - returns true if this is a C++0x 354bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-specifier. By default, unless in Obj-C++, only a cursory check is 355bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// performed that will simply return true if a [[ is seen. Currently C++ has no 356bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// syntactical ambiguities from this check, but it may inhibit error recovery. 357bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// If CheckClosing is true, a check is made for closing ]] brackets. 358bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 359bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// If given, After is set to the token after the attribute-specifier so that 360bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// appropriate parsing decisions can be made; it is left untouched if false is 361bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// returned. 362bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 363bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// FIXME: If an error is in the closing ]] brackets, the program assumes 364bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the absence of an attribute-specifier, which can cause very yucky errors 365bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// to occur. 366bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 367bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-specifier: 368bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' '[' attribute-list ']' ']' 369bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 370bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-list: 371bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute[opt] 372bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-list ',' attribute[opt] 373bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 374bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute: 375bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-token attribute-argument-clause[opt] 376bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 377bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-token: 378bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 379bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-scoped-token 380bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 381bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-scoped-token: 382bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-namespace '::' identifier 383bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 384bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-namespace: 385bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 386bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 387bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-argument-clause: 388bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 389bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 390bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token-seq: 391bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token 392bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token-seq balanced-token 393bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 394bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token: 395bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 396bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' balanced-token-seq ']' 397bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '{' balanced-token-seq '}' 398bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// any token but '(', ')', '[', ']', '{', or '}' 399bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntbool Parser::isCXX0XAttributeSpecifier (bool CheckClosing, 400bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt tok::TokenKind *After) { 401bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) 402bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return false; 403bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 404bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // No tentative parsing if we don't need to look for ]] 405bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!CheckClosing && !getLang().ObjC1) 406bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return true; 407bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 408bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt struct TentativeReverter { 409bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt TentativeParsingAction PA; 410bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 411bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt TentativeReverter (Parser& P) 412bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt : PA(P) 413bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt {} 414bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ~TentativeReverter () { 415bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt PA.Revert(); 416bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 417bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } R(*this); 418bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // Opening brackets were checked for above. 420bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 421bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 422bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 423bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // SkipUntil will handle balanced tokens, which are guaranteed in attributes. 424bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 425bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 426bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.isNot(tok::r_square)) 427bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return false; 428bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 429bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 430bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (After) 431bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt *After = Tok.getKind(); 432bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 433bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return true; 434bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 435bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 4365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator: 4375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator 4385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator declarator 4395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator: 4415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator-id 4425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator '(' parameter-declaration-clause ')' 4435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier-seq[opt] exception-specification[opt] 4445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator '[' constant-expression[opt] ']' 4455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' declarator ')' 4461ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// [GNU] '(' attributes declarator ')' 4475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// abstract-declarator: 4495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator abstract-declarator[opt] 4505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator 4515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator: 4535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator[opt] 4545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 4555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 4565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 4575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' abstract-declarator ')' 4585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator: 4605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '*' cv-qualifier-seq[opt] 4615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '&' 4625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x] '&&' [TODO] 4638edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 4645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier-seq: 4665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier cv-qualifier-seq[opt] 4675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier: 4695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'const' 4705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'volatile' 4715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator-id: 4735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// id-expression 4745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// id-expression: 4765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// unqualified-id 4775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// qualified-id [TODO] 4785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// unqualified-id: 4805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 4815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// operator-function-id [TODO] 4825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// conversion-function-id [TODO] 4835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '~' class-name [TODO] 4845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// template-id [TODO] 4855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 48678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios KyrtzidisParser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 48778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis bool mayHaveIdentifier) { 4885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator: 4895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator 4905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // ptr-operator declarator 4915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 4925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 4938edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 4949ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (TryAnnotateCXXScopeToken(true)) 4959ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::Error(); 4968edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl 4979af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 4988edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 4995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // ptr-operator 5005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 5015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (Tok.is(tok::kw_const) || 5025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_volatile) || 5039af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner Tok.is(tok::kw_restrict)) 5045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 5055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 5065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 5075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 5105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator: 5115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator: 5125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 5131e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis if ((Tok.is(tok::identifier) || 5141e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) && 5151e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis mayHaveIdentifier) { 5165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator-id 5171e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) 5181e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis ConsumeToken(); 5195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 5205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (Tok.is(tok::l_paren)) { 521d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis ConsumeParen(); 522d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (mayBeAbstract && 523d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis (Tok.is(tok::r_paren) || // 'int()' is a function. 524d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis Tok.is(tok::ellipsis) || // 'int(...)' is a function. 525d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis isDeclarationSpecifier())) { // 'int(int)' is a function. 5265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 5275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification[opt] 528b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseFunctionDeclarator(); 529b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 5305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 5315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 5325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' declarator ')' 5331ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis // '(' attributes declarator ')' 5345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' abstract-declarator ')' 5351ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 536b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // attributes indicate declaration 53778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 538b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 5395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 5405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) 541b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 5425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 5435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (!mayBeAbstract) { 545b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 5465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 5485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 549b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR(TPResult::Ambiguous()); 5505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 5515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::l_paren)) { 552d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // Check whether we have a function declarator or a possible ctor-style 553d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // initializer that follows the declarator. Note that ctor-style 554d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // initializers are not possible in contexts where abstract declarators 555d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // are allowed. 556e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidis if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/)) 557d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis break; 558d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 5595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator '(' parameter-declaration-clause ')' 5605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier-seq[opt] exception-specification[opt] 561d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis ConsumeParen(); 5625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseFunctionDeclarator(); 5635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (Tok.is(tok::l_square)) { 5645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator '[' constant-expression[opt] ']' 5655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 5665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseBracketDeclarator(); 5675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 5685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 5695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 571b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 5725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 5735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 575b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 5765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 5775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 578b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 579b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 580b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// be either a decl-specifier or a function-style cast, and TPResult::Error() 581b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// if a parsing error was found and reported. 5825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier: 5845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// storage-class-specifier 5855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-specifier 5865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// function-specifier 5875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'friend' 5885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typedef' 5892ac67239b4ab81c439ffcc56367574c869f87daeSebastian Redl/// [C++0x] 'constexpr' 5905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] attributes declaration-specifiers[opt] 5915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// storage-class-specifier: 5935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'register' 5945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'static' 5955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'extern' 5965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'mutable' 5975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'auto' 5985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] '__thread' 5995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// function-specifier: 6015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'inline' 6025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'virtual' 6035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'explicit' 6045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// typedef-name: 6065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 6075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-specifier: 6095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-type-specifier 6105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-specifier 6115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-specifier 6125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// elaborated-type-specifier 613d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// typename-specifier 6145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier 6155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-type-specifier: 617d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// '::'[opt] nested-name-specifier[opt] type-name 6185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' 6195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-template-id [TODO] 6205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'char' 6215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'wchar_t' 6225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'bool' 6235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'short' 6245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'int' 6255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'long' 6265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'signed' 6275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'unsigned' 6285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'float' 6295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'double' 6305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'void' 6315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] typeof-specifier 6325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] '_Complex' 6335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x] 'auto' [TODO] 6346fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// [C++0x] 'decltype' ( expression ) 6355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-name: 6375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-name 6385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-name 6395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// typedef-name 6405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// elaborated-type-specifier: 6425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key '::'[opt] nested-name-specifier[opt] identifier 6435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 6445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-template-id 6455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' '::'[opt] nested-name-specifier[opt] identifier 6465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-name: 6485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 6495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-specifier: 6515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 6525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' identifier[opt] '{' enumerator-list ',' '}' 6535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-specifier: 6555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-head '{' member-specification[opt] '}' 6565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-head: 6585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key identifier[opt] base-clause[opt] 6595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key nested-name-specifier identifier base-clause[opt] 6605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key nested-name-specifier[opt] simple-template-id 6615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// base-clause[opt] 6625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key: 6645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'class' 6655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'struct' 6665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'union' 6675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 6685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier: 6695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'const' 6705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'volatile' 6715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] restrict 6725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 673b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::isCXXDeclarationSpecifier() { 6745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis switch (Tok.getKind()) { 675e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner case tok::identifier: // foo::bar 67682287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // Check for need to substitute AltiVec __vector keyword 67782287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // for "vector" identifier. 67882287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson if (TryAltiVecVectorToken()) 67982287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson return TPResult::True(); 68082287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // Fall through. 681d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor case tok::kw_typename: // typename T::type 682e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // Annotate typenames and C++ scope specifiers. If we get one, just 683e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // recurse to handle whatever we get. 684e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner if (TryAnnotateTypeOrScopeToken()) 6859ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::Error(); 6869ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (Tok.is(tok::identifier)) 6879ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::False(); 6889ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return isCXXDeclarationSpecifier(); 689e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner 6902ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner case tok::coloncolon: { // ::foo::bar 6912ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner const Token &Next = NextToken(); 6922ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner if (Next.is(tok::kw_new) || // ::new 6932ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner Next.is(tok::kw_delete)) // ::delete 694ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall return TPResult::False(); 6951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 696e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // Annotate typenames and C++ scope specifiers. If we get one, just 697e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // recurse to handle whatever we get. 698e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner if (TryAnnotateTypeOrScopeToken()) 6999ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::Error(); 7009ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return isCXXDeclarationSpecifier(); 7012ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner } 7022ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner 7035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // decl-specifier: 7045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // storage-class-specifier 7055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // type-specifier 7065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // function-specifier 7075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 'friend' 7085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 'typedef' 7092ac67239b4ab81c439ffcc56367574c869f87daeSebastian Redl // 'constexpr' 7105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_friend: 7115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_typedef: 7122ac67239b4ab81c439ffcc56367574c869f87daeSebastian Redl case tok::kw_constexpr: 7135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // storage-class-specifier 7145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_register: 7155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_static: 7165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_extern: 7175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_mutable: 7185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_auto: 7195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw___thread: 7205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // function-specifier 7215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_inline: 7225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_virtual: 7235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_explicit: 7245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // type-specifier: 7265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier 7275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // class-specifier 7285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // enum-specifier 7295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // elaborated-type-specifier 7305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // typename-specifier 7315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier 7325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // class-specifier 7345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // elaborated-type-specifier 7355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_class: 7365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_struct: 7375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_union: 7385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // enum-specifier 7395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_enum: 7405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier 7415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_const: 7425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_volatile: 7435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // GNU 7455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_restrict: 7465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw__Complex: 7475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw___attribute: 748b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7507ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff // Microsoft 75147f5209a80c7c75592e87eb296d2b51e03208ae0Steve Naroff case tok::kw___declspec: 7527ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___cdecl: 7537ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___stdcall: 7547ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___fastcall: 755f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case tok::kw___thiscall: 756290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___w64: 757290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___ptr64: 758290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___forceinline: 759290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return TPResult::True(); 76082287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson 76182287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // AltiVec 76282287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson case tok::kw___vector: 76382287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson return TPResult::True(); 7645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 76551e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall case tok::annot_template_id: { 76651e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall TemplateIdAnnotation *TemplateId 76751e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 76851e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall if (TemplateId->Kind != TNK_Type_template) 76951e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall return TPResult::False(); 77051e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall CXXScopeSpec SS; 77151e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall AnnotateTemplateIdTokenAsType(&SS); 77251e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall assert(Tok.is(tok::annot_typename)); 77351e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall goto case_typename; 77451e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall } 77551e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall 776ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed 777ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall // We've already annotated a scope; try to annotate a type. 7789ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (TryAnnotateTypeOrScopeToken()) 7799ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::Error(); 7809ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (!Tok.is(tok::annot_typename)) 781ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall return TPResult::False(); 782ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall // If that succeeded, fallthrough into the generic simple-type-id case. 783ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall 7845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // The ambiguity resides in a simple-type-specifier/typename-specifier 7855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // followed by a '('. The '(' could either be the start of: 7865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 7875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator: 7885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' declarator ')' 7895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 7905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator: 7915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 7925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification[opt] 7935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' abstract-declarator ')' 7945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 7955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // or part of a function-style cast expression: 7965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 7975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier '(' expression-list[opt] ')' 7985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 7995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier: 8015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_char: 8035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_wchar_t: 804f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char16_t: 805f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char32_t: 8065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_bool: 8075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_short: 8085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_int: 8095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_long: 8105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_signed: 8115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_unsigned: 8125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_float: 8135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_double: 8145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_void: 815b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner case tok::annot_typename: 81651e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall case_typename: 8175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (NextToken().is(tok::l_paren)) 818b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 8195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 820b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 8215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8226fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // GNU typeof support. 8235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_typeof: { 8245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (NextToken().isNot(tok::l_paren)) 825b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 8265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 8285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 829b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseTypeofSpecifier(); 8305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis bool isFollowedByParen = Tok.is(tok::l_paren); 8315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 8335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 834b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 835b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 8365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (isFollowedByParen) 838b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 8395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 840b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 8415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 8425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8436fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // C++0x decltype support. 8446fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson case tok::kw_decltype: 8456fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson return TPResult::True(); 8466fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 8475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis default: 848b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 8495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 8505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 8515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] typeof-specifier: 8535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typeof' '(' expressions ')' 8545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typeof' '(' type-name ')' 8555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 856b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseTypeofSpecifier() { 8575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 8585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 8595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 8615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens after 'typeof'. 8625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 8635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 864b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 8655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 866b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 8675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 8685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 869b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseDeclarationSpecifier() { 870b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 871b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 8725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 8735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 8755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TryParseTypeofSpecifier(); 8765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis else 8775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 8781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 880b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 8815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 8825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXFunctionDeclarator - Disambiguates between a function declarator or 8845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// a constructor-style initializer, when parsing declaration statements. 8855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// Returns true for function declarator and false for constructor-style 8865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer. 8875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 8885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 8895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 8905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 8915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 8925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 893e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidisbool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) { 894d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 895d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // C++ 8.2p1: 896d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // The ambiguity arising from the similarity between a function-style cast and 897d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // a declaration mentioned in 6.8 can also occur in the context of a 898d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // declaration. In that context, the choice is between a function declaration 899d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // with a redundant set of parentheses around a parameter name and an object 900d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // declaration with a function-style cast as the initializer. Just as for the 901d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // ambiguities mentioned in 6.8, the resolution is to consider any construct 902d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // that could possibly be a declaration a declaration. 903d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 9045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 9055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 907b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseParameterDeclarationClause(); 908b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 909b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::False(); 9105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 911259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis SourceLocation TPLoc = Tok.getLocation(); 9125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 9135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 915b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 9165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return true; 9175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 918259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 919259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis // Function declarator has precedence over constructor-style initializer. 920259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis // Emit a warning just in case the author intended a variable definition. 921e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidis if (warnIfAmbiguous) 922ef708fd4abccf4d21b1f82ab2ab62f6ae7cc1265Chris Lattner Diag(Tok, diag::warn_parens_disambiguated_as_function_decl) 923ef708fd4abccf4d21b1f82ab2ab62f6ae7cc1265Chris Lattner << SourceRange(Tok.getLocation(), TPLoc); 924b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return true; 925259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis } 926b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis 927b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 9285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 9295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-clause: 9315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list[opt] '...'[opt] 9325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list ',' '...' 9335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 9345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list: 9355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration 9365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list ',' parameter-declaration 9375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 9385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration: 9395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq declarator 9405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq declarator '=' assignment-expression 9415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq abstract-declarator[opt] 9425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq abstract-declarator[opt] '=' assignment-expression 9435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 944b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseParameterDeclarationClause() { 9455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::r_paren)) 947b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 9485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list[opt] '...'[opt] 9505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list ',' '...' 9515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 9525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list: 9535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration 9545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list ',' parameter-declaration 9555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 9565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 9575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '...'[opt] 9585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::ellipsis)) { 9595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 960b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // '...' is a sign of a function declarator. 9615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 9625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // decl-specifier-seq 964b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseDeclarationSpecifier(); 965b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 9665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 9675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator 9695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // abstract-declarator[opt] 9705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseDeclarator(true/*mayBeAbstract*/); 971b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 9725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 9735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::equal)) { 9755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '=' assignment-expression 9765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through assignment-expression. 9775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis tok::TokenKind StopToks[3] ={ tok::comma, tok::ellipsis, tok::r_paren }; 9785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(StopToks, 3, true/*StopAtSemi*/, true/*DontConsume*/)) 979b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 9805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 9815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::ellipsis)) { 9835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 984b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // '...' is a sign of a function declarator. 9855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 9865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 9885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 9895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); // the comma. 9905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 9915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 992b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 9935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 9945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 995d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 996d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// parsing as a function declarator. 997d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// If TryParseFunctionDeclarator fully parsed the function declarator, it will 998d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// return TPResult::Ambiguous(), otherwise it will return either False() or 999d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// Error(). 10001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 10015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 10025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 10035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 10045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification: 10055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'throw' '(' type-id-list[opt] ')' 10065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1007b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseFunctionDeclarator() { 1008d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 1009d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // The '(' is already parsed. 1010d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 1011d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis TPResult TPR = TryParseParameterDeclarationClause(); 1012d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1013d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis TPR = TPResult::False(); 1014d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 1015d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (TPR == TPResult::False() || TPR == TPResult::Error()) 1016d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis return TPR; 1017d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 10185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens. 10195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 1020b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 10215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier-seq 10235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (Tok.is(tok::kw_const) || 10245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_volatile) || 10255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_restrict) ) 10265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 10275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification 10295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_throw)) { 10305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 10315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::l_paren)) 1032b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 10335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens after 'throw'. 10355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 10365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 1037b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 10385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 10395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1040b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 10415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 10425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '[' constant-expression[opt] ']' 10445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1045b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseBracketDeclarator() { 10465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeBracket(); 10475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_square)) 1048b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 10495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1050b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 10515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 1052