ParseTentative.cpp revision 3840281126e7d10552c55f6fd8b1ec9483898906
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: 61c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne case tok::kw__Static_assert: 62511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return true; 635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-declaration 64bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt default: 655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return isCXXSimpleDeclaration(); 665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXSimpleDeclaration - C++-specialized function that disambiguates 705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// between a simple-declaration or an expression-statement. 715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// Returns false if the statement is disambiguated as expression. 745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-declaration: 765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq init-declarator-list[opt] ';' 775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidisbool Parser::isCXXSimpleDeclaration() { 795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // C++ 6.8p1: 805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // There is an ambiguity in the grammar involving expression-statements and 815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarations: An expression-statement with a function-style explicit type 825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // conversion (5.2.3) as its leftmost subexpression can be indistinguishable 835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // from a declaration where the first declarator starts with a '('. In those 845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cases the statement is a declaration. [Note: To disambiguate, the whole 855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // statement might have to be examined to determine if it is an 865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // expression-statement or a declaration]. 875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // C++ 6.8p3: 895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // The disambiguation is purely syntactic; that is, the meaning of the names 905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // occurring in such a statement, beyond whether they are type-names or not, 915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // is not generally used in or changed by the disambiguation. Class 925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // templates are instantiated as necessary to determine if a qualified name 935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // is a type-name. Disambiguation precedes parsing, and a statement 945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // disambiguated as a declaration may be an ill-formed declaration. 955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We don't have to parse all of the decl-specifier-seq part. There's only 975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // an ambiguity if the first decl-specifier is 985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier/typename-specifier followed by a '(', which may 995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // indicate a function-style cast expression. 100b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such 101b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // a case. 1025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 103b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 104b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 105b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 106b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // TPResult::Error(). 1075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 1095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 1105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 1125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We need tentative parsing... 1135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 1155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseSimpleDeclaration(); 1165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 1175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 119b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 1205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return true; 1215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Declarations take precedence over expressions. 123b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) 124b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 1255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 126b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 127b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 1285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 1295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-declaration: 1315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq init-declarator-list[opt] ';' 1325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 133b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseSimpleDeclaration() { 1345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We know that we have a simple-type-specifier/typename-specifier followed 1355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // by a '('. 136b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous()); 1375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 1395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TryParseTypeofSpecifier(); 1409bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor else { 1415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 1429bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 1439bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (getLang().ObjC1 && Tok.is(tok::less)) 1449bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor TryParseProtocolQualifiers(); 1459bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor } 1469bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 1475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 1485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 149b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseInitDeclaratorList(); 150b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 1515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 1525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::semi)) 154b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 1555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 156b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 1575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 1585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1591ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator-list: 1601ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator 1611ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator-list ',' init-declarator 1625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1631ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator: 1641ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// declarator initializer[opt] 1651ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 1665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer: 1685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '=' initializer-clause 1695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' expression-list ')' 1705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer-clause: 1725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// assignment-expression 1735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '{' initializer-list ','[opt] '}' 1745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '{' '}' 1755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 176b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseInitDeclaratorList() { 1775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 1785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator 179b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 180b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 1815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 1825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1831ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis // [GNU] simple-asm-expr[opt] attributes[opt] 1841ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 185b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 1861ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis 1875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // initializer[opt] 1885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::l_paren)) { 1895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens. 1905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 1915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 192b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 193f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { 19406b7080b04ba799379469c03471558e4222921ceDouglas Gregor // MSVC and g++ won't examine the rest of declarators if '=' is 19506b7080b04ba799379469c03471558e4222921ceDouglas Gregor // encountered; they just conclude that we have a declaration. 19606b7080b04ba799379469c03471558e4222921ceDouglas Gregor // EDG parses the initializer completely, which is the proper behavior 19706b7080b04ba799379469c03471558e4222921ceDouglas Gregor // for this case. 1985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 19906b7080b04ba799379469c03471558e4222921ceDouglas Gregor // At present, Clang follows MSVC and g++, since the parser does not have 20006b7080b04ba799379469c03471558e4222921ceDouglas Gregor // the ability to parse an expression fully without recording the 20106b7080b04ba799379469c03471558e4222921ceDouglas Gregor // results of that parse. 202f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // Also allow 'in' after on objective-c declaration as in: 203f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // for (int (^b)(void) in array). Ideally this should be done in the 204f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // context of parsing for-init-statement of a foreach statement only. But, 205f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // in any other context 'in' is invalid after a declaration and parser 206f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // issues the error regardless of outcome of this decision. 207f459beb2fa7c5441eae4b1f5311f6a2ea60f6b00Fariborz Jahanian // FIXME. Change if above assumption does not hold. 20806b7080b04ba799379469c03471558e4222921ceDouglas Gregor return TPResult::True(); 2095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 2105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 2115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 2125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 2135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); // the comma. 2145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 2155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 216b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 2175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 2185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 219a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// isCXXConditionDeclaration - Disambiguates between a declaration or an 220a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// expression for a condition of a if/switch/while/for statement. 221a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 222a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 223a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// 224a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// condition: 225a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// expression 226a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 227a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 228a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// '=' assignment-expression 229a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// 230a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidisbool Parser::isCXXConditionDeclaration() { 231b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 232b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 233b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 234b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // TPResult::Error(). 235a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 236a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 237a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 238a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 239a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 240a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // We need tentative parsing... 241a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 242a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TentativeParsingAction PA(*this); 243a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 244a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // type-specifier-seq 245a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 246a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TryParseTypeofSpecifier(); 2479bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor else { 248a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis ConsumeToken(); 2499bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 2509bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (getLang().ObjC1 && Tok.is(tok::less)) 2519bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor TryParseProtocolQualifiers(); 2529bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor } 253a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 254a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 255a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // declarator 256a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TPR = TryParseDeclarator(false/*mayBeAbstract*/); 257a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 258a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 259b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 260b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 261a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 262b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 263a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // '=' 264a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // [GNU] simple-asm-expr[opt] attributes[opt] 265a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (Tok.is(tok::equal) || 266a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 267b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 268a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis else 269b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::False(); 270a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis } 271a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 272ca35baa788ccba7a213365b9d64d6b2f7bdb9afeArgyrios Kyrtzidis PA.Revert(); 273ca35baa788ccba7a213365b9d64d6b2f7bdb9afeArgyrios Kyrtzidis 274b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 275b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 276a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis} 277a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// \brief Determine whether the next set of tokens contains a type-id. 2798b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 2808b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// The context parameter states what context we're parsing right 2818b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// now, which affects how this routine copes with the token 2828b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// following the type-id. If the context is TypeIdInParens, we have 2838b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// already parsed the '(' and we will cease lookahead when we hit 2848b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// the corresponding ')'. If the context is 2858b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 2868b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// before this template argument, and will cease lookahead when we 2878b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 2888b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// and false for an expression. If during the disambiguation 2898b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// process a parsing error is encountered, the function returns 2908b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// true to let the declaration parsing code handle it. 2918b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 2928b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// type-id: 2938b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// type-specifier-seq abstract-declarator[opt] 2948b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 295f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidisbool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 297f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = false; 298d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 299d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // C++ 8.2p2: 300d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // The ambiguity arising from the similarity between a function-style cast and 301d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // a type-id can occur in different contexts. The ambiguity appears as a 302d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // choice between a function-style cast expression and a declaration of a 303d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // type. The resolution is that any construct that could possibly be a type-id 304d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // in its syntactic context shall be considered a type-id. 305d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 30678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 30778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 30878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 30978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // TPResult::Error(). 31078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 31178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 31278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 31378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 31478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 31578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // We need tentative parsing... 31678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 31778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TentativeParsingAction PA(*this); 31878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 31978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // type-specifier-seq 32078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 32178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TryParseTypeofSpecifier(); 3229bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor else { 32378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis ConsumeToken(); 3249bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 3259bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (getLang().ObjC1 && Tok.is(tok::less)) 3269bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor TryParseProtocolQualifiers(); 3279bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor } 3289bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 32978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 33078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 33178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // declarator 33278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 33378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 33478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 33578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR == TPResult::Error()) 33678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::True(); 33778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 33878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 33978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // We are supposed to be inside parens, so if after the abstract declarator 34078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // we encounter a ')' this is a type-id, otherwise it's an expression. 341f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 3428b642592a35167a3780074e78674e0bece87c40cDouglas Gregor TPR = TPResult::True(); 343f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = true; 344f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 3458b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // We are supposed to be inside a template argument, so if after 3468b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // the abstract declarator we encounter a '>', '>>' (in C++0x), or 3478b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // ',', this is a type-id. Otherwise, it's an expression. 348f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } else if (Context == TypeIdAsTemplateArgument && 349f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis (Tok.is(tok::greater) || Tok.is(tok::comma) || 350f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) { 35178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::True(); 352f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = true; 353f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 354f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } else 35578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::False(); 35678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis } 35778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 35878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis PA.Revert(); 35978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 36078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 36178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis return TPR == TPResult::True(); 36278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis} 36378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 364bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// isCXX0XAttributeSpecifier - returns true if this is a C++0x 365bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-specifier. By default, unless in Obj-C++, only a cursory check is 366bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// performed that will simply return true if a [[ is seen. Currently C++ has no 367bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// syntactical ambiguities from this check, but it may inhibit error recovery. 368bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// If CheckClosing is true, a check is made for closing ]] brackets. 369bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 370bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// If given, After is set to the token after the attribute-specifier so that 371bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// appropriate parsing decisions can be made; it is left untouched if false is 372bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// returned. 373bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 374bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// FIXME: If an error is in the closing ]] brackets, the program assumes 375bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the absence of an attribute-specifier, which can cause very yucky errors 376bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// to occur. 377bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 378bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-specifier: 379bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' '[' attribute-list ']' ']' 380bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 381bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-list: 382bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute[opt] 383bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-list ',' attribute[opt] 384bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 385bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute: 386bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-token attribute-argument-clause[opt] 387bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 388bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-token: 389bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 390bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-scoped-token 391bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 392bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-scoped-token: 393bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-namespace '::' identifier 394bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 395bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-namespace: 396bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 397bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 398bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-argument-clause: 399bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 400bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 401bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token-seq: 402bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token 403bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token-seq balanced-token 404bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 405bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token: 406bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 407bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' balanced-token-seq ']' 408bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '{' balanced-token-seq '}' 409bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// any token but '(', ')', '[', ']', '{', or '}' 410bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntbool Parser::isCXX0XAttributeSpecifier (bool CheckClosing, 411bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt tok::TokenKind *After) { 412bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) 413bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return false; 414bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 415bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // No tentative parsing if we don't need to look for ]] 416bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!CheckClosing && !getLang().ObjC1) 417bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return true; 418bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt struct TentativeReverter { 420bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt TentativeParsingAction PA; 421bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 422bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt TentativeReverter (Parser& P) 423bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt : PA(P) 424bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt {} 425bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ~TentativeReverter () { 426bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt PA.Revert(); 427bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 428bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } R(*this); 429bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 430bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // Opening brackets were checked for above. 431bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 432bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 433bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 434bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // SkipUntil will handle balanced tokens, which are guaranteed in attributes. 435bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 436bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 437bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.isNot(tok::r_square)) 438bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return false; 439bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 440bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 441bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (After) 442bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt *After = Tok.getKind(); 443bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 444bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return true; 445bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 446bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 4475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator: 4485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator 4495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator declarator 4505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator: 4525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator-id 4535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator '(' parameter-declaration-clause ')' 4545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier-seq[opt] exception-specification[opt] 4555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator '[' constant-expression[opt] ']' 4565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' declarator ')' 4571ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// [GNU] '(' attributes declarator ')' 4585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// abstract-declarator: 4605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator abstract-declarator[opt] 4615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator 462a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor/// ... 4635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator: 4655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator[opt] 4665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 4675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 4685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 4695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' abstract-declarator ')' 4705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator: 4725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '*' cv-qualifier-seq[opt] 4735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '&' 4745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x] '&&' [TODO] 4758edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 4765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier-seq: 4785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier cv-qualifier-seq[opt] 4795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier: 4815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'const' 4825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'volatile' 4835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator-id: 485a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor/// '...'[opt] id-expression 4865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// id-expression: 4885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// unqualified-id 4895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// qualified-id [TODO] 4905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 4915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// unqualified-id: 4925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 4935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// operator-function-id [TODO] 4945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// conversion-function-id [TODO] 4955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '~' class-name [TODO] 4965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// template-id [TODO] 4975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 49878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios KyrtzidisParser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 49978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis bool mayHaveIdentifier) { 5005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator: 5015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator 5025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // ptr-operator declarator 5035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 5045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 5058edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 5069ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (TryAnnotateCXXScopeToken(true)) 5079ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::Error(); 5088edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl 5099af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 51069d831645f429d3b806d2ae220aee45ca44f8c6cDouglas Gregor Tok.is(tok::ampamp) || 5118edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 5125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // ptr-operator 5135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 5145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (Tok.is(tok::kw_const) || 5155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_volatile) || 5169af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner Tok.is(tok::kw_restrict)) 5175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 5185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 5195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 5205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 5235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator: 5245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator: 525a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor if (Tok.is(tok::ellipsis)) 526a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor ConsumeToken(); 527a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor 5281e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis if ((Tok.is(tok::identifier) || 5291e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) && 5301e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis mayHaveIdentifier) { 5315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator-id 5321e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) 5331e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis ConsumeToken(); 5345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 5355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (Tok.is(tok::l_paren)) { 536d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis ConsumeParen(); 537d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (mayBeAbstract && 538d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis (Tok.is(tok::r_paren) || // 'int()' is a function. 539d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis Tok.is(tok::ellipsis) || // 'int(...)' is a function. 540d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis isDeclarationSpecifier())) { // 'int(int)' is a function. 5415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 5425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification[opt] 543b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseFunctionDeclarator(); 544b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 5455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 5465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 5475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' declarator ')' 5481ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis // '(' attributes declarator ')' 5495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' abstract-declarator ')' 5506229c8e7ecccbc6b661df0b4399eb205587c61b4Chris Lattner if (Tok.is(tok::kw___attribute) || 5516229c8e7ecccbc6b661df0b4399eb205587c61b4Chris Lattner Tok.is(tok::kw___declspec) || 5526229c8e7ecccbc6b661df0b4399eb205587c61b4Chris Lattner Tok.is(tok::kw___cdecl) || 5536229c8e7ecccbc6b661df0b4399eb205587c61b4Chris Lattner Tok.is(tok::kw___stdcall) || 5546229c8e7ecccbc6b661df0b4399eb205587c61b4Chris Lattner Tok.is(tok::kw___fastcall) || 5556229c8e7ecccbc6b661df0b4399eb205587c61b4Chris Lattner Tok.is(tok::kw___thiscall)) 556b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // attributes indicate declaration 55778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 558b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 5595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 5605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) 561b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 5625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 5635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (!mayBeAbstract) { 565b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 5665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 5685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 569b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR(TPResult::Ambiguous()); 5705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 571a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor // abstract-declarator: ... 572a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor if (Tok.is(tok::ellipsis)) 573a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor ConsumeToken(); 574a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor 5755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::l_paren)) { 576d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // Check whether we have a function declarator or a possible ctor-style 577d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // initializer that follows the declarator. Note that ctor-style 578d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // initializers are not possible in contexts where abstract declarators 579d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // are allowed. 580e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidis if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/)) 581d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis break; 582d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 5835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator '(' parameter-declaration-clause ')' 5845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier-seq[opt] exception-specification[opt] 585d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis ConsumeParen(); 5865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseFunctionDeclarator(); 5875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (Tok.is(tok::l_square)) { 5885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator '[' constant-expression[opt] ']' 5895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 5905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseBracketDeclarator(); 5915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 5925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 5935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 595b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 5965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 5975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 5985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 599b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 6005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 6015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 602a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas GregorParser::TPResult 603a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas GregorParser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { 604a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor switch (Kind) { 605a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor // Obviously starts an expression. 606a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::numeric_constant: 607a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::char_constant: 608a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::string_literal: 609a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::wide_string_literal: 610a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::l_square: 611a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::l_paren: 612a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::amp: 61369d831645f429d3b806d2ae220aee45ca44f8c6cDouglas Gregor case tok::ampamp: 614a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::star: 615a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::plus: 616a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::plusplus: 617a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::minus: 618a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::minusminus: 619a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::tilde: 620a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::exclaim: 621a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_sizeof: 622a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___func__: 623a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_const_cast: 624a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_delete: 625a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_dynamic_cast: 626a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_false: 627a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_new: 628a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_operator: 629a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_reinterpret_cast: 630a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_static_cast: 631a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_this: 632a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_throw: 633a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_true: 634a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_typeid: 635a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_alignof: 636a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_noexcept: 637a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_nullptr: 638a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___null: 639a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___alignof: 640a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___builtin_choose_expr: 641a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___builtin_offsetof: 642a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___builtin_types_compatible_p: 643a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___builtin_va_arg: 644a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___imag: 645a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___real: 646a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___FUNCTION__: 647a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___PRETTY_FUNCTION__: 648a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___has_nothrow_assign: 649a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___has_nothrow_copy: 650a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___has_nothrow_constructor: 651a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___has_trivial_assign: 652a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___has_trivial_copy: 653a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___has_trivial_constructor: 654a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___has_trivial_destructor: 655a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___has_virtual_destructor: 656a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___is_abstract: 657a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___is_base_of: 658a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___is_class: 6599f3611365d0f2297a910cf246e056708726ed10aDouglas Gregor case tok::kw___is_convertible_to: 660a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___is_empty: 661a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___is_enum: 6624e61ddd644e9c6293697a966d98d7c1905cf63a8Chandler Carruth case tok::kw___is_literal: 6633840281126e7d10552c55f6fd8b1ec9483898906Chandler Carruth case tok::kw___is_literal_type: 664a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___is_pod: 665a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___is_polymorphic: 666b7e9589bce9852b4db9575f55ac9137572147eb5Chandler Carruth case tok::kw___is_trivial: 667a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___is_union: 668a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___uuidof: 669a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor return TPResult::True(); 670a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor 671a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor // Obviously starts a type-specifier-seq: 672a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_char: 673a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_const: 674a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_double: 675a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_enum: 676a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_float: 677a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_int: 678a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_long: 679a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_restrict: 680a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_short: 681a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_signed: 682a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_struct: 683a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_union: 684a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_unsigned: 685a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_void: 686a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_volatile: 687a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw__Bool: 688a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw__Complex: 689a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_class: 690a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_typename: 691a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_wchar_t: 692a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_char16_t: 693a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_char32_t: 694a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_decltype: 695a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_thread_local: 696a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw__Decimal32: 697a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw__Decimal64: 698a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw__Decimal128: 699a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___thread: 700a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw_typeof: 701a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___cdecl: 702a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___stdcall: 703a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___fastcall: 704a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___thiscall: 705a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___vector: 706a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor case tok::kw___pixel: 707a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor return TPResult::False(); 708a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor 709a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor default: 710a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor break; 711a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor } 712a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor 713a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor return TPResult::Ambiguous(); 714a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor} 715a61b3e7443056f8d05b24ca4cbea90fe66235d6bDouglas Gregor 716b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 717b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 718b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// be either a decl-specifier or a function-style cast, and TPResult::Error() 719b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// if a parsing error was found and reported. 7205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier: 7225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// storage-class-specifier 7235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-specifier 7245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// function-specifier 7255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'friend' 7265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typedef' 7272ac67239b4ab81c439ffcc56367574c869f87daeSebastian Redl/// [C++0x] 'constexpr' 7285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] attributes declaration-specifiers[opt] 7295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// storage-class-specifier: 7315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'register' 7325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'static' 7335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'extern' 7345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'mutable' 7355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'auto' 7365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] '__thread' 7375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// function-specifier: 7395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'inline' 7405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'virtual' 7415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'explicit' 7425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// typedef-name: 7445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 7455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-specifier: 7475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-type-specifier 7485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-specifier 7495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-specifier 7505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// elaborated-type-specifier 751d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// typename-specifier 7525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier 7535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-type-specifier: 755d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// '::'[opt] nested-name-specifier[opt] type-name 7565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' 7575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-template-id [TODO] 7585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'char' 7595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'wchar_t' 7605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'bool' 7615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'short' 7625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'int' 7635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'long' 7645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'signed' 7655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'unsigned' 7665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'float' 7675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'double' 7685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'void' 7695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] typeof-specifier 7705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] '_Complex' 7715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x] 'auto' [TODO] 7726fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// [C++0x] 'decltype' ( expression ) 7735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-name: 7755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-name 7765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-name 7775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// typedef-name 7785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// elaborated-type-specifier: 7805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key '::'[opt] nested-name-specifier[opt] identifier 7815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 7825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-template-id 7835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' '::'[opt] nested-name-specifier[opt] identifier 7845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-name: 7865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 7875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-specifier: 7895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 7905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' identifier[opt] '{' enumerator-list ',' '}' 7915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-specifier: 7935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-head '{' member-specification[opt] '}' 7945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-head: 7965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key identifier[opt] base-clause[opt] 7975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key nested-name-specifier identifier base-clause[opt] 7985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key nested-name-specifier[opt] simple-template-id 7995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// base-clause[opt] 8005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 8015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key: 8025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'class' 8035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'struct' 8045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'union' 8055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 8065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier: 8075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'const' 8085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'volatile' 8095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] restrict 8105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 811b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::isCXXDeclarationSpecifier() { 8125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis switch (Tok.getKind()) { 813e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner case tok::identifier: // foo::bar 81482287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // Check for need to substitute AltiVec __vector keyword 81582287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // for "vector" identifier. 81682287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson if (TryAltiVecVectorToken()) 81782287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson return TPResult::True(); 81882287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // Fall through. 819d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor case tok::kw_typename: // typename T::type 820e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // Annotate typenames and C++ scope specifiers. If we get one, just 821e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // recurse to handle whatever we get. 822e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner if (TryAnnotateTypeOrScopeToken()) 8239ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::Error(); 8249ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (Tok.is(tok::identifier)) 8259ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::False(); 8269ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return isCXXDeclarationSpecifier(); 827e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner 8282ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner case tok::coloncolon: { // ::foo::bar 8292ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner const Token &Next = NextToken(); 8302ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner if (Next.is(tok::kw_new) || // ::new 8312ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner Next.is(tok::kw_delete)) // ::delete 832ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall return TPResult::False(); 8331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 834e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // Annotate typenames and C++ scope specifiers. If we get one, just 835e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // recurse to handle whatever we get. 836e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner if (TryAnnotateTypeOrScopeToken()) 8379ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::Error(); 8389ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return isCXXDeclarationSpecifier(); 8392ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner } 8402ee9b408a5cf3055fd974f01025b80fb3fd5f7e6Chris Lattner 8415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // decl-specifier: 8425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // storage-class-specifier 8435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // type-specifier 8445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // function-specifier 8455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 'friend' 8465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 'typedef' 8472ac67239b4ab81c439ffcc56367574c869f87daeSebastian Redl // 'constexpr' 8485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_friend: 8495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_typedef: 8502ac67239b4ab81c439ffcc56367574c869f87daeSebastian Redl case tok::kw_constexpr: 8515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // storage-class-specifier 8525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_register: 8535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_static: 8545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_extern: 8555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_mutable: 8565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_auto: 8575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw___thread: 8585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // function-specifier 8595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_inline: 8605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_virtual: 8615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_explicit: 8625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // type-specifier: 8645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier 8655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // class-specifier 8665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // enum-specifier 8675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // elaborated-type-specifier 8685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // typename-specifier 8695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier 8705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // class-specifier 8725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // elaborated-type-specifier 8735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_class: 8745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_struct: 8755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_union: 8765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // enum-specifier 8775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_enum: 8785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier 8795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_const: 8805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_volatile: 8815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // GNU 8835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_restrict: 8845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw__Complex: 8855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw___attribute: 886b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 8871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8887ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff // Microsoft 88947f5209a80c7c75592e87eb296d2b51e03208ae0Steve Naroff case tok::kw___declspec: 8907ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___cdecl: 8917ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___stdcall: 8927ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___fastcall: 893f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case tok::kw___thiscall: 894290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___w64: 895290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___ptr64: 896290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___forceinline: 897290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return TPResult::True(); 89852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik 89952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik // Borland 90052fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case tok::kw___pascal: 90152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return TPResult::True(); 90282287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson 90382287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // AltiVec 90482287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson case tok::kw___vector: 90582287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson return TPResult::True(); 9065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 90751e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall case tok::annot_template_id: { 90851e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall TemplateIdAnnotation *TemplateId 90951e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 91051e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall if (TemplateId->Kind != TNK_Type_template) 91151e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall return TPResult::False(); 91251e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall CXXScopeSpec SS; 913059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 91451e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall assert(Tok.is(tok::annot_typename)); 91551e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall goto case_typename; 91651e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall } 91751e2a5d45d321c53355fe038b3a3e7a2f502afa4John McCall 918ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed 919ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall // We've already annotated a scope; try to annotate a type. 9209ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (TryAnnotateTypeOrScopeToken()) 9219ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return TPResult::Error(); 9229ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (!Tok.is(tok::annot_typename)) 923ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall return TPResult::False(); 924ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall // If that succeeded, fallthrough into the generic simple-type-id case. 925ae03cb5a84d13c7a0d4b21865bd63aabd18120d2John McCall 9265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // The ambiguity resides in a simple-type-specifier/typename-specifier 9275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // followed by a '('. The '(' could either be the start of: 9285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 9295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator: 9305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' declarator ')' 9315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 9325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator: 9335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 9345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification[opt] 9355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' abstract-declarator ')' 9365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 9375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // or part of a function-style cast expression: 9385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 9395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier '(' expression-list[opt] ')' 9405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 9415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier: 9435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9449bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor case tok::annot_typename: 9459bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor case_typename: 9469bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // In Objective-C, we might have a protocol-qualified type. 9479bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (getLang().ObjC1 && NextToken().is(tok::less)) { 9489bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // Tentatively parse the 9499bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor TentativeParsingAction PA(*this); 9509bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ConsumeToken(); // The type token 9519bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 9529bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor TPResult TPR = TryParseProtocolQualifiers(); 9539bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor bool isFollowedByParen = Tok.is(tok::l_paren); 9549bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 9559bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor PA.Revert(); 9569bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 9579bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (TPR == TPResult::Error()) 9589bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor return TPResult::Error(); 9599bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 9609bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (isFollowedByParen) 9619bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor return TPResult::Ambiguous(); 9629bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 9639bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor return TPResult::True(); 9649bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor } 9659bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 9665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_char: 9675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_wchar_t: 968f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char16_t: 969f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char32_t: 9705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_bool: 9715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_short: 9725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_int: 9735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_long: 9745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_signed: 9755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_unsigned: 9765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_float: 9775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_double: 9785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_void: 9795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (NextToken().is(tok::l_paren)) 980b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 9815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9829497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor if (isStartOfObjCClassMessageMissingOpenBracket()) 9839497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor return TPResult::False(); 9849497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor 985b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 9865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9876fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // GNU typeof support. 9885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_typeof: { 9895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (NextToken().isNot(tok::l_paren)) 990b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 9915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 9935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 994b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseTypeofSpecifier(); 9955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis bool isFollowedByParen = Tok.is(tok::l_paren); 9965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 9985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 999b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 1000b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 10015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (isFollowedByParen) 1003b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 10045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1005b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 10065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 10075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10086fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // C++0x decltype support. 10096fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson case tok::kw_decltype: 10106fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson return TPResult::True(); 10116fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 10125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis default: 1013b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 10145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 10155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 10165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] typeof-specifier: 10185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typeof' '(' expressions ')' 10195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typeof' '(' type-name ')' 10205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1021b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseTypeofSpecifier() { 10225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 10235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 10245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 10265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens after 'typeof'. 10275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 10285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 1029b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 10305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1031b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 10325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 10335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10349bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor/// [ObjC] protocol-qualifiers: 10359bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor//// '<' identifier-list '>' 10369bd1d8d174a9d15ae343246c8322299248b9e92aDouglas GregorParser::TPResult Parser::TryParseProtocolQualifiers() { 10379bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor assert(Tok.is(tok::less) && "Expected '<' for qualifier list"); 10389bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ConsumeToken(); 10399bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor do { 10409bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (Tok.isNot(tok::identifier)) 10419bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor return TPResult::Error(); 10429bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ConsumeToken(); 10439bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 10449bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (Tok.is(tok::comma)) { 10459bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ConsumeToken(); 10469bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor continue; 10479bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor } 10489bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 10499bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (Tok.is(tok::greater)) { 10509bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ConsumeToken(); 10519bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor return TPResult::Ambiguous(); 10529bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor } 10539bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor } while (false); 10549bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 10559bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor return TPResult::Error(); 10569bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor} 10579bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 1058b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseDeclarationSpecifier() { 1059b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 1060b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 10615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 10625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 10645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TryParseTypeofSpecifier(); 10659bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor else { 10665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 10679bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 10689bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (getLang().ObjC1 && Tok.is(tok::less)) 10699bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor TryParseProtocolQualifiers(); 10709bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor } 10711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 1073b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 10745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 10755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXFunctionDeclarator - Disambiguates between a function declarator or 10775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// a constructor-style initializer, when parsing declaration statements. 10785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// Returns true for function declarator and false for constructor-style 10795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer. 10805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 10815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 10825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 10835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 10845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 10855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1086e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidisbool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) { 1087d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 1088d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // C++ 8.2p1: 1089d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // The ambiguity arising from the similarity between a function-style cast and 1090d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // a declaration mentioned in 6.8 can also occur in the context of a 1091d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // declaration. In that context, the choice is between a function declaration 1092d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // with a redundant set of parentheses around a parameter name and an object 1093d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // declaration with a function-style cast as the initializer. Just as for the 1094d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // ambiguities mentioned in 6.8, the resolution is to consider any construct 1095d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // that could possibly be a declaration a declaration. 1096d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 10975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 10985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 10995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 1100b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseParameterDeclarationClause(); 1101b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1102b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::False(); 11035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1104259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis SourceLocation TPLoc = Tok.getLocation(); 11055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 11065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 11075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 1108b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 11095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return true; 11105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1111259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 1112259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis // Function declarator has precedence over constructor-style initializer. 1113259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis // Emit a warning just in case the author intended a variable definition. 1114e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidis if (warnIfAmbiguous) 1115ef708fd4abccf4d21b1f82ab2ab62f6ae7cc1265Chris Lattner Diag(Tok, diag::warn_parens_disambiguated_as_function_decl) 1116ef708fd4abccf4d21b1f82ab2ab62f6ae7cc1265Chris Lattner << SourceRange(Tok.getLocation(), TPLoc); 1117b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return true; 1118259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis } 1119b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis 1120b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 11215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 11225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 11235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-clause: 11245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list[opt] '...'[opt] 11255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list ',' '...' 11265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 11275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list: 11285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration 11295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list ',' parameter-declaration 11305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 11315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration: 1132346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis/// decl-specifier-seq declarator attributes[opt] 1133346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis/// decl-specifier-seq declarator attributes[opt] '=' assignment-expression 1134346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis/// decl-specifier-seq abstract-declarator[opt] attributes[opt] 1135346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis/// decl-specifier-seq abstract-declarator[opt] attributes[opt] 1136346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis/// '=' assignment-expression 11375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1138b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseParameterDeclarationClause() { 11395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 11405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::r_paren)) 1141b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 11425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 11435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list[opt] '...'[opt] 11445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list ',' '...' 11455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 11465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list: 11475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration 11485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list ',' parameter-declaration 11495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 11505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 11515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '...'[opt] 11525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::ellipsis)) { 11535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 1154b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // '...' is a sign of a function declarator. 11555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 11565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 11570b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 11587f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 1159334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet 11605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // decl-specifier-seq 1161b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseDeclarationSpecifier(); 1162b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 11635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 11645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 11655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator 11665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // abstract-declarator[opt] 11675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseDeclarator(true/*mayBeAbstract*/); 1168b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 11695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 11705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1171346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis // [GNU] attributes[opt] 1172346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 1173346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis return TPResult::True(); 1174346af03b21db01264852afb8a86719c9284855feArgyrios Kyrtzidis 11755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::equal)) { 11765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '=' assignment-expression 11775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through assignment-expression. 1178a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor tok::TokenKind StopToks[2] ={ tok::comma, tok::r_paren }; 1179a8bc8c9e9ba5bffebde00340786fe8542469c435Douglas Gregor if (!SkipUntil(StopToks, 2, true/*StopAtSemi*/, true/*DontConsume*/)) 1180b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 11815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 11825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 11835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::ellipsis)) { 11845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 1185b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // '...' is a sign of a function declarator. 11865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 11875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 11885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 11895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 11905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); // the comma. 11915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 11925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1193b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 11945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 11955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1196d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 1197d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// parsing as a function declarator. 1198d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// If TryParseFunctionDeclarator fully parsed the function declarator, it will 1199d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// return TPResult::Ambiguous(), otherwise it will return either False() or 1200d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// Error(). 12011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 12025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 12035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 12045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 12055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification: 12065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'throw' '(' type-id-list[opt] ')' 12075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1208b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseFunctionDeclarator() { 1209d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 1210d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // The '(' is already parsed. 1211d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 1212d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis TPResult TPR = TryParseParameterDeclarationClause(); 1213d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 1214d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis TPR = TPResult::False(); 1215d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 1216d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (TPR == TPResult::False() || TPR == TPResult::Error()) 1217d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis return TPR; 1218d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 12195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens. 12205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 1221b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 12225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 12235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier-seq 12245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (Tok.is(tok::kw_const) || 12255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_volatile) || 12265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_restrict) ) 12275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 12285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1229e3c7a7ca66c02567543dbb5ec493818e00e8b177Douglas Gregor // ref-qualifier[opt] 1230e3c7a7ca66c02567543dbb5ec493818e00e8b177Douglas Gregor if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) 1231e3c7a7ca66c02567543dbb5ec493818e00e8b177Douglas Gregor ConsumeToken(); 1232e3c7a7ca66c02567543dbb5ec493818e00e8b177Douglas Gregor 12335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification 12345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_throw)) { 12355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 12365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::l_paren)) 1237b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 12385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 12395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens after 'throw'. 12405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 12415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 1242b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 12435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 124460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (Tok.is(tok::kw_noexcept)) { 124560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ConsumeToken(); 124660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Possibly an expression as well. 124760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (Tok.is(tok::l_paren)) { 124860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Find the matching rparen. 124960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ConsumeParen(); 125060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (!SkipUntil(tok::r_paren)) 125160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return TPResult::Error(); 125260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 125360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 12545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1255b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 12565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 12575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 12585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '[' constant-expression[opt] ']' 12595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1260b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseBracketDeclarator() { 12615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeBracket(); 12625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_square)) 1263b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 12645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1265b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 12665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 1267