ParseExprCXX.cpp revision 193326
1193326Sed//===--- ParseExprCXX.cpp - C++ Expression 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 Expression parsing implementation for C++.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/Parse/ParseDiagnostic.h"
15193326Sed#include "clang/Parse/Parser.h"
16193326Sed#include "clang/Parse/DeclSpec.h"
17193326Sedusing namespace clang;
18193326Sed
19193326Sed/// ParseOptionalCXXScopeSpecifier - Parse global scope or
20193326Sed/// nested-name-specifier if present.  Returns true if a nested-name-specifier
21193326Sed/// was parsed from the token stream.  Note that this routine will not parse
22193326Sed/// ::new or ::delete, it will just leave them in the token stream.
23193326Sed///
24193326Sed///       '::'[opt] nested-name-specifier
25193326Sed///       '::'
26193326Sed///
27193326Sed///       nested-name-specifier:
28193326Sed///         type-name '::'
29193326Sed///         namespace-name '::'
30193326Sed///         nested-name-specifier identifier '::'
31193326Sed///         nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
32193326Sed///
33193326Sedbool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
34193326Sed  assert(getLang().CPlusPlus &&
35193326Sed         "Call sites of this function should be guarded by checking for C++");
36193326Sed
37193326Sed  if (Tok.is(tok::annot_cxxscope)) {
38193326Sed    SS.setScopeRep(Tok.getAnnotationValue());
39193326Sed    SS.setRange(Tok.getAnnotationRange());
40193326Sed    ConsumeToken();
41193326Sed    return true;
42193326Sed  }
43193326Sed
44193326Sed  bool HasScopeSpecifier = false;
45193326Sed
46193326Sed  if (Tok.is(tok::coloncolon)) {
47193326Sed    // ::new and ::delete aren't nested-name-specifiers.
48193326Sed    tok::TokenKind NextKind = NextToken().getKind();
49193326Sed    if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
50193326Sed      return false;
51193326Sed
52193326Sed    // '::' - Global scope qualifier.
53193326Sed    SourceLocation CCLoc = ConsumeToken();
54193326Sed    SS.setBeginLoc(CCLoc);
55193326Sed    SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
56193326Sed    SS.setEndLoc(CCLoc);
57193326Sed    HasScopeSpecifier = true;
58193326Sed  }
59193326Sed
60193326Sed  while (true) {
61193326Sed    // nested-name-specifier:
62193326Sed    //   type-name '::'
63193326Sed    //   namespace-name '::'
64193326Sed    //   nested-name-specifier identifier '::'
65193326Sed    if (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) {
66193326Sed      // We have an identifier followed by a '::'. Lookup this name
67193326Sed      // as the name in a nested-name-specifier.
68193326Sed      IdentifierInfo *II = Tok.getIdentifierInfo();
69193326Sed      SourceLocation IdLoc = ConsumeToken();
70193326Sed      assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
71193326Sed      SourceLocation CCLoc = ConsumeToken();
72193326Sed
73193326Sed      if (!HasScopeSpecifier) {
74193326Sed        SS.setBeginLoc(IdLoc);
75193326Sed        HasScopeSpecifier = true;
76193326Sed      }
77193326Sed
78193326Sed      if (SS.isInvalid())
79193326Sed        continue;
80193326Sed
81193326Sed      SS.setScopeRep(
82193326Sed        Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
83193326Sed      SS.setEndLoc(CCLoc);
84193326Sed      continue;
85193326Sed    }
86193326Sed
87193326Sed    // nested-name-specifier:
88193326Sed    //   type-name '::'
89193326Sed    //   nested-name-specifier 'template'[opt] simple-template-id '::'
90193326Sed    if ((Tok.is(tok::identifier) && NextToken().is(tok::less)) ||
91193326Sed        Tok.is(tok::kw_template)) {
92193326Sed      // Parse the optional 'template' keyword, then make sure we have
93193326Sed      // 'identifier <' after it.
94193326Sed      if (Tok.is(tok::kw_template)) {
95193326Sed        SourceLocation TemplateKWLoc = ConsumeToken();
96193326Sed
97193326Sed        if (Tok.isNot(tok::identifier)) {
98193326Sed          Diag(Tok.getLocation(),
99193326Sed               diag::err_id_after_template_in_nested_name_spec)
100193326Sed            << SourceRange(TemplateKWLoc);
101193326Sed          break;
102193326Sed        }
103193326Sed
104193326Sed        if (NextToken().isNot(tok::less)) {
105193326Sed          Diag(NextToken().getLocation(),
106193326Sed               diag::err_less_after_template_name_in_nested_name_spec)
107193326Sed            << Tok.getIdentifierInfo()->getName()
108193326Sed            << SourceRange(TemplateKWLoc, Tok.getLocation());
109193326Sed          break;
110193326Sed        }
111193326Sed
112193326Sed        TemplateTy Template
113193326Sed          = Actions.ActOnDependentTemplateName(TemplateKWLoc,
114193326Sed                                               *Tok.getIdentifierInfo(),
115193326Sed                                               Tok.getLocation(),
116193326Sed                                               SS);
117193326Sed        AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
118193326Sed                                &SS, TemplateKWLoc, false);
119193326Sed        continue;
120193326Sed      }
121193326Sed
122193326Sed      TemplateTy Template;
123193326Sed      TemplateNameKind TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(),
124193326Sed                                                    CurScope, Template, &SS);
125193326Sed      if (TNK) {
126193326Sed        // We have found a template name, so annotate this this token
127193326Sed        // with a template-id annotation. We do not permit the
128193326Sed        // template-id to be translated into a type annotation,
129193326Sed        // because some clients (e.g., the parsing of class template
130193326Sed        // specializations) still want to see the original template-id
131193326Sed        // token.
132193326Sed        AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(), false);
133193326Sed        continue;
134193326Sed      }
135193326Sed    }
136193326Sed
137193326Sed    if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
138193326Sed      // We have
139193326Sed      //
140193326Sed      //   simple-template-id '::'
141193326Sed      //
142193326Sed      // So we need to check whether the simple-template-id is of the
143193326Sed      // right kind (it should name a type or be dependent), and then
144193326Sed      // convert it into a type within the nested-name-specifier.
145193326Sed      TemplateIdAnnotation *TemplateId
146193326Sed        = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
147193326Sed
148193326Sed      if (TemplateId->Kind == TNK_Type_template ||
149193326Sed          TemplateId->Kind == TNK_Dependent_template_name) {
150193326Sed        AnnotateTemplateIdTokenAsType(&SS);
151193326Sed        SS.setScopeRep(0);
152193326Sed
153193326Sed        assert(Tok.is(tok::annot_typename) &&
154193326Sed               "AnnotateTemplateIdTokenAsType isn't working");
155193326Sed        Token TypeToken = Tok;
156193326Sed        ConsumeToken();
157193326Sed        assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
158193326Sed        SourceLocation CCLoc = ConsumeToken();
159193326Sed
160193326Sed        if (!HasScopeSpecifier) {
161193326Sed          SS.setBeginLoc(TypeToken.getLocation());
162193326Sed          HasScopeSpecifier = true;
163193326Sed        }
164193326Sed
165193326Sed        if (TypeToken.getAnnotationValue())
166193326Sed          SS.setScopeRep(
167193326Sed            Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
168193326Sed                                                TypeToken.getAnnotationValue(),
169193326Sed                                                TypeToken.getAnnotationRange(),
170193326Sed                                                CCLoc));
171193326Sed        else
172193326Sed          SS.setScopeRep(0);
173193326Sed        SS.setEndLoc(CCLoc);
174193326Sed        continue;
175193326Sed      } else
176193326Sed        assert(false && "FIXME: Only type template names supported here");
177193326Sed    }
178193326Sed
179193326Sed    // We don't have any tokens that form the beginning of a
180193326Sed    // nested-name-specifier, so we're done.
181193326Sed    break;
182193326Sed  }
183193326Sed
184193326Sed  return HasScopeSpecifier;
185193326Sed}
186193326Sed
187193326Sed/// ParseCXXIdExpression - Handle id-expression.
188193326Sed///
189193326Sed///       id-expression:
190193326Sed///         unqualified-id
191193326Sed///         qualified-id
192193326Sed///
193193326Sed///       unqualified-id:
194193326Sed///         identifier
195193326Sed///         operator-function-id
196193326Sed///         conversion-function-id                [TODO]
197193326Sed///         '~' class-name                        [TODO]
198193326Sed///         template-id                           [TODO]
199193326Sed///
200193326Sed///       qualified-id:
201193326Sed///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
202193326Sed///         '::' identifier
203193326Sed///         '::' operator-function-id
204193326Sed///         '::' template-id                      [TODO]
205193326Sed///
206193326Sed///       nested-name-specifier:
207193326Sed///         type-name '::'
208193326Sed///         namespace-name '::'
209193326Sed///         nested-name-specifier identifier '::'
210193326Sed///         nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
211193326Sed///
212193326Sed/// NOTE: The standard specifies that, for qualified-id, the parser does not
213193326Sed/// expect:
214193326Sed///
215193326Sed///   '::' conversion-function-id
216193326Sed///   '::' '~' class-name
217193326Sed///
218193326Sed/// This may cause a slight inconsistency on diagnostics:
219193326Sed///
220193326Sed/// class C {};
221193326Sed/// namespace A {}
222193326Sed/// void f() {
223193326Sed///   :: A :: ~ C(); // Some Sema error about using destructor with a
224193326Sed///                  // namespace.
225193326Sed///   :: ~ C(); // Some Parser error like 'unexpected ~'.
226193326Sed/// }
227193326Sed///
228193326Sed/// We simplify the parser a bit and make it work like:
229193326Sed///
230193326Sed///       qualified-id:
231193326Sed///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
232193326Sed///         '::' unqualified-id
233193326Sed///
234193326Sed/// That way Sema can handle and report similar errors for namespaces and the
235193326Sed/// global scope.
236193326Sed///
237193326Sed/// The isAddressOfOperand parameter indicates that this id-expression is a
238193326Sed/// direct operand of the address-of operator. This is, besides member contexts,
239193326Sed/// the only place where a qualified-id naming a non-static class member may
240193326Sed/// appear.
241193326Sed///
242193326SedParser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
243193326Sed  // qualified-id:
244193326Sed  //   '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
245193326Sed  //   '::' unqualified-id
246193326Sed  //
247193326Sed  CXXScopeSpec SS;
248193326Sed  ParseOptionalCXXScopeSpecifier(SS);
249193326Sed
250193326Sed  // unqualified-id:
251193326Sed  //   identifier
252193326Sed  //   operator-function-id
253193326Sed  //   conversion-function-id
254193326Sed  //   '~' class-name                        [TODO]
255193326Sed  //   template-id                           [TODO]
256193326Sed  //
257193326Sed  switch (Tok.getKind()) {
258193326Sed  default:
259193326Sed    return ExprError(Diag(Tok, diag::err_expected_unqualified_id));
260193326Sed
261193326Sed  case tok::identifier: {
262193326Sed    // Consume the identifier so that we can see if it is followed by a '('.
263193326Sed    IdentifierInfo &II = *Tok.getIdentifierInfo();
264193326Sed    SourceLocation L = ConsumeToken();
265193326Sed    return Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren),
266193326Sed                                       &SS, isAddressOfOperand);
267193326Sed  }
268193326Sed
269193326Sed  case tok::kw_operator: {
270193326Sed    SourceLocation OperatorLoc = Tok.getLocation();
271193326Sed    if (OverloadedOperatorKind Op = TryParseOperatorFunctionId())
272193326Sed      return Actions.ActOnCXXOperatorFunctionIdExpr(
273193326Sed                       CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS,
274193326Sed                       isAddressOfOperand);
275193326Sed    if (TypeTy *Type = ParseConversionFunctionId())
276193326Sed      return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type,
277193326Sed                                                    Tok.is(tok::l_paren), SS,
278193326Sed                                                    isAddressOfOperand);
279193326Sed
280193326Sed    // We already complained about a bad conversion-function-id,
281193326Sed    // above.
282193326Sed    return ExprError();
283193326Sed  }
284193326Sed
285193326Sed  } // switch.
286193326Sed
287193326Sed  assert(0 && "The switch was supposed to take care everything.");
288193326Sed}
289193326Sed
290193326Sed/// ParseCXXCasts - This handles the various ways to cast expressions to another
291193326Sed/// type.
292193326Sed///
293193326Sed///       postfix-expression: [C++ 5.2p1]
294193326Sed///         'dynamic_cast' '<' type-name '>' '(' expression ')'
295193326Sed///         'static_cast' '<' type-name '>' '(' expression ')'
296193326Sed///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
297193326Sed///         'const_cast' '<' type-name '>' '(' expression ')'
298193326Sed///
299193326SedParser::OwningExprResult Parser::ParseCXXCasts() {
300193326Sed  tok::TokenKind Kind = Tok.getKind();
301193326Sed  const char *CastName = 0;     // For error messages
302193326Sed
303193326Sed  switch (Kind) {
304193326Sed  default: assert(0 && "Unknown C++ cast!"); abort();
305193326Sed  case tok::kw_const_cast:       CastName = "const_cast";       break;
306193326Sed  case tok::kw_dynamic_cast:     CastName = "dynamic_cast";     break;
307193326Sed  case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
308193326Sed  case tok::kw_static_cast:      CastName = "static_cast";      break;
309193326Sed  }
310193326Sed
311193326Sed  SourceLocation OpLoc = ConsumeToken();
312193326Sed  SourceLocation LAngleBracketLoc = Tok.getLocation();
313193326Sed
314193326Sed  if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
315193326Sed    return ExprError();
316193326Sed
317193326Sed  TypeResult CastTy = ParseTypeName();
318193326Sed  SourceLocation RAngleBracketLoc = Tok.getLocation();
319193326Sed
320193326Sed  if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
321193326Sed    return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
322193326Sed
323193326Sed  SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
324193326Sed
325193326Sed  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName))
326193326Sed    return ExprError();
327193326Sed
328193326Sed  OwningExprResult Result = ParseExpression();
329193326Sed
330193326Sed  // Match the ')'.
331193326Sed  if (Result.isInvalid())
332193326Sed    SkipUntil(tok::r_paren);
333193326Sed
334193326Sed  if (Tok.is(tok::r_paren))
335193326Sed    RParenLoc = ConsumeParen();
336193326Sed  else
337193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
338193326Sed
339193326Sed  if (!Result.isInvalid() && !CastTy.isInvalid())
340193326Sed    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
341193326Sed                                       LAngleBracketLoc, CastTy.get(),
342193326Sed                                       RAngleBracketLoc,
343193326Sed                                       LParenLoc, move(Result), RParenLoc);
344193326Sed
345193326Sed  return move(Result);
346193326Sed}
347193326Sed
348193326Sed/// ParseCXXTypeid - This handles the C++ typeid expression.
349193326Sed///
350193326Sed///       postfix-expression: [C++ 5.2p1]
351193326Sed///         'typeid' '(' expression ')'
352193326Sed///         'typeid' '(' type-id ')'
353193326Sed///
354193326SedParser::OwningExprResult Parser::ParseCXXTypeid() {
355193326Sed  assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
356193326Sed
357193326Sed  SourceLocation OpLoc = ConsumeToken();
358193326Sed  SourceLocation LParenLoc = Tok.getLocation();
359193326Sed  SourceLocation RParenLoc;
360193326Sed
361193326Sed  // typeid expressions are always parenthesized.
362193326Sed  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
363193326Sed      "typeid"))
364193326Sed    return ExprError();
365193326Sed
366193326Sed  OwningExprResult Result(Actions);
367193326Sed
368193326Sed  if (isTypeIdInParens()) {
369193326Sed    TypeResult Ty = ParseTypeName();
370193326Sed
371193326Sed    // Match the ')'.
372193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
373193326Sed
374193326Sed    if (Ty.isInvalid())
375193326Sed      return ExprError();
376193326Sed
377193326Sed    Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
378193326Sed                                    Ty.get(), RParenLoc);
379193326Sed  } else {
380193326Sed    Result = ParseExpression();
381193326Sed
382193326Sed    // Match the ')'.
383193326Sed    if (Result.isInvalid())
384193326Sed      SkipUntil(tok::r_paren);
385193326Sed    else {
386193326Sed      MatchRHSPunctuation(tok::r_paren, LParenLoc);
387193326Sed
388193326Sed      Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
389193326Sed                                      Result.release(), RParenLoc);
390193326Sed    }
391193326Sed  }
392193326Sed
393193326Sed  return move(Result);
394193326Sed}
395193326Sed
396193326Sed/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
397193326Sed///
398193326Sed///       boolean-literal: [C++ 2.13.5]
399193326Sed///         'true'
400193326Sed///         'false'
401193326SedParser::OwningExprResult Parser::ParseCXXBoolLiteral() {
402193326Sed  tok::TokenKind Kind = Tok.getKind();
403193326Sed  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
404193326Sed}
405193326Sed
406193326Sed/// ParseThrowExpression - This handles the C++ throw expression.
407193326Sed///
408193326Sed///       throw-expression: [C++ 15]
409193326Sed///         'throw' assignment-expression[opt]
410193326SedParser::OwningExprResult Parser::ParseThrowExpression() {
411193326Sed  assert(Tok.is(tok::kw_throw) && "Not throw!");
412193326Sed  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
413193326Sed
414193326Sed  // If the current token isn't the start of an assignment-expression,
415193326Sed  // then the expression is not present.  This handles things like:
416193326Sed  //   "C ? throw : (void)42", which is crazy but legal.
417193326Sed  switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
418193326Sed  case tok::semi:
419193326Sed  case tok::r_paren:
420193326Sed  case tok::r_square:
421193326Sed  case tok::r_brace:
422193326Sed  case tok::colon:
423193326Sed  case tok::comma:
424193326Sed    return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
425193326Sed
426193326Sed  default:
427193326Sed    OwningExprResult Expr(ParseAssignmentExpression());
428193326Sed    if (Expr.isInvalid()) return move(Expr);
429193326Sed    return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
430193326Sed  }
431193326Sed}
432193326Sed
433193326Sed/// ParseCXXThis - This handles the C++ 'this' pointer.
434193326Sed///
435193326Sed/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
436193326Sed/// a non-lvalue expression whose value is the address of the object for which
437193326Sed/// the function is called.
438193326SedParser::OwningExprResult Parser::ParseCXXThis() {
439193326Sed  assert(Tok.is(tok::kw_this) && "Not 'this'!");
440193326Sed  SourceLocation ThisLoc = ConsumeToken();
441193326Sed  return Actions.ActOnCXXThis(ThisLoc);
442193326Sed}
443193326Sed
444193326Sed/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
445193326Sed/// Can be interpreted either as function-style casting ("int(x)")
446193326Sed/// or class type construction ("ClassType(x,y,z)")
447193326Sed/// or creation of a value-initialized type ("int()").
448193326Sed///
449193326Sed///       postfix-expression: [C++ 5.2p1]
450193326Sed///         simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
451193326Sed///         typename-specifier '(' expression-list[opt] ')'         [TODO]
452193326Sed///
453193326SedParser::OwningExprResult
454193326SedParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
455193326Sed  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
456193326Sed  TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
457193326Sed
458193326Sed  assert(Tok.is(tok::l_paren) && "Expected '('!");
459193326Sed  SourceLocation LParenLoc = ConsumeParen();
460193326Sed
461193326Sed  ExprVector Exprs(Actions);
462193326Sed  CommaLocsTy CommaLocs;
463193326Sed
464193326Sed  if (Tok.isNot(tok::r_paren)) {
465193326Sed    if (ParseExpressionList(Exprs, CommaLocs)) {
466193326Sed      SkipUntil(tok::r_paren);
467193326Sed      return ExprError();
468193326Sed    }
469193326Sed  }
470193326Sed
471193326Sed  // Match the ')'.
472193326Sed  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
473193326Sed
474193326Sed  assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
475193326Sed         "Unexpected number of commas!");
476193326Sed  return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
477193326Sed                                           LParenLoc, move_arg(Exprs),
478193326Sed                                           CommaLocs.data(), RParenLoc);
479193326Sed}
480193326Sed
481193326Sed/// ParseCXXCondition - if/switch/while/for condition expression.
482193326Sed///
483193326Sed///       condition:
484193326Sed///         expression
485193326Sed///         type-specifier-seq declarator '=' assignment-expression
486193326Sed/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
487193326Sed///             '=' assignment-expression
488193326Sed///
489193326SedParser::OwningExprResult Parser::ParseCXXCondition() {
490193326Sed  if (!isCXXConditionDeclaration())
491193326Sed    return ParseExpression(); // expression
492193326Sed
493193326Sed  SourceLocation StartLoc = Tok.getLocation();
494193326Sed
495193326Sed  // type-specifier-seq
496193326Sed  DeclSpec DS;
497193326Sed  ParseSpecifierQualifierList(DS);
498193326Sed
499193326Sed  // declarator
500193326Sed  Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
501193326Sed  ParseDeclarator(DeclaratorInfo);
502193326Sed
503193326Sed  // simple-asm-expr[opt]
504193326Sed  if (Tok.is(tok::kw_asm)) {
505193326Sed    SourceLocation Loc;
506193326Sed    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
507193326Sed    if (AsmLabel.isInvalid()) {
508193326Sed      SkipUntil(tok::semi);
509193326Sed      return ExprError();
510193326Sed    }
511193326Sed    DeclaratorInfo.setAsmLabel(AsmLabel.release());
512193326Sed    DeclaratorInfo.SetRangeEnd(Loc);
513193326Sed  }
514193326Sed
515193326Sed  // If attributes are present, parse them.
516193326Sed  if (Tok.is(tok::kw___attribute)) {
517193326Sed    SourceLocation Loc;
518193326Sed    AttributeList *AttrList = ParseAttributes(&Loc);
519193326Sed    DeclaratorInfo.AddAttributes(AttrList, Loc);
520193326Sed  }
521193326Sed
522193326Sed  // '=' assignment-expression
523193326Sed  if (Tok.isNot(tok::equal))
524193326Sed    return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator));
525193326Sed  SourceLocation EqualLoc = ConsumeToken();
526193326Sed  OwningExprResult AssignExpr(ParseAssignmentExpression());
527193326Sed  if (AssignExpr.isInvalid())
528193326Sed    return ExprError();
529193326Sed
530193326Sed  return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
531193326Sed                                                  DeclaratorInfo,EqualLoc,
532193326Sed                                                  move(AssignExpr));
533193326Sed}
534193326Sed
535193326Sed/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
536193326Sed/// This should only be called when the current token is known to be part of
537193326Sed/// simple-type-specifier.
538193326Sed///
539193326Sed///       simple-type-specifier:
540193326Sed///         '::'[opt] nested-name-specifier[opt] type-name
541193326Sed///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
542193326Sed///         char
543193326Sed///         wchar_t
544193326Sed///         bool
545193326Sed///         short
546193326Sed///         int
547193326Sed///         long
548193326Sed///         signed
549193326Sed///         unsigned
550193326Sed///         float
551193326Sed///         double
552193326Sed///         void
553193326Sed/// [GNU]   typeof-specifier
554193326Sed/// [C++0x] auto               [TODO]
555193326Sed///
556193326Sed///       type-name:
557193326Sed///         class-name
558193326Sed///         enum-name
559193326Sed///         typedef-name
560193326Sed///
561193326Sedvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
562193326Sed  DS.SetRangeStart(Tok.getLocation());
563193326Sed  const char *PrevSpec;
564193326Sed  SourceLocation Loc = Tok.getLocation();
565193326Sed
566193326Sed  switch (Tok.getKind()) {
567193326Sed  case tok::identifier:   // foo::bar
568193326Sed  case tok::coloncolon:   // ::foo::bar
569193326Sed    assert(0 && "Annotation token should already be formed!");
570193326Sed  default:
571193326Sed    assert(0 && "Not a simple-type-specifier token!");
572193326Sed    abort();
573193326Sed
574193326Sed  // type-name
575193326Sed  case tok::annot_typename: {
576193326Sed    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
577193326Sed                       Tok.getAnnotationValue());
578193326Sed    break;
579193326Sed  }
580193326Sed
581193326Sed  // builtin types
582193326Sed  case tok::kw_short:
583193326Sed    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
584193326Sed    break;
585193326Sed  case tok::kw_long:
586193326Sed    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
587193326Sed    break;
588193326Sed  case tok::kw_signed:
589193326Sed    DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
590193326Sed    break;
591193326Sed  case tok::kw_unsigned:
592193326Sed    DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
593193326Sed    break;
594193326Sed  case tok::kw_void:
595193326Sed    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
596193326Sed    break;
597193326Sed  case tok::kw_char:
598193326Sed    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
599193326Sed    break;
600193326Sed  case tok::kw_int:
601193326Sed    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
602193326Sed    break;
603193326Sed  case tok::kw_float:
604193326Sed    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
605193326Sed    break;
606193326Sed  case tok::kw_double:
607193326Sed    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
608193326Sed    break;
609193326Sed  case tok::kw_wchar_t:
610193326Sed    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
611193326Sed    break;
612193326Sed  case tok::kw_bool:
613193326Sed    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
614193326Sed    break;
615193326Sed
616193326Sed  // GNU typeof support.
617193326Sed  case tok::kw_typeof:
618193326Sed    ParseTypeofSpecifier(DS);
619193326Sed    DS.Finish(Diags, PP);
620193326Sed    return;
621193326Sed  }
622193326Sed  if (Tok.is(tok::annot_typename))
623193326Sed    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
624193326Sed  else
625193326Sed    DS.SetRangeEnd(Tok.getLocation());
626193326Sed  ConsumeToken();
627193326Sed  DS.Finish(Diags, PP);
628193326Sed}
629193326Sed
630193326Sed/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
631193326Sed/// [dcl.name]), which is a non-empty sequence of type-specifiers,
632193326Sed/// e.g., "const short int". Note that the DeclSpec is *not* finished
633193326Sed/// by parsing the type-specifier-seq, because these sequences are
634193326Sed/// typically followed by some form of declarator. Returns true and
635193326Sed/// emits diagnostics if this is not a type-specifier-seq, false
636193326Sed/// otherwise.
637193326Sed///
638193326Sed///   type-specifier-seq: [C++ 8.1]
639193326Sed///     type-specifier type-specifier-seq[opt]
640193326Sed///
641193326Sedbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
642193326Sed  DS.SetRangeStart(Tok.getLocation());
643193326Sed  const char *PrevSpec = 0;
644193326Sed  int isInvalid = 0;
645193326Sed
646193326Sed  // Parse one or more of the type specifiers.
647193326Sed  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) {
648193326Sed    Diag(Tok, diag::err_operator_missing_type_specifier);
649193326Sed    return true;
650193326Sed  }
651193326Sed
652193326Sed  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) ;
653193326Sed
654193326Sed  return false;
655193326Sed}
656193326Sed
657193326Sed/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded
658193326Sed/// operator name (C++ [over.oper]). If successful, returns the
659193326Sed/// predefined identifier that corresponds to that overloaded
660193326Sed/// operator. Otherwise, returns NULL and does not consume any tokens.
661193326Sed///
662193326Sed///       operator-function-id: [C++ 13.5]
663193326Sed///         'operator' operator
664193326Sed///
665193326Sed/// operator: one of
666193326Sed///            new   delete  new[]   delete[]
667193326Sed///            +     -    *  /    %  ^    &   |   ~
668193326Sed///            !     =    <  >    += -=   *=  /=  %=
669193326Sed///            ^=    &=   |= <<   >> >>= <<=  ==  !=
670193326Sed///            <=    >=   && ||   ++ --   ,   ->* ->
671193326Sed///            ()    []
672193326SedOverloadedOperatorKind
673193326SedParser::TryParseOperatorFunctionId(SourceLocation *EndLoc) {
674193326Sed  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
675193326Sed  SourceLocation Loc;
676193326Sed
677193326Sed  OverloadedOperatorKind Op = OO_None;
678193326Sed  switch (NextToken().getKind()) {
679193326Sed  case tok::kw_new:
680193326Sed    ConsumeToken(); // 'operator'
681193326Sed    Loc = ConsumeToken(); // 'new'
682193326Sed    if (Tok.is(tok::l_square)) {
683193326Sed      ConsumeBracket(); // '['
684193326Sed      Loc = Tok.getLocation();
685193326Sed      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
686193326Sed      Op = OO_Array_New;
687193326Sed    } else {
688193326Sed      Op = OO_New;
689193326Sed    }
690193326Sed    if (EndLoc)
691193326Sed      *EndLoc = Loc;
692193326Sed    return Op;
693193326Sed
694193326Sed  case tok::kw_delete:
695193326Sed    ConsumeToken(); // 'operator'
696193326Sed    Loc = ConsumeToken(); // 'delete'
697193326Sed    if (Tok.is(tok::l_square)) {
698193326Sed      ConsumeBracket(); // '['
699193326Sed      Loc = Tok.getLocation();
700193326Sed      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
701193326Sed      Op = OO_Array_Delete;
702193326Sed    } else {
703193326Sed      Op = OO_Delete;
704193326Sed    }
705193326Sed    if (EndLoc)
706193326Sed      *EndLoc = Loc;
707193326Sed    return Op;
708193326Sed
709193326Sed#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)  \
710193326Sed    case tok::Token:  Op = OO_##Name; break;
711193326Sed#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
712193326Sed#include "clang/Basic/OperatorKinds.def"
713193326Sed
714193326Sed  case tok::l_paren:
715193326Sed    ConsumeToken(); // 'operator'
716193326Sed    ConsumeParen(); // '('
717193326Sed    Loc = Tok.getLocation();
718193326Sed    ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
719193326Sed    if (EndLoc)
720193326Sed      *EndLoc = Loc;
721193326Sed    return OO_Call;
722193326Sed
723193326Sed  case tok::l_square:
724193326Sed    ConsumeToken(); // 'operator'
725193326Sed    ConsumeBracket(); // '['
726193326Sed    Loc = Tok.getLocation();
727193326Sed    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
728193326Sed    if (EndLoc)
729193326Sed      *EndLoc = Loc;
730193326Sed    return OO_Subscript;
731193326Sed
732193326Sed  default:
733193326Sed    return OO_None;
734193326Sed  }
735193326Sed
736193326Sed  ConsumeToken(); // 'operator'
737193326Sed  Loc = ConsumeAnyToken(); // the operator itself
738193326Sed  if (EndLoc)
739193326Sed    *EndLoc = Loc;
740193326Sed  return Op;
741193326Sed}
742193326Sed
743193326Sed/// ParseConversionFunctionId - Parse a C++ conversion-function-id,
744193326Sed/// which expresses the name of a user-defined conversion operator
745193326Sed/// (C++ [class.conv.fct]p1). Returns the type that this operator is
746193326Sed/// specifying a conversion for, or NULL if there was an error.
747193326Sed///
748193326Sed///        conversion-function-id: [C++ 12.3.2]
749193326Sed///                   operator conversion-type-id
750193326Sed///
751193326Sed///        conversion-type-id:
752193326Sed///                   type-specifier-seq conversion-declarator[opt]
753193326Sed///
754193326Sed///        conversion-declarator:
755193326Sed///                   ptr-operator conversion-declarator[opt]
756193326SedParser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) {
757193326Sed  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
758193326Sed  ConsumeToken(); // 'operator'
759193326Sed
760193326Sed  // Parse the type-specifier-seq.
761193326Sed  DeclSpec DS;
762193326Sed  if (ParseCXXTypeSpecifierSeq(DS))
763193326Sed    return 0;
764193326Sed
765193326Sed  // Parse the conversion-declarator, which is merely a sequence of
766193326Sed  // ptr-operators.
767193326Sed  Declarator D(DS, Declarator::TypeNameContext);
768193326Sed  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
769193326Sed  if (EndLoc)
770193326Sed    *EndLoc = D.getSourceRange().getEnd();
771193326Sed
772193326Sed  // Finish up the type.
773193326Sed  Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
774193326Sed  if (Result.isInvalid())
775193326Sed    return 0;
776193326Sed  else
777193326Sed    return Result.get();
778193326Sed}
779193326Sed
780193326Sed/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
781193326Sed/// memory in a typesafe manner and call constructors.
782193326Sed///
783193326Sed/// This method is called to parse the new expression after the optional :: has
784193326Sed/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
785193326Sed/// is its location.  Otherwise, "Start" is the location of the 'new' token.
786193326Sed///
787193326Sed///        new-expression:
788193326Sed///                   '::'[opt] 'new' new-placement[opt] new-type-id
789193326Sed///                                     new-initializer[opt]
790193326Sed///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
791193326Sed///                                     new-initializer[opt]
792193326Sed///
793193326Sed///        new-placement:
794193326Sed///                   '(' expression-list ')'
795193326Sed///
796193326Sed///        new-type-id:
797193326Sed///                   type-specifier-seq new-declarator[opt]
798193326Sed///
799193326Sed///        new-declarator:
800193326Sed///                   ptr-operator new-declarator[opt]
801193326Sed///                   direct-new-declarator
802193326Sed///
803193326Sed///        new-initializer:
804193326Sed///                   '(' expression-list[opt] ')'
805193326Sed/// [C++0x]           braced-init-list                                   [TODO]
806193326Sed///
807193326SedParser::OwningExprResult
808193326SedParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
809193326Sed  assert(Tok.is(tok::kw_new) && "expected 'new' token");
810193326Sed  ConsumeToken();   // Consume 'new'
811193326Sed
812193326Sed  // A '(' now can be a new-placement or the '(' wrapping the type-id in the
813193326Sed  // second form of new-expression. It can't be a new-type-id.
814193326Sed
815193326Sed  ExprVector PlacementArgs(Actions);
816193326Sed  SourceLocation PlacementLParen, PlacementRParen;
817193326Sed
818193326Sed  bool ParenTypeId;
819193326Sed  DeclSpec DS;
820193326Sed  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
821193326Sed  if (Tok.is(tok::l_paren)) {
822193326Sed    // If it turns out to be a placement, we change the type location.
823193326Sed    PlacementLParen = ConsumeParen();
824193326Sed    if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
825193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
826193326Sed      return ExprError();
827193326Sed    }
828193326Sed
829193326Sed    PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
830193326Sed    if (PlacementRParen.isInvalid()) {
831193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
832193326Sed      return ExprError();
833193326Sed    }
834193326Sed
835193326Sed    if (PlacementArgs.empty()) {
836193326Sed      // Reset the placement locations. There was no placement.
837193326Sed      PlacementLParen = PlacementRParen = SourceLocation();
838193326Sed      ParenTypeId = true;
839193326Sed    } else {
840193326Sed      // We still need the type.
841193326Sed      if (Tok.is(tok::l_paren)) {
842193326Sed        SourceLocation LParen = ConsumeParen();
843193326Sed        ParseSpecifierQualifierList(DS);
844193326Sed        DeclaratorInfo.SetSourceRange(DS.getSourceRange());
845193326Sed        ParseDeclarator(DeclaratorInfo);
846193326Sed        MatchRHSPunctuation(tok::r_paren, LParen);
847193326Sed        ParenTypeId = true;
848193326Sed      } else {
849193326Sed        if (ParseCXXTypeSpecifierSeq(DS))
850193326Sed          DeclaratorInfo.setInvalidType(true);
851193326Sed        else {
852193326Sed          DeclaratorInfo.SetSourceRange(DS.getSourceRange());
853193326Sed          ParseDeclaratorInternal(DeclaratorInfo,
854193326Sed                                  &Parser::ParseDirectNewDeclarator);
855193326Sed        }
856193326Sed        ParenTypeId = false;
857193326Sed      }
858193326Sed    }
859193326Sed  } else {
860193326Sed    // A new-type-id is a simplified type-id, where essentially the
861193326Sed    // direct-declarator is replaced by a direct-new-declarator.
862193326Sed    if (ParseCXXTypeSpecifierSeq(DS))
863193326Sed      DeclaratorInfo.setInvalidType(true);
864193326Sed    else {
865193326Sed      DeclaratorInfo.SetSourceRange(DS.getSourceRange());
866193326Sed      ParseDeclaratorInternal(DeclaratorInfo,
867193326Sed                              &Parser::ParseDirectNewDeclarator);
868193326Sed    }
869193326Sed    ParenTypeId = false;
870193326Sed  }
871193326Sed  if (DeclaratorInfo.isInvalidType()) {
872193326Sed    SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
873193326Sed    return ExprError();
874193326Sed  }
875193326Sed
876193326Sed  ExprVector ConstructorArgs(Actions);
877193326Sed  SourceLocation ConstructorLParen, ConstructorRParen;
878193326Sed
879193326Sed  if (Tok.is(tok::l_paren)) {
880193326Sed    ConstructorLParen = ConsumeParen();
881193326Sed    if (Tok.isNot(tok::r_paren)) {
882193326Sed      CommaLocsTy CommaLocs;
883193326Sed      if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
884193326Sed        SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
885193326Sed        return ExprError();
886193326Sed      }
887193326Sed    }
888193326Sed    ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
889193326Sed    if (ConstructorRParen.isInvalid()) {
890193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
891193326Sed      return ExprError();
892193326Sed    }
893193326Sed  }
894193326Sed
895193326Sed  return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
896193326Sed                             move_arg(PlacementArgs), PlacementRParen,
897193326Sed                             ParenTypeId, DeclaratorInfo, ConstructorLParen,
898193326Sed                             move_arg(ConstructorArgs), ConstructorRParen);
899193326Sed}
900193326Sed
901193326Sed/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
902193326Sed/// passed to ParseDeclaratorInternal.
903193326Sed///
904193326Sed///        direct-new-declarator:
905193326Sed///                   '[' expression ']'
906193326Sed///                   direct-new-declarator '[' constant-expression ']'
907193326Sed///
908193326Sedvoid Parser::ParseDirectNewDeclarator(Declarator &D) {
909193326Sed  // Parse the array dimensions.
910193326Sed  bool first = true;
911193326Sed  while (Tok.is(tok::l_square)) {
912193326Sed    SourceLocation LLoc = ConsumeBracket();
913193326Sed    OwningExprResult Size(first ? ParseExpression()
914193326Sed                                : ParseConstantExpression());
915193326Sed    if (Size.isInvalid()) {
916193326Sed      // Recover
917193326Sed      SkipUntil(tok::r_square);
918193326Sed      return;
919193326Sed    }
920193326Sed    first = false;
921193326Sed
922193326Sed    SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
923193326Sed    D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
924193326Sed                                            Size.release(), LLoc),
925193326Sed                  RLoc);
926193326Sed
927193326Sed    if (RLoc.isInvalid())
928193326Sed      return;
929193326Sed  }
930193326Sed}
931193326Sed
932193326Sed/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
933193326Sed/// This ambiguity appears in the syntax of the C++ new operator.
934193326Sed///
935193326Sed///        new-expression:
936193326Sed///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
937193326Sed///                                     new-initializer[opt]
938193326Sed///
939193326Sed///        new-placement:
940193326Sed///                   '(' expression-list ')'
941193326Sed///
942193326Sedbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
943193326Sed                                         Declarator &D) {
944193326Sed  // The '(' was already consumed.
945193326Sed  if (isTypeIdInParens()) {
946193326Sed    ParseSpecifierQualifierList(D.getMutableDeclSpec());
947193326Sed    D.SetSourceRange(D.getDeclSpec().getSourceRange());
948193326Sed    ParseDeclarator(D);
949193326Sed    return D.isInvalidType();
950193326Sed  }
951193326Sed
952193326Sed  // It's not a type, it has to be an expression list.
953193326Sed  // Discard the comma locations - ActOnCXXNew has enough parameters.
954193326Sed  CommaLocsTy CommaLocs;
955193326Sed  return ParseExpressionList(PlacementArgs, CommaLocs);
956193326Sed}
957193326Sed
958193326Sed/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
959193326Sed/// to free memory allocated by new.
960193326Sed///
961193326Sed/// This method is called to parse the 'delete' expression after the optional
962193326Sed/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
963193326Sed/// and "Start" is its location.  Otherwise, "Start" is the location of the
964193326Sed/// 'delete' token.
965193326Sed///
966193326Sed///        delete-expression:
967193326Sed///                   '::'[opt] 'delete' cast-expression
968193326Sed///                   '::'[opt] 'delete' '[' ']' cast-expression
969193326SedParser::OwningExprResult
970193326SedParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
971193326Sed  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
972193326Sed  ConsumeToken(); // Consume 'delete'
973193326Sed
974193326Sed  // Array delete?
975193326Sed  bool ArrayDelete = false;
976193326Sed  if (Tok.is(tok::l_square)) {
977193326Sed    ArrayDelete = true;
978193326Sed    SourceLocation LHS = ConsumeBracket();
979193326Sed    SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
980193326Sed    if (RHS.isInvalid())
981193326Sed      return ExprError();
982193326Sed  }
983193326Sed
984193326Sed  OwningExprResult Operand(ParseCastExpression(false));
985193326Sed  if (Operand.isInvalid())
986193326Sed    return move(Operand);
987193326Sed
988193326Sed  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
989193326Sed}
990193326Sed
991193326Sedstatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind)
992193326Sed{
993193326Sed  switch(kind) {
994193326Sed  default: assert(false && "Not a known unary type trait.");
995193326Sed  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
996193326Sed  case tok::kw___has_nothrow_copy:        return UTT_HasNothrowCopy;
997193326Sed  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
998193326Sed  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
999193326Sed  case tok::kw___has_trivial_copy:        return UTT_HasTrivialCopy;
1000193326Sed  case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
1001193326Sed  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
1002193326Sed  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
1003193326Sed  case tok::kw___is_abstract:             return UTT_IsAbstract;
1004193326Sed  case tok::kw___is_class:                return UTT_IsClass;
1005193326Sed  case tok::kw___is_empty:                return UTT_IsEmpty;
1006193326Sed  case tok::kw___is_enum:                 return UTT_IsEnum;
1007193326Sed  case tok::kw___is_pod:                  return UTT_IsPOD;
1008193326Sed  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
1009193326Sed  case tok::kw___is_union:                return UTT_IsUnion;
1010193326Sed  }
1011193326Sed}
1012193326Sed
1013193326Sed/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
1014193326Sed/// pseudo-functions that allow implementation of the TR1/C++0x type traits
1015193326Sed/// templates.
1016193326Sed///
1017193326Sed///       primary-expression:
1018193326Sed/// [GNU]             unary-type-trait '(' type-id ')'
1019193326Sed///
1020193326SedParser::OwningExprResult Parser::ParseUnaryTypeTrait()
1021193326Sed{
1022193326Sed  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
1023193326Sed  SourceLocation Loc = ConsumeToken();
1024193326Sed
1025193326Sed  SourceLocation LParen = Tok.getLocation();
1026193326Sed  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
1027193326Sed    return ExprError();
1028193326Sed
1029193326Sed  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
1030193326Sed  // there will be cryptic errors about mismatched parentheses and missing
1031193326Sed  // specifiers.
1032193326Sed  TypeResult Ty = ParseTypeName();
1033193326Sed
1034193326Sed  SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
1035193326Sed
1036193326Sed  if (Ty.isInvalid())
1037193326Sed    return ExprError();
1038193326Sed
1039193326Sed  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
1040193326Sed}
1041193326Sed
1042193326Sed/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
1043193326Sed/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
1044193326Sed/// based on the context past the parens.
1045193326SedParser::OwningExprResult
1046193326SedParser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
1047193326Sed                                         TypeTy *&CastTy,
1048193326Sed                                         SourceLocation LParenLoc,
1049193326Sed                                         SourceLocation &RParenLoc) {
1050193326Sed  assert(getLang().CPlusPlus && "Should only be called for C++!");
1051193326Sed  assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
1052193326Sed  assert(isTypeIdInParens() && "Not a type-id!");
1053193326Sed
1054193326Sed  OwningExprResult Result(Actions, true);
1055193326Sed  CastTy = 0;
1056193326Sed
1057193326Sed  // We need to disambiguate a very ugly part of the C++ syntax:
1058193326Sed  //
1059193326Sed  // (T())x;  - type-id
1060193326Sed  // (T())*x; - type-id
1061193326Sed  // (T())/x; - expression
1062193326Sed  // (T());   - expression
1063193326Sed  //
1064193326Sed  // The bad news is that we cannot use the specialized tentative parser, since
1065193326Sed  // it can only verify that the thing inside the parens can be parsed as
1066193326Sed  // type-id, it is not useful for determining the context past the parens.
1067193326Sed  //
1068193326Sed  // The good news is that the parser can disambiguate this part without
1069193326Sed  // making any unnecessary Action calls.
1070193326Sed  //
1071193326Sed  // It uses a scheme similar to parsing inline methods. The parenthesized
1072193326Sed  // tokens are cached, the context that follows is determined (possibly by
1073193326Sed  // parsing a cast-expression), and then we re-introduce the cached tokens
1074193326Sed  // into the token stream and parse them appropriately.
1075193326Sed
1076193326Sed  ParenParseOption ParseAs;
1077193326Sed  CachedTokens Toks;
1078193326Sed
1079193326Sed  // Store the tokens of the parentheses. We will parse them after we determine
1080193326Sed  // the context that follows them.
1081193326Sed  if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) {
1082193326Sed    // We didn't find the ')' we expected.
1083193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1084193326Sed    return ExprError();
1085193326Sed  }
1086193326Sed
1087193326Sed  if (Tok.is(tok::l_brace)) {
1088193326Sed    ParseAs = CompoundLiteral;
1089193326Sed  } else {
1090193326Sed    bool NotCastExpr;
1091193326Sed    // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
1092193326Sed    if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
1093193326Sed      NotCastExpr = true;
1094193326Sed    } else {
1095193326Sed      // Try parsing the cast-expression that may follow.
1096193326Sed      // If it is not a cast-expression, NotCastExpr will be true and no token
1097193326Sed      // will be consumed.
1098193326Sed      Result = ParseCastExpression(false/*isUnaryExpression*/,
1099193326Sed                                   false/*isAddressofOperand*/,
1100193326Sed                                   NotCastExpr);
1101193326Sed    }
1102193326Sed
1103193326Sed    // If we parsed a cast-expression, it's really a type-id, otherwise it's
1104193326Sed    // an expression.
1105193326Sed    ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
1106193326Sed  }
1107193326Sed
1108193326Sed  // The current token should go after the cached tokens.
1109193326Sed  Toks.push_back(Tok);
1110193326Sed  // Re-enter the stored parenthesized tokens into the token stream, so we may
1111193326Sed  // parse them now.
1112193326Sed  PP.EnterTokenStream(Toks.data(), Toks.size(),
1113193326Sed                      true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
1114193326Sed  // Drop the current token and bring the first cached one. It's the same token
1115193326Sed  // as when we entered this function.
1116193326Sed  ConsumeAnyToken();
1117193326Sed
1118193326Sed  if (ParseAs >= CompoundLiteral) {
1119193326Sed    TypeResult Ty = ParseTypeName();
1120193326Sed
1121193326Sed    // Match the ')'.
1122193326Sed    if (Tok.is(tok::r_paren))
1123193326Sed      RParenLoc = ConsumeParen();
1124193326Sed    else
1125193326Sed      MatchRHSPunctuation(tok::r_paren, LParenLoc);
1126193326Sed
1127193326Sed    if (ParseAs == CompoundLiteral) {
1128193326Sed      ExprType = CompoundLiteral;
1129193326Sed      return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
1130193326Sed    }
1131193326Sed
1132193326Sed    // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
1133193326Sed    assert(ParseAs == CastExpr);
1134193326Sed
1135193326Sed    if (Ty.isInvalid())
1136193326Sed      return ExprError();
1137193326Sed
1138193326Sed    CastTy = Ty.get();
1139193326Sed
1140193326Sed    // Result is what ParseCastExpression returned earlier.
1141193326Sed    if (!Result.isInvalid())
1142193326Sed      Result = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc,move(Result));
1143193326Sed    return move(Result);
1144193326Sed  }
1145193326Sed
1146193326Sed  // Not a compound literal, and not followed by a cast-expression.
1147193326Sed  assert(ParseAs == SimpleExpr);
1148193326Sed
1149193326Sed  ExprType = SimpleExpr;
1150193326Sed  Result = ParseExpression();
1151193326Sed  if (!Result.isInvalid() && Tok.is(tok::r_paren))
1152193326Sed    Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
1153193326Sed
1154193326Sed  // Match the ')'.
1155193326Sed  if (Result.isInvalid()) {
1156193326Sed    SkipUntil(tok::r_paren);
1157193326Sed    return ExprError();
1158193326Sed  }
1159193326Sed
1160193326Sed  if (Tok.is(tok::r_paren))
1161193326Sed    RParenLoc = ConsumeParen();
1162193326Sed  else
1163193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1164193326Sed
1165193326Sed  return move(Result);
1166193326Sed}
1167