ParseTentative.cpp revision 47f5209a80c7c75592e87eb296d2b51e03208ae0
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"
165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis#include "clang/Basic/Diagnostic.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
325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x]   static_assert-declaration                          [TODO]
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 Kyrtzidis/// [C++0x] static_assert-declaration:                           [TODO]
505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x]   static_assert '(' constant-expression ',' string-literal ')' ';'
515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidisbool Parser::isCXXDeclarationStatement() {
535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  switch (Tok.getKind()) {
545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // asm-definition
555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_asm:
565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // namespace-alias-definition
575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_namespace:
585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // using-declaration
595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // using-directive
605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_using:
615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    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
273d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis/// isCXXTypeIdInParens - Assumes that a '(' was parsed and now we want to
274d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis/// know whether the parens contain an expression or a type-id.
275d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis/// Returns true for a type-id and false for an expression.
276d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered,
277d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it.
278d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis///
279d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis/// type-id:
28078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis///   type-specifier-seq abstract-declarator[opt]
28178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis///
28278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidisbool Parser::isCXXTypeIdInParens() {
283d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis
284d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // C++ 8.2p2:
285d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // The ambiguity arising from the similarity between a function-style cast and
286d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // a type-id can occur in different contexts. The ambiguity appears as a
287d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // choice between a function-style cast expression and a declaration of a
288d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // type. The resolution is that any construct that could possibly be a type-id
289d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // in its syntactic context shall be considered a type-id.
290d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis
29178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  TPResult TPR = isCXXDeclarationSpecifier();
29278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  if (TPR != TPResult::Ambiguous())
29378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis    return TPR != TPResult::False(); // Returns true for TPResult::True() or
29478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis                                     // TPResult::Error().
29578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
29678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  // FIXME: Add statistics about the number of ambiguous statements encountered
29778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  // and how they were resolved (number of declarations+number of expressions).
29878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
29978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
30078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  // We need tentative parsing...
30178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
30278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  TentativeParsingAction PA(*this);
30378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
30478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  // type-specifier-seq
30578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  if (Tok.is(tok::kw_typeof))
30678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis    TryParseTypeofSpecifier();
30778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  else
30878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis    ConsumeToken();
30978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  assert(Tok.is(tok::l_paren) && "Expected '('");
31078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
31178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  // declarator
31278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
31378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
31478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  // In case of an error, let the declaration parsing code handle it.
31578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  if (TPR == TPResult::Error())
31678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis    TPR = TPResult::True();
31778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
31878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  if (TPR == TPResult::Ambiguous()) {
31978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis    // We are supposed to be inside parens, so if after the abstract declarator
32078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis    // we encounter a ')' this is a type-id, otherwise it's an expression.
32178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis    if (Tok.is(tok::r_paren))
32278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis      TPR = TPResult::True();
32378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis    else
32478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis      TPR = TPResult::False();
32578c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  }
32678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
32778c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  PA.Revert();
32878c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
32978c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  assert(TPR == TPResult::True() || TPR == TPResult::False());
33078c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  return TPR == TPResult::True();
33178c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis}
33278c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis
3335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         declarator:
3345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           direct-declarator
3355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           ptr-operator declarator
3365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         direct-declarator:
3385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           declarator-id
3395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           direct-declarator '(' parameter-declaration-clause ')'
3405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///                 cv-qualifier-seq[opt] exception-specification[opt]
3415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           direct-declarator '[' constant-expression[opt] ']'
3425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '(' declarator ')'
3431ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis/// [GNU]     '(' attributes declarator ')'
3445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         abstract-declarator:
3465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           ptr-operator abstract-declarator[opt]
3475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           direct-abstract-declarator
3485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         direct-abstract-declarator:
3505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           direct-abstract-declarator[opt]
3515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
3525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///                 exception-specification[opt]
3535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
3545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '(' abstract-declarator ')'
3555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         ptr-operator:
3575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '*' cv-qualifier-seq[opt]
3585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '&'
3595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x]   '&&'                                                        [TODO]
3605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]   [TODO]
3615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         cv-qualifier-seq:
3635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           cv-qualifier cv-qualifier-seq[opt]
3645404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         cv-qualifier:
3665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'const'
3675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'volatile'
3685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         declarator-id:
3705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           id-expression
3715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         id-expression:
3735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           unqualified-id
3745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           qualified-id                                                [TODO]
3755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
3765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         unqualified-id:
3775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           identifier
3785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           operator-function-id                                        [TODO]
3795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           conversion-function-id                                      [TODO]
3805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '~' class-name                                              [TODO]
3815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           template-id                                                 [TODO]
3825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
38378c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios KyrtzidisParser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
38478c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis                                            bool mayHaveIdentifier) {
3855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // declarator:
3865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  //   direct-declarator
3875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  //   ptr-operator declarator
3885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
3895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  while (1) {
390a4f34eaab2c8b32582af339279d5dc9ba648174cChris Lattner    if (Tok.is(tok::star) || Tok.is(tok::amp) ||
391a4f34eaab2c8b32582af339279d5dc9ba648174cChris Lattner        (Tok.is(tok::caret) && getLang().Blocks)) {
3925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // ptr-operator
3935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      ConsumeToken();
3945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      while (Tok.is(tok::kw_const)    ||
3955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis             Tok.is(tok::kw_volatile) ||
3965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis             Tok.is(tok::kw_restrict)   )
3975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis        ConsumeToken();
3985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    } else {
3995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      break;
4005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    }
4015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  }
4025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
4035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // direct-declarator:
4045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // direct-abstract-declarator:
4055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
40678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis  if (Tok.is(tok::identifier) && mayHaveIdentifier) {
4075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // declarator-id
4085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    ConsumeToken();
4095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  } else if (Tok.is(tok::l_paren)) {
410d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis    ConsumeParen();
411d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis    if (mayBeAbstract &&
412d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis        (Tok.is(tok::r_paren) ||       // 'int()' is a function.
413d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis         Tok.is(tok::ellipsis) ||      // 'int(...)' is a function.
414d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis         isDeclarationSpecifier())) {   // 'int(int)' is a function.
4155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
4165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      //        exception-specification[opt]
417b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      TPResult TPR = TryParseFunctionDeclarator();
418b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      if (TPR != TPResult::Ambiguous())
4195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis        return TPR;
4205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    } else {
4215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // '(' declarator ')'
4221ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis      // '(' attributes declarator ')'
4235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // '(' abstract-declarator ')'
4241ee2c43bc0c281b60b29f1883e1e206cae28aed6Argyrios Kyrtzidis      if (Tok.is(tok::kw___attribute))
425b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis        return TPResult::True(); // attributes indicate declaration
42678c8d80f19cb0bccd4f3d590e71a230e727cfab5Argyrios Kyrtzidis      TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
427b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      if (TPR != TPResult::Ambiguous())
4285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis        return TPR;
4295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      if (Tok.isNot(tok::r_paren))
430b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis        return TPResult::False();
4315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      ConsumeParen();
4325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    }
4335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  } else if (!mayBeAbstract) {
434b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::False();
4355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  }
4365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
4375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  while (1) {
438b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    TPResult TPR(TPResult::Ambiguous());
4395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
4405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (Tok.is(tok::l_paren)) {
441d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis      // Check whether we have a function declarator or a possible ctor-style
442d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis      // initializer that follows the declarator. Note that ctor-style
443d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis      // initializers are not possible in contexts where abstract declarators
444d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis      // are allowed.
445e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidis      if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/))
446d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis        break;
447d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis
4485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // direct-declarator '(' parameter-declaration-clause ')'
4495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      //        cv-qualifier-seq[opt] exception-specification[opt]
450d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis      ConsumeParen();
4515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      TPR = TryParseFunctionDeclarator();
4525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    } else if (Tok.is(tok::l_square)) {
4535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // direct-declarator '[' constant-expression[opt] ']'
4545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
4555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      TPR = TryParseBracketDeclarator();
4565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    } else {
4575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      break;
4585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    }
4595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
460b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    if (TPR != TPResult::Ambiguous())
4615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      return TPR;
4625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  }
4635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
464b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  return TPResult::Ambiguous();
4655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis}
4665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
467b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
468b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
469b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// be either a decl-specifier or a function-style cast, and TPResult::Error()
470b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis/// if a parsing error was found and reported.
4715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
4725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         decl-specifier:
4735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           storage-class-specifier
4745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           type-specifier
4755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           function-specifier
4765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'friend'
4775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'typedef'
4785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU]     attributes declaration-specifiers[opt]
4795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
4805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         storage-class-specifier:
4815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'register'
4825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'static'
4835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'extern'
4845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'mutable'
4855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'auto'
4865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU]     '__thread'
4875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
4885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         function-specifier:
4895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'inline'
4905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'virtual'
4915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'explicit'
4925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
4935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         typedef-name:
4945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           identifier
4955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
4965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         type-specifier:
4975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           simple-type-specifier
4985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           class-specifier
4995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           enum-specifier
5005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           elaborated-type-specifier
5015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           typename-specifier                                    [TODO]
5025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           cv-qualifier
5035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         simple-type-specifier:
5055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '::'[opt] nested-name-specifier[opt] type-name        [TODO]
5065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           '::'[opt] nested-name-specifier 'template'
5075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///                 simple-template-id                              [TODO]
5085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'char'
5095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'wchar_t'
5105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'bool'
5115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'short'
5125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'int'
5135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'long'
5145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'signed'
5155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'unsigned'
5165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'float'
5175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'double'
5185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'void'
5195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU]     typeof-specifier
5205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU]     '_Complex'
5215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [C++0x]   'auto'                                                [TODO]
5225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         type-name:
5245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           class-name
5255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           enum-name
5265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           typedef-name
5275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         elaborated-type-specifier:
5295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           class-key '::'[opt] nested-name-specifier[opt] identifier
5305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
5315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///               simple-template-id
5325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'enum' '::'[opt] nested-name-specifier[opt] identifier
5335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         enum-name:
5355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           identifier
5365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         enum-specifier:
5385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'enum' identifier[opt] '{' enumerator-list[opt] '}'
5395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'enum' identifier[opt] '{' enumerator-list ',' '}'
5405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         class-specifier:
5425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           class-head '{' member-specification[opt] '}'
5435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         class-head:
5455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           class-key identifier[opt] base-clause[opt]
5465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           class-key nested-name-specifier identifier base-clause[opt]
5475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           class-key nested-name-specifier[opt] simple-template-id
5485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///               base-clause[opt]
5495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         class-key:
5515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'class'
5525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'struct'
5535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'union'
5545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
5555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         cv-qualifier:
5565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'const'
5575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///           'volatile'
5585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU]     restrict
5595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
560b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::isCXXDeclarationSpecifier() {
5615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  switch (Tok.getKind()) {
562e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner  case tok::identifier:   // foo::bar
563e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    // Annotate typenames and C++ scope specifiers.  If we get one, just
564e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    // recurse to handle whatever we get.
565e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    if (TryAnnotateTypeOrScopeToken())
566e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner      return isCXXDeclarationSpecifier();
567e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    // Otherwise, not a typename.
568e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    return TPResult::False();
569e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner
570e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner  case tok::coloncolon:   // ::foo::bar
571e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner      if (NextToken().is(tok::kw_new) ||    // ::new
572e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner          NextToken().is(tok::kw_delete))   // ::delete
573e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner        return TPResult::False();
574e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner
575e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    // Annotate typenames and C++ scope specifiers.  If we get one, just
576e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    // recurse to handle whatever we get.
577e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    if (TryAnnotateTypeOrScopeToken())
578e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner      return isCXXDeclarationSpecifier();
579e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    // Otherwise, not a typename.
580e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner    return TPResult::False();
581e584926b8602c26d442f34090dfd5293695f4af5Chris Lattner
5825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // decl-specifier:
5835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   storage-class-specifier
5845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   type-specifier
5855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   function-specifier
5865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   'friend'
5875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   'typedef'
5885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
5895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_friend:
5905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_typedef:
5915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // storage-class-specifier
5925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_register:
5935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_static:
5945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_extern:
5955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_mutable:
5965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_auto:
5975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw___thread:
5985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // function-specifier
5995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_inline:
6005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_virtual:
6015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_explicit:
6025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // type-specifier:
6045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   simple-type-specifier
6055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   class-specifier
6065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   enum-specifier
6075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   elaborated-type-specifier
6085404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   typename-specifier
6095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   cv-qualifier
6105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // class-specifier
6125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // elaborated-type-specifier
6135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_class:
6145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_struct:
6155404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_union:
6165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // enum-specifier
6175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_enum:
6185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // cv-qualifier
6195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_const:
6205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_volatile:
6215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // GNU
6235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_restrict:
6245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw__Complex:
6255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw___attribute:
626b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::True();
6277ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff
6287ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff    // Microsoft
62947f5209a80c7c75592e87eb296d2b51e03208ae0Steve Naroff  case tok::kw___declspec:
6307ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff  case tok::kw___cdecl:
6317ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff  case tok::kw___stdcall:
6327ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff  case tok::kw___fastcall:
6337ec5658f92fd5b65f682b6e942b95210426fc6e2Steve Naroff    return PP.getLangOptions().Microsoft ? TPResult::True() : TPResult::False();
6345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // The ambiguity resides in a simple-type-specifier/typename-specifier
6365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // followed by a '('. The '(' could either be the start of:
6375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //
6385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   direct-declarator:
6395404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //     '(' declarator ')'
6405404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //
6415404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //   direct-abstract-declarator:
6425404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //     '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
6435404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //              exception-specification[opt]
6445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //     '(' abstract-declarator ')'
6455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //
6465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // or part of a function-style cast expression:
6475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //
6485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //     simple-type-specifier '(' expression-list[opt] ')'
6495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    //
6505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6515404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // simple-type-specifier:
6525404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6535404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_char:
6545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_wchar_t:
6555404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_bool:
6565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_short:
6575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_int:
6585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_long:
6595404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_signed:
6605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_unsigned:
6615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_float:
6625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_double:
6635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_void:
664b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner  case tok::annot_typename:
6655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (NextToken().is(tok::l_paren))
666b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      return TPResult::Ambiguous();
6675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
668b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::True();
6695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // GNU typeof support.
6715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  case tok::kw_typeof: {
6725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (NextToken().isNot(tok::l_paren))
673b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      return TPResult::True();
6745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    TentativeParsingAction PA(*this);
6765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
677b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    TPResult TPR = TryParseTypeofSpecifier();
6785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    bool isFollowedByParen = Tok.is(tok::l_paren);
6795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    PA.Revert();
6815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
682b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    if (TPR == TPResult::Error())
683b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      return TPResult::Error();
6845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (isFollowedByParen)
686b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      return TPResult::Ambiguous();
6875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
688b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::True();
6895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  }
6905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  default:
692b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::False();
6935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  }
6945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis}
6955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
6965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// [GNU] typeof-specifier:
6975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         'typeof' '(' expressions ')'
6985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         'typeof' '(' type-name ')'
6995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
700b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseTypeofSpecifier() {
7015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
7025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  ConsumeToken();
7035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7045404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  assert(Tok.is(tok::l_paren) && "Expected '('");
7055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // Parse through the parens after 'typeof'.
7065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  ConsumeParen();
7075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  if (!SkipUntil(tok::r_paren))
708b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::Error();
7095404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
710b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  return TPResult::Ambiguous();
7115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis}
7125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
713b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseDeclarationSpecifier() {
714b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  TPResult TPR = isCXXDeclarationSpecifier();
715b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  if (TPR != TPResult::Ambiguous())
7165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    return TPR;
7175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  if (Tok.is(tok::kw_typeof))
7195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    TryParseTypeofSpecifier();
7205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  else
7215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    ConsumeToken();
7225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7235404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  assert(Tok.is(tok::l_paren) && "Expected '('!");
724b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  return TPResult::Ambiguous();
7255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis}
7265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
7285404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// a constructor-style initializer, when parsing declaration statements.
7295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// Returns true for function declarator and false for constructor-style
7305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// initializer.
7315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// If during the disambiguation process a parsing error is encountered,
7325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// the function returns true to let the declaration parsing code handle it.
7335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
7345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
7355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         exception-specification[opt]
7365404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
737e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidisbool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) {
738d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis
739d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // C++ 8.2p1:
740d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // The ambiguity arising from the similarity between a function-style cast and
741d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // a declaration mentioned in 6.8 can also occur in the context of a
742d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // declaration. In that context, the choice is between a function declaration
743d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // with a redundant set of parentheses around a parameter name and an object
744d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // declaration with a function-style cast as the initializer. Just as for the
745d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // ambiguities mentioned in 6.8, the resolution is to consider any construct
746d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis  // that could possibly be a declaration a declaration.
747d3dbbb68b1050da2f58d4bea6b23016f451968c9Argyrios Kyrtzidis
7485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  TentativeParsingAction PA(*this);
7495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  ConsumeParen();
751b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  TPResult TPR = TryParseParameterDeclarationClause();
752b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
753b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    TPR = TPResult::False();
7545404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
755259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis  SourceLocation TPLoc = Tok.getLocation();
7565404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  PA.Revert();
7575404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7585404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // In case of an error, let the declaration parsing code handle it.
759b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  if (TPR == TPResult::Error())
7605404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    return true;
7615404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
762259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis  if (TPR == TPResult::Ambiguous()) {
763259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis    // Function declarator has precedence over constructor-style initializer.
764259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis    // Emit a warning just in case the author intended a variable definition.
765e75d849d9141d8e47d05a91b7b5c04194854e47aArgyrios Kyrtzidis    if (warnIfAmbiguous)
766ef708fd4abccf4d21b1f82ab2ab62f6ae7cc1265Chris Lattner      Diag(Tok, diag::warn_parens_disambiguated_as_function_decl)
767ef708fd4abccf4d21b1f82ab2ab62f6ae7cc1265Chris Lattner        << SourceRange(Tok.getLocation(), TPLoc);
768b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return true;
769259b0d91f2ff90d8daf39221fe133bf1596c5ffbArgyrios Kyrtzidis  }
770b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis
771b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  return TPR == TPResult::True();
7725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis}
7735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-clause:
7755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   parameter-declaration-list[opt] '...'[opt]
7765404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   parameter-declaration-list ',' '...'
7775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
7785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration-list:
7795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   parameter-declaration
7805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   parameter-declaration-list ',' parameter-declaration
7815404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
7825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// parameter-declaration:
7835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   decl-specifier-seq declarator
7845404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   decl-specifier-seq declarator '=' assignment-expression
7855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   decl-specifier-seq abstract-declarator[opt]
7865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   decl-specifier-seq abstract-declarator[opt] '=' assignment-expression
7875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
788b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseParameterDeclarationClause() {
7895404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  if (Tok.is(tok::r_paren))
791b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::True();
7925404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
7935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  //   parameter-declaration-list[opt] '...'[opt]
7945404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  //   parameter-declaration-list ',' '...'
7955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  //
7965404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // parameter-declaration-list:
7975404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  //   parameter-declaration
7985404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  //   parameter-declaration-list ',' parameter-declaration
7995404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  //
8005404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  while (1) {
8015404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // '...'[opt]
8025404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (Tok.is(tok::ellipsis)) {
8035404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      ConsumeToken();
804b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      return TPResult::True(); // '...' is a sign of a function declarator.
8055404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    }
8065404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8075404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // decl-specifier-seq
808b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    TPResult TPR = TryParseDeclarationSpecifier();
809b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    if (TPR != TPResult::Ambiguous())
8105404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      return TPR;
8115404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8125404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // declarator
8135404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // abstract-declarator[opt]
8145404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    TPR = TryParseDeclarator(true/*mayBeAbstract*/);
815b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    if (TPR != TPResult::Ambiguous())
8165404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      return TPR;
8175404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8185404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (Tok.is(tok::equal)) {
8195404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // '=' assignment-expression
8205404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      // Parse through assignment-expression.
8215404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      tok::TokenKind StopToks[3] ={ tok::comma, tok::ellipsis, tok::r_paren };
8225404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      if (!SkipUntil(StopToks, 3, true/*StopAtSemi*/, true/*DontConsume*/))
823b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis        return TPResult::Error();
8245404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    }
8255404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8265404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (Tok.is(tok::ellipsis)) {
8275404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      ConsumeToken();
828b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      return TPResult::True(); // '...' is a sign of a function declarator.
8295404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    }
8305404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8315404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
8325404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis      break;
8335404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    ConsumeToken(); // the comma.
8345404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  }
8355404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
836b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  return TPResult::Ambiguous();
8375404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis}
8385404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
839d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
840d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// parsing as a function declarator.
841d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
842d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// return TPResult::Ambiguous(), otherwise it will return either False() or
843d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis/// Error().
8445404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
8455404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
8465404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///         exception-specification[opt]
8475404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
8485404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// exception-specification:
8495404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///   'throw' '(' type-id-list[opt] ')'
8505404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
851b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseFunctionDeclarator() {
852d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis
853d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis  // The '(' is already parsed.
854d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis
855d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis  TPResult TPR = TryParseParameterDeclarationClause();
856d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
857d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis    TPR = TPResult::False();
858d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis
859d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis  if (TPR == TPResult::False() || TPR == TPResult::Error())
860d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis    return TPR;
861d3616a8d0b1506966cb669c19dbfc91bf42c810aArgyrios Kyrtzidis
8625404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // Parse through the parens.
8635404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  if (!SkipUntil(tok::r_paren))
864b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::Error();
8655404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8665404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // cv-qualifier-seq
8675404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  while (Tok.is(tok::kw_const)    ||
8685404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis         Tok.is(tok::kw_volatile) ||
8695404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis         Tok.is(tok::kw_restrict)   )
8705404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    ConsumeToken();
8715404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8725404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  // exception-specification
8735404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  if (Tok.is(tok::kw_throw)) {
8745404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    ConsumeToken();
8755404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (Tok.isNot(tok::l_paren))
876b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      return TPResult::Error();
8775404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8785404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    // Parse through the parens after 'throw'.
8795404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    ConsumeParen();
8805404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis    if (!SkipUntil(tok::r_paren))
881b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis      return TPResult::Error();
8825404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  }
8835404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
884b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  return TPResult::Ambiguous();
8855404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis}
8865404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
8875404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis/// '[' constant-expression[opt] ']'
8885404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis///
889b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios KyrtzidisParser::TPResult Parser::TryParseBracketDeclarator() {
8905404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  ConsumeBracket();
8915404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis  if (!SkipUntil(tok::r_square))
892b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis    return TPResult::Error();
8935404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis
894b9f341916e484ff6ba2c2d28c8b2dd5fa12b0015Argyrios Kyrtzidis  return TPResult::Ambiguous();
8955404a156be26de1c63ca9916187f970848bb4dbbArgyrios Kyrtzidis}
896