ParseExprCXX.cpp revision 194613
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 {
380194613Sed    // C++0x [expr.typeid]p3:
381194613Sed    //   When typeid is applied to an expression other than an lvalue of a
382194613Sed    //   polymorphic class type [...] The expression is an unevaluated
383194613Sed    //   operand (Clause 5).
384194613Sed    //
385194613Sed    // Note that we can't tell whether the expression is an lvalue of a
386194613Sed    // polymorphic class type until after we've parsed the expression, so
387194613Sed    // we treat the expression as an unevaluated operand and let semantic
388194613Sed    // analysis cope with case where the expression is not an unevaluated
389194613Sed    // operand.
390194613Sed    EnterUnevaluatedOperand Unevaluated(Actions);
391193326Sed    Result = ParseExpression();
392193326Sed
393193326Sed    // Match the ')'.
394193326Sed    if (Result.isInvalid())
395193326Sed      SkipUntil(tok::r_paren);
396193326Sed    else {
397193326Sed      MatchRHSPunctuation(tok::r_paren, LParenLoc);
398193326Sed
399193326Sed      Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
400193326Sed                                      Result.release(), RParenLoc);
401193326Sed    }
402193326Sed  }
403193326Sed
404193326Sed  return move(Result);
405193326Sed}
406193326Sed
407193326Sed/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
408193326Sed///
409193326Sed///       boolean-literal: [C++ 2.13.5]
410193326Sed///         'true'
411193326Sed///         'false'
412193326SedParser::OwningExprResult Parser::ParseCXXBoolLiteral() {
413193326Sed  tok::TokenKind Kind = Tok.getKind();
414193326Sed  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
415193326Sed}
416193326Sed
417193326Sed/// ParseThrowExpression - This handles the C++ throw expression.
418193326Sed///
419193326Sed///       throw-expression: [C++ 15]
420193326Sed///         'throw' assignment-expression[opt]
421193326SedParser::OwningExprResult Parser::ParseThrowExpression() {
422193326Sed  assert(Tok.is(tok::kw_throw) && "Not throw!");
423193326Sed  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
424193326Sed
425193326Sed  // If the current token isn't the start of an assignment-expression,
426193326Sed  // then the expression is not present.  This handles things like:
427193326Sed  //   "C ? throw : (void)42", which is crazy but legal.
428193326Sed  switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
429193326Sed  case tok::semi:
430193326Sed  case tok::r_paren:
431193326Sed  case tok::r_square:
432193326Sed  case tok::r_brace:
433193326Sed  case tok::colon:
434193326Sed  case tok::comma:
435193326Sed    return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
436193326Sed
437193326Sed  default:
438193326Sed    OwningExprResult Expr(ParseAssignmentExpression());
439193326Sed    if (Expr.isInvalid()) return move(Expr);
440193326Sed    return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
441193326Sed  }
442193326Sed}
443193326Sed
444193326Sed/// ParseCXXThis - This handles the C++ 'this' pointer.
445193326Sed///
446193326Sed/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
447193326Sed/// a non-lvalue expression whose value is the address of the object for which
448193326Sed/// the function is called.
449193326SedParser::OwningExprResult Parser::ParseCXXThis() {
450193326Sed  assert(Tok.is(tok::kw_this) && "Not 'this'!");
451193326Sed  SourceLocation ThisLoc = ConsumeToken();
452193326Sed  return Actions.ActOnCXXThis(ThisLoc);
453193326Sed}
454193326Sed
455193326Sed/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
456193326Sed/// Can be interpreted either as function-style casting ("int(x)")
457193326Sed/// or class type construction ("ClassType(x,y,z)")
458193326Sed/// or creation of a value-initialized type ("int()").
459193326Sed///
460193326Sed///       postfix-expression: [C++ 5.2p1]
461193326Sed///         simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
462193326Sed///         typename-specifier '(' expression-list[opt] ')'         [TODO]
463193326Sed///
464193326SedParser::OwningExprResult
465193326SedParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
466193326Sed  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
467193326Sed  TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
468193326Sed
469193326Sed  assert(Tok.is(tok::l_paren) && "Expected '('!");
470193326Sed  SourceLocation LParenLoc = ConsumeParen();
471193326Sed
472193326Sed  ExprVector Exprs(Actions);
473193326Sed  CommaLocsTy CommaLocs;
474193326Sed
475193326Sed  if (Tok.isNot(tok::r_paren)) {
476193326Sed    if (ParseExpressionList(Exprs, CommaLocs)) {
477193326Sed      SkipUntil(tok::r_paren);
478193326Sed      return ExprError();
479193326Sed    }
480193326Sed  }
481193326Sed
482193326Sed  // Match the ')'.
483193326Sed  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
484193326Sed
485193326Sed  assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
486193326Sed         "Unexpected number of commas!");
487193326Sed  return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
488193326Sed                                           LParenLoc, move_arg(Exprs),
489193326Sed                                           CommaLocs.data(), RParenLoc);
490193326Sed}
491193326Sed
492193326Sed/// ParseCXXCondition - if/switch/while/for condition expression.
493193326Sed///
494193326Sed///       condition:
495193326Sed///         expression
496193326Sed///         type-specifier-seq declarator '=' assignment-expression
497193326Sed/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
498193326Sed///             '=' assignment-expression
499193326Sed///
500193326SedParser::OwningExprResult Parser::ParseCXXCondition() {
501193326Sed  if (!isCXXConditionDeclaration())
502193326Sed    return ParseExpression(); // expression
503193326Sed
504193326Sed  SourceLocation StartLoc = Tok.getLocation();
505193326Sed
506193326Sed  // type-specifier-seq
507193326Sed  DeclSpec DS;
508193326Sed  ParseSpecifierQualifierList(DS);
509193326Sed
510193326Sed  // declarator
511193326Sed  Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
512193326Sed  ParseDeclarator(DeclaratorInfo);
513193326Sed
514193326Sed  // simple-asm-expr[opt]
515193326Sed  if (Tok.is(tok::kw_asm)) {
516193326Sed    SourceLocation Loc;
517193326Sed    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
518193326Sed    if (AsmLabel.isInvalid()) {
519193326Sed      SkipUntil(tok::semi);
520193326Sed      return ExprError();
521193326Sed    }
522193326Sed    DeclaratorInfo.setAsmLabel(AsmLabel.release());
523193326Sed    DeclaratorInfo.SetRangeEnd(Loc);
524193326Sed  }
525193326Sed
526193326Sed  // If attributes are present, parse them.
527193326Sed  if (Tok.is(tok::kw___attribute)) {
528193326Sed    SourceLocation Loc;
529193326Sed    AttributeList *AttrList = ParseAttributes(&Loc);
530193326Sed    DeclaratorInfo.AddAttributes(AttrList, Loc);
531193326Sed  }
532193326Sed
533193326Sed  // '=' assignment-expression
534193326Sed  if (Tok.isNot(tok::equal))
535193326Sed    return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator));
536193326Sed  SourceLocation EqualLoc = ConsumeToken();
537193326Sed  OwningExprResult AssignExpr(ParseAssignmentExpression());
538193326Sed  if (AssignExpr.isInvalid())
539193326Sed    return ExprError();
540193326Sed
541193326Sed  return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
542193326Sed                                                  DeclaratorInfo,EqualLoc,
543193326Sed                                                  move(AssignExpr));
544193326Sed}
545193326Sed
546193326Sed/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
547193326Sed/// This should only be called when the current token is known to be part of
548193326Sed/// simple-type-specifier.
549193326Sed///
550193326Sed///       simple-type-specifier:
551193326Sed///         '::'[opt] nested-name-specifier[opt] type-name
552193326Sed///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
553193326Sed///         char
554193326Sed///         wchar_t
555193326Sed///         bool
556193326Sed///         short
557193326Sed///         int
558193326Sed///         long
559193326Sed///         signed
560193326Sed///         unsigned
561193326Sed///         float
562193326Sed///         double
563193326Sed///         void
564193326Sed/// [GNU]   typeof-specifier
565193326Sed/// [C++0x] auto               [TODO]
566193326Sed///
567193326Sed///       type-name:
568193326Sed///         class-name
569193326Sed///         enum-name
570193326Sed///         typedef-name
571193326Sed///
572193326Sedvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
573193326Sed  DS.SetRangeStart(Tok.getLocation());
574193326Sed  const char *PrevSpec;
575193326Sed  SourceLocation Loc = Tok.getLocation();
576193326Sed
577193326Sed  switch (Tok.getKind()) {
578193326Sed  case tok::identifier:   // foo::bar
579193326Sed  case tok::coloncolon:   // ::foo::bar
580193326Sed    assert(0 && "Annotation token should already be formed!");
581193326Sed  default:
582193326Sed    assert(0 && "Not a simple-type-specifier token!");
583193326Sed    abort();
584193326Sed
585193326Sed  // type-name
586193326Sed  case tok::annot_typename: {
587193326Sed    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
588193326Sed                       Tok.getAnnotationValue());
589193326Sed    break;
590193326Sed  }
591193326Sed
592193326Sed  // builtin types
593193326Sed  case tok::kw_short:
594193326Sed    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
595193326Sed    break;
596193326Sed  case tok::kw_long:
597193326Sed    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
598193326Sed    break;
599193326Sed  case tok::kw_signed:
600193326Sed    DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
601193326Sed    break;
602193326Sed  case tok::kw_unsigned:
603193326Sed    DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
604193326Sed    break;
605193326Sed  case tok::kw_void:
606193326Sed    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
607193326Sed    break;
608193326Sed  case tok::kw_char:
609193326Sed    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
610193326Sed    break;
611193326Sed  case tok::kw_int:
612193326Sed    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
613193326Sed    break;
614193326Sed  case tok::kw_float:
615193326Sed    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
616193326Sed    break;
617193326Sed  case tok::kw_double:
618193326Sed    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
619193326Sed    break;
620193326Sed  case tok::kw_wchar_t:
621193326Sed    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
622193326Sed    break;
623193326Sed  case tok::kw_bool:
624193326Sed    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
625193326Sed    break;
626193326Sed
627193326Sed  // GNU typeof support.
628193326Sed  case tok::kw_typeof:
629193326Sed    ParseTypeofSpecifier(DS);
630193326Sed    DS.Finish(Diags, PP);
631193326Sed    return;
632193326Sed  }
633193326Sed  if (Tok.is(tok::annot_typename))
634193326Sed    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
635193326Sed  else
636193326Sed    DS.SetRangeEnd(Tok.getLocation());
637193326Sed  ConsumeToken();
638193326Sed  DS.Finish(Diags, PP);
639193326Sed}
640193326Sed
641193326Sed/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
642193326Sed/// [dcl.name]), which is a non-empty sequence of type-specifiers,
643193326Sed/// e.g., "const short int". Note that the DeclSpec is *not* finished
644193326Sed/// by parsing the type-specifier-seq, because these sequences are
645193326Sed/// typically followed by some form of declarator. Returns true and
646193326Sed/// emits diagnostics if this is not a type-specifier-seq, false
647193326Sed/// otherwise.
648193326Sed///
649193326Sed///   type-specifier-seq: [C++ 8.1]
650193326Sed///     type-specifier type-specifier-seq[opt]
651193326Sed///
652193326Sedbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
653193326Sed  DS.SetRangeStart(Tok.getLocation());
654193326Sed  const char *PrevSpec = 0;
655193326Sed  int isInvalid = 0;
656193326Sed
657193326Sed  // Parse one or more of the type specifiers.
658193326Sed  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) {
659193326Sed    Diag(Tok, diag::err_operator_missing_type_specifier);
660193326Sed    return true;
661193326Sed  }
662193326Sed
663193326Sed  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) ;
664193326Sed
665193326Sed  return false;
666193326Sed}
667193326Sed
668193326Sed/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded
669193326Sed/// operator name (C++ [over.oper]). If successful, returns the
670193326Sed/// predefined identifier that corresponds to that overloaded
671193326Sed/// operator. Otherwise, returns NULL and does not consume any tokens.
672193326Sed///
673193326Sed///       operator-function-id: [C++ 13.5]
674193326Sed///         'operator' operator
675193326Sed///
676193326Sed/// operator: one of
677193326Sed///            new   delete  new[]   delete[]
678193326Sed///            +     -    *  /    %  ^    &   |   ~
679193326Sed///            !     =    <  >    += -=   *=  /=  %=
680193326Sed///            ^=    &=   |= <<   >> >>= <<=  ==  !=
681193326Sed///            <=    >=   && ||   ++ --   ,   ->* ->
682193326Sed///            ()    []
683193326SedOverloadedOperatorKind
684193326SedParser::TryParseOperatorFunctionId(SourceLocation *EndLoc) {
685193326Sed  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
686193326Sed  SourceLocation Loc;
687193326Sed
688193326Sed  OverloadedOperatorKind Op = OO_None;
689193326Sed  switch (NextToken().getKind()) {
690193326Sed  case tok::kw_new:
691193326Sed    ConsumeToken(); // 'operator'
692193326Sed    Loc = ConsumeToken(); // 'new'
693193326Sed    if (Tok.is(tok::l_square)) {
694193326Sed      ConsumeBracket(); // '['
695193326Sed      Loc = Tok.getLocation();
696193326Sed      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
697193326Sed      Op = OO_Array_New;
698193326Sed    } else {
699193326Sed      Op = OO_New;
700193326Sed    }
701193326Sed    if (EndLoc)
702193326Sed      *EndLoc = Loc;
703193326Sed    return Op;
704193326Sed
705193326Sed  case tok::kw_delete:
706193326Sed    ConsumeToken(); // 'operator'
707193326Sed    Loc = ConsumeToken(); // 'delete'
708193326Sed    if (Tok.is(tok::l_square)) {
709193326Sed      ConsumeBracket(); // '['
710193326Sed      Loc = Tok.getLocation();
711193326Sed      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
712193326Sed      Op = OO_Array_Delete;
713193326Sed    } else {
714193326Sed      Op = OO_Delete;
715193326Sed    }
716193326Sed    if (EndLoc)
717193326Sed      *EndLoc = Loc;
718193326Sed    return Op;
719193326Sed
720193326Sed#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)  \
721193326Sed    case tok::Token:  Op = OO_##Name; break;
722193326Sed#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
723193326Sed#include "clang/Basic/OperatorKinds.def"
724193326Sed
725193326Sed  case tok::l_paren:
726193326Sed    ConsumeToken(); // 'operator'
727193326Sed    ConsumeParen(); // '('
728193326Sed    Loc = Tok.getLocation();
729193326Sed    ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
730193326Sed    if (EndLoc)
731193326Sed      *EndLoc = Loc;
732193326Sed    return OO_Call;
733193326Sed
734193326Sed  case tok::l_square:
735193326Sed    ConsumeToken(); // 'operator'
736193326Sed    ConsumeBracket(); // '['
737193326Sed    Loc = Tok.getLocation();
738193326Sed    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
739193326Sed    if (EndLoc)
740193326Sed      *EndLoc = Loc;
741193326Sed    return OO_Subscript;
742193326Sed
743193326Sed  default:
744193326Sed    return OO_None;
745193326Sed  }
746193326Sed
747193326Sed  ConsumeToken(); // 'operator'
748193326Sed  Loc = ConsumeAnyToken(); // the operator itself
749193326Sed  if (EndLoc)
750193326Sed    *EndLoc = Loc;
751193326Sed  return Op;
752193326Sed}
753193326Sed
754193326Sed/// ParseConversionFunctionId - Parse a C++ conversion-function-id,
755193326Sed/// which expresses the name of a user-defined conversion operator
756193326Sed/// (C++ [class.conv.fct]p1). Returns the type that this operator is
757193326Sed/// specifying a conversion for, or NULL if there was an error.
758193326Sed///
759193326Sed///        conversion-function-id: [C++ 12.3.2]
760193326Sed///                   operator conversion-type-id
761193326Sed///
762193326Sed///        conversion-type-id:
763193326Sed///                   type-specifier-seq conversion-declarator[opt]
764193326Sed///
765193326Sed///        conversion-declarator:
766193326Sed///                   ptr-operator conversion-declarator[opt]
767193326SedParser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) {
768193326Sed  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
769193326Sed  ConsumeToken(); // 'operator'
770193326Sed
771193326Sed  // Parse the type-specifier-seq.
772193326Sed  DeclSpec DS;
773193326Sed  if (ParseCXXTypeSpecifierSeq(DS))
774193326Sed    return 0;
775193326Sed
776193326Sed  // Parse the conversion-declarator, which is merely a sequence of
777193326Sed  // ptr-operators.
778193326Sed  Declarator D(DS, Declarator::TypeNameContext);
779193326Sed  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
780193326Sed  if (EndLoc)
781193326Sed    *EndLoc = D.getSourceRange().getEnd();
782193326Sed
783193326Sed  // Finish up the type.
784193326Sed  Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
785193326Sed  if (Result.isInvalid())
786193326Sed    return 0;
787193326Sed  else
788193326Sed    return Result.get();
789193326Sed}
790193326Sed
791193326Sed/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
792193326Sed/// memory in a typesafe manner and call constructors.
793193326Sed///
794193326Sed/// This method is called to parse the new expression after the optional :: has
795193326Sed/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
796193326Sed/// is its location.  Otherwise, "Start" is the location of the 'new' token.
797193326Sed///
798193326Sed///        new-expression:
799193326Sed///                   '::'[opt] 'new' new-placement[opt] new-type-id
800193326Sed///                                     new-initializer[opt]
801193326Sed///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
802193326Sed///                                     new-initializer[opt]
803193326Sed///
804193326Sed///        new-placement:
805193326Sed///                   '(' expression-list ')'
806193326Sed///
807193326Sed///        new-type-id:
808193326Sed///                   type-specifier-seq new-declarator[opt]
809193326Sed///
810193326Sed///        new-declarator:
811193326Sed///                   ptr-operator new-declarator[opt]
812193326Sed///                   direct-new-declarator
813193326Sed///
814193326Sed///        new-initializer:
815193326Sed///                   '(' expression-list[opt] ')'
816193326Sed/// [C++0x]           braced-init-list                                   [TODO]
817193326Sed///
818193326SedParser::OwningExprResult
819193326SedParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
820193326Sed  assert(Tok.is(tok::kw_new) && "expected 'new' token");
821193326Sed  ConsumeToken();   // Consume 'new'
822193326Sed
823193326Sed  // A '(' now can be a new-placement or the '(' wrapping the type-id in the
824193326Sed  // second form of new-expression. It can't be a new-type-id.
825193326Sed
826193326Sed  ExprVector PlacementArgs(Actions);
827193326Sed  SourceLocation PlacementLParen, PlacementRParen;
828193326Sed
829193326Sed  bool ParenTypeId;
830193326Sed  DeclSpec DS;
831193326Sed  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
832193326Sed  if (Tok.is(tok::l_paren)) {
833193326Sed    // If it turns out to be a placement, we change the type location.
834193326Sed    PlacementLParen = ConsumeParen();
835193326Sed    if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
836193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
837193326Sed      return ExprError();
838193326Sed    }
839193326Sed
840193326Sed    PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
841193326Sed    if (PlacementRParen.isInvalid()) {
842193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
843193326Sed      return ExprError();
844193326Sed    }
845193326Sed
846193326Sed    if (PlacementArgs.empty()) {
847193326Sed      // Reset the placement locations. There was no placement.
848193326Sed      PlacementLParen = PlacementRParen = SourceLocation();
849193326Sed      ParenTypeId = true;
850193326Sed    } else {
851193326Sed      // We still need the type.
852193326Sed      if (Tok.is(tok::l_paren)) {
853193326Sed        SourceLocation LParen = ConsumeParen();
854193326Sed        ParseSpecifierQualifierList(DS);
855193326Sed        DeclaratorInfo.SetSourceRange(DS.getSourceRange());
856193326Sed        ParseDeclarator(DeclaratorInfo);
857193326Sed        MatchRHSPunctuation(tok::r_paren, LParen);
858193326Sed        ParenTypeId = true;
859193326Sed      } else {
860193326Sed        if (ParseCXXTypeSpecifierSeq(DS))
861193326Sed          DeclaratorInfo.setInvalidType(true);
862193326Sed        else {
863193326Sed          DeclaratorInfo.SetSourceRange(DS.getSourceRange());
864193326Sed          ParseDeclaratorInternal(DeclaratorInfo,
865193326Sed                                  &Parser::ParseDirectNewDeclarator);
866193326Sed        }
867193326Sed        ParenTypeId = false;
868193326Sed      }
869193326Sed    }
870193326Sed  } else {
871193326Sed    // A new-type-id is a simplified type-id, where essentially the
872193326Sed    // direct-declarator is replaced by a direct-new-declarator.
873193326Sed    if (ParseCXXTypeSpecifierSeq(DS))
874193326Sed      DeclaratorInfo.setInvalidType(true);
875193326Sed    else {
876193326Sed      DeclaratorInfo.SetSourceRange(DS.getSourceRange());
877193326Sed      ParseDeclaratorInternal(DeclaratorInfo,
878193326Sed                              &Parser::ParseDirectNewDeclarator);
879193326Sed    }
880193326Sed    ParenTypeId = false;
881193326Sed  }
882193326Sed  if (DeclaratorInfo.isInvalidType()) {
883193326Sed    SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
884193326Sed    return ExprError();
885193326Sed  }
886193326Sed
887193326Sed  ExprVector ConstructorArgs(Actions);
888193326Sed  SourceLocation ConstructorLParen, ConstructorRParen;
889193326Sed
890193326Sed  if (Tok.is(tok::l_paren)) {
891193326Sed    ConstructorLParen = ConsumeParen();
892193326Sed    if (Tok.isNot(tok::r_paren)) {
893193326Sed      CommaLocsTy CommaLocs;
894193326Sed      if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
895193326Sed        SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
896193326Sed        return ExprError();
897193326Sed      }
898193326Sed    }
899193326Sed    ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
900193326Sed    if (ConstructorRParen.isInvalid()) {
901193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
902193326Sed      return ExprError();
903193326Sed    }
904193326Sed  }
905193326Sed
906193326Sed  return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
907193326Sed                             move_arg(PlacementArgs), PlacementRParen,
908193326Sed                             ParenTypeId, DeclaratorInfo, ConstructorLParen,
909193326Sed                             move_arg(ConstructorArgs), ConstructorRParen);
910193326Sed}
911193326Sed
912193326Sed/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
913193326Sed/// passed to ParseDeclaratorInternal.
914193326Sed///
915193326Sed///        direct-new-declarator:
916193326Sed///                   '[' expression ']'
917193326Sed///                   direct-new-declarator '[' constant-expression ']'
918193326Sed///
919193326Sedvoid Parser::ParseDirectNewDeclarator(Declarator &D) {
920193326Sed  // Parse the array dimensions.
921193326Sed  bool first = true;
922193326Sed  while (Tok.is(tok::l_square)) {
923193326Sed    SourceLocation LLoc = ConsumeBracket();
924193326Sed    OwningExprResult Size(first ? ParseExpression()
925193326Sed                                : ParseConstantExpression());
926193326Sed    if (Size.isInvalid()) {
927193326Sed      // Recover
928193326Sed      SkipUntil(tok::r_square);
929193326Sed      return;
930193326Sed    }
931193326Sed    first = false;
932193326Sed
933193326Sed    SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
934193326Sed    D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
935193326Sed                                            Size.release(), LLoc),
936193326Sed                  RLoc);
937193326Sed
938193326Sed    if (RLoc.isInvalid())
939193326Sed      return;
940193326Sed  }
941193326Sed}
942193326Sed
943193326Sed/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
944193326Sed/// This ambiguity appears in the syntax of the C++ new operator.
945193326Sed///
946193326Sed///        new-expression:
947193326Sed///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
948193326Sed///                                     new-initializer[opt]
949193326Sed///
950193326Sed///        new-placement:
951193326Sed///                   '(' expression-list ')'
952193326Sed///
953193326Sedbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
954193326Sed                                         Declarator &D) {
955193326Sed  // The '(' was already consumed.
956193326Sed  if (isTypeIdInParens()) {
957193326Sed    ParseSpecifierQualifierList(D.getMutableDeclSpec());
958193326Sed    D.SetSourceRange(D.getDeclSpec().getSourceRange());
959193326Sed    ParseDeclarator(D);
960193326Sed    return D.isInvalidType();
961193326Sed  }
962193326Sed
963193326Sed  // It's not a type, it has to be an expression list.
964193326Sed  // Discard the comma locations - ActOnCXXNew has enough parameters.
965193326Sed  CommaLocsTy CommaLocs;
966193326Sed  return ParseExpressionList(PlacementArgs, CommaLocs);
967193326Sed}
968193326Sed
969193326Sed/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
970193326Sed/// to free memory allocated by new.
971193326Sed///
972193326Sed/// This method is called to parse the 'delete' expression after the optional
973193326Sed/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
974193326Sed/// and "Start" is its location.  Otherwise, "Start" is the location of the
975193326Sed/// 'delete' token.
976193326Sed///
977193326Sed///        delete-expression:
978193326Sed///                   '::'[opt] 'delete' cast-expression
979193326Sed///                   '::'[opt] 'delete' '[' ']' cast-expression
980193326SedParser::OwningExprResult
981193326SedParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
982193326Sed  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
983193326Sed  ConsumeToken(); // Consume 'delete'
984193326Sed
985193326Sed  // Array delete?
986193326Sed  bool ArrayDelete = false;
987193326Sed  if (Tok.is(tok::l_square)) {
988193326Sed    ArrayDelete = true;
989193326Sed    SourceLocation LHS = ConsumeBracket();
990193326Sed    SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
991193326Sed    if (RHS.isInvalid())
992193326Sed      return ExprError();
993193326Sed  }
994193326Sed
995193326Sed  OwningExprResult Operand(ParseCastExpression(false));
996193326Sed  if (Operand.isInvalid())
997193326Sed    return move(Operand);
998193326Sed
999193326Sed  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
1000193326Sed}
1001193326Sed
1002193326Sedstatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind)
1003193326Sed{
1004193326Sed  switch(kind) {
1005193326Sed  default: assert(false && "Not a known unary type trait.");
1006193326Sed  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
1007193326Sed  case tok::kw___has_nothrow_copy:        return UTT_HasNothrowCopy;
1008193326Sed  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
1009193326Sed  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
1010193326Sed  case tok::kw___has_trivial_copy:        return UTT_HasTrivialCopy;
1011193326Sed  case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
1012193326Sed  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
1013193326Sed  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
1014193326Sed  case tok::kw___is_abstract:             return UTT_IsAbstract;
1015193326Sed  case tok::kw___is_class:                return UTT_IsClass;
1016193326Sed  case tok::kw___is_empty:                return UTT_IsEmpty;
1017193326Sed  case tok::kw___is_enum:                 return UTT_IsEnum;
1018193326Sed  case tok::kw___is_pod:                  return UTT_IsPOD;
1019193326Sed  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
1020193326Sed  case tok::kw___is_union:                return UTT_IsUnion;
1021193326Sed  }
1022193326Sed}
1023193326Sed
1024193326Sed/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
1025193326Sed/// pseudo-functions that allow implementation of the TR1/C++0x type traits
1026193326Sed/// templates.
1027193326Sed///
1028193326Sed///       primary-expression:
1029193326Sed/// [GNU]             unary-type-trait '(' type-id ')'
1030193326Sed///
1031193326SedParser::OwningExprResult Parser::ParseUnaryTypeTrait()
1032193326Sed{
1033193326Sed  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
1034193326Sed  SourceLocation Loc = ConsumeToken();
1035193326Sed
1036193326Sed  SourceLocation LParen = Tok.getLocation();
1037193326Sed  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
1038193326Sed    return ExprError();
1039193326Sed
1040193326Sed  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
1041193326Sed  // there will be cryptic errors about mismatched parentheses and missing
1042193326Sed  // specifiers.
1043193326Sed  TypeResult Ty = ParseTypeName();
1044193326Sed
1045193326Sed  SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
1046193326Sed
1047193326Sed  if (Ty.isInvalid())
1048193326Sed    return ExprError();
1049193326Sed
1050193326Sed  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
1051193326Sed}
1052193326Sed
1053193326Sed/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
1054193326Sed/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
1055193326Sed/// based on the context past the parens.
1056193326SedParser::OwningExprResult
1057193326SedParser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
1058193326Sed                                         TypeTy *&CastTy,
1059193326Sed                                         SourceLocation LParenLoc,
1060193326Sed                                         SourceLocation &RParenLoc) {
1061193326Sed  assert(getLang().CPlusPlus && "Should only be called for C++!");
1062193326Sed  assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
1063193326Sed  assert(isTypeIdInParens() && "Not a type-id!");
1064193326Sed
1065193326Sed  OwningExprResult Result(Actions, true);
1066193326Sed  CastTy = 0;
1067193326Sed
1068193326Sed  // We need to disambiguate a very ugly part of the C++ syntax:
1069193326Sed  //
1070193326Sed  // (T())x;  - type-id
1071193326Sed  // (T())*x; - type-id
1072193326Sed  // (T())/x; - expression
1073193326Sed  // (T());   - expression
1074193326Sed  //
1075193326Sed  // The bad news is that we cannot use the specialized tentative parser, since
1076193326Sed  // it can only verify that the thing inside the parens can be parsed as
1077193326Sed  // type-id, it is not useful for determining the context past the parens.
1078193326Sed  //
1079193326Sed  // The good news is that the parser can disambiguate this part without
1080193326Sed  // making any unnecessary Action calls.
1081193326Sed  //
1082193326Sed  // It uses a scheme similar to parsing inline methods. The parenthesized
1083193326Sed  // tokens are cached, the context that follows is determined (possibly by
1084193326Sed  // parsing a cast-expression), and then we re-introduce the cached tokens
1085193326Sed  // into the token stream and parse them appropriately.
1086193326Sed
1087193326Sed  ParenParseOption ParseAs;
1088193326Sed  CachedTokens Toks;
1089193326Sed
1090193326Sed  // Store the tokens of the parentheses. We will parse them after we determine
1091193326Sed  // the context that follows them.
1092193326Sed  if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) {
1093193326Sed    // We didn't find the ')' we expected.
1094193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1095193326Sed    return ExprError();
1096193326Sed  }
1097193326Sed
1098193326Sed  if (Tok.is(tok::l_brace)) {
1099193326Sed    ParseAs = CompoundLiteral;
1100193326Sed  } else {
1101193326Sed    bool NotCastExpr;
1102193326Sed    // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
1103193326Sed    if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
1104193326Sed      NotCastExpr = true;
1105193326Sed    } else {
1106193326Sed      // Try parsing the cast-expression that may follow.
1107193326Sed      // If it is not a cast-expression, NotCastExpr will be true and no token
1108193326Sed      // will be consumed.
1109193326Sed      Result = ParseCastExpression(false/*isUnaryExpression*/,
1110193326Sed                                   false/*isAddressofOperand*/,
1111193326Sed                                   NotCastExpr);
1112193326Sed    }
1113193326Sed
1114193326Sed    // If we parsed a cast-expression, it's really a type-id, otherwise it's
1115193326Sed    // an expression.
1116193326Sed    ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
1117193326Sed  }
1118193326Sed
1119193326Sed  // The current token should go after the cached tokens.
1120193326Sed  Toks.push_back(Tok);
1121193326Sed  // Re-enter the stored parenthesized tokens into the token stream, so we may
1122193326Sed  // parse them now.
1123193326Sed  PP.EnterTokenStream(Toks.data(), Toks.size(),
1124193326Sed                      true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
1125193326Sed  // Drop the current token and bring the first cached one. It's the same token
1126193326Sed  // as when we entered this function.
1127193326Sed  ConsumeAnyToken();
1128193326Sed
1129193326Sed  if (ParseAs >= CompoundLiteral) {
1130193326Sed    TypeResult Ty = ParseTypeName();
1131193326Sed
1132193326Sed    // Match the ')'.
1133193326Sed    if (Tok.is(tok::r_paren))
1134193326Sed      RParenLoc = ConsumeParen();
1135193326Sed    else
1136193326Sed      MatchRHSPunctuation(tok::r_paren, LParenLoc);
1137193326Sed
1138193326Sed    if (ParseAs == CompoundLiteral) {
1139193326Sed      ExprType = CompoundLiteral;
1140193326Sed      return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
1141193326Sed    }
1142193326Sed
1143193326Sed    // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
1144193326Sed    assert(ParseAs == CastExpr);
1145193326Sed
1146193326Sed    if (Ty.isInvalid())
1147193326Sed      return ExprError();
1148193326Sed
1149193326Sed    CastTy = Ty.get();
1150193326Sed
1151193326Sed    // Result is what ParseCastExpression returned earlier.
1152193326Sed    if (!Result.isInvalid())
1153193326Sed      Result = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc,move(Result));
1154193326Sed    return move(Result);
1155193326Sed  }
1156193326Sed
1157193326Sed  // Not a compound literal, and not followed by a cast-expression.
1158193326Sed  assert(ParseAs == SimpleExpr);
1159193326Sed
1160193326Sed  ExprType = SimpleExpr;
1161193326Sed  Result = ParseExpression();
1162193326Sed  if (!Result.isInvalid() && Tok.is(tok::r_paren))
1163193326Sed    Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
1164193326Sed
1165193326Sed  // Match the ')'.
1166193326Sed  if (Result.isInvalid()) {
1167193326Sed    SkipUntil(tok::r_paren);
1168193326Sed    return ExprError();
1169193326Sed  }
1170193326Sed
1171193326Sed  if (Tok.is(tok::r_paren))
1172193326Sed    RParenLoc = ConsumeParen();
1173193326Sed  else
1174193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1175193326Sed
1176193326Sed  return move(Result);
1177193326Sed}
1178