ParseTentative.cpp revision 194179
1193326Sed//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file implements the tentative parsing portions of the Parser
11193326Sed//  interfaces, for ambiguity resolution.
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#include "clang/Parse/Parser.h"
16193326Sed#include "clang/Parse/ParseDiagnostic.h"
17193326Sedusing namespace clang;
18193326Sed
19193326Sed/// isCXXDeclarationStatement - C++-specialized function that disambiguates
20193326Sed/// between a declaration or an expression statement, when parsing function
21193326Sed/// bodies. Returns true for declaration, false for expression.
22193326Sed///
23193326Sed///         declaration-statement:
24193326Sed///           block-declaration
25193326Sed///
26193326Sed///         block-declaration:
27193326Sed///           simple-declaration
28193326Sed///           asm-definition
29193326Sed///           namespace-alias-definition
30193326Sed///           using-declaration
31193326Sed///           using-directive
32193326Sed/// [C++0x]   static_assert-declaration
33193326Sed///
34193326Sed///         asm-definition:
35193326Sed///           'asm' '(' string-literal ')' ';'
36193326Sed///
37193326Sed///         namespace-alias-definition:
38193326Sed///           'namespace' identifier = qualified-namespace-specifier ';'
39193326Sed///
40193326Sed///         using-declaration:
41193326Sed///           'using' typename[opt] '::'[opt] nested-name-specifier
42193326Sed///                 unqualified-id ';'
43193326Sed///           'using' '::' unqualified-id ;
44193326Sed///
45193326Sed///         using-directive:
46193326Sed///           'using' 'namespace' '::'[opt] nested-name-specifier[opt]
47193326Sed///                 namespace-name ';'
48193326Sed///
49193326Sedbool Parser::isCXXDeclarationStatement() {
50193326Sed  switch (Tok.getKind()) {
51193326Sed    // asm-definition
52193326Sed  case tok::kw_asm:
53193326Sed    // namespace-alias-definition
54193326Sed  case tok::kw_namespace:
55193326Sed    // using-declaration
56193326Sed    // using-directive
57193326Sed  case tok::kw_using:
58193326Sed    return true;
59193326Sed  case tok::kw_static_assert:
60193326Sed    // static_assert-declaration
61193326Sed    return true;
62193326Sed  default:
63193326Sed    // simple-declaration
64193326Sed    return isCXXSimpleDeclaration();
65193326Sed  }
66193326Sed}
67193326Sed
68193326Sed/// isCXXSimpleDeclaration - C++-specialized function that disambiguates
69193326Sed/// between a simple-declaration or an expression-statement.
70193326Sed/// If during the disambiguation process a parsing error is encountered,
71193326Sed/// the function returns true to let the declaration parsing code handle it.
72193326Sed/// Returns false if the statement is disambiguated as expression.
73193326Sed///
74193326Sed/// simple-declaration:
75193326Sed///   decl-specifier-seq init-declarator-list[opt] ';'
76193326Sed///
77193326Sedbool Parser::isCXXSimpleDeclaration() {
78193326Sed  // C++ 6.8p1:
79193326Sed  // There is an ambiguity in the grammar involving expression-statements and
80193326Sed  // declarations: An expression-statement with a function-style explicit type
81193326Sed  // conversion (5.2.3) as its leftmost subexpression can be indistinguishable
82193326Sed  // from a declaration where the first declarator starts with a '('. In those
83193326Sed  // cases the statement is a declaration. [Note: To disambiguate, the whole
84193326Sed  // statement might have to be examined to determine if it is an
85193326Sed  // expression-statement or a declaration].
86193326Sed
87193326Sed  // C++ 6.8p3:
88193326Sed  // The disambiguation is purely syntactic; that is, the meaning of the names
89193326Sed  // occurring in such a statement, beyond whether they are type-names or not,
90193326Sed  // is not generally used in or changed by the disambiguation. Class
91193326Sed  // templates are instantiated as necessary to determine if a qualified name
92193326Sed  // is a type-name. Disambiguation precedes parsing, and a statement
93193326Sed  // disambiguated as a declaration may be an ill-formed declaration.
94193326Sed
95193326Sed  // We don't have to parse all of the decl-specifier-seq part. There's only
96193326Sed  // an ambiguity if the first decl-specifier is
97193326Sed  // simple-type-specifier/typename-specifier followed by a '(', which may
98193326Sed  // indicate a function-style cast expression.
99193326Sed  // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such
100193326Sed  // a case.
101193326Sed
102193326Sed  TPResult TPR = isCXXDeclarationSpecifier();
103193326Sed  if (TPR != TPResult::Ambiguous())
104193326Sed    return TPR != TPResult::False(); // Returns true for TPResult::True() or
105193326Sed                                     // TPResult::Error().
106193326Sed
107193326Sed  // FIXME: Add statistics about the number of ambiguous statements encountered
108193326Sed  // and how they were resolved (number of declarations+number of expressions).
109193326Sed
110193326Sed  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
111193326Sed  // We need tentative parsing...
112193326Sed
113193326Sed  TentativeParsingAction PA(*this);
114193326Sed
115193326Sed  TPR = TryParseSimpleDeclaration();
116193326Sed  SourceLocation TentativeParseLoc = Tok.getLocation();
117193326Sed
118193326Sed  PA.Revert();
119193326Sed
120193326Sed  // In case of an error, let the declaration parsing code handle it.
121193326Sed  if (TPR == TPResult::Error())
122193326Sed    return true;
123193326Sed
124193326Sed  // Declarations take precedence over expressions.
125193326Sed  if (TPR == TPResult::Ambiguous())
126193326Sed    TPR = TPResult::True();
127193326Sed
128193326Sed  assert(TPR == TPResult::True() || TPR == TPResult::False());
129193326Sed  return TPR == TPResult::True();
130193326Sed}
131193326Sed
132193326Sed/// simple-declaration:
133193326Sed///   decl-specifier-seq init-declarator-list[opt] ';'
134193326Sed///
135193326SedParser::TPResult Parser::TryParseSimpleDeclaration() {
136193326Sed  // We know that we have a simple-type-specifier/typename-specifier followed
137193326Sed  // by a '('.
138193326Sed  assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous());
139193326Sed
140193326Sed  if (Tok.is(tok::kw_typeof))
141193326Sed    TryParseTypeofSpecifier();
142193326Sed  else
143193326Sed    ConsumeToken();
144193326Sed
145193326Sed  assert(Tok.is(tok::l_paren) && "Expected '('");
146193326Sed
147193326Sed  TPResult TPR = TryParseInitDeclaratorList();
148193326Sed  if (TPR != TPResult::Ambiguous())
149193326Sed    return TPR;
150193326Sed
151193326Sed  if (Tok.isNot(tok::semi))
152193326Sed    return TPResult::False();
153193326Sed
154193326Sed  return TPResult::Ambiguous();
155193326Sed}
156193326Sed
157193326Sed///       init-declarator-list:
158193326Sed///         init-declarator
159193326Sed///         init-declarator-list ',' init-declarator
160193326Sed///
161193326Sed///       init-declarator:
162193326Sed///         declarator initializer[opt]
163193326Sed/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
164193326Sed///
165193326Sed/// initializer:
166193326Sed///   '=' initializer-clause
167193326Sed///   '(' expression-list ')'
168193326Sed///
169193326Sed/// initializer-clause:
170193326Sed///   assignment-expression
171193326Sed///   '{' initializer-list ','[opt] '}'
172193326Sed///   '{' '}'
173193326Sed///
174193326SedParser::TPResult Parser::TryParseInitDeclaratorList() {
175193326Sed  // GCC only examines the first declarator for disambiguation:
176193326Sed  // i.e:
177193326Sed  // int(x), ++x; // GCC regards it as ill-formed declaration.
178193326Sed  //
179193326Sed  // Comeau and MSVC will regard the above statement as correct expression.
180193326Sed  // Clang examines all of the declarators and also regards the above statement
181193326Sed  // as correct expression.
182193326Sed
183193326Sed  while (1) {
184193326Sed    // declarator
185193326Sed    TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
186193326Sed    if (TPR != TPResult::Ambiguous())
187193326Sed      return TPR;
188193326Sed
189193326Sed    // [GNU] simple-asm-expr[opt] attributes[opt]
190193326Sed    if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
191193326Sed      return TPResult::True();
192193326Sed
193193326Sed    // initializer[opt]
194193326Sed    if (Tok.is(tok::l_paren)) {
195193326Sed      // Parse through the parens.
196193326Sed      ConsumeParen();
197193326Sed      if (!SkipUntil(tok::r_paren))
198193326Sed        return TPResult::Error();
199193326Sed    } else if (Tok.is(tok::equal)) {
200193326Sed      // MSVC won't examine the rest of declarators if '=' is encountered, it
201193326Sed      // will conclude that it is a declaration.
202193326Sed      // Comeau and Clang will examine the rest of declarators.
203193326Sed      // Note that "int(x) = {0}, ++x;" will be interpreted as ill-formed
204193326Sed      // expression.
205193326Sed      //
206193326Sed      // Parse through the initializer-clause.
207193326Sed      SkipUntil(tok::comma, true/*StopAtSemi*/, true/*DontConsume*/);
208193326Sed    }
209193326Sed
210193326Sed    if (Tok.isNot(tok::comma))
211193326Sed      break;
212193326Sed    ConsumeToken(); // the comma.
213193326Sed  }
214193326Sed
215193326Sed  return TPResult::Ambiguous();
216193326Sed}
217193326Sed
218193326Sed/// isCXXConditionDeclaration - Disambiguates between a declaration or an
219193326Sed/// expression for a condition of a if/switch/while/for statement.
220193326Sed/// If during the disambiguation process a parsing error is encountered,
221193326Sed/// the function returns true to let the declaration parsing code handle it.
222193326Sed///
223193326Sed///       condition:
224193326Sed///         expression
225193326Sed///         type-specifier-seq declarator '=' assignment-expression
226193326Sed/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
227193326Sed///             '=' assignment-expression
228193326Sed///
229193326Sedbool Parser::isCXXConditionDeclaration() {
230193326Sed  TPResult TPR = isCXXDeclarationSpecifier();
231193326Sed  if (TPR != TPResult::Ambiguous())
232193326Sed    return TPR != TPResult::False(); // Returns true for TPResult::True() or
233193326Sed                                     // TPResult::Error().
234193326Sed
235193326Sed  // FIXME: Add statistics about the number of ambiguous statements encountered
236193326Sed  // and how they were resolved (number of declarations+number of expressions).
237193326Sed
238193326Sed  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
239193326Sed  // We need tentative parsing...
240193326Sed
241193326Sed  TentativeParsingAction PA(*this);
242193326Sed
243193326Sed  // type-specifier-seq
244193326Sed  if (Tok.is(tok::kw_typeof))
245193326Sed    TryParseTypeofSpecifier();
246193326Sed  else
247193326Sed    ConsumeToken();
248193326Sed  assert(Tok.is(tok::l_paren) && "Expected '('");
249193326Sed
250193326Sed  // declarator
251193326Sed  TPR = TryParseDeclarator(false/*mayBeAbstract*/);
252193326Sed
253193326Sed  // In case of an error, let the declaration parsing code handle it.
254193326Sed  if (TPR == TPResult::Error())
255193326Sed    TPR = TPResult::True();
256193326Sed
257193326Sed  if (TPR == TPResult::Ambiguous()) {
258193326Sed    // '='
259193326Sed    // [GNU] simple-asm-expr[opt] attributes[opt]
260193326Sed    if (Tok.is(tok::equal)  ||
261193326Sed        Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
262193326Sed      TPR = TPResult::True();
263193326Sed    else
264193326Sed      TPR = TPResult::False();
265193326Sed  }
266193326Sed
267193326Sed  PA.Revert();
268193326Sed
269193326Sed  assert(TPR == TPResult::True() || TPR == TPResult::False());
270193326Sed  return TPR == TPResult::True();
271193326Sed}
272193326Sed
273193326Sed  /// \brief Determine whether the next set of tokens contains a type-id.
274193326Sed  ///
275193326Sed  /// The context parameter states what context we're parsing right
276193326Sed  /// now, which affects how this routine copes with the token
277193326Sed  /// following the type-id. If the context is TypeIdInParens, we have
278193326Sed  /// already parsed the '(' and we will cease lookahead when we hit
279193326Sed  /// the corresponding ')'. If the context is
280193326Sed  /// TypeIdAsTemplateArgument, we've already parsed the '<' or ','
281193326Sed  /// before this template argument, and will cease lookahead when we
282193326Sed  /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id
283193326Sed  /// and false for an expression.  If during the disambiguation
284193326Sed  /// process a parsing error is encountered, the function returns
285193326Sed  /// true to let the declaration parsing code handle it.
286193326Sed  ///
287193326Sed  /// type-id:
288193326Sed  ///   type-specifier-seq abstract-declarator[opt]
289193326Sed  ///
290193326Sedbool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
291193326Sed
292193326Sed  isAmbiguous = false;
293193326Sed
294193326Sed  // C++ 8.2p2:
295193326Sed  // The ambiguity arising from the similarity between a function-style cast and
296193326Sed  // a type-id can occur in different contexts. The ambiguity appears as a
297193326Sed  // choice between a function-style cast expression and a declaration of a
298193326Sed  // type. The resolution is that any construct that could possibly be a type-id
299193326Sed  // in its syntactic context shall be considered a type-id.
300193326Sed
301193326Sed  TPResult TPR = isCXXDeclarationSpecifier();
302193326Sed  if (TPR != TPResult::Ambiguous())
303193326Sed    return TPR != TPResult::False(); // Returns true for TPResult::True() or
304193326Sed                                     // TPResult::Error().
305193326Sed
306193326Sed  // FIXME: Add statistics about the number of ambiguous statements encountered
307193326Sed  // and how they were resolved (number of declarations+number of expressions).
308193326Sed
309193326Sed  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
310193326Sed  // We need tentative parsing...
311193326Sed
312193326Sed  TentativeParsingAction PA(*this);
313193326Sed
314193326Sed  // type-specifier-seq
315193326Sed  if (Tok.is(tok::kw_typeof))
316193326Sed    TryParseTypeofSpecifier();
317193326Sed  else
318193326Sed    ConsumeToken();
319193326Sed  assert(Tok.is(tok::l_paren) && "Expected '('");
320193326Sed
321193326Sed  // declarator
322193326Sed  TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
323193326Sed
324193326Sed  // In case of an error, let the declaration parsing code handle it.
325193326Sed  if (TPR == TPResult::Error())
326193326Sed    TPR = TPResult::True();
327193326Sed
328193326Sed  if (TPR == TPResult::Ambiguous()) {
329193326Sed    // We are supposed to be inside parens, so if after the abstract declarator
330193326Sed    // we encounter a ')' this is a type-id, otherwise it's an expression.
331193326Sed    if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
332193326Sed      TPR = TPResult::True();
333193326Sed      isAmbiguous = true;
334193326Sed
335193326Sed    // We are supposed to be inside a template argument, so if after
336193326Sed    // the abstract declarator we encounter a '>', '>>' (in C++0x), or
337193326Sed    // ',', this is a type-id. Otherwise, it's an expression.
338193326Sed    } else if (Context == TypeIdAsTemplateArgument &&
339193326Sed               (Tok.is(tok::greater) || Tok.is(tok::comma) ||
340193326Sed                (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) {
341193326Sed      TPR = TPResult::True();
342193326Sed      isAmbiguous = true;
343193326Sed
344193326Sed    } else
345193326Sed      TPR = TPResult::False();
346193326Sed  }
347193326Sed
348193326Sed  PA.Revert();
349193326Sed
350193326Sed  assert(TPR == TPResult::True() || TPR == TPResult::False());
351193326Sed  return TPR == TPResult::True();
352193326Sed}
353193326Sed
354193326Sed///         declarator:
355193326Sed///           direct-declarator
356193326Sed///           ptr-operator declarator
357193326Sed///
358193326Sed///         direct-declarator:
359193326Sed///           declarator-id
360193326Sed///           direct-declarator '(' parameter-declaration-clause ')'
361193326Sed///                 cv-qualifier-seq[opt] exception-specification[opt]
362193326Sed///           direct-declarator '[' constant-expression[opt] ']'
363193326Sed///           '(' declarator ')'
364193326Sed/// [GNU]     '(' attributes declarator ')'
365193326Sed///
366193326Sed///         abstract-declarator:
367193326Sed///           ptr-operator abstract-declarator[opt]
368193326Sed///           direct-abstract-declarator
369193326Sed///
370193326Sed///         direct-abstract-declarator:
371193326Sed///           direct-abstract-declarator[opt]
372193326Sed///           '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
373193326Sed///                 exception-specification[opt]
374193326Sed///           direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
375193326Sed///           '(' abstract-declarator ')'
376193326Sed///
377193326Sed///         ptr-operator:
378193326Sed///           '*' cv-qualifier-seq[opt]
379193326Sed///           '&'
380193326Sed/// [C++0x]   '&&'                                                        [TODO]
381193326Sed///           '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
382193326Sed///
383193326Sed///         cv-qualifier-seq:
384193326Sed///           cv-qualifier cv-qualifier-seq[opt]
385193326Sed///
386193326Sed///         cv-qualifier:
387193326Sed///           'const'
388193326Sed///           'volatile'
389193326Sed///
390193326Sed///         declarator-id:
391193326Sed///           id-expression
392193326Sed///
393193326Sed///         id-expression:
394193326Sed///           unqualified-id
395193326Sed///           qualified-id                                                [TODO]
396193326Sed///
397193326Sed///         unqualified-id:
398193326Sed///           identifier
399193326Sed///           operator-function-id                                        [TODO]
400193326Sed///           conversion-function-id                                      [TODO]
401193326Sed///           '~' class-name                                              [TODO]
402193326Sed///           template-id                                                 [TODO]
403193326Sed///
404193326SedParser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
405193326Sed                                            bool mayHaveIdentifier) {
406193326Sed  // declarator:
407193326Sed  //   direct-declarator
408193326Sed  //   ptr-operator declarator
409193326Sed
410193326Sed  while (1) {
411193326Sed    if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))
412193326Sed      TryAnnotateCXXScopeToken();
413193326Sed
414193326Sed    if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
415193326Sed        (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
416193326Sed      // ptr-operator
417193326Sed      ConsumeToken();
418193326Sed      while (Tok.is(tok::kw_const)    ||
419193326Sed             Tok.is(tok::kw_volatile) ||
420193326Sed             Tok.is(tok::kw_restrict))
421193326Sed        ConsumeToken();
422193326Sed    } else {
423193326Sed      break;
424193326Sed    }
425193326Sed  }
426193326Sed
427193326Sed  // direct-declarator:
428193326Sed  // direct-abstract-declarator:
429193326Sed
430193326Sed  if (Tok.is(tok::identifier) && mayHaveIdentifier) {
431193326Sed    // declarator-id
432193326Sed    ConsumeToken();
433193326Sed  } else if (Tok.is(tok::l_paren)) {
434193326Sed    ConsumeParen();
435193326Sed    if (mayBeAbstract &&
436193326Sed        (Tok.is(tok::r_paren) ||       // 'int()' is a function.
437193326Sed         Tok.is(tok::ellipsis) ||      // 'int(...)' is a function.
438193326Sed         isDeclarationSpecifier())) {   // 'int(int)' is a function.
439193326Sed      // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
440193326Sed      //        exception-specification[opt]
441193326Sed      TPResult TPR = TryParseFunctionDeclarator();
442193326Sed      if (TPR != TPResult::Ambiguous())
443193326Sed        return TPR;
444193326Sed    } else {
445193326Sed      // '(' declarator ')'
446193326Sed      // '(' attributes declarator ')'
447193326Sed      // '(' abstract-declarator ')'
448193326Sed      if (Tok.is(tok::kw___attribute))
449193326Sed        return TPResult::True(); // attributes indicate declaration
450193326Sed      TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
451193326Sed      if (TPR != TPResult::Ambiguous())
452193326Sed        return TPR;
453193326Sed      if (Tok.isNot(tok::r_paren))
454193326Sed        return TPResult::False();
455193326Sed      ConsumeParen();
456193326Sed    }
457193326Sed  } else if (!mayBeAbstract) {
458193326Sed    return TPResult::False();
459193326Sed  }
460193326Sed
461193326Sed  while (1) {
462193326Sed    TPResult TPR(TPResult::Ambiguous());
463193326Sed
464193326Sed    if (Tok.is(tok::l_paren)) {
465193326Sed      // Check whether we have a function declarator or a possible ctor-style
466193326Sed      // initializer that follows the declarator. Note that ctor-style
467193326Sed      // initializers are not possible in contexts where abstract declarators
468193326Sed      // are allowed.
469193326Sed      if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/))
470193326Sed        break;
471193326Sed
472193326Sed      // direct-declarator '(' parameter-declaration-clause ')'
473193326Sed      //        cv-qualifier-seq[opt] exception-specification[opt]
474193326Sed      ConsumeParen();
475193326Sed      TPR = TryParseFunctionDeclarator();
476193326Sed    } else if (Tok.is(tok::l_square)) {
477193326Sed      // direct-declarator '[' constant-expression[opt] ']'
478193326Sed      // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
479193326Sed      TPR = TryParseBracketDeclarator();
480193326Sed    } else {
481193326Sed      break;
482193326Sed    }
483193326Sed
484193326Sed    if (TPR != TPResult::Ambiguous())
485193326Sed      return TPR;
486193326Sed  }
487193326Sed
488193326Sed  return TPResult::Ambiguous();
489193326Sed}
490193326Sed
491193326Sed/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
492193326Sed/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
493193326Sed/// be either a decl-specifier or a function-style cast, and TPResult::Error()
494193326Sed/// if a parsing error was found and reported.
495193326Sed///
496193326Sed///         decl-specifier:
497193326Sed///           storage-class-specifier
498193326Sed///           type-specifier
499193326Sed///           function-specifier
500193326Sed///           'friend'
501193326Sed///           'typedef'
502193326Sed/// [GNU]     attributes declaration-specifiers[opt]
503193326Sed///
504193326Sed///         storage-class-specifier:
505193326Sed///           'register'
506193326Sed///           'static'
507193326Sed///           'extern'
508193326Sed///           'mutable'
509193326Sed///           'auto'
510193326Sed/// [GNU]     '__thread'
511193326Sed///
512193326Sed///         function-specifier:
513193326Sed///           'inline'
514193326Sed///           'virtual'
515193326Sed///           'explicit'
516193326Sed///
517193326Sed///         typedef-name:
518193326Sed///           identifier
519193326Sed///
520193326Sed///         type-specifier:
521193326Sed///           simple-type-specifier
522193326Sed///           class-specifier
523193326Sed///           enum-specifier
524193326Sed///           elaborated-type-specifier
525193326Sed///           typename-specifier
526193326Sed///           cv-qualifier
527193326Sed///
528193326Sed///         simple-type-specifier:
529193326Sed///           '::'[opt] nested-name-specifier[opt] type-name
530193326Sed///           '::'[opt] nested-name-specifier 'template'
531193326Sed///                 simple-template-id                              [TODO]
532193326Sed///           'char'
533193326Sed///           'wchar_t'
534193326Sed///           'bool'
535193326Sed///           'short'
536193326Sed///           'int'
537193326Sed///           'long'
538193326Sed///           'signed'
539193326Sed///           'unsigned'
540193326Sed///           'float'
541193326Sed///           'double'
542193326Sed///           'void'
543193326Sed/// [GNU]     typeof-specifier
544193326Sed/// [GNU]     '_Complex'
545193326Sed/// [C++0x]   'auto'                                                [TODO]
546193326Sed///
547193326Sed///         type-name:
548193326Sed///           class-name
549193326Sed///           enum-name
550193326Sed///           typedef-name
551193326Sed///
552193326Sed///         elaborated-type-specifier:
553193326Sed///           class-key '::'[opt] nested-name-specifier[opt] identifier
554193326Sed///           class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
555193326Sed///               simple-template-id
556193326Sed///           'enum' '::'[opt] nested-name-specifier[opt] identifier
557193326Sed///
558193326Sed///         enum-name:
559193326Sed///           identifier
560193326Sed///
561193326Sed///         enum-specifier:
562193326Sed///           'enum' identifier[opt] '{' enumerator-list[opt] '}'
563193326Sed///           'enum' identifier[opt] '{' enumerator-list ',' '}'
564193326Sed///
565193326Sed///         class-specifier:
566193326Sed///           class-head '{' member-specification[opt] '}'
567193326Sed///
568193326Sed///         class-head:
569193326Sed///           class-key identifier[opt] base-clause[opt]
570193326Sed///           class-key nested-name-specifier identifier base-clause[opt]
571193326Sed///           class-key nested-name-specifier[opt] simple-template-id
572193326Sed///               base-clause[opt]
573193326Sed///
574193326Sed///         class-key:
575193326Sed///           'class'
576193326Sed///           'struct'
577193326Sed///           'union'
578193326Sed///
579193326Sed///         cv-qualifier:
580193326Sed///           'const'
581193326Sed///           'volatile'
582193326Sed/// [GNU]     restrict
583193326Sed///
584193326SedParser::TPResult Parser::isCXXDeclarationSpecifier() {
585193326Sed  switch (Tok.getKind()) {
586193326Sed  case tok::identifier:   // foo::bar
587193326Sed  case tok::kw_typename:  // typename T::type
588193326Sed    // Annotate typenames and C++ scope specifiers.  If we get one, just
589193326Sed    // recurse to handle whatever we get.
590193326Sed    if (TryAnnotateTypeOrScopeToken())
591193326Sed      return isCXXDeclarationSpecifier();
592193326Sed    // Otherwise, not a typename.
593193326Sed    return TPResult::False();
594193326Sed
595193326Sed  case tok::coloncolon:   // ::foo::bar
596193326Sed      if (NextToken().is(tok::kw_new) ||    // ::new
597193326Sed          NextToken().is(tok::kw_delete))   // ::delete
598193326Sed        return TPResult::False();
599193326Sed
600193326Sed    // Annotate typenames and C++ scope specifiers.  If we get one, just
601193326Sed    // recurse to handle whatever we get.
602193326Sed    if (TryAnnotateTypeOrScopeToken())
603193326Sed      return isCXXDeclarationSpecifier();
604193326Sed    // Otherwise, not a typename.
605193326Sed    return TPResult::False();
606193326Sed
607193326Sed    // decl-specifier:
608193326Sed    //   storage-class-specifier
609193326Sed    //   type-specifier
610193326Sed    //   function-specifier
611193326Sed    //   'friend'
612193326Sed    //   'typedef'
613193326Sed
614193326Sed  case tok::kw_friend:
615193326Sed  case tok::kw_typedef:
616193326Sed    // storage-class-specifier
617193326Sed  case tok::kw_register:
618193326Sed  case tok::kw_static:
619193326Sed  case tok::kw_extern:
620193326Sed  case tok::kw_mutable:
621193326Sed  case tok::kw_auto:
622193326Sed  case tok::kw___thread:
623193326Sed    // function-specifier
624193326Sed  case tok::kw_inline:
625193326Sed  case tok::kw_virtual:
626193326Sed  case tok::kw_explicit:
627193326Sed
628193326Sed    // type-specifier:
629193326Sed    //   simple-type-specifier
630193326Sed    //   class-specifier
631193326Sed    //   enum-specifier
632193326Sed    //   elaborated-type-specifier
633193326Sed    //   typename-specifier
634193326Sed    //   cv-qualifier
635193326Sed
636193326Sed    // class-specifier
637193326Sed    // elaborated-type-specifier
638193326Sed  case tok::kw_class:
639193326Sed  case tok::kw_struct:
640193326Sed  case tok::kw_union:
641193326Sed    // enum-specifier
642193326Sed  case tok::kw_enum:
643193326Sed    // cv-qualifier
644193326Sed  case tok::kw_const:
645193326Sed  case tok::kw_volatile:
646193326Sed
647193326Sed    // GNU
648193326Sed  case tok::kw_restrict:
649193326Sed  case tok::kw__Complex:
650193326Sed  case tok::kw___attribute:
651193326Sed    return TPResult::True();
652193326Sed
653193326Sed    // Microsoft
654193326Sed  case tok::kw___declspec:
655193326Sed  case tok::kw___cdecl:
656193326Sed  case tok::kw___stdcall:
657193326Sed  case tok::kw___fastcall:
658194179Sed  case tok::kw___w64:
659194179Sed  case tok::kw___ptr64:
660194179Sed  case tok::kw___forceinline:
661194179Sed    return TPResult::True();
662193326Sed
663193326Sed    // The ambiguity resides in a simple-type-specifier/typename-specifier
664193326Sed    // followed by a '('. The '(' could either be the start of:
665193326Sed    //
666193326Sed    //   direct-declarator:
667193326Sed    //     '(' declarator ')'
668193326Sed    //
669193326Sed    //   direct-abstract-declarator:
670193326Sed    //     '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
671193326Sed    //              exception-specification[opt]
672193326Sed    //     '(' abstract-declarator ')'
673193326Sed    //
674193326Sed    // or part of a function-style cast expression:
675193326Sed    //
676193326Sed    //     simple-type-specifier '(' expression-list[opt] ')'
677193326Sed    //
678193326Sed
679193326Sed    // simple-type-specifier:
680193326Sed
681193326Sed  case tok::kw_char:
682193326Sed  case tok::kw_wchar_t:
683193326Sed  case tok::kw_bool:
684193326Sed  case tok::kw_short:
685193326Sed  case tok::kw_int:
686193326Sed  case tok::kw_long:
687193326Sed  case tok::kw_signed:
688193326Sed  case tok::kw_unsigned:
689193326Sed  case tok::kw_float:
690193326Sed  case tok::kw_double:
691193326Sed  case tok::kw_void:
692193326Sed  case tok::annot_typename:
693193326Sed    if (NextToken().is(tok::l_paren))
694193326Sed      return TPResult::Ambiguous();
695193326Sed
696193326Sed    return TPResult::True();
697193326Sed
698193326Sed    // GNU typeof support.
699193326Sed  case tok::kw_typeof: {
700193326Sed    if (NextToken().isNot(tok::l_paren))
701193326Sed      return TPResult::True();
702193326Sed
703193326Sed    TentativeParsingAction PA(*this);
704193326Sed
705193326Sed    TPResult TPR = TryParseTypeofSpecifier();
706193326Sed    bool isFollowedByParen = Tok.is(tok::l_paren);
707193326Sed
708193326Sed    PA.Revert();
709193326Sed
710193326Sed    if (TPR == TPResult::Error())
711193326Sed      return TPResult::Error();
712193326Sed
713193326Sed    if (isFollowedByParen)
714193326Sed      return TPResult::Ambiguous();
715193326Sed
716193326Sed    return TPResult::True();
717193326Sed  }
718193326Sed
719193326Sed  default:
720193326Sed    return TPResult::False();
721193326Sed  }
722193326Sed}
723193326Sed
724193326Sed/// [GNU] typeof-specifier:
725193326Sed///         'typeof' '(' expressions ')'
726193326Sed///         'typeof' '(' type-name ')'
727193326Sed///
728193326SedParser::TPResult Parser::TryParseTypeofSpecifier() {
729193326Sed  assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
730193326Sed  ConsumeToken();
731193326Sed
732193326Sed  assert(Tok.is(tok::l_paren) && "Expected '('");
733193326Sed  // Parse through the parens after 'typeof'.
734193326Sed  ConsumeParen();
735193326Sed  if (!SkipUntil(tok::r_paren))
736193326Sed    return TPResult::Error();
737193326Sed
738193326Sed  return TPResult::Ambiguous();
739193326Sed}
740193326Sed
741193326SedParser::TPResult Parser::TryParseDeclarationSpecifier() {
742193326Sed  TPResult TPR = isCXXDeclarationSpecifier();
743193326Sed  if (TPR != TPResult::Ambiguous())
744193326Sed    return TPR;
745193326Sed
746193326Sed  if (Tok.is(tok::kw_typeof))
747193326Sed    TryParseTypeofSpecifier();
748193326Sed  else
749193326Sed    ConsumeToken();
750193326Sed
751193326Sed  assert(Tok.is(tok::l_paren) && "Expected '('!");
752193326Sed  return TPResult::Ambiguous();
753193326Sed}
754193326Sed
755193326Sed/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
756193326Sed/// a constructor-style initializer, when parsing declaration statements.
757193326Sed/// Returns true for function declarator and false for constructor-style
758193326Sed/// initializer.
759193326Sed/// If during the disambiguation process a parsing error is encountered,
760193326Sed/// the function returns true to let the declaration parsing code handle it.
761193326Sed///
762193326Sed/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
763193326Sed///         exception-specification[opt]
764193326Sed///
765193326Sedbool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) {
766193326Sed
767193326Sed  // C++ 8.2p1:
768193326Sed  // The ambiguity arising from the similarity between a function-style cast and
769193326Sed  // a declaration mentioned in 6.8 can also occur in the context of a
770193326Sed  // declaration. In that context, the choice is between a function declaration
771193326Sed  // with a redundant set of parentheses around a parameter name and an object
772193326Sed  // declaration with a function-style cast as the initializer. Just as for the
773193326Sed  // ambiguities mentioned in 6.8, the resolution is to consider any construct
774193326Sed  // that could possibly be a declaration a declaration.
775193326Sed
776193326Sed  TentativeParsingAction PA(*this);
777193326Sed
778193326Sed  ConsumeParen();
779193326Sed  TPResult TPR = TryParseParameterDeclarationClause();
780193326Sed  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
781193326Sed    TPR = TPResult::False();
782193326Sed
783193326Sed  SourceLocation TPLoc = Tok.getLocation();
784193326Sed  PA.Revert();
785193326Sed
786193326Sed  // In case of an error, let the declaration parsing code handle it.
787193326Sed  if (TPR == TPResult::Error())
788193326Sed    return true;
789193326Sed
790193326Sed  if (TPR == TPResult::Ambiguous()) {
791193326Sed    // Function declarator has precedence over constructor-style initializer.
792193326Sed    // Emit a warning just in case the author intended a variable definition.
793193326Sed    if (warnIfAmbiguous)
794193326Sed      Diag(Tok, diag::warn_parens_disambiguated_as_function_decl)
795193326Sed        << SourceRange(Tok.getLocation(), TPLoc);
796193326Sed    return true;
797193326Sed  }
798193326Sed
799193326Sed  return TPR == TPResult::True();
800193326Sed}
801193326Sed
802193326Sed/// parameter-declaration-clause:
803193326Sed///   parameter-declaration-list[opt] '...'[opt]
804193326Sed///   parameter-declaration-list ',' '...'
805193326Sed///
806193326Sed/// parameter-declaration-list:
807193326Sed///   parameter-declaration
808193326Sed///   parameter-declaration-list ',' parameter-declaration
809193326Sed///
810193326Sed/// parameter-declaration:
811193326Sed///   decl-specifier-seq declarator
812193326Sed///   decl-specifier-seq declarator '=' assignment-expression
813193326Sed///   decl-specifier-seq abstract-declarator[opt]
814193326Sed///   decl-specifier-seq abstract-declarator[opt] '=' assignment-expression
815193326Sed///
816193326SedParser::TPResult Parser::TryParseParameterDeclarationClause() {
817193326Sed
818193326Sed  if (Tok.is(tok::r_paren))
819193326Sed    return TPResult::True();
820193326Sed
821193326Sed  //   parameter-declaration-list[opt] '...'[opt]
822193326Sed  //   parameter-declaration-list ',' '...'
823193326Sed  //
824193326Sed  // parameter-declaration-list:
825193326Sed  //   parameter-declaration
826193326Sed  //   parameter-declaration-list ',' parameter-declaration
827193326Sed  //
828193326Sed  while (1) {
829193326Sed    // '...'[opt]
830193326Sed    if (Tok.is(tok::ellipsis)) {
831193326Sed      ConsumeToken();
832193326Sed      return TPResult::True(); // '...' is a sign of a function declarator.
833193326Sed    }
834193326Sed
835193326Sed    // decl-specifier-seq
836193326Sed    TPResult TPR = TryParseDeclarationSpecifier();
837193326Sed    if (TPR != TPResult::Ambiguous())
838193326Sed      return TPR;
839193326Sed
840193326Sed    // declarator
841193326Sed    // abstract-declarator[opt]
842193326Sed    TPR = TryParseDeclarator(true/*mayBeAbstract*/);
843193326Sed    if (TPR != TPResult::Ambiguous())
844193326Sed      return TPR;
845193326Sed
846193326Sed    if (Tok.is(tok::equal)) {
847193326Sed      // '=' assignment-expression
848193326Sed      // Parse through assignment-expression.
849193326Sed      tok::TokenKind StopToks[3] ={ tok::comma, tok::ellipsis, tok::r_paren };
850193326Sed      if (!SkipUntil(StopToks, 3, true/*StopAtSemi*/, true/*DontConsume*/))
851193326Sed        return TPResult::Error();
852193326Sed    }
853193326Sed
854193326Sed    if (Tok.is(tok::ellipsis)) {
855193326Sed      ConsumeToken();
856193326Sed      return TPResult::True(); // '...' is a sign of a function declarator.
857193326Sed    }
858193326Sed
859193326Sed    if (Tok.isNot(tok::comma))
860193326Sed      break;
861193326Sed    ConsumeToken(); // the comma.
862193326Sed  }
863193326Sed
864193326Sed  return TPResult::Ambiguous();
865193326Sed}
866193326Sed
867193326Sed/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
868193326Sed/// parsing as a function declarator.
869193326Sed/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
870193326Sed/// return TPResult::Ambiguous(), otherwise it will return either False() or
871193326Sed/// Error().
872193326Sed///
873193326Sed/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
874193326Sed///         exception-specification[opt]
875193326Sed///
876193326Sed/// exception-specification:
877193326Sed///   'throw' '(' type-id-list[opt] ')'
878193326Sed///
879193326SedParser::TPResult Parser::TryParseFunctionDeclarator() {
880193326Sed
881193326Sed  // The '(' is already parsed.
882193326Sed
883193326Sed  TPResult TPR = TryParseParameterDeclarationClause();
884193326Sed  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
885193326Sed    TPR = TPResult::False();
886193326Sed
887193326Sed  if (TPR == TPResult::False() || TPR == TPResult::Error())
888193326Sed    return TPR;
889193326Sed
890193326Sed  // Parse through the parens.
891193326Sed  if (!SkipUntil(tok::r_paren))
892193326Sed    return TPResult::Error();
893193326Sed
894193326Sed  // cv-qualifier-seq
895193326Sed  while (Tok.is(tok::kw_const)    ||
896193326Sed         Tok.is(tok::kw_volatile) ||
897193326Sed         Tok.is(tok::kw_restrict)   )
898193326Sed    ConsumeToken();
899193326Sed
900193326Sed  // exception-specification
901193326Sed  if (Tok.is(tok::kw_throw)) {
902193326Sed    ConsumeToken();
903193326Sed    if (Tok.isNot(tok::l_paren))
904193326Sed      return TPResult::Error();
905193326Sed
906193326Sed    // Parse through the parens after 'throw'.
907193326Sed    ConsumeParen();
908193326Sed    if (!SkipUntil(tok::r_paren))
909193326Sed      return TPResult::Error();
910193326Sed  }
911193326Sed
912193326Sed  return TPResult::Ambiguous();
913193326Sed}
914193326Sed
915193326Sed/// '[' constant-expression[opt] ']'
916193326Sed///
917193326SedParser::TPResult Parser::TryParseBracketDeclarator() {
918193326Sed  ConsumeBracket();
919193326Sed  if (!SkipUntil(tok::r_square))
920193326Sed    return TPResult::Error();
921193326Sed
922193326Sed  return TPResult::Ambiguous();
923193326Sed}
924