ParseTentative.cpp revision 1eb4433ac451dc16f4133a88af2d002ac26c58ef
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" 175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidisusing namespace clang; 185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXDeclarationStatement - C++-specialized function that disambiguates 205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// between a declaration or an expression statement, when parsing function 215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// bodies. Returns true for declaration, false for expression. 225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declaration-statement: 245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// block-declaration 255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// block-declaration: 275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-declaration 285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// asm-definition 295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// namespace-alias-definition 305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// using-declaration 315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// using-directive 32511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration 335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// asm-definition: 355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'asm' '(' string-literal ')' ';' 365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// namespace-alias-definition: 385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'namespace' identifier = qualified-namespace-specifier ';' 395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// using-declaration: 415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'using' typename[opt] '::'[opt] nested-name-specifier 425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// unqualified-id ';' 435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'using' '::' unqualified-id ; 445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// using-directive: 465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'using' 'namespace' '::'[opt] nested-name-specifier[opt] 475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// namespace-name ';' 485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidisbool Parser::isCXXDeclarationStatement() { 505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis switch (Tok.getKind()) { 515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // asm-definition 525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_asm: 535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // namespace-alias-definition 545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_namespace: 555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // using-declaration 565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // using-directive 575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_using: 585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return true; 59511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson case tok::kw_static_assert: 60511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson // static_assert-declaration 61511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return true; 625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis default: 635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-declaration 645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return isCXXSimpleDeclaration(); 655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXSimpleDeclaration - C++-specialized function that disambiguates 695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// between a simple-declaration or an expression-statement. 705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// Returns false if the statement is disambiguated as expression. 735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-declaration: 755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq init-declarator-list[opt] ';' 765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidisbool Parser::isCXXSimpleDeclaration() { 785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // C++ 6.8p1: 795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // There is an ambiguity in the grammar involving expression-statements and 805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarations: An expression-statement with a function-style explicit type 815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // conversion (5.2.3) as its leftmost subexpression can be indistinguishable 825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // from a declaration where the first declarator starts with a '('. In those 835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cases the statement is a declaration. [Note: To disambiguate, the whole 845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // statement might have to be examined to determine if it is an 855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // expression-statement or a declaration]. 865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // C++ 6.8p3: 885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // The disambiguation is purely syntactic; that is, the meaning of the names 895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // occurring in such a statement, beyond whether they are type-names or not, 905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // is not generally used in or changed by the disambiguation. Class 915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // templates are instantiated as necessary to determine if a qualified name 925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // is a type-name. Disambiguation precedes parsing, and a statement 935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // disambiguated as a declaration may be an ill-formed declaration. 945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We don't have to parse all of the decl-specifier-seq part. There's only 965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // an ambiguity if the first decl-specifier is 975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier/typename-specifier followed by a '(', which may 985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // indicate a function-style cast expression. 99b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such 100b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // a case. 1015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 102b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 103b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 104b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 105b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // TPResult::Error(). 1065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 1085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 1095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 1115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We need tentative parsing... 1125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 1145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseSimpleDeclaration(); 1165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis SourceLocation TentativeParseLoc = Tok.getLocation(); 1175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 1195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 121b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 1225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return true; 1235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Declarations take precedence over expressions. 125b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) 126b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 1275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 128b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 129b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 1305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 1315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-declaration: 1335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq init-declarator-list[opt] ';' 1345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 135b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseSimpleDeclaration() { 1365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // We know that we have a simple-type-specifier/typename-specifier followed 1375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // by a '('. 138b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous()); 1395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 1415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TryParseTypeofSpecifier(); 1425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis else 1435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 1445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 1465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 147b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseInitDeclaratorList(); 148b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 1495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 1505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::semi)) 152b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 1535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 154b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 1555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 1565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1571ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator-list: 1581ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator 1591ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator-list ',' init-declarator 1605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1611ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// init-declarator: 1621ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// declarator initializer[opt] 1631ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 1645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer: 1665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '=' initializer-clause 1675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' expression-list ')' 1685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 1695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer-clause: 1705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// assignment-expression 1715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '{' initializer-list ','[opt] '}' 1725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '{' '}' 1735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 174b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseInitDeclaratorList() { 1755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // GCC only examines the first declarator for disambiguation: 1765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // i.e: 1775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // int(x), ++x; // GCC regards it as ill-formed declaration. 1785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 1795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Comeau and MSVC will regard the above statement as correct expression. 1805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Clang examines all of the declarators and also regards the above statement 1815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // as correct expression. 1825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 1845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator 185b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 186b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 1875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 1885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 1891ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis // [GNU] simple-asm-expr[opt] attributes[opt] 1901ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 191b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 1921ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis 1935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // initializer[opt] 1945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::l_paren)) { 1955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens. 1965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 1975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 198b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 1995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (Tok.is(tok::equal)) { 2005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // MSVC won't examine the rest of declarators if '=' is encountered, it 2015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // will conclude that it is a declaration. 2025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Comeau and Clang will examine the rest of declarators. 2035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Note that "int(x) = {0}, ++x;" will be interpreted as ill-formed 2045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // expression. 2055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 2065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the initializer-clause. 2075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis SkipUntil(tok::comma, true/*StopAtSemi*/, true/*DontConsume*/); 2085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 2095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 2105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 2115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 2125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); // the comma. 2135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 2145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 215b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 2165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 2175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 218a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// isCXXConditionDeclaration - Disambiguates between a declaration or an 219a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// expression for a condition of a if/switch/while/for statement. 220a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 221a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 222a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// 223a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// condition: 224a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// expression 225a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 226a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 227a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// '=' assignment-expression 228a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis/// 229a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidisbool Parser::isCXXConditionDeclaration() { 230b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 231b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 232b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 233b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis // TPResult::Error(). 234a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 235a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 236a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 237a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 238a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 239a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // We need tentative parsing... 240a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 241a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TentativeParsingAction PA(*this); 242a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 243a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // type-specifier-seq 244a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 245a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TryParseTypeofSpecifier(); 246a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis else 247a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis ConsumeToken(); 248a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 249a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 250a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // declarator 251a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis TPR = TryParseDeclarator(false/*mayBeAbstract*/); 252a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 253a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 254b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 255b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 256a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 257b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 258a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // '=' 259a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis // [GNU] simple-asm-expr[opt] attributes[opt] 260a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (Tok.is(tok::equal) || 261a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 262b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::True(); 263a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis else 264b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::False(); 265a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis } 266a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 267ca35baa788ccba7a213365b9d64d6b2f7bdb9afeArgyrios Kyrtzidis PA.Revert(); 268ca35baa788ccba7a213365b9d64d6b2f7bdb9afeArgyrios Kyrtzidis 269b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 270b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 271a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis} 272a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis 2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// \brief Determine whether the next set of tokens contains a type-id. 2748b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 2758b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// The context parameter states what context we're parsing right 2768b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// now, which affects how this routine copes with the token 2778b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// following the type-id. If the context is TypeIdInParens, we have 2788b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// already parsed the '(' and we will cease lookahead when we hit 2798b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// the corresponding ')'. If the context is 2808b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 2818b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// before this template argument, and will cease lookahead when we 2828b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 2838b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// and false for an expression. If during the disambiguation 2848b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// process a parsing error is encountered, the function returns 2858b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// true to let the declaration parsing code handle it. 2868b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 2878b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// type-id: 2888b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// type-specifier-seq abstract-declarator[opt] 2898b642592a35167a3780074e78674e0bece87c40cDouglas Gregor /// 290f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidisbool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 292f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = false; 293d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 294d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // C++ 8.2p2: 295d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // The ambiguity arising from the similarity between a function-style cast and 296d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // a type-id can occur in different contexts. The ambiguity appears as a 297d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // choice between a function-style cast expression and a declaration of a 298d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // type. The resolution is that any construct that could possibly be a type-id 299d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // in its syntactic context shall be considered a type-id. 300d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 30178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 30278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 30378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis return TPR != TPResult::False(); // Returns true for TPResult::True() or 30478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // TPResult::Error(). 30578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 30678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // FIXME: Add statistics about the number of ambiguous statements encountered 30778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // and how they were resolved (number of declarations+number of expressions). 30878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 30978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 31078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // We need tentative parsing... 31178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 31278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TentativeParsingAction PA(*this); 31378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 31478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // type-specifier-seq 31578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 31678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TryParseTypeofSpecifier(); 31778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis else 31878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis ConsumeToken(); 31978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 32078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 32178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // declarator 32278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 32378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 32478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 32578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR == TPResult::Error()) 32678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::True(); 32778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 32878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 32978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // We are supposed to be inside parens, so if after the abstract declarator 33078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis // we encounter a ')' this is a type-id, otherwise it's an expression. 331f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 3328b642592a35167a3780074e78674e0bece87c40cDouglas Gregor TPR = TPResult::True(); 333f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = true; 334f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 3358b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // We are supposed to be inside a template argument, so if after 3368b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // the abstract declarator we encounter a '>', '>>' (in C++0x), or 3378b642592a35167a3780074e78674e0bece87c40cDouglas Gregor // ',', this is a type-id. Otherwise, it's an expression. 338f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } else if (Context == TypeIdAsTemplateArgument && 339f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis (Tok.is(tok::greater) || Tok.is(tok::comma) || 340f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) { 34178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::True(); 342f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis isAmbiguous = true; 343f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 344f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } else 34578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPR = TPResult::False(); 34678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis } 34778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 34878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis PA.Revert(); 34978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 35078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis assert(TPR == TPResult::True() || TPR == TPResult::False()); 35178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis return TPR == TPResult::True(); 35278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis} 35378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis 3545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator: 3555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator 3565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator declarator 3575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator: 3595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator-id 3605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator '(' parameter-declaration-clause ')' 3615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier-seq[opt] exception-specification[opt] 3625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-declarator '[' constant-expression[opt] ']' 3635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' declarator ')' 3641ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// [GNU] '(' attributes declarator ')' 3655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// abstract-declarator: 3675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator abstract-declarator[opt] 3685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator 3695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator: 3715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator[opt] 3725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 3735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 3745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 3755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' abstract-declarator ')' 3765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// ptr-operator: 3785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '*' cv-qualifier-seq[opt] 3795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '&' 3805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x] '&&' [TODO] 3818edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 3825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier-seq: 3845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier cv-qualifier-seq[opt] 3855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier: 3875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'const' 3885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'volatile' 3895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// declarator-id: 3915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// id-expression 3925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// id-expression: 3945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// unqualified-id 3955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// qualified-id [TODO] 3965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 3975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// unqualified-id: 3985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 3995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// operator-function-id [TODO] 4005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// conversion-function-id [TODO] 4015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '~' class-name [TODO] 4025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// template-id [TODO] 4035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 40478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios KyrtzidisParser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 40578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis bool mayHaveIdentifier) { 4065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator: 4075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator 4085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // ptr-operator declarator 4095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 4105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 4118edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 412495c35d291da48c4f5655bbb54d15128ddde0d4dDouglas Gregor TryAnnotateCXXScopeToken(true); 4138edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl 4149af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 4158edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 4165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // ptr-operator 4175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 4185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (Tok.is(tok::kw_const) || 4195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_volatile) || 4209af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner Tok.is(tok::kw_restrict)) 4215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 4225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 4235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 4245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 4255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 4265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 4275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator: 4285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator: 4295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 4301e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis if ((Tok.is(tok::identifier) || 4311e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) && 4321e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis mayHaveIdentifier) { 4335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator-id 4341e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) 4351e054213f8416a48866105216ad4a45f1e7c24deArgyrios Kyrtzidis ConsumeToken(); 4365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 4375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (Tok.is(tok::l_paren)) { 438d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis ConsumeParen(); 439d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (mayBeAbstract && 440d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis (Tok.is(tok::r_paren) || // 'int()' is a function. 441d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis Tok.is(tok::ellipsis) || // 'int(...)' is a function. 442d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis isDeclarationSpecifier())) { // 'int(int)' is a function. 4435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 4445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification[opt] 445b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseFunctionDeclarator(); 446b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 4475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 4485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 4495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' declarator ')' 4501ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis // '(' attributes declarator ')' 4515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' abstract-declarator ')' 4521ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 453b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // attributes indicate declaration 45478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 455b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 4565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 4575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) 458b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 4595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 4605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 4615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (!mayBeAbstract) { 462b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 4635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 4645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 4655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 466b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR(TPResult::Ambiguous()); 4675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 4685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::l_paren)) { 469d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // Check whether we have a function declarator or a possible ctor-style 470d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // initializer that follows the declarator. Note that ctor-style 471d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // initializers are not possible in contexts where abstract declarators 472d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // are allowed. 473e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidis if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/)) 474d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis break; 475d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 4765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator '(' parameter-declaration-clause ')' 4775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier-seq[opt] exception-specification[opt] 478d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis ConsumeParen(); 4795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseFunctionDeclarator(); 4805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else if (Tok.is(tok::l_square)) { 4815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator '[' constant-expression[opt] ']' 4825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 4835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseBracketDeclarator(); 4845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } else { 4855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 4865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 4875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 488b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 4895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 4905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 4915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 492b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 4935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 4945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 495b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 496b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 497b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// be either a decl-specifier or a function-style cast, and TPResult::Error() 498b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// if a parsing error was found and reported. 4995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier: 5015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// storage-class-specifier 5025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-specifier 5035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// function-specifier 5045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'friend' 5055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typedef' 5065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] attributes declaration-specifiers[opt] 5075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// storage-class-specifier: 5095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'register' 5105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'static' 5115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'extern' 5125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'mutable' 5135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'auto' 5145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] '__thread' 5155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// function-specifier: 5175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'inline' 5185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'virtual' 5195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'explicit' 5205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// typedef-name: 5225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 5235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-specifier: 5255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-type-specifier 5265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-specifier 5275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-specifier 5285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// elaborated-type-specifier 529d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// typename-specifier 5305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier 5315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-type-specifier: 533d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// '::'[opt] nested-name-specifier[opt] type-name 5345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' 5355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-template-id [TODO] 5365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'char' 5375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'wchar_t' 5385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'bool' 5395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'short' 5405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'int' 5415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'long' 5425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'signed' 5435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'unsigned' 5445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'float' 5455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'double' 5465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'void' 5475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] typeof-specifier 5485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] '_Complex' 5495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x] 'auto' [TODO] 5506fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// [C++0x] 'decltype' ( expression ) 5515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// type-name: 5535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-name 5545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-name 5555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// typedef-name 5565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// elaborated-type-specifier: 5585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key '::'[opt] nested-name-specifier[opt] identifier 5595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 5605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// simple-template-id 5615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' '::'[opt] nested-name-specifier[opt] identifier 5625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-name: 5645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// identifier 5655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// enum-specifier: 5675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 5685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'enum' identifier[opt] '{' enumerator-list ',' '}' 5695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-specifier: 5715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-head '{' member-specification[opt] '}' 5725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-head: 5745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key identifier[opt] base-clause[opt] 5755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key nested-name-specifier identifier base-clause[opt] 5765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key nested-name-specifier[opt] simple-template-id 5775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// base-clause[opt] 5785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// class-key: 5805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'class' 5815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'struct' 5825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'union' 5835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 5845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// cv-qualifier: 5855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'const' 5865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'volatile' 5875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] restrict 5885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 589b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::isCXXDeclarationSpecifier() { 5905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis switch (Tok.getKind()) { 591e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner case tok::identifier: // foo::bar 592d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor case tok::kw_typename: // typename T::type 593e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // Annotate typenames and C++ scope specifiers. If we get one, just 594e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // recurse to handle whatever we get. 595e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner if (TryAnnotateTypeOrScopeToken()) 596e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner return isCXXDeclarationSpecifier(); 597e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // Otherwise, not a typename. 598e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner return TPResult::False(); 599e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner 600e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner case tok::coloncolon: // ::foo::bar 601e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner if (NextToken().is(tok::kw_new) || // ::new 602e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner NextToken().is(tok::kw_delete)) // ::delete 603e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner return TPResult::False(); 6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 605e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // Annotate typenames and C++ scope specifiers. If we get one, just 606e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // recurse to handle whatever we get. 607e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner if (TryAnnotateTypeOrScopeToken()) 608e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner return isCXXDeclarationSpecifier(); 609e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner // Otherwise, not a typename. 610e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner return TPResult::False(); 6111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // decl-specifier: 6135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // storage-class-specifier 6145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // type-specifier 6155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // function-specifier 6165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 'friend' 6175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 'typedef' 6185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 6195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_friend: 6205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_typedef: 6215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // storage-class-specifier 6225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_register: 6235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_static: 6245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_extern: 6255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_mutable: 6265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_auto: 6275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw___thread: 6285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // function-specifier 6295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_inline: 6305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_virtual: 6315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_explicit: 6325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 6335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // type-specifier: 6345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier 6355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // class-specifier 6365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // enum-specifier 6375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // elaborated-type-specifier 6385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // typename-specifier 6395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier 6405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 6415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // class-specifier 6425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // elaborated-type-specifier 6435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_class: 6445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_struct: 6455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_union: 6465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // enum-specifier 6475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_enum: 6485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier 6495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_const: 6505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_volatile: 6515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 6525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // GNU 6535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_restrict: 6545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw__Complex: 6555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw___attribute: 656b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 6571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6587ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff // Microsoft 65947f5209a80c7c75592e87eb296d2b51e03208ae0Steve Naroff case tok::kw___declspec: 6607ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___cdecl: 6617ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___stdcall: 6627ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff case tok::kw___fastcall: 663290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___w64: 664290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___ptr64: 665290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman case tok::kw___forceinline: 666290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return TPResult::True(); 6675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 6685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // The ambiguity resides in a simple-type-specifier/typename-specifier 6695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // followed by a '('. The '(' could either be the start of: 6705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 6715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-declarator: 6725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' declarator ')' 6735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 6745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // direct-abstract-declarator: 6755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 6765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification[opt] 6775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '(' abstract-declarator ')' 6785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 6795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // or part of a function-style cast expression: 6805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 6815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier '(' expression-list[opt] ')' 6825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 6835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 6845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // simple-type-specifier: 6855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 6865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_char: 6875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_wchar_t: 688f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char16_t: 689f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char32_t: 6905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_bool: 6915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_short: 6925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_int: 6935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_long: 6945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_signed: 6955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_unsigned: 6965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_float: 6975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_double: 6985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_void: 699b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner case tok::annot_typename: 7005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (NextToken().is(tok::l_paren)) 701b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 7025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 703b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 7045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7056fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // GNU typeof support. 7065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis case tok::kw_typeof: { 7075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (NextToken().isNot(tok::l_paren)) 708b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 7095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 7115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 712b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseTypeofSpecifier(); 7135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis bool isFollowedByParen = Tok.is(tok::l_paren); 7145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 7165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 717b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 718b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 7195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (isFollowedByParen) 721b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 7225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 723b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 7245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 7255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7266fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // C++0x decltype support. 7276fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson case tok::kw_decltype: 7286fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson return TPResult::True(); 7296fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 7305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis default: 731b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::False(); 7325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 7335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 7345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] typeof-specifier: 7365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typeof' '(' expressions ')' 7375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'typeof' '(' type-name ')' 7385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 739b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseTypeofSpecifier() { 7405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 7415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 7425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('"); 7445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens after 'typeof'. 7455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 7465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 747b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 7485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 749b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 7505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 7515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 752b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseDeclarationSpecifier() { 753b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = isCXXDeclarationSpecifier(); 754b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 7555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 7565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_typeof)) 7585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TryParseTypeofSpecifier(); 7595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis else 7605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 7611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 763b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 7645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 7655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXFunctionDeclarator - Disambiguates between a function declarator or 7675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// a constructor-style initializer, when parsing declaration statements. 7685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// Returns true for function declarator and false for constructor-style 7695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer. 7705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered, 7715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it. 7725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 7735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 7745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 7755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 776e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidisbool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) { 777d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 778d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // C++ 8.2p1: 779d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // The ambiguity arising from the similarity between a function-style cast and 780d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // a declaration mentioned in 6.8 can also occur in the context of a 781d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // declaration. In that context, the choice is between a function declaration 782d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // with a redundant set of parentheses around a parameter name and an object 783d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // declaration with a function-style cast as the initializer. Just as for the 784d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // ambiguities mentioned in 6.8, the resolution is to consider any construct 785d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis // that could possibly be a declaration a declaration. 786d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis 7875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TentativeParsingAction PA(*this); 7885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 790b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseParameterDeclarationClause(); 791b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 792b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPR = TPResult::False(); 7935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 794259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis SourceLocation TPLoc = Tok.getLocation(); 7955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis PA.Revert(); 7965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 7975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // In case of an error, let the declaration parsing code handle it. 798b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR == TPResult::Error()) 7995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return true; 8005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 801259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis if (TPR == TPResult::Ambiguous()) { 802259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis // Function declarator has precedence over constructor-style initializer. 803259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis // Emit a warning just in case the author intended a variable definition. 804e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidis if (warnIfAmbiguous) 805ef708fd4abccf4d21b1f82ab2ab62f6ae7cc1265Chris Lattner Diag(Tok, diag::warn_parens_disambiguated_as_function_decl) 806ef708fd4abccf4d21b1f82ab2ab62f6ae7cc1265Chris Lattner << SourceRange(Tok.getLocation(), TPLoc); 807b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return true; 808259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis } 809b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis 810b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPR == TPResult::True(); 8115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 8125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-clause: 8145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list[opt] '...'[opt] 8155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list ',' '...' 8165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 8175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list: 8185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration 8195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list ',' parameter-declaration 8205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 8215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration: 8225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq declarator 8235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq declarator '=' assignment-expression 8245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq abstract-declarator[opt] 8255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// decl-specifier-seq abstract-declarator[opt] '=' assignment-expression 8265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 827b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseParameterDeclarationClause() { 8285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::r_paren)) 830b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); 8315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list[opt] '...'[opt] 8335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list ',' '...' 8345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 8355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list: 8365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration 8375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // parameter-declaration-list ',' parameter-declaration 8385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // 8395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (1) { 8405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '...'[opt] 8415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::ellipsis)) { 8425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 843b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // '...' is a sign of a function declarator. 8445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 8455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // decl-specifier-seq 847b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis TPResult TPR = TryParseDeclarationSpecifier(); 848b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 8495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 8505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // declarator 8525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // abstract-declarator[opt] 8535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis TPR = TryParseDeclarator(true/*mayBeAbstract*/); 854b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis if (TPR != TPResult::Ambiguous()) 8555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis return TPR; 8565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::equal)) { 8585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // '=' assignment-expression 8595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through assignment-expression. 8605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis tok::TokenKind StopToks[3] ={ tok::comma, tok::ellipsis, tok::r_paren }; 8615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(StopToks, 3, true/*StopAtSemi*/, true/*DontConsume*/)) 862b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 8635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 8645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::ellipsis)) { 8665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 867b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::True(); // '...' is a sign of a function declarator. 8685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 8695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 8705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 8715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis break; 8725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); // the comma. 8735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 8745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 875b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 8765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 8775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 878d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 879d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// parsing as a function declarator. 880d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// If TryParseFunctionDeclarator fully parsed the function declarator, it will 881d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// return TPResult::Ambiguous(), otherwise it will return either False() or 882d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// Error(). 8831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 8845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 8855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification[opt] 8865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 8875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification: 8885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 'throw' '(' type-id-list[opt] ')' 8895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 890b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseFunctionDeclarator() { 891d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 892d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis // The '(' is already parsed. 893d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 894d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis TPResult TPR = TryParseParameterDeclarationClause(); 895d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 896d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis TPR = TPResult::False(); 897d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 898d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis if (TPR == TPResult::False() || TPR == TPResult::Error()) 899d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis return TPR; 900d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis 9015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens. 9025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 903b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 9045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // cv-qualifier-seq 9065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis while (Tok.is(tok::kw_const) || 9075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_volatile) || 9085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis Tok.is(tok::kw_restrict) ) 9095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 9105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // exception-specification 9125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.is(tok::kw_throw)) { 9135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeToken(); 9145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (Tok.isNot(tok::l_paren)) 915b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 9165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis // Parse through the parens after 'throw'. 9185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeParen(); 9195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_paren)) 920b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 9215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis } 9225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 923b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 9245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 9255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 9265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '[' constant-expression[opt] ']' 9275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// 928b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseBracketDeclarator() { 9295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis ConsumeBracket(); 9305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis if (!SkipUntil(tok::r_square)) 931b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Error(); 9325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis 933b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis return TPResult::Ambiguous(); 9345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis} 935