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