ParseExprCXX.cpp revision 204643
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"
17199482Srdivacky#include "clang/Parse/Template.h"
18198893Srdivacky#include "llvm/Support/ErrorHandling.h"
19198893Srdivacky
20193326Sedusing namespace clang;
21193326Sed
22198092Srdivacky/// \brief Parse global scope or nested-name-specifier if present.
23193326Sed///
24198092Srdivacky/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
25198092Srdivacky/// may be preceded by '::'). Note that this routine will not parse ::new or
26198092Srdivacky/// ::delete; it will just leave them in the token stream.
27198092Srdivacky///
28193326Sed///       '::'[opt] nested-name-specifier
29193326Sed///       '::'
30193326Sed///
31193326Sed///       nested-name-specifier:
32193326Sed///         type-name '::'
33193326Sed///         namespace-name '::'
34193326Sed///         nested-name-specifier identifier '::'
35198092Srdivacky///         nested-name-specifier 'template'[opt] simple-template-id '::'
36193326Sed///
37198092Srdivacky///
38198092Srdivacky/// \param SS the scope specifier that will be set to the parsed
39198092Srdivacky/// nested-name-specifier (or empty)
40198092Srdivacky///
41198092Srdivacky/// \param ObjectType if this nested-name-specifier is being parsed following
42198092Srdivacky/// the "." or "->" of a member access expression, this parameter provides the
43198092Srdivacky/// type of the object whose members are being accessed.
44198092Srdivacky///
45198092Srdivacky/// \param EnteringContext whether we will be entering into the context of
46198092Srdivacky/// the nested-name-specifier after parsing it.
47198092Srdivacky///
48204643Srdivacky/// \param MayBePseudoDestructor When non-NULL, points to a flag that
49204643Srdivacky/// indicates whether this nested-name-specifier may be part of a
50204643Srdivacky/// pseudo-destructor name. In this case, the flag will be set false
51204643Srdivacky/// if we don't actually end up parsing a destructor name. Moreorover,
52204643Srdivacky/// if we do end up determining that we are parsing a destructor name,
53204643Srdivacky/// the last component of the nested-name-specifier is not parsed as
54204643Srdivacky/// part of the scope specifier.
55204643Srdivacky
56204643Srdivacky/// member access expression, e.g., the \p T:: in \p p->T::m.
57204643Srdivacky///
58204643Srdivacky/// \returns true if there was an error parsing a scope specifier
59198092Srdivackybool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
60198092Srdivacky                                            Action::TypeTy *ObjectType,
61204643Srdivacky                                            bool EnteringContext,
62204643Srdivacky                                            bool *MayBePseudoDestructor) {
63193326Sed  assert(getLang().CPlusPlus &&
64193326Sed         "Call sites of this function should be guarded by checking for C++");
65193326Sed
66193326Sed  if (Tok.is(tok::annot_cxxscope)) {
67193326Sed    SS.setScopeRep(Tok.getAnnotationValue());
68193326Sed    SS.setRange(Tok.getAnnotationRange());
69193326Sed    ConsumeToken();
70204643Srdivacky    return false;
71193326Sed  }
72193326Sed
73193326Sed  bool HasScopeSpecifier = false;
74193326Sed
75193326Sed  if (Tok.is(tok::coloncolon)) {
76193326Sed    // ::new and ::delete aren't nested-name-specifiers.
77193326Sed    tok::TokenKind NextKind = NextToken().getKind();
78193326Sed    if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
79193326Sed      return false;
80198092Srdivacky
81193326Sed    // '::' - Global scope qualifier.
82193326Sed    SourceLocation CCLoc = ConsumeToken();
83193326Sed    SS.setBeginLoc(CCLoc);
84193326Sed    SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
85193326Sed    SS.setEndLoc(CCLoc);
86193326Sed    HasScopeSpecifier = true;
87193326Sed  }
88193326Sed
89204643Srdivacky  bool CheckForDestructor = false;
90204643Srdivacky  if (MayBePseudoDestructor && *MayBePseudoDestructor) {
91204643Srdivacky    CheckForDestructor = true;
92204643Srdivacky    *MayBePseudoDestructor = false;
93204643Srdivacky  }
94204643Srdivacky
95193326Sed  while (true) {
96198092Srdivacky    if (HasScopeSpecifier) {
97198092Srdivacky      // C++ [basic.lookup.classref]p5:
98198092Srdivacky      //   If the qualified-id has the form
99198092Srdivacky      //
100198092Srdivacky      //       ::class-name-or-namespace-name::...
101198092Srdivacky      //
102198092Srdivacky      //   the class-name-or-namespace-name is looked up in global scope as a
103198092Srdivacky      //   class-name or namespace-name.
104198092Srdivacky      //
105198092Srdivacky      // To implement this, we clear out the object type as soon as we've
106198092Srdivacky      // seen a leading '::' or part of a nested-name-specifier.
107198092Srdivacky      ObjectType = 0;
108198092Srdivacky
109198092Srdivacky      if (Tok.is(tok::code_completion)) {
110198092Srdivacky        // Code completion for a nested-name-specifier, where the code
111198092Srdivacky        // code completion token follows the '::'.
112198092Srdivacky        Actions.CodeCompleteQualifiedId(CurScope, SS, EnteringContext);
113198092Srdivacky        ConsumeToken();
114198092Srdivacky      }
115198092Srdivacky    }
116198092Srdivacky
117193326Sed    // nested-name-specifier:
118195099Sed    //   nested-name-specifier 'template'[opt] simple-template-id '::'
119195099Sed
120195099Sed    // Parse the optional 'template' keyword, then make sure we have
121195099Sed    // 'identifier <' after it.
122195099Sed    if (Tok.is(tok::kw_template)) {
123198092Srdivacky      // If we don't have a scope specifier or an object type, this isn't a
124198092Srdivacky      // nested-name-specifier, since they aren't allowed to start with
125198092Srdivacky      // 'template'.
126198092Srdivacky      if (!HasScopeSpecifier && !ObjectType)
127198092Srdivacky        break;
128198092Srdivacky
129199482Srdivacky      TentativeParsingAction TPA(*this);
130195099Sed      SourceLocation TemplateKWLoc = ConsumeToken();
131198893Srdivacky
132198893Srdivacky      UnqualifiedId TemplateName;
133198893Srdivacky      if (Tok.is(tok::identifier)) {
134199482Srdivacky        // Consume the identifier.
135198893Srdivacky        TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
136198893Srdivacky        ConsumeToken();
137198893Srdivacky      } else if (Tok.is(tok::kw_operator)) {
138198893Srdivacky        if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType,
139199482Srdivacky                                       TemplateName)) {
140199482Srdivacky          TPA.Commit();
141198893Srdivacky          break;
142199482Srdivacky        }
143198893Srdivacky
144199990Srdivacky        if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId &&
145199990Srdivacky            TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) {
146198893Srdivacky          Diag(TemplateName.getSourceRange().getBegin(),
147198893Srdivacky               diag::err_id_after_template_in_nested_name_spec)
148198893Srdivacky            << TemplateName.getSourceRange();
149199482Srdivacky          TPA.Commit();
150198893Srdivacky          break;
151198893Srdivacky        }
152198893Srdivacky      } else {
153199482Srdivacky        TPA.Revert();
154195099Sed        break;
155193326Sed      }
156198092Srdivacky
157199482Srdivacky      // If the next token is not '<', we have a qualified-id that refers
158199482Srdivacky      // to a template name, such as T::template apply, but is not a
159199482Srdivacky      // template-id.
160199482Srdivacky      if (Tok.isNot(tok::less)) {
161199482Srdivacky        TPA.Revert();
162199482Srdivacky        break;
163199482Srdivacky      }
164199482Srdivacky
165199482Srdivacky      // Commit to parsing the template-id.
166199482Srdivacky      TPA.Commit();
167198092Srdivacky      TemplateTy Template
168198893Srdivacky        = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, TemplateName,
169199990Srdivacky                                             ObjectType, EnteringContext);
170198092Srdivacky      if (!Template)
171204643Srdivacky        return true;
172195099Sed      if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
173198893Srdivacky                                  &SS, TemplateName, TemplateKWLoc, false))
174204643Srdivacky        return true;
175198092Srdivacky
176193326Sed      continue;
177193326Sed    }
178198092Srdivacky
179193326Sed    if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
180198092Srdivacky      // We have
181193326Sed      //
182193326Sed      //   simple-template-id '::'
183193326Sed      //
184193326Sed      // So we need to check whether the simple-template-id is of the
185193326Sed      // right kind (it should name a type or be dependent), and then
186193326Sed      // convert it into a type within the nested-name-specifier.
187198092Srdivacky      TemplateIdAnnotation *TemplateId
188193326Sed        = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
189204643Srdivacky      if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {
190204643Srdivacky        *MayBePseudoDestructor = true;
191204643Srdivacky        return false;
192204643Srdivacky      }
193193326Sed
194198092Srdivacky      if (TemplateId->Kind == TNK_Type_template ||
195193326Sed          TemplateId->Kind == TNK_Dependent_template_name) {
196193326Sed        AnnotateTemplateIdTokenAsType(&SS);
197193326Sed
198198092Srdivacky        assert(Tok.is(tok::annot_typename) &&
199193326Sed               "AnnotateTemplateIdTokenAsType isn't working");
200193326Sed        Token TypeToken = Tok;
201193326Sed        ConsumeToken();
202193326Sed        assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
203193326Sed        SourceLocation CCLoc = ConsumeToken();
204198092Srdivacky
205193326Sed        if (!HasScopeSpecifier) {
206193326Sed          SS.setBeginLoc(TypeToken.getLocation());
207193326Sed          HasScopeSpecifier = true;
208193326Sed        }
209198092Srdivacky
210193326Sed        if (TypeToken.getAnnotationValue())
211193326Sed          SS.setScopeRep(
212198092Srdivacky            Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
213193326Sed                                                TypeToken.getAnnotationValue(),
214193326Sed                                                TypeToken.getAnnotationRange(),
215193326Sed                                                CCLoc));
216193326Sed        else
217193326Sed          SS.setScopeRep(0);
218193326Sed        SS.setEndLoc(CCLoc);
219193326Sed        continue;
220195099Sed      }
221198092Srdivacky
222195099Sed      assert(false && "FIXME: Only type template names supported here");
223193326Sed    }
224193326Sed
225195099Sed
226195099Sed    // The rest of the nested-name-specifier possibilities start with
227195099Sed    // tok::identifier.
228195099Sed    if (Tok.isNot(tok::identifier))
229195099Sed      break;
230195099Sed
231195099Sed    IdentifierInfo &II = *Tok.getIdentifierInfo();
232195099Sed
233195099Sed    // nested-name-specifier:
234195099Sed    //   type-name '::'
235195099Sed    //   namespace-name '::'
236195099Sed    //   nested-name-specifier identifier '::'
237195099Sed    Token Next = NextToken();
238200583Srdivacky
239200583Srdivacky    // If we get foo:bar, this is almost certainly a typo for foo::bar.  Recover
240200583Srdivacky    // and emit a fixit hint for it.
241204643Srdivacky    if (Next.is(tok::colon) && !ColonIsSacred) {
242204643Srdivacky      if (Actions.IsInvalidUnlessNestedName(CurScope, SS, II, ObjectType,
243204643Srdivacky                                            EnteringContext) &&
244204643Srdivacky          // If the token after the colon isn't an identifier, it's still an
245204643Srdivacky          // error, but they probably meant something else strange so don't
246204643Srdivacky          // recover like this.
247204643Srdivacky          PP.LookAhead(1).is(tok::identifier)) {
248204643Srdivacky        Diag(Next, diag::err_unexected_colon_in_nested_name_spec)
249204643Srdivacky          << CodeModificationHint::CreateReplacement(Next.getLocation(), "::");
250204643Srdivacky
251204643Srdivacky        // Recover as if the user wrote '::'.
252204643Srdivacky        Next.setKind(tok::coloncolon);
253204643Srdivacky      }
254200583Srdivacky    }
255200583Srdivacky
256195099Sed    if (Next.is(tok::coloncolon)) {
257204643Srdivacky      if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) &&
258204643Srdivacky          !Actions.isNonTypeNestedNameSpecifier(CurScope, SS, Tok.getLocation(),
259204643Srdivacky                                                II, ObjectType)) {
260204643Srdivacky        *MayBePseudoDestructor = true;
261204643Srdivacky        return false;
262204643Srdivacky      }
263204643Srdivacky
264195099Sed      // We have an identifier followed by a '::'. Lookup this name
265195099Sed      // as the name in a nested-name-specifier.
266195099Sed      SourceLocation IdLoc = ConsumeToken();
267200583Srdivacky      assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) &&
268200583Srdivacky             "NextToken() not working properly!");
269195099Sed      SourceLocation CCLoc = ConsumeToken();
270198092Srdivacky
271195099Sed      if (!HasScopeSpecifier) {
272195099Sed        SS.setBeginLoc(IdLoc);
273195099Sed        HasScopeSpecifier = true;
274195099Sed      }
275198092Srdivacky
276195099Sed      if (SS.isInvalid())
277195099Sed        continue;
278198092Srdivacky
279195099Sed      SS.setScopeRep(
280198092Srdivacky        Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, II,
281198092Srdivacky                                            ObjectType, EnteringContext));
282195099Sed      SS.setEndLoc(CCLoc);
283195099Sed      continue;
284195099Sed    }
285198092Srdivacky
286195099Sed    // nested-name-specifier:
287195099Sed    //   type-name '<'
288195099Sed    if (Next.is(tok::less)) {
289195099Sed      TemplateTy Template;
290198893Srdivacky      UnqualifiedId TemplateName;
291198893Srdivacky      TemplateName.setIdentifier(&II, Tok.getLocation());
292198893Srdivacky      if (TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS,
293198893Srdivacky                                                        TemplateName,
294198092Srdivacky                                                        ObjectType,
295198092Srdivacky                                                        EnteringContext,
296198092Srdivacky                                                        Template)) {
297195099Sed        // We have found a template name, so annotate this this token
298195099Sed        // with a template-id annotation. We do not permit the
299195099Sed        // template-id to be translated into a type annotation,
300195099Sed        // because some clients (e.g., the parsing of class template
301195099Sed        // specializations) still want to see the original template-id
302195099Sed        // token.
303198893Srdivacky        ConsumeToken();
304198893Srdivacky        if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName,
305198893Srdivacky                                    SourceLocation(), false))
306204643Srdivacky          return true;
307195099Sed        continue;
308195099Sed      }
309195099Sed    }
310195099Sed
311193326Sed    // We don't have any tokens that form the beginning of a
312193326Sed    // nested-name-specifier, so we're done.
313193326Sed    break;
314193326Sed  }
315198092Srdivacky
316204643Srdivacky  // Even if we didn't see any pieces of a nested-name-specifier, we
317204643Srdivacky  // still check whether there is a tilde in this position, which
318204643Srdivacky  // indicates a potential pseudo-destructor.
319204643Srdivacky  if (CheckForDestructor && Tok.is(tok::tilde))
320204643Srdivacky    *MayBePseudoDestructor = true;
321204643Srdivacky
322204643Srdivacky  return false;
323193326Sed}
324193326Sed
325193326Sed/// ParseCXXIdExpression - Handle id-expression.
326193326Sed///
327193326Sed///       id-expression:
328193326Sed///         unqualified-id
329193326Sed///         qualified-id
330193326Sed///
331193326Sed///       qualified-id:
332193326Sed///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
333193326Sed///         '::' identifier
334193326Sed///         '::' operator-function-id
335195341Sed///         '::' template-id
336193326Sed///
337193326Sed/// NOTE: The standard specifies that, for qualified-id, the parser does not
338193326Sed/// expect:
339193326Sed///
340193326Sed///   '::' conversion-function-id
341193326Sed///   '::' '~' class-name
342193326Sed///
343193326Sed/// This may cause a slight inconsistency on diagnostics:
344193326Sed///
345193326Sed/// class C {};
346193326Sed/// namespace A {}
347193326Sed/// void f() {
348193326Sed///   :: A :: ~ C(); // Some Sema error about using destructor with a
349193326Sed///                  // namespace.
350193326Sed///   :: ~ C(); // Some Parser error like 'unexpected ~'.
351193326Sed/// }
352193326Sed///
353193326Sed/// We simplify the parser a bit and make it work like:
354193326Sed///
355193326Sed///       qualified-id:
356193326Sed///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
357193326Sed///         '::' unqualified-id
358193326Sed///
359193326Sed/// That way Sema can handle and report similar errors for namespaces and the
360193326Sed/// global scope.
361193326Sed///
362193326Sed/// The isAddressOfOperand parameter indicates that this id-expression is a
363193326Sed/// direct operand of the address-of operator. This is, besides member contexts,
364193326Sed/// the only place where a qualified-id naming a non-static class member may
365193326Sed/// appear.
366193326Sed///
367193326SedParser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
368193326Sed  // qualified-id:
369193326Sed  //   '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
370193326Sed  //   '::' unqualified-id
371193326Sed  //
372193326Sed  CXXScopeSpec SS;
373198092Srdivacky  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
374198893Srdivacky
375198893Srdivacky  UnqualifiedId Name;
376198893Srdivacky  if (ParseUnqualifiedId(SS,
377198893Srdivacky                         /*EnteringContext=*/false,
378198893Srdivacky                         /*AllowDestructorName=*/false,
379198893Srdivacky                         /*AllowConstructorName=*/false,
380198893Srdivacky                         /*ObjectType=*/0,
381198893Srdivacky                         Name))
382193326Sed    return ExprError();
383199990Srdivacky
384199990Srdivacky  // This is only the direct operand of an & operator if it is not
385199990Srdivacky  // followed by a postfix-expression suffix.
386199990Srdivacky  if (isAddressOfOperand) {
387199990Srdivacky    switch (Tok.getKind()) {
388199990Srdivacky    case tok::l_square:
389199990Srdivacky    case tok::l_paren:
390199990Srdivacky    case tok::arrow:
391199990Srdivacky    case tok::period:
392199990Srdivacky    case tok::plusplus:
393199990Srdivacky    case tok::minusminus:
394199990Srdivacky      isAddressOfOperand = false;
395199990Srdivacky      break;
396199990Srdivacky
397199990Srdivacky    default:
398199990Srdivacky      break;
399199990Srdivacky    }
400199990Srdivacky  }
401198893Srdivacky
402198893Srdivacky  return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
403198893Srdivacky                                   isAddressOfOperand);
404198893Srdivacky
405193326Sed}
406193326Sed
407193326Sed/// ParseCXXCasts - This handles the various ways to cast expressions to another
408193326Sed/// type.
409193326Sed///
410193326Sed///       postfix-expression: [C++ 5.2p1]
411193326Sed///         'dynamic_cast' '<' type-name '>' '(' expression ')'
412193326Sed///         'static_cast' '<' type-name '>' '(' expression ')'
413193326Sed///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
414193326Sed///         'const_cast' '<' type-name '>' '(' expression ')'
415193326Sed///
416193326SedParser::OwningExprResult Parser::ParseCXXCasts() {
417193326Sed  tok::TokenKind Kind = Tok.getKind();
418193326Sed  const char *CastName = 0;     // For error messages
419193326Sed
420193326Sed  switch (Kind) {
421193326Sed  default: assert(0 && "Unknown C++ cast!"); abort();
422193326Sed  case tok::kw_const_cast:       CastName = "const_cast";       break;
423193326Sed  case tok::kw_dynamic_cast:     CastName = "dynamic_cast";     break;
424193326Sed  case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
425193326Sed  case tok::kw_static_cast:      CastName = "static_cast";      break;
426193326Sed  }
427193326Sed
428193326Sed  SourceLocation OpLoc = ConsumeToken();
429193326Sed  SourceLocation LAngleBracketLoc = Tok.getLocation();
430193326Sed
431193326Sed  if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
432193326Sed    return ExprError();
433193326Sed
434193326Sed  TypeResult CastTy = ParseTypeName();
435193326Sed  SourceLocation RAngleBracketLoc = Tok.getLocation();
436193326Sed
437193326Sed  if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
438193326Sed    return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
439193326Sed
440193326Sed  SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
441193326Sed
442193326Sed  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName))
443193326Sed    return ExprError();
444193326Sed
445193326Sed  OwningExprResult Result = ParseExpression();
446198092Srdivacky
447193326Sed  // Match the ')'.
448199482Srdivacky  RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
449198092Srdivacky
450193326Sed  if (!Result.isInvalid() && !CastTy.isInvalid())
451193326Sed    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
452193326Sed                                       LAngleBracketLoc, CastTy.get(),
453193326Sed                                       RAngleBracketLoc,
454193326Sed                                       LParenLoc, move(Result), RParenLoc);
455193326Sed
456193326Sed  return move(Result);
457193326Sed}
458193326Sed
459193326Sed/// ParseCXXTypeid - This handles the C++ typeid expression.
460193326Sed///
461193326Sed///       postfix-expression: [C++ 5.2p1]
462193326Sed///         'typeid' '(' expression ')'
463193326Sed///         'typeid' '(' type-id ')'
464193326Sed///
465193326SedParser::OwningExprResult Parser::ParseCXXTypeid() {
466193326Sed  assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
467193326Sed
468193326Sed  SourceLocation OpLoc = ConsumeToken();
469193326Sed  SourceLocation LParenLoc = Tok.getLocation();
470193326Sed  SourceLocation RParenLoc;
471193326Sed
472193326Sed  // typeid expressions are always parenthesized.
473193326Sed  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
474193326Sed      "typeid"))
475193326Sed    return ExprError();
476193326Sed
477193326Sed  OwningExprResult Result(Actions);
478193326Sed
479193326Sed  if (isTypeIdInParens()) {
480193326Sed    TypeResult Ty = ParseTypeName();
481193326Sed
482193326Sed    // Match the ')'.
483193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
484193326Sed
485193326Sed    if (Ty.isInvalid())
486193326Sed      return ExprError();
487193326Sed
488193326Sed    Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
489193326Sed                                    Ty.get(), RParenLoc);
490193326Sed  } else {
491194613Sed    // C++0x [expr.typeid]p3:
492198092Srdivacky    //   When typeid is applied to an expression other than an lvalue of a
493198092Srdivacky    //   polymorphic class type [...] The expression is an unevaluated
494194613Sed    //   operand (Clause 5).
495194613Sed    //
496198092Srdivacky    // Note that we can't tell whether the expression is an lvalue of a
497194613Sed    // polymorphic class type until after we've parsed the expression, so
498194711Sed    // we the expression is potentially potentially evaluated.
499194711Sed    EnterExpressionEvaluationContext Unevaluated(Actions,
500194711Sed                                       Action::PotentiallyPotentiallyEvaluated);
501193326Sed    Result = ParseExpression();
502193326Sed
503193326Sed    // Match the ')'.
504193326Sed    if (Result.isInvalid())
505193326Sed      SkipUntil(tok::r_paren);
506193326Sed    else {
507193326Sed      MatchRHSPunctuation(tok::r_paren, LParenLoc);
508193326Sed
509193326Sed      Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
510193326Sed                                      Result.release(), RParenLoc);
511193326Sed    }
512193326Sed  }
513193326Sed
514193326Sed  return move(Result);
515193326Sed}
516193326Sed
517204643Srdivacky/// \brief Parse a C++ pseudo-destructor expression after the base,
518204643Srdivacky/// . or -> operator, and nested-name-specifier have already been
519204643Srdivacky/// parsed.
520204643Srdivacky///
521204643Srdivacky///       postfix-expression: [C++ 5.2]
522204643Srdivacky///         postfix-expression . pseudo-destructor-name
523204643Srdivacky///         postfix-expression -> pseudo-destructor-name
524204643Srdivacky///
525204643Srdivacky///       pseudo-destructor-name:
526204643Srdivacky///         ::[opt] nested-name-specifier[opt] type-name :: ~type-name
527204643Srdivacky///         ::[opt] nested-name-specifier template simple-template-id ::
528204643Srdivacky///                 ~type-name
529204643Srdivacky///         ::[opt] nested-name-specifier[opt] ~type-name
530204643Srdivacky///
531204643SrdivackyParser::OwningExprResult
532204643SrdivackyParser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
533204643Srdivacky                                 tok::TokenKind OpKind,
534204643Srdivacky                                 CXXScopeSpec &SS,
535204643Srdivacky                                 Action::TypeTy *ObjectType) {
536204643Srdivacky  // We're parsing either a pseudo-destructor-name or a dependent
537204643Srdivacky  // member access that has the same form as a
538204643Srdivacky  // pseudo-destructor-name. We parse both in the same way and let
539204643Srdivacky  // the action model sort them out.
540204643Srdivacky  //
541204643Srdivacky  // Note that the ::[opt] nested-name-specifier[opt] has already
542204643Srdivacky  // been parsed, and if there was a simple-template-id, it has
543204643Srdivacky  // been coalesced into a template-id annotation token.
544204643Srdivacky  UnqualifiedId FirstTypeName;
545204643Srdivacky  SourceLocation CCLoc;
546204643Srdivacky  if (Tok.is(tok::identifier)) {
547204643Srdivacky    FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
548204643Srdivacky    ConsumeToken();
549204643Srdivacky    assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
550204643Srdivacky    CCLoc = ConsumeToken();
551204643Srdivacky  } else if (Tok.is(tok::annot_template_id)) {
552204643Srdivacky    FirstTypeName.setTemplateId(
553204643Srdivacky                              (TemplateIdAnnotation *)Tok.getAnnotationValue());
554204643Srdivacky    ConsumeToken();
555204643Srdivacky    assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
556204643Srdivacky    CCLoc = ConsumeToken();
557204643Srdivacky  } else {
558204643Srdivacky    FirstTypeName.setIdentifier(0, SourceLocation());
559204643Srdivacky  }
560204643Srdivacky
561204643Srdivacky  // Parse the tilde.
562204643Srdivacky  assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");
563204643Srdivacky  SourceLocation TildeLoc = ConsumeToken();
564204643Srdivacky  if (!Tok.is(tok::identifier)) {
565204643Srdivacky    Diag(Tok, diag::err_destructor_tilde_identifier);
566204643Srdivacky    return ExprError();
567204643Srdivacky  }
568204643Srdivacky
569204643Srdivacky  // Parse the second type.
570204643Srdivacky  UnqualifiedId SecondTypeName;
571204643Srdivacky  IdentifierInfo *Name = Tok.getIdentifierInfo();
572204643Srdivacky  SourceLocation NameLoc = ConsumeToken();
573204643Srdivacky  SecondTypeName.setIdentifier(Name, NameLoc);
574204643Srdivacky
575204643Srdivacky  // If there is a '<', the second type name is a template-id. Parse
576204643Srdivacky  // it as such.
577204643Srdivacky  if (Tok.is(tok::less) &&
578204643Srdivacky      ParseUnqualifiedIdTemplateId(SS, Name, NameLoc, false, ObjectType,
579204643Srdivacky                                   SecondTypeName, /*AssumeTemplateName=*/true))
580204643Srdivacky    return ExprError();
581204643Srdivacky
582204643Srdivacky  return Actions.ActOnPseudoDestructorExpr(CurScope, move(Base), OpLoc, OpKind,
583204643Srdivacky                                           SS, FirstTypeName, CCLoc,
584204643Srdivacky                                           TildeLoc, SecondTypeName,
585204643Srdivacky                                           Tok.is(tok::l_paren));
586204643Srdivacky}
587204643Srdivacky
588193326Sed/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
589193326Sed///
590193326Sed///       boolean-literal: [C++ 2.13.5]
591193326Sed///         'true'
592193326Sed///         'false'
593193326SedParser::OwningExprResult Parser::ParseCXXBoolLiteral() {
594193326Sed  tok::TokenKind Kind = Tok.getKind();
595193326Sed  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
596193326Sed}
597193326Sed
598193326Sed/// ParseThrowExpression - This handles the C++ throw expression.
599193326Sed///
600193326Sed///       throw-expression: [C++ 15]
601193326Sed///         'throw' assignment-expression[opt]
602193326SedParser::OwningExprResult Parser::ParseThrowExpression() {
603193326Sed  assert(Tok.is(tok::kw_throw) && "Not throw!");
604193326Sed  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
605193326Sed
606193326Sed  // If the current token isn't the start of an assignment-expression,
607193326Sed  // then the expression is not present.  This handles things like:
608193326Sed  //   "C ? throw : (void)42", which is crazy but legal.
609193326Sed  switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
610193326Sed  case tok::semi:
611193326Sed  case tok::r_paren:
612193326Sed  case tok::r_square:
613193326Sed  case tok::r_brace:
614193326Sed  case tok::colon:
615193326Sed  case tok::comma:
616193326Sed    return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
617193326Sed
618193326Sed  default:
619193326Sed    OwningExprResult Expr(ParseAssignmentExpression());
620193326Sed    if (Expr.isInvalid()) return move(Expr);
621193326Sed    return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
622193326Sed  }
623193326Sed}
624193326Sed
625193326Sed/// ParseCXXThis - This handles the C++ 'this' pointer.
626193326Sed///
627193326Sed/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
628193326Sed/// a non-lvalue expression whose value is the address of the object for which
629193326Sed/// the function is called.
630193326SedParser::OwningExprResult Parser::ParseCXXThis() {
631193326Sed  assert(Tok.is(tok::kw_this) && "Not 'this'!");
632193326Sed  SourceLocation ThisLoc = ConsumeToken();
633193326Sed  return Actions.ActOnCXXThis(ThisLoc);
634193326Sed}
635193326Sed
636193326Sed/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
637193326Sed/// Can be interpreted either as function-style casting ("int(x)")
638193326Sed/// or class type construction ("ClassType(x,y,z)")
639193326Sed/// or creation of a value-initialized type ("int()").
640193326Sed///
641193326Sed///       postfix-expression: [C++ 5.2p1]
642193326Sed///         simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
643193326Sed///         typename-specifier '(' expression-list[opt] ')'         [TODO]
644193326Sed///
645193326SedParser::OwningExprResult
646193326SedParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
647193326Sed  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
648193326Sed  TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
649193326Sed
650193326Sed  assert(Tok.is(tok::l_paren) && "Expected '('!");
651193326Sed  SourceLocation LParenLoc = ConsumeParen();
652193326Sed
653193326Sed  ExprVector Exprs(Actions);
654193326Sed  CommaLocsTy CommaLocs;
655193326Sed
656193326Sed  if (Tok.isNot(tok::r_paren)) {
657193326Sed    if (ParseExpressionList(Exprs, CommaLocs)) {
658193326Sed      SkipUntil(tok::r_paren);
659193326Sed      return ExprError();
660193326Sed    }
661193326Sed  }
662193326Sed
663193326Sed  // Match the ')'.
664193326Sed  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
665193326Sed
666198092Srdivacky  // TypeRep could be null, if it references an invalid typedef.
667198092Srdivacky  if (!TypeRep)
668198092Srdivacky    return ExprError();
669198092Srdivacky
670193326Sed  assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
671193326Sed         "Unexpected number of commas!");
672193326Sed  return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
673193326Sed                                           LParenLoc, move_arg(Exprs),
674193326Sed                                           CommaLocs.data(), RParenLoc);
675193326Sed}
676193326Sed
677199990Srdivacky/// ParseCXXCondition - if/switch/while condition expression.
678193326Sed///
679193326Sed///       condition:
680193326Sed///         expression
681193326Sed///         type-specifier-seq declarator '=' assignment-expression
682193326Sed/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
683193326Sed///             '=' assignment-expression
684193326Sed///
685199990Srdivacky/// \param ExprResult if the condition was parsed as an expression, the
686199990Srdivacky/// parsed expression.
687199990Srdivacky///
688199990Srdivacky/// \param DeclResult if the condition was parsed as a declaration, the
689199990Srdivacky/// parsed declaration.
690199990Srdivacky///
691199990Srdivacky/// \returns true if there was a parsing, false otherwise.
692199990Srdivackybool Parser::ParseCXXCondition(OwningExprResult &ExprResult,
693199990Srdivacky                               DeclPtrTy &DeclResult) {
694202379Srdivacky  if (Tok.is(tok::code_completion)) {
695202379Srdivacky    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Condition);
696202379Srdivacky    ConsumeToken();
697202379Srdivacky  }
698202379Srdivacky
699199990Srdivacky  if (!isCXXConditionDeclaration()) {
700199990Srdivacky    ExprResult = ParseExpression(); // expression
701199990Srdivacky    DeclResult = DeclPtrTy();
702199990Srdivacky    return ExprResult.isInvalid();
703199990Srdivacky  }
704193326Sed
705193326Sed  // type-specifier-seq
706193326Sed  DeclSpec DS;
707193326Sed  ParseSpecifierQualifierList(DS);
708193326Sed
709193326Sed  // declarator
710193326Sed  Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
711193326Sed  ParseDeclarator(DeclaratorInfo);
712193326Sed
713193326Sed  // simple-asm-expr[opt]
714193326Sed  if (Tok.is(tok::kw_asm)) {
715193326Sed    SourceLocation Loc;
716193326Sed    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
717193326Sed    if (AsmLabel.isInvalid()) {
718193326Sed      SkipUntil(tok::semi);
719199990Srdivacky      return true;
720193326Sed    }
721193326Sed    DeclaratorInfo.setAsmLabel(AsmLabel.release());
722193326Sed    DeclaratorInfo.SetRangeEnd(Loc);
723193326Sed  }
724193326Sed
725193326Sed  // If attributes are present, parse them.
726193326Sed  if (Tok.is(tok::kw___attribute)) {
727193326Sed    SourceLocation Loc;
728199990Srdivacky    AttributeList *AttrList = ParseGNUAttributes(&Loc);
729193326Sed    DeclaratorInfo.AddAttributes(AttrList, Loc);
730193326Sed  }
731193326Sed
732199990Srdivacky  // Type-check the declaration itself.
733199990Srdivacky  Action::DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(CurScope,
734199990Srdivacky                                                                DeclaratorInfo);
735199990Srdivacky  DeclResult = Dcl.get();
736199990Srdivacky  ExprResult = ExprError();
737199990Srdivacky
738193326Sed  // '=' assignment-expression
739199990Srdivacky  if (Tok.is(tok::equal)) {
740199990Srdivacky    SourceLocation EqualLoc = ConsumeToken();
741199990Srdivacky    OwningExprResult AssignExpr(ParseAssignmentExpression());
742199990Srdivacky    if (!AssignExpr.isInvalid())
743199990Srdivacky      Actions.AddInitializerToDecl(DeclResult, move(AssignExpr));
744199990Srdivacky  } else {
745199990Srdivacky    // FIXME: C++0x allows a braced-init-list
746199990Srdivacky    Diag(Tok, diag::err_expected_equal_after_declarator);
747199990Srdivacky  }
748199990Srdivacky
749199990Srdivacky  return false;
750193326Sed}
751193326Sed
752193326Sed/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
753193326Sed/// This should only be called when the current token is known to be part of
754193326Sed/// simple-type-specifier.
755193326Sed///
756193326Sed///       simple-type-specifier:
757193326Sed///         '::'[opt] nested-name-specifier[opt] type-name
758193326Sed///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
759193326Sed///         char
760193326Sed///         wchar_t
761193326Sed///         bool
762193326Sed///         short
763193326Sed///         int
764193326Sed///         long
765193326Sed///         signed
766193326Sed///         unsigned
767193326Sed///         float
768193326Sed///         double
769193326Sed///         void
770193326Sed/// [GNU]   typeof-specifier
771193326Sed/// [C++0x] auto               [TODO]
772193326Sed///
773193326Sed///       type-name:
774193326Sed///         class-name
775193326Sed///         enum-name
776193326Sed///         typedef-name
777193326Sed///
778193326Sedvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
779193326Sed  DS.SetRangeStart(Tok.getLocation());
780193326Sed  const char *PrevSpec;
781198092Srdivacky  unsigned DiagID;
782193326Sed  SourceLocation Loc = Tok.getLocation();
783198092Srdivacky
784193326Sed  switch (Tok.getKind()) {
785193326Sed  case tok::identifier:   // foo::bar
786193326Sed  case tok::coloncolon:   // ::foo::bar
787193326Sed    assert(0 && "Annotation token should already be formed!");
788198092Srdivacky  default:
789193326Sed    assert(0 && "Not a simple-type-specifier token!");
790193326Sed    abort();
791193326Sed
792193326Sed  // type-name
793193326Sed  case tok::annot_typename: {
794198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
795193326Sed                       Tok.getAnnotationValue());
796193326Sed    break;
797193326Sed  }
798198092Srdivacky
799193326Sed  // builtin types
800193326Sed  case tok::kw_short:
801198092Srdivacky    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
802193326Sed    break;
803193326Sed  case tok::kw_long:
804198092Srdivacky    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID);
805193326Sed    break;
806193326Sed  case tok::kw_signed:
807198092Srdivacky    DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
808193326Sed    break;
809193326Sed  case tok::kw_unsigned:
810198092Srdivacky    DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID);
811193326Sed    break;
812193326Sed  case tok::kw_void:
813198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
814193326Sed    break;
815193326Sed  case tok::kw_char:
816198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
817193326Sed    break;
818193326Sed  case tok::kw_int:
819198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
820193326Sed    break;
821193326Sed  case tok::kw_float:
822198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
823193326Sed    break;
824193326Sed  case tok::kw_double:
825198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
826193326Sed    break;
827193326Sed  case tok::kw_wchar_t:
828198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
829193326Sed    break;
830198092Srdivacky  case tok::kw_char16_t:
831198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
832198092Srdivacky    break;
833198092Srdivacky  case tok::kw_char32_t:
834198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
835198092Srdivacky    break;
836193326Sed  case tok::kw_bool:
837198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
838193326Sed    break;
839198092Srdivacky
840193326Sed  // GNU typeof support.
841193326Sed  case tok::kw_typeof:
842193326Sed    ParseTypeofSpecifier(DS);
843193326Sed    DS.Finish(Diags, PP);
844193326Sed    return;
845193326Sed  }
846193326Sed  if (Tok.is(tok::annot_typename))
847193326Sed    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
848193326Sed  else
849193326Sed    DS.SetRangeEnd(Tok.getLocation());
850193326Sed  ConsumeToken();
851193326Sed  DS.Finish(Diags, PP);
852193326Sed}
853193326Sed
854193326Sed/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
855193326Sed/// [dcl.name]), which is a non-empty sequence of type-specifiers,
856193326Sed/// e.g., "const short int". Note that the DeclSpec is *not* finished
857193326Sed/// by parsing the type-specifier-seq, because these sequences are
858193326Sed/// typically followed by some form of declarator. Returns true and
859193326Sed/// emits diagnostics if this is not a type-specifier-seq, false
860193326Sed/// otherwise.
861193326Sed///
862193326Sed///   type-specifier-seq: [C++ 8.1]
863193326Sed///     type-specifier type-specifier-seq[opt]
864193326Sed///
865193326Sedbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
866193326Sed  DS.SetRangeStart(Tok.getLocation());
867193326Sed  const char *PrevSpec = 0;
868198092Srdivacky  unsigned DiagID;
869198092Srdivacky  bool isInvalid = 0;
870193326Sed
871193326Sed  // Parse one or more of the type specifiers.
872203955Srdivacky  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
873203955Srdivacky      ParsedTemplateInfo(), /*SuppressDeclarations*/true)) {
874193326Sed    Diag(Tok, diag::err_operator_missing_type_specifier);
875193326Sed    return true;
876193326Sed  }
877193326Sed
878203955Srdivacky  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
879203955Srdivacky         ParsedTemplateInfo(), /*SuppressDeclarations*/true))
880203955Srdivacky  {}
881198092Srdivacky
882204643Srdivacky  DS.Finish(Diags, PP);
883193326Sed  return false;
884193326Sed}
885193326Sed
886198893Srdivacky/// \brief Finish parsing a C++ unqualified-id that is a template-id of
887198893Srdivacky/// some form.
888198893Srdivacky///
889198893Srdivacky/// This routine is invoked when a '<' is encountered after an identifier or
890198893Srdivacky/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine
891198893Srdivacky/// whether the unqualified-id is actually a template-id. This routine will
892198893Srdivacky/// then parse the template arguments and form the appropriate template-id to
893198893Srdivacky/// return to the caller.
894198893Srdivacky///
895198893Srdivacky/// \param SS the nested-name-specifier that precedes this template-id, if
896198893Srdivacky/// we're actually parsing a qualified-id.
897198893Srdivacky///
898198893Srdivacky/// \param Name for constructor and destructor names, this is the actual
899198893Srdivacky/// identifier that may be a template-name.
900198893Srdivacky///
901198893Srdivacky/// \param NameLoc the location of the class-name in a constructor or
902198893Srdivacky/// destructor.
903198893Srdivacky///
904198893Srdivacky/// \param EnteringContext whether we're entering the scope of the
905198893Srdivacky/// nested-name-specifier.
906198893Srdivacky///
907198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access
908198893Srdivacky/// expression, the type of the base object whose member is being accessed.
909198893Srdivacky///
910198893Srdivacky/// \param Id as input, describes the template-name or operator-function-id
911198893Srdivacky/// that precedes the '<'. If template arguments were parsed successfully,
912198893Srdivacky/// will be updated with the template-id.
913198893Srdivacky///
914204643Srdivacky/// \param AssumeTemplateId When true, this routine will assume that the name
915204643Srdivacky/// refers to a template without performing name lookup to verify.
916204643Srdivacky///
917198893Srdivacky/// \returns true if a parse error occurred, false otherwise.
918198893Srdivackybool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
919198893Srdivacky                                          IdentifierInfo *Name,
920198893Srdivacky                                          SourceLocation NameLoc,
921198893Srdivacky                                          bool EnteringContext,
922198893Srdivacky                                          TypeTy *ObjectType,
923204643Srdivacky                                          UnqualifiedId &Id,
924204643Srdivacky                                          bool AssumeTemplateId) {
925198893Srdivacky  assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
926198893Srdivacky
927198893Srdivacky  TemplateTy Template;
928198893Srdivacky  TemplateNameKind TNK = TNK_Non_template;
929198893Srdivacky  switch (Id.getKind()) {
930198893Srdivacky  case UnqualifiedId::IK_Identifier:
931198893Srdivacky  case UnqualifiedId::IK_OperatorFunctionId:
932199990Srdivacky  case UnqualifiedId::IK_LiteralOperatorId:
933204643Srdivacky    if (AssumeTemplateId) {
934204643Srdivacky      Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS,
935204643Srdivacky                                                    Id, ObjectType,
936204643Srdivacky                                                    EnteringContext);
937204643Srdivacky      TNK = TNK_Dependent_template_name;
938204643Srdivacky      if (!Template.get())
939204643Srdivacky        return true;
940204643Srdivacky    } else
941204643Srdivacky      TNK = Actions.isTemplateName(CurScope, SS, Id, ObjectType,
942204643Srdivacky                                   EnteringContext, Template);
943198893Srdivacky    break;
944198893Srdivacky
945198893Srdivacky  case UnqualifiedId::IK_ConstructorName: {
946198893Srdivacky    UnqualifiedId TemplateName;
947198893Srdivacky    TemplateName.setIdentifier(Name, NameLoc);
948198893Srdivacky    TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType,
949198893Srdivacky                                 EnteringContext, Template);
950198893Srdivacky    break;
951198893Srdivacky  }
952198893Srdivacky
953198893Srdivacky  case UnqualifiedId::IK_DestructorName: {
954198893Srdivacky    UnqualifiedId TemplateName;
955198893Srdivacky    TemplateName.setIdentifier(Name, NameLoc);
956198893Srdivacky    if (ObjectType) {
957198893Srdivacky      Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS,
958199990Srdivacky                                                    TemplateName, ObjectType,
959199990Srdivacky                                                    EnteringContext);
960198893Srdivacky      TNK = TNK_Dependent_template_name;
961198893Srdivacky      if (!Template.get())
962198893Srdivacky        return true;
963198893Srdivacky    } else {
964198893Srdivacky      TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType,
965198893Srdivacky                                   EnteringContext, Template);
966198893Srdivacky
967198893Srdivacky      if (TNK == TNK_Non_template && Id.DestructorName == 0) {
968204643Srdivacky        Diag(NameLoc, diag::err_destructor_template_id)
969204643Srdivacky          << Name << SS.getRange();
970198893Srdivacky        return true;
971198893Srdivacky      }
972198893Srdivacky    }
973198893Srdivacky    break;
974198893Srdivacky  }
975198893Srdivacky
976198893Srdivacky  default:
977198893Srdivacky    return false;
978198893Srdivacky  }
979198893Srdivacky
980198893Srdivacky  if (TNK == TNK_Non_template)
981198893Srdivacky    return false;
982198893Srdivacky
983198893Srdivacky  // Parse the enclosed template argument list.
984198893Srdivacky  SourceLocation LAngleLoc, RAngleLoc;
985198893Srdivacky  TemplateArgList TemplateArgs;
986198893Srdivacky  if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
987198893Srdivacky                                       &SS, true, LAngleLoc,
988198893Srdivacky                                       TemplateArgs,
989198893Srdivacky                                       RAngleLoc))
990198893Srdivacky    return true;
991198893Srdivacky
992198893Srdivacky  if (Id.getKind() == UnqualifiedId::IK_Identifier ||
993199990Srdivacky      Id.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
994199990Srdivacky      Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
995198893Srdivacky    // Form a parsed representation of the template-id to be stored in the
996198893Srdivacky    // UnqualifiedId.
997198893Srdivacky    TemplateIdAnnotation *TemplateId
998198893Srdivacky      = TemplateIdAnnotation::Allocate(TemplateArgs.size());
999198893Srdivacky
1000198893Srdivacky    if (Id.getKind() == UnqualifiedId::IK_Identifier) {
1001198893Srdivacky      TemplateId->Name = Id.Identifier;
1002198893Srdivacky      TemplateId->Operator = OO_None;
1003198893Srdivacky      TemplateId->TemplateNameLoc = Id.StartLocation;
1004198893Srdivacky    } else {
1005198893Srdivacky      TemplateId->Name = 0;
1006198893Srdivacky      TemplateId->Operator = Id.OperatorFunctionId.Operator;
1007198893Srdivacky      TemplateId->TemplateNameLoc = Id.StartLocation;
1008198893Srdivacky    }
1009198893Srdivacky
1010198893Srdivacky    TemplateId->Template = Template.getAs<void*>();
1011198893Srdivacky    TemplateId->Kind = TNK;
1012198893Srdivacky    TemplateId->LAngleLoc = LAngleLoc;
1013198893Srdivacky    TemplateId->RAngleLoc = RAngleLoc;
1014199482Srdivacky    ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
1015198893Srdivacky    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size();
1016199482Srdivacky         Arg != ArgEnd; ++Arg)
1017198893Srdivacky      Args[Arg] = TemplateArgs[Arg];
1018198893Srdivacky
1019198893Srdivacky    Id.setTemplateId(TemplateId);
1020198893Srdivacky    return false;
1021198893Srdivacky  }
1022198893Srdivacky
1023198893Srdivacky  // Bundle the template arguments together.
1024198893Srdivacky  ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
1025198893Srdivacky                                     TemplateArgs.size());
1026198893Srdivacky
1027198893Srdivacky  // Constructor and destructor names.
1028198893Srdivacky  Action::TypeResult Type
1029198893Srdivacky    = Actions.ActOnTemplateIdType(Template, NameLoc,
1030198893Srdivacky                                  LAngleLoc, TemplateArgsPtr,
1031198893Srdivacky                                  RAngleLoc);
1032198893Srdivacky  if (Type.isInvalid())
1033198893Srdivacky    return true;
1034198893Srdivacky
1035198893Srdivacky  if (Id.getKind() == UnqualifiedId::IK_ConstructorName)
1036198893Srdivacky    Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);
1037198893Srdivacky  else
1038198893Srdivacky    Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);
1039198893Srdivacky
1040198893Srdivacky  return false;
1041198893Srdivacky}
1042198893Srdivacky
1043198893Srdivacky/// \brief Parse an operator-function-id or conversion-function-id as part
1044198893Srdivacky/// of a C++ unqualified-id.
1045198893Srdivacky///
1046198893Srdivacky/// This routine is responsible only for parsing the operator-function-id or
1047198893Srdivacky/// conversion-function-id; it does not handle template arguments in any way.
1048198893Srdivacky///
1049198893Srdivacky/// \code
1050198893Srdivacky///       operator-function-id: [C++ 13.5]
1051198893Srdivacky///         'operator' operator
1052198893Srdivacky///
1053198893Srdivacky///       operator: one of
1054198893Srdivacky///            new   delete  new[]   delete[]
1055198893Srdivacky///            +     -    *  /    %  ^    &   |   ~
1056198893Srdivacky///            !     =    <  >    += -=   *=  /=  %=
1057198893Srdivacky///            ^=    &=   |= <<   >> >>= <<=  ==  !=
1058198893Srdivacky///            <=    >=   && ||   ++ --   ,   ->* ->
1059198893Srdivacky///            ()    []
1060198893Srdivacky///
1061198893Srdivacky///       conversion-function-id: [C++ 12.3.2]
1062198893Srdivacky///         operator conversion-type-id
1063198893Srdivacky///
1064198893Srdivacky///       conversion-type-id:
1065198893Srdivacky///         type-specifier-seq conversion-declarator[opt]
1066198893Srdivacky///
1067198893Srdivacky///       conversion-declarator:
1068198893Srdivacky///         ptr-operator conversion-declarator[opt]
1069198893Srdivacky/// \endcode
1070198893Srdivacky///
1071198893Srdivacky/// \param The nested-name-specifier that preceded this unqualified-id. If
1072198893Srdivacky/// non-empty, then we are parsing the unqualified-id of a qualified-id.
1073198893Srdivacky///
1074198893Srdivacky/// \param EnteringContext whether we are entering the scope of the
1075198893Srdivacky/// nested-name-specifier.
1076198893Srdivacky///
1077198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access
1078198893Srdivacky/// expression, the type of the base object whose member is being accessed.
1079198893Srdivacky///
1080198893Srdivacky/// \param Result on a successful parse, contains the parsed unqualified-id.
1081198893Srdivacky///
1082198893Srdivacky/// \returns true if parsing fails, false otherwise.
1083198893Srdivackybool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
1084198893Srdivacky                                        TypeTy *ObjectType,
1085198893Srdivacky                                        UnqualifiedId &Result) {
1086198893Srdivacky  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
1087198893Srdivacky
1088198893Srdivacky  // Consume the 'operator' keyword.
1089198893Srdivacky  SourceLocation KeywordLoc = ConsumeToken();
1090198893Srdivacky
1091198893Srdivacky  // Determine what kind of operator name we have.
1092198893Srdivacky  unsigned SymbolIdx = 0;
1093198893Srdivacky  SourceLocation SymbolLocations[3];
1094198893Srdivacky  OverloadedOperatorKind Op = OO_None;
1095198893Srdivacky  switch (Tok.getKind()) {
1096198893Srdivacky    case tok::kw_new:
1097198893Srdivacky    case tok::kw_delete: {
1098198893Srdivacky      bool isNew = Tok.getKind() == tok::kw_new;
1099198893Srdivacky      // Consume the 'new' or 'delete'.
1100198893Srdivacky      SymbolLocations[SymbolIdx++] = ConsumeToken();
1101198893Srdivacky      if (Tok.is(tok::l_square)) {
1102198893Srdivacky        // Consume the '['.
1103198893Srdivacky        SourceLocation LBracketLoc = ConsumeBracket();
1104198893Srdivacky        // Consume the ']'.
1105198893Srdivacky        SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square,
1106198893Srdivacky                                                         LBracketLoc);
1107198893Srdivacky        if (RBracketLoc.isInvalid())
1108198893Srdivacky          return true;
1109198893Srdivacky
1110198893Srdivacky        SymbolLocations[SymbolIdx++] = LBracketLoc;
1111198893Srdivacky        SymbolLocations[SymbolIdx++] = RBracketLoc;
1112198893Srdivacky        Op = isNew? OO_Array_New : OO_Array_Delete;
1113198893Srdivacky      } else {
1114198893Srdivacky        Op = isNew? OO_New : OO_Delete;
1115198893Srdivacky      }
1116198893Srdivacky      break;
1117198893Srdivacky    }
1118198893Srdivacky
1119198893Srdivacky#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1120198893Srdivacky    case tok::Token:                                                     \
1121198893Srdivacky      SymbolLocations[SymbolIdx++] = ConsumeToken();                     \
1122198893Srdivacky      Op = OO_##Name;                                                    \
1123198893Srdivacky      break;
1124198893Srdivacky#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
1125198893Srdivacky#include "clang/Basic/OperatorKinds.def"
1126198893Srdivacky
1127198893Srdivacky    case tok::l_paren: {
1128198893Srdivacky      // Consume the '('.
1129198893Srdivacky      SourceLocation LParenLoc = ConsumeParen();
1130198893Srdivacky      // Consume the ')'.
1131198893Srdivacky      SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren,
1132198893Srdivacky                                                     LParenLoc);
1133198893Srdivacky      if (RParenLoc.isInvalid())
1134198893Srdivacky        return true;
1135198893Srdivacky
1136198893Srdivacky      SymbolLocations[SymbolIdx++] = LParenLoc;
1137198893Srdivacky      SymbolLocations[SymbolIdx++] = RParenLoc;
1138198893Srdivacky      Op = OO_Call;
1139198893Srdivacky      break;
1140198893Srdivacky    }
1141198893Srdivacky
1142198893Srdivacky    case tok::l_square: {
1143198893Srdivacky      // Consume the '['.
1144198893Srdivacky      SourceLocation LBracketLoc = ConsumeBracket();
1145198893Srdivacky      // Consume the ']'.
1146198893Srdivacky      SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square,
1147198893Srdivacky                                                       LBracketLoc);
1148198893Srdivacky      if (RBracketLoc.isInvalid())
1149198893Srdivacky        return true;
1150198893Srdivacky
1151198893Srdivacky      SymbolLocations[SymbolIdx++] = LBracketLoc;
1152198893Srdivacky      SymbolLocations[SymbolIdx++] = RBracketLoc;
1153198893Srdivacky      Op = OO_Subscript;
1154198893Srdivacky      break;
1155198893Srdivacky    }
1156198893Srdivacky
1157198893Srdivacky    case tok::code_completion: {
1158198893Srdivacky      // Code completion for the operator name.
1159198893Srdivacky      Actions.CodeCompleteOperatorName(CurScope);
1160198893Srdivacky
1161198893Srdivacky      // Consume the operator token.
1162198893Srdivacky      ConsumeToken();
1163198893Srdivacky
1164198893Srdivacky      // Don't try to parse any further.
1165198893Srdivacky      return true;
1166198893Srdivacky    }
1167198893Srdivacky
1168198893Srdivacky    default:
1169198893Srdivacky      break;
1170198893Srdivacky  }
1171198893Srdivacky
1172198893Srdivacky  if (Op != OO_None) {
1173198893Srdivacky    // We have parsed an operator-function-id.
1174198893Srdivacky    Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);
1175198893Srdivacky    return false;
1176198893Srdivacky  }
1177199990Srdivacky
1178199990Srdivacky  // Parse a literal-operator-id.
1179199990Srdivacky  //
1180199990Srdivacky  //   literal-operator-id: [C++0x 13.5.8]
1181199990Srdivacky  //     operator "" identifier
1182199990Srdivacky
1183199990Srdivacky  if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) {
1184199990Srdivacky    if (Tok.getLength() != 2)
1185199990Srdivacky      Diag(Tok.getLocation(), diag::err_operator_string_not_empty);
1186199990Srdivacky    ConsumeStringToken();
1187199990Srdivacky
1188199990Srdivacky    if (Tok.isNot(tok::identifier)) {
1189199990Srdivacky      Diag(Tok.getLocation(), diag::err_expected_ident);
1190199990Srdivacky      return true;
1191199990Srdivacky    }
1192199990Srdivacky
1193199990Srdivacky    IdentifierInfo *II = Tok.getIdentifierInfo();
1194199990Srdivacky    Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken());
1195199990Srdivacky    return false;
1196199990Srdivacky  }
1197198893Srdivacky
1198198893Srdivacky  // Parse a conversion-function-id.
1199198893Srdivacky  //
1200198893Srdivacky  //   conversion-function-id: [C++ 12.3.2]
1201198893Srdivacky  //     operator conversion-type-id
1202198893Srdivacky  //
1203198893Srdivacky  //   conversion-type-id:
1204198893Srdivacky  //     type-specifier-seq conversion-declarator[opt]
1205198893Srdivacky  //
1206198893Srdivacky  //   conversion-declarator:
1207198893Srdivacky  //     ptr-operator conversion-declarator[opt]
1208198893Srdivacky
1209198893Srdivacky  // Parse the type-specifier-seq.
1210198893Srdivacky  DeclSpec DS;
1211199990Srdivacky  if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
1212198893Srdivacky    return true;
1213198893Srdivacky
1214198893Srdivacky  // Parse the conversion-declarator, which is merely a sequence of
1215198893Srdivacky  // ptr-operators.
1216198893Srdivacky  Declarator D(DS, Declarator::TypeNameContext);
1217198893Srdivacky  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
1218198893Srdivacky
1219198893Srdivacky  // Finish up the type.
1220198893Srdivacky  Action::TypeResult Ty = Actions.ActOnTypeName(CurScope, D);
1221198893Srdivacky  if (Ty.isInvalid())
1222198893Srdivacky    return true;
1223198893Srdivacky
1224198893Srdivacky  // Note that this is a conversion-function-id.
1225198893Srdivacky  Result.setConversionFunctionId(KeywordLoc, Ty.get(),
1226198893Srdivacky                                 D.getSourceRange().getEnd());
1227198893Srdivacky  return false;
1228198893Srdivacky}
1229198893Srdivacky
1230198893Srdivacky/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the
1231198893Srdivacky/// name of an entity.
1232198893Srdivacky///
1233198893Srdivacky/// \code
1234198893Srdivacky///       unqualified-id: [C++ expr.prim.general]
1235198893Srdivacky///         identifier
1236198893Srdivacky///         operator-function-id
1237198893Srdivacky///         conversion-function-id
1238198893Srdivacky/// [C++0x] literal-operator-id [TODO]
1239198893Srdivacky///         ~ class-name
1240198893Srdivacky///         template-id
1241198893Srdivacky///
1242198893Srdivacky/// \endcode
1243198893Srdivacky///
1244198893Srdivacky/// \param The nested-name-specifier that preceded this unqualified-id. If
1245198893Srdivacky/// non-empty, then we are parsing the unqualified-id of a qualified-id.
1246198893Srdivacky///
1247198893Srdivacky/// \param EnteringContext whether we are entering the scope of the
1248198893Srdivacky/// nested-name-specifier.
1249198893Srdivacky///
1250198893Srdivacky/// \param AllowDestructorName whether we allow parsing of a destructor name.
1251198893Srdivacky///
1252198893Srdivacky/// \param AllowConstructorName whether we allow parsing a constructor name.
1253198893Srdivacky///
1254198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access
1255198893Srdivacky/// expression, the type of the base object whose member is being accessed.
1256198893Srdivacky///
1257198893Srdivacky/// \param Result on a successful parse, contains the parsed unqualified-id.
1258198893Srdivacky///
1259198893Srdivacky/// \returns true if parsing fails, false otherwise.
1260198893Srdivackybool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
1261198893Srdivacky                                bool AllowDestructorName,
1262198893Srdivacky                                bool AllowConstructorName,
1263198893Srdivacky                                TypeTy *ObjectType,
1264198893Srdivacky                                UnqualifiedId &Result) {
1265198893Srdivacky  // unqualified-id:
1266198893Srdivacky  //   identifier
1267198893Srdivacky  //   template-id (when it hasn't already been annotated)
1268198893Srdivacky  if (Tok.is(tok::identifier)) {
1269198893Srdivacky    // Consume the identifier.
1270198893Srdivacky    IdentifierInfo *Id = Tok.getIdentifierInfo();
1271198893Srdivacky    SourceLocation IdLoc = ConsumeToken();
1272198893Srdivacky
1273202379Srdivacky    if (!getLang().CPlusPlus) {
1274202379Srdivacky      // If we're not in C++, only identifiers matter. Record the
1275202379Srdivacky      // identifier and return.
1276202379Srdivacky      Result.setIdentifier(Id, IdLoc);
1277202379Srdivacky      return false;
1278202379Srdivacky    }
1279202379Srdivacky
1280198893Srdivacky    if (AllowConstructorName &&
1281198893Srdivacky        Actions.isCurrentClassName(*Id, CurScope, &SS)) {
1282198893Srdivacky      // We have parsed a constructor name.
1283198893Srdivacky      Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, CurScope,
1284198893Srdivacky                                                    &SS, false),
1285198893Srdivacky                                IdLoc, IdLoc);
1286198893Srdivacky    } else {
1287198893Srdivacky      // We have parsed an identifier.
1288198893Srdivacky      Result.setIdentifier(Id, IdLoc);
1289198893Srdivacky    }
1290198893Srdivacky
1291198893Srdivacky    // If the next token is a '<', we may have a template.
1292198893Srdivacky    if (Tok.is(tok::less))
1293198893Srdivacky      return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext,
1294198893Srdivacky                                          ObjectType, Result);
1295198893Srdivacky
1296198893Srdivacky    return false;
1297198893Srdivacky  }
1298198893Srdivacky
1299198893Srdivacky  // unqualified-id:
1300198893Srdivacky  //   template-id (already parsed and annotated)
1301198893Srdivacky  if (Tok.is(tok::annot_template_id)) {
1302202379Srdivacky    TemplateIdAnnotation *TemplateId
1303202379Srdivacky      = static_cast<TemplateIdAnnotation*>(Tok.getAnnotationValue());
1304202379Srdivacky
1305202379Srdivacky    // If the template-name names the current class, then this is a constructor
1306202379Srdivacky    if (AllowConstructorName && TemplateId->Name &&
1307202379Srdivacky        Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) {
1308202379Srdivacky      if (SS.isSet()) {
1309202379Srdivacky        // C++ [class.qual]p2 specifies that a qualified template-name
1310202379Srdivacky        // is taken as the constructor name where a constructor can be
1311202379Srdivacky        // declared. Thus, the template arguments are extraneous, so
1312202379Srdivacky        // complain about them and remove them entirely.
1313202379Srdivacky        Diag(TemplateId->TemplateNameLoc,
1314202379Srdivacky             diag::err_out_of_line_constructor_template_id)
1315202379Srdivacky          << TemplateId->Name
1316202379Srdivacky          << CodeModificationHint::CreateRemoval(
1317202379Srdivacky                    SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
1318202379Srdivacky        Result.setConstructorName(Actions.getTypeName(*TemplateId->Name,
1319202379Srdivacky                                                  TemplateId->TemplateNameLoc,
1320202379Srdivacky                                                      CurScope,
1321202379Srdivacky                                                      &SS, false),
1322202379Srdivacky                                  TemplateId->TemplateNameLoc,
1323202379Srdivacky                                  TemplateId->RAngleLoc);
1324202379Srdivacky        TemplateId->Destroy();
1325202379Srdivacky        ConsumeToken();
1326202379Srdivacky        return false;
1327202379Srdivacky      }
1328202379Srdivacky
1329202379Srdivacky      Result.setConstructorTemplateId(TemplateId);
1330202379Srdivacky      ConsumeToken();
1331202379Srdivacky      return false;
1332202379Srdivacky    }
1333202379Srdivacky
1334198893Srdivacky    // We have already parsed a template-id; consume the annotation token as
1335198893Srdivacky    // our unqualified-id.
1336202379Srdivacky    Result.setTemplateId(TemplateId);
1337198893Srdivacky    ConsumeToken();
1338198893Srdivacky    return false;
1339198893Srdivacky  }
1340198893Srdivacky
1341198893Srdivacky  // unqualified-id:
1342198893Srdivacky  //   operator-function-id
1343198893Srdivacky  //   conversion-function-id
1344198893Srdivacky  if (Tok.is(tok::kw_operator)) {
1345198893Srdivacky    if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result))
1346198893Srdivacky      return true;
1347198893Srdivacky
1348199990Srdivacky    // If we have an operator-function-id or a literal-operator-id and the next
1349199990Srdivacky    // token is a '<', we may have a
1350198893Srdivacky    //
1351198893Srdivacky    //   template-id:
1352198893Srdivacky    //     operator-function-id < template-argument-list[opt] >
1353199990Srdivacky    if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
1354199990Srdivacky         Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) &&
1355198893Srdivacky        Tok.is(tok::less))
1356198893Srdivacky      return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(),
1357198893Srdivacky                                          EnteringContext, ObjectType,
1358198893Srdivacky                                          Result);
1359198893Srdivacky
1360198893Srdivacky    return false;
1361198893Srdivacky  }
1362198893Srdivacky
1363202379Srdivacky  if (getLang().CPlusPlus &&
1364202379Srdivacky      (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {
1365198893Srdivacky    // C++ [expr.unary.op]p10:
1366198893Srdivacky    //   There is an ambiguity in the unary-expression ~X(), where X is a
1367198893Srdivacky    //   class-name. The ambiguity is resolved in favor of treating ~ as a
1368198893Srdivacky    //    unary complement rather than treating ~X as referring to a destructor.
1369198893Srdivacky
1370198893Srdivacky    // Parse the '~'.
1371198893Srdivacky    SourceLocation TildeLoc = ConsumeToken();
1372198893Srdivacky
1373198893Srdivacky    // Parse the class-name.
1374198893Srdivacky    if (Tok.isNot(tok::identifier)) {
1375204643Srdivacky      Diag(Tok, diag::err_destructor_tilde_identifier);
1376198893Srdivacky      return true;
1377198893Srdivacky    }
1378198893Srdivacky
1379198893Srdivacky    // Parse the class-name (or template-name in a simple-template-id).
1380198893Srdivacky    IdentifierInfo *ClassName = Tok.getIdentifierInfo();
1381198893Srdivacky    SourceLocation ClassNameLoc = ConsumeToken();
1382198893Srdivacky
1383198893Srdivacky    if (Tok.is(tok::less)) {
1384198893Srdivacky      Result.setDestructorName(TildeLoc, 0, ClassNameLoc);
1385198893Srdivacky      return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
1386198893Srdivacky                                          EnteringContext, ObjectType, Result);
1387198893Srdivacky    }
1388198893Srdivacky
1389198893Srdivacky    // Note that this is a destructor name.
1390204643Srdivacky    Action::TypeTy *Ty = Actions.getDestructorName(TildeLoc, *ClassName,
1391204643Srdivacky                                                   ClassNameLoc, CurScope,
1392204643Srdivacky                                                   SS, ObjectType,
1393204643Srdivacky                                                   EnteringContext);
1394204643Srdivacky    if (!Ty)
1395198893Srdivacky      return true;
1396204643Srdivacky
1397198893Srdivacky    Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
1398198893Srdivacky    return false;
1399198893Srdivacky  }
1400198893Srdivacky
1401198893Srdivacky  Diag(Tok, diag::err_expected_unqualified_id)
1402198893Srdivacky    << getLang().CPlusPlus;
1403198893Srdivacky  return true;
1404198893Srdivacky}
1405198893Srdivacky
1406193326Sed/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
1407193326Sed/// memory in a typesafe manner and call constructors.
1408198092Srdivacky///
1409193326Sed/// This method is called to parse the new expression after the optional :: has
1410193326Sed/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
1411193326Sed/// is its location.  Otherwise, "Start" is the location of the 'new' token.
1412193326Sed///
1413193326Sed///        new-expression:
1414193326Sed///                   '::'[opt] 'new' new-placement[opt] new-type-id
1415193326Sed///                                     new-initializer[opt]
1416193326Sed///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
1417193326Sed///                                     new-initializer[opt]
1418193326Sed///
1419193326Sed///        new-placement:
1420193326Sed///                   '(' expression-list ')'
1421193326Sed///
1422193326Sed///        new-type-id:
1423193326Sed///                   type-specifier-seq new-declarator[opt]
1424193326Sed///
1425193326Sed///        new-declarator:
1426193326Sed///                   ptr-operator new-declarator[opt]
1427193326Sed///                   direct-new-declarator
1428193326Sed///
1429193326Sed///        new-initializer:
1430193326Sed///                   '(' expression-list[opt] ')'
1431193326Sed/// [C++0x]           braced-init-list                                   [TODO]
1432193326Sed///
1433193326SedParser::OwningExprResult
1434193326SedParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
1435193326Sed  assert(Tok.is(tok::kw_new) && "expected 'new' token");
1436193326Sed  ConsumeToken();   // Consume 'new'
1437193326Sed
1438193326Sed  // A '(' now can be a new-placement or the '(' wrapping the type-id in the
1439193326Sed  // second form of new-expression. It can't be a new-type-id.
1440193326Sed
1441193326Sed  ExprVector PlacementArgs(Actions);
1442193326Sed  SourceLocation PlacementLParen, PlacementRParen;
1443193326Sed
1444193326Sed  bool ParenTypeId;
1445193326Sed  DeclSpec DS;
1446193326Sed  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1447193326Sed  if (Tok.is(tok::l_paren)) {
1448193326Sed    // If it turns out to be a placement, we change the type location.
1449193326Sed    PlacementLParen = ConsumeParen();
1450193326Sed    if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
1451193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
1452193326Sed      return ExprError();
1453193326Sed    }
1454193326Sed
1455193326Sed    PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
1456193326Sed    if (PlacementRParen.isInvalid()) {
1457193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
1458193326Sed      return ExprError();
1459193326Sed    }
1460193326Sed
1461193326Sed    if (PlacementArgs.empty()) {
1462193326Sed      // Reset the placement locations. There was no placement.
1463193326Sed      PlacementLParen = PlacementRParen = SourceLocation();
1464193326Sed      ParenTypeId = true;
1465193326Sed    } else {
1466193326Sed      // We still need the type.
1467193326Sed      if (Tok.is(tok::l_paren)) {
1468193326Sed        SourceLocation LParen = ConsumeParen();
1469193326Sed        ParseSpecifierQualifierList(DS);
1470193326Sed        DeclaratorInfo.SetSourceRange(DS.getSourceRange());
1471193326Sed        ParseDeclarator(DeclaratorInfo);
1472193326Sed        MatchRHSPunctuation(tok::r_paren, LParen);
1473193326Sed        ParenTypeId = true;
1474193326Sed      } else {
1475193326Sed        if (ParseCXXTypeSpecifierSeq(DS))
1476193326Sed          DeclaratorInfo.setInvalidType(true);
1477193326Sed        else {
1478193326Sed          DeclaratorInfo.SetSourceRange(DS.getSourceRange());
1479193326Sed          ParseDeclaratorInternal(DeclaratorInfo,
1480193326Sed                                  &Parser::ParseDirectNewDeclarator);
1481193326Sed        }
1482193326Sed        ParenTypeId = false;
1483193326Sed      }
1484193326Sed    }
1485193326Sed  } else {
1486193326Sed    // A new-type-id is a simplified type-id, where essentially the
1487193326Sed    // direct-declarator is replaced by a direct-new-declarator.
1488193326Sed    if (ParseCXXTypeSpecifierSeq(DS))
1489193326Sed      DeclaratorInfo.setInvalidType(true);
1490193326Sed    else {
1491193326Sed      DeclaratorInfo.SetSourceRange(DS.getSourceRange());
1492193326Sed      ParseDeclaratorInternal(DeclaratorInfo,
1493193326Sed                              &Parser::ParseDirectNewDeclarator);
1494193326Sed    }
1495193326Sed    ParenTypeId = false;
1496193326Sed  }
1497193326Sed  if (DeclaratorInfo.isInvalidType()) {
1498193326Sed    SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
1499193326Sed    return ExprError();
1500193326Sed  }
1501193326Sed
1502193326Sed  ExprVector ConstructorArgs(Actions);
1503193326Sed  SourceLocation ConstructorLParen, ConstructorRParen;
1504193326Sed
1505193326Sed  if (Tok.is(tok::l_paren)) {
1506193326Sed    ConstructorLParen = ConsumeParen();
1507193326Sed    if (Tok.isNot(tok::r_paren)) {
1508193326Sed      CommaLocsTy CommaLocs;
1509193326Sed      if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
1510193326Sed        SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
1511193326Sed        return ExprError();
1512193326Sed      }
1513193326Sed    }
1514193326Sed    ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
1515193326Sed    if (ConstructorRParen.isInvalid()) {
1516193326Sed      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
1517193326Sed      return ExprError();
1518193326Sed    }
1519193326Sed  }
1520193326Sed
1521193326Sed  return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
1522193326Sed                             move_arg(PlacementArgs), PlacementRParen,
1523193326Sed                             ParenTypeId, DeclaratorInfo, ConstructorLParen,
1524193326Sed                             move_arg(ConstructorArgs), ConstructorRParen);
1525193326Sed}
1526193326Sed
1527193326Sed/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
1528193326Sed/// passed to ParseDeclaratorInternal.
1529193326Sed///
1530193326Sed///        direct-new-declarator:
1531193326Sed///                   '[' expression ']'
1532193326Sed///                   direct-new-declarator '[' constant-expression ']'
1533193326Sed///
1534193326Sedvoid Parser::ParseDirectNewDeclarator(Declarator &D) {
1535193326Sed  // Parse the array dimensions.
1536193326Sed  bool first = true;
1537193326Sed  while (Tok.is(tok::l_square)) {
1538193326Sed    SourceLocation LLoc = ConsumeBracket();
1539193326Sed    OwningExprResult Size(first ? ParseExpression()
1540193326Sed                                : ParseConstantExpression());
1541193326Sed    if (Size.isInvalid()) {
1542193326Sed      // Recover
1543193326Sed      SkipUntil(tok::r_square);
1544193326Sed      return;
1545193326Sed    }
1546193326Sed    first = false;
1547193326Sed
1548193326Sed    SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
1549193326Sed    D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
1550198092Srdivacky                                            Size.release(), LLoc, RLoc),
1551193326Sed                  RLoc);
1552193326Sed
1553193326Sed    if (RLoc.isInvalid())
1554193326Sed      return;
1555193326Sed  }
1556193326Sed}
1557193326Sed
1558193326Sed/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
1559193326Sed/// This ambiguity appears in the syntax of the C++ new operator.
1560193326Sed///
1561193326Sed///        new-expression:
1562193326Sed///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
1563193326Sed///                                     new-initializer[opt]
1564193326Sed///
1565193326Sed///        new-placement:
1566193326Sed///                   '(' expression-list ')'
1567193326Sed///
1568193326Sedbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
1569193326Sed                                         Declarator &D) {
1570193326Sed  // The '(' was already consumed.
1571193326Sed  if (isTypeIdInParens()) {
1572193326Sed    ParseSpecifierQualifierList(D.getMutableDeclSpec());
1573193326Sed    D.SetSourceRange(D.getDeclSpec().getSourceRange());
1574193326Sed    ParseDeclarator(D);
1575193326Sed    return D.isInvalidType();
1576193326Sed  }
1577193326Sed
1578193326Sed  // It's not a type, it has to be an expression list.
1579193326Sed  // Discard the comma locations - ActOnCXXNew has enough parameters.
1580193326Sed  CommaLocsTy CommaLocs;
1581193326Sed  return ParseExpressionList(PlacementArgs, CommaLocs);
1582193326Sed}
1583193326Sed
1584193326Sed/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
1585193326Sed/// to free memory allocated by new.
1586193326Sed///
1587193326Sed/// This method is called to parse the 'delete' expression after the optional
1588193326Sed/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
1589193326Sed/// and "Start" is its location.  Otherwise, "Start" is the location of the
1590193326Sed/// 'delete' token.
1591193326Sed///
1592193326Sed///        delete-expression:
1593193326Sed///                   '::'[opt] 'delete' cast-expression
1594193326Sed///                   '::'[opt] 'delete' '[' ']' cast-expression
1595193326SedParser::OwningExprResult
1596193326SedParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
1597193326Sed  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
1598193326Sed  ConsumeToken(); // Consume 'delete'
1599193326Sed
1600193326Sed  // Array delete?
1601193326Sed  bool ArrayDelete = false;
1602193326Sed  if (Tok.is(tok::l_square)) {
1603193326Sed    ArrayDelete = true;
1604193326Sed    SourceLocation LHS = ConsumeBracket();
1605193326Sed    SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
1606193326Sed    if (RHS.isInvalid())
1607193326Sed      return ExprError();
1608193326Sed  }
1609193326Sed
1610193326Sed  OwningExprResult Operand(ParseCastExpression(false));
1611193326Sed  if (Operand.isInvalid())
1612193326Sed    return move(Operand);
1613193326Sed
1614193326Sed  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
1615193326Sed}
1616193326Sed
1617198092Srdivackystatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
1618193326Sed  switch(kind) {
1619193326Sed  default: assert(false && "Not a known unary type trait.");
1620193326Sed  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
1621193326Sed  case tok::kw___has_nothrow_copy:        return UTT_HasNothrowCopy;
1622193326Sed  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
1623193326Sed  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
1624193326Sed  case tok::kw___has_trivial_copy:        return UTT_HasTrivialCopy;
1625193326Sed  case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
1626193326Sed  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
1627193326Sed  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
1628193326Sed  case tok::kw___is_abstract:             return UTT_IsAbstract;
1629193326Sed  case tok::kw___is_class:                return UTT_IsClass;
1630193326Sed  case tok::kw___is_empty:                return UTT_IsEmpty;
1631193326Sed  case tok::kw___is_enum:                 return UTT_IsEnum;
1632193326Sed  case tok::kw___is_pod:                  return UTT_IsPOD;
1633193326Sed  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
1634193326Sed  case tok::kw___is_union:                return UTT_IsUnion;
1635200583Srdivacky  case tok::kw___is_literal:              return UTT_IsLiteral;
1636193326Sed  }
1637193326Sed}
1638193326Sed
1639193326Sed/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
1640193326Sed/// pseudo-functions that allow implementation of the TR1/C++0x type traits
1641193326Sed/// templates.
1642193326Sed///
1643193326Sed///       primary-expression:
1644193326Sed/// [GNU]             unary-type-trait '(' type-id ')'
1645193326Sed///
1646198092SrdivackyParser::OwningExprResult Parser::ParseUnaryTypeTrait() {
1647193326Sed  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
1648193326Sed  SourceLocation Loc = ConsumeToken();
1649193326Sed
1650193326Sed  SourceLocation LParen = Tok.getLocation();
1651193326Sed  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
1652193326Sed    return ExprError();
1653193326Sed
1654193326Sed  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
1655193326Sed  // there will be cryptic errors about mismatched parentheses and missing
1656193326Sed  // specifiers.
1657193326Sed  TypeResult Ty = ParseTypeName();
1658193326Sed
1659193326Sed  SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
1660193326Sed
1661193326Sed  if (Ty.isInvalid())
1662193326Sed    return ExprError();
1663193326Sed
1664193326Sed  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
1665193326Sed}
1666193326Sed
1667193326Sed/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
1668193326Sed/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
1669193326Sed/// based on the context past the parens.
1670193326SedParser::OwningExprResult
1671193326SedParser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
1672193326Sed                                         TypeTy *&CastTy,
1673193326Sed                                         SourceLocation LParenLoc,
1674193326Sed                                         SourceLocation &RParenLoc) {
1675193326Sed  assert(getLang().CPlusPlus && "Should only be called for C++!");
1676193326Sed  assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
1677193326Sed  assert(isTypeIdInParens() && "Not a type-id!");
1678193326Sed
1679193326Sed  OwningExprResult Result(Actions, true);
1680193326Sed  CastTy = 0;
1681193326Sed
1682193326Sed  // We need to disambiguate a very ugly part of the C++ syntax:
1683193326Sed  //
1684193326Sed  // (T())x;  - type-id
1685193326Sed  // (T())*x; - type-id
1686193326Sed  // (T())/x; - expression
1687193326Sed  // (T());   - expression
1688193326Sed  //
1689193326Sed  // The bad news is that we cannot use the specialized tentative parser, since
1690193326Sed  // it can only verify that the thing inside the parens can be parsed as
1691193326Sed  // type-id, it is not useful for determining the context past the parens.
1692193326Sed  //
1693193326Sed  // The good news is that the parser can disambiguate this part without
1694193326Sed  // making any unnecessary Action calls.
1695193326Sed  //
1696193326Sed  // It uses a scheme similar to parsing inline methods. The parenthesized
1697193326Sed  // tokens are cached, the context that follows is determined (possibly by
1698193326Sed  // parsing a cast-expression), and then we re-introduce the cached tokens
1699193326Sed  // into the token stream and parse them appropriately.
1700193326Sed
1701198092Srdivacky  ParenParseOption ParseAs;
1702193326Sed  CachedTokens Toks;
1703193326Sed
1704193326Sed  // Store the tokens of the parentheses. We will parse them after we determine
1705193326Sed  // the context that follows them.
1706193326Sed  if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) {
1707193326Sed    // We didn't find the ')' we expected.
1708193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1709193326Sed    return ExprError();
1710193326Sed  }
1711193326Sed
1712193326Sed  if (Tok.is(tok::l_brace)) {
1713193326Sed    ParseAs = CompoundLiteral;
1714193326Sed  } else {
1715193326Sed    bool NotCastExpr;
1716193326Sed    // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
1717193326Sed    if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
1718193326Sed      NotCastExpr = true;
1719193326Sed    } else {
1720193326Sed      // Try parsing the cast-expression that may follow.
1721193326Sed      // If it is not a cast-expression, NotCastExpr will be true and no token
1722193326Sed      // will be consumed.
1723193326Sed      Result = ParseCastExpression(false/*isUnaryExpression*/,
1724193326Sed                                   false/*isAddressofOperand*/,
1725198092Srdivacky                                   NotCastExpr, false);
1726193326Sed    }
1727193326Sed
1728193326Sed    // If we parsed a cast-expression, it's really a type-id, otherwise it's
1729193326Sed    // an expression.
1730193326Sed    ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
1731193326Sed  }
1732193326Sed
1733198092Srdivacky  // The current token should go after the cached tokens.
1734193326Sed  Toks.push_back(Tok);
1735193326Sed  // Re-enter the stored parenthesized tokens into the token stream, so we may
1736193326Sed  // parse them now.
1737193326Sed  PP.EnterTokenStream(Toks.data(), Toks.size(),
1738193326Sed                      true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
1739193326Sed  // Drop the current token and bring the first cached one. It's the same token
1740193326Sed  // as when we entered this function.
1741193326Sed  ConsumeAnyToken();
1742193326Sed
1743193326Sed  if (ParseAs >= CompoundLiteral) {
1744193326Sed    TypeResult Ty = ParseTypeName();
1745193326Sed
1746193326Sed    // Match the ')'.
1747193326Sed    if (Tok.is(tok::r_paren))
1748193326Sed      RParenLoc = ConsumeParen();
1749193326Sed    else
1750193326Sed      MatchRHSPunctuation(tok::r_paren, LParenLoc);
1751193326Sed
1752193326Sed    if (ParseAs == CompoundLiteral) {
1753193326Sed      ExprType = CompoundLiteral;
1754193326Sed      return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
1755193326Sed    }
1756198092Srdivacky
1757193326Sed    // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
1758193326Sed    assert(ParseAs == CastExpr);
1759193326Sed
1760193326Sed    if (Ty.isInvalid())
1761193326Sed      return ExprError();
1762193326Sed
1763193326Sed    CastTy = Ty.get();
1764193326Sed
1765193326Sed    // Result is what ParseCastExpression returned earlier.
1766193326Sed    if (!Result.isInvalid())
1767198092Srdivacky      Result = Actions.ActOnCastExpr(CurScope, LParenLoc, CastTy, RParenLoc,
1768198092Srdivacky                                     move(Result));
1769193326Sed    return move(Result);
1770193326Sed  }
1771198092Srdivacky
1772193326Sed  // Not a compound literal, and not followed by a cast-expression.
1773193326Sed  assert(ParseAs == SimpleExpr);
1774193326Sed
1775193326Sed  ExprType = SimpleExpr;
1776193326Sed  Result = ParseExpression();
1777193326Sed  if (!Result.isInvalid() && Tok.is(tok::r_paren))
1778193326Sed    Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
1779193326Sed
1780193326Sed  // Match the ')'.
1781193326Sed  if (Result.isInvalid()) {
1782193326Sed    SkipUntil(tok::r_paren);
1783193326Sed    return ExprError();
1784193326Sed  }
1785198092Srdivacky
1786193326Sed  if (Tok.is(tok::r_paren))
1787193326Sed    RParenLoc = ConsumeParen();
1788193326Sed  else
1789193326Sed    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1790193326Sed
1791193326Sed  return move(Result);
1792193326Sed}
1793