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//===----------------------------------------------------------------------===//
13263508Sdim#include "clang/AST/DeclTemplate.h"
14193326Sed#include "clang/Parse/Parser.h"
15218893Sdim#include "RAIIObjectsForParser.h"
16234353Sdim#include "clang/Basic/PrettyStackTrace.h"
17234353Sdim#include "clang/Lex/LiteralSupport.h"
18249423Sdim#include "clang/Parse/ParseDiagnostic.h"
19212904Sdim#include "clang/Sema/DeclSpec.h"
20249423Sdim#include "clang/Sema/ParsedTemplate.h"
21226633Sdim#include "clang/Sema/Scope.h"
22198893Srdivacky#include "llvm/Support/ErrorHandling.h"
23198893Srdivacky
24263508Sdim
25193326Sedusing namespace clang;
26193326Sed
27221345Sdimstatic int SelectDigraphErrorMessage(tok::TokenKind Kind) {
28221345Sdim  switch (Kind) {
29221345Sdim    case tok::kw_template:         return 0;
30221345Sdim    case tok::kw_const_cast:       return 1;
31221345Sdim    case tok::kw_dynamic_cast:     return 2;
32221345Sdim    case tok::kw_reinterpret_cast: return 3;
33221345Sdim    case tok::kw_static_cast:      return 4;
34221345Sdim    default:
35226633Sdim      llvm_unreachable("Unknown type for digraph error message.");
36221345Sdim  }
37221345Sdim}
38221345Sdim
39221345Sdim// Are the two tokens adjacent in the same source file?
40239462Sdimbool Parser::areTokensAdjacent(const Token &First, const Token &Second) {
41221345Sdim  SourceManager &SM = PP.getSourceManager();
42221345Sdim  SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation());
43226633Sdim  SourceLocation FirstEnd = FirstLoc.getLocWithOffset(First.getLength());
44221345Sdim  return FirstEnd == SM.getSpellingLoc(Second.getLocation());
45221345Sdim}
46221345Sdim
47221345Sdim// Suggest fixit for "<::" after a cast.
48221345Sdimstatic void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken,
49221345Sdim                       Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) {
50221345Sdim  // Pull '<:' and ':' off token stream.
51221345Sdim  if (!AtDigraph)
52221345Sdim    PP.Lex(DigraphToken);
53221345Sdim  PP.Lex(ColonToken);
54221345Sdim
55221345Sdim  SourceRange Range;
56221345Sdim  Range.setBegin(DigraphToken.getLocation());
57221345Sdim  Range.setEnd(ColonToken.getLocation());
58221345Sdim  P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph)
59221345Sdim      << SelectDigraphErrorMessage(Kind)
60221345Sdim      << FixItHint::CreateReplacement(Range, "< ::");
61221345Sdim
62221345Sdim  // Update token information to reflect their change in token type.
63221345Sdim  ColonToken.setKind(tok::coloncolon);
64226633Sdim  ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(-1));
65221345Sdim  ColonToken.setLength(2);
66221345Sdim  DigraphToken.setKind(tok::less);
67221345Sdim  DigraphToken.setLength(1);
68221345Sdim
69221345Sdim  // Push new tokens back to token stream.
70221345Sdim  PP.EnterToken(ColonToken);
71221345Sdim  if (!AtDigraph)
72221345Sdim    PP.EnterToken(DigraphToken);
73221345Sdim}
74221345Sdim
75226633Sdim// Check for '<::' which should be '< ::' instead of '[:' when following
76226633Sdim// a template name.
77226633Sdimvoid Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
78226633Sdim                                        bool EnteringContext,
79226633Sdim                                        IdentifierInfo &II, CXXScopeSpec &SS) {
80226633Sdim  if (!Next.is(tok::l_square) || Next.getLength() != 2)
81226633Sdim    return;
82226633Sdim
83226633Sdim  Token SecondToken = GetLookAheadToken(2);
84239462Sdim  if (!SecondToken.is(tok::colon) || !areTokensAdjacent(Next, SecondToken))
85226633Sdim    return;
86226633Sdim
87226633Sdim  TemplateTy Template;
88226633Sdim  UnqualifiedId TemplateName;
89226633Sdim  TemplateName.setIdentifier(&II, Tok.getLocation());
90226633Sdim  bool MemberOfUnknownSpecialization;
91226633Sdim  if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false,
92226633Sdim                              TemplateName, ObjectType, EnteringContext,
93226633Sdim                              Template, MemberOfUnknownSpecialization))
94226633Sdim    return;
95226633Sdim
96226633Sdim  FixDigraph(*this, PP, Next, SecondToken, tok::kw_template,
97226633Sdim             /*AtDigraph*/false);
98226633Sdim}
99226633Sdim
100243830Sdim/// \brief Emits an error for a left parentheses after a double colon.
101243830Sdim///
102243830Sdim/// When a '(' is found after a '::', emit an error.  Attempt to fix the token
103249423Sdim/// stream by removing the '(', and the matching ')' if found.
104243830Sdimvoid Parser::CheckForLParenAfterColonColon() {
105243830Sdim  if (!Tok.is(tok::l_paren))
106243830Sdim    return;
107243830Sdim
108243830Sdim  SourceLocation l_parenLoc = ConsumeParen(), r_parenLoc;
109243830Sdim  Token Tok1 = getCurToken();
110243830Sdim  if (!Tok1.is(tok::identifier) && !Tok1.is(tok::star))
111243830Sdim    return;
112243830Sdim
113243830Sdim  if (Tok1.is(tok::identifier)) {
114243830Sdim    Token Tok2 = GetLookAheadToken(1);
115243830Sdim    if (Tok2.is(tok::r_paren)) {
116243830Sdim      ConsumeToken();
117243830Sdim      PP.EnterToken(Tok1);
118243830Sdim      r_parenLoc = ConsumeParen();
119243830Sdim    }
120243830Sdim  } else if (Tok1.is(tok::star)) {
121243830Sdim    Token Tok2 = GetLookAheadToken(1);
122243830Sdim    if (Tok2.is(tok::identifier)) {
123243830Sdim      Token Tok3 = GetLookAheadToken(2);
124243830Sdim      if (Tok3.is(tok::r_paren)) {
125243830Sdim        ConsumeToken();
126243830Sdim        ConsumeToken();
127243830Sdim        PP.EnterToken(Tok2);
128243830Sdim        PP.EnterToken(Tok1);
129243830Sdim        r_parenLoc = ConsumeParen();
130243830Sdim      }
131243830Sdim    }
132243830Sdim  }
133243830Sdim
134243830Sdim  Diag(l_parenLoc, diag::err_paren_after_colon_colon)
135243830Sdim      << FixItHint::CreateRemoval(l_parenLoc)
136243830Sdim      << FixItHint::CreateRemoval(r_parenLoc);
137243830Sdim}
138243830Sdim
139198092Srdivacky/// \brief Parse global scope or nested-name-specifier if present.
140193326Sed///
141198092Srdivacky/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
142198092Srdivacky/// may be preceded by '::'). Note that this routine will not parse ::new or
143198092Srdivacky/// ::delete; it will just leave them in the token stream.
144198092Srdivacky///
145193326Sed///       '::'[opt] nested-name-specifier
146193326Sed///       '::'
147193326Sed///
148193326Sed///       nested-name-specifier:
149193326Sed///         type-name '::'
150193326Sed///         namespace-name '::'
151193326Sed///         nested-name-specifier identifier '::'
152198092Srdivacky///         nested-name-specifier 'template'[opt] simple-template-id '::'
153193326Sed///
154198092Srdivacky///
155198092Srdivacky/// \param SS the scope specifier that will be set to the parsed
156198092Srdivacky/// nested-name-specifier (or empty)
157198092Srdivacky///
158198092Srdivacky/// \param ObjectType if this nested-name-specifier is being parsed following
159198092Srdivacky/// the "." or "->" of a member access expression, this parameter provides the
160198092Srdivacky/// type of the object whose members are being accessed.
161198092Srdivacky///
162198092Srdivacky/// \param EnteringContext whether we will be entering into the context of
163198092Srdivacky/// the nested-name-specifier after parsing it.
164198092Srdivacky///
165204643Srdivacky/// \param MayBePseudoDestructor When non-NULL, points to a flag that
166204643Srdivacky/// indicates whether this nested-name-specifier may be part of a
167204643Srdivacky/// pseudo-destructor name. In this case, the flag will be set false
168204643Srdivacky/// if we don't actually end up parsing a destructor name. Moreorover,
169204643Srdivacky/// if we do end up determining that we are parsing a destructor name,
170204643Srdivacky/// the last component of the nested-name-specifier is not parsed as
171204643Srdivacky/// part of the scope specifier.
172204643Srdivacky///
173249423Sdim/// \param IsTypename If \c true, this nested-name-specifier is known to be
174249423Sdim/// part of a type name. This is used to improve error recovery.
175249423Sdim///
176249423Sdim/// \param LastII When non-NULL, points to an IdentifierInfo* that will be
177249423Sdim/// filled in with the leading identifier in the last component of the
178249423Sdim/// nested-name-specifier, if any.
179249423Sdim///
180204643Srdivacky/// \returns true if there was an error parsing a scope specifier
181198092Srdivackybool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
182212904Sdim                                            ParsedType ObjectType,
183204643Srdivacky                                            bool EnteringContext,
184221345Sdim                                            bool *MayBePseudoDestructor,
185249423Sdim                                            bool IsTypename,
186249423Sdim                                            IdentifierInfo **LastII) {
187234353Sdim  assert(getLangOpts().CPlusPlus &&
188193326Sed         "Call sites of this function should be guarded by checking for C++");
189193326Sed
190193326Sed  if (Tok.is(tok::annot_cxxscope)) {
191249423Sdim    assert(!LastII && "want last identifier but have already annotated scope");
192219077Sdim    Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
193219077Sdim                                                 Tok.getAnnotationRange(),
194219077Sdim                                                 SS);
195193326Sed    ConsumeToken();
196204643Srdivacky    return false;
197193326Sed  }
198193326Sed
199263508Sdim  if (Tok.is(tok::annot_template_id)) {
200263508Sdim    // If the current token is an annotated template id, it may already have
201263508Sdim    // a scope specifier. Restore it.
202263508Sdim    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
203263508Sdim    SS = TemplateId->SS;
204263508Sdim  }
205263508Sdim
206249423Sdim  if (LastII)
207249423Sdim    *LastII = 0;
208249423Sdim
209193326Sed  bool HasScopeSpecifier = false;
210193326Sed
211193326Sed  if (Tok.is(tok::coloncolon)) {
212193326Sed    // ::new and ::delete aren't nested-name-specifiers.
213193326Sed    tok::TokenKind NextKind = NextToken().getKind();
214193326Sed    if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
215193326Sed      return false;
216198092Srdivacky
217193326Sed    // '::' - Global scope qualifier.
218219077Sdim    if (Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), ConsumeToken(), SS))
219219077Sdim      return true;
220243830Sdim
221243830Sdim    CheckForLParenAfterColonColon();
222243830Sdim
223193326Sed    HasScopeSpecifier = true;
224193326Sed  }
225193326Sed
226204643Srdivacky  bool CheckForDestructor = false;
227204643Srdivacky  if (MayBePseudoDestructor && *MayBePseudoDestructor) {
228204643Srdivacky    CheckForDestructor = true;
229204643Srdivacky    *MayBePseudoDestructor = false;
230204643Srdivacky  }
231204643Srdivacky
232234353Sdim  if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) {
233234353Sdim    DeclSpec DS(AttrFactory);
234234353Sdim    SourceLocation DeclLoc = Tok.getLocation();
235234353Sdim    SourceLocation EndLoc  = ParseDecltypeSpecifier(DS);
236234353Sdim    if (Tok.isNot(tok::coloncolon)) {
237234353Sdim      AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc);
238234353Sdim      return false;
239234353Sdim    }
240234353Sdim
241234353Sdim    SourceLocation CCLoc = ConsumeToken();
242234353Sdim    if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, CCLoc))
243234353Sdim      SS.SetInvalid(SourceRange(DeclLoc, CCLoc));
244234353Sdim
245234353Sdim    HasScopeSpecifier = true;
246234353Sdim  }
247234353Sdim
248193326Sed  while (true) {
249198092Srdivacky    if (HasScopeSpecifier) {
250198092Srdivacky      // C++ [basic.lookup.classref]p5:
251198092Srdivacky      //   If the qualified-id has the form
252198092Srdivacky      //
253198092Srdivacky      //       ::class-name-or-namespace-name::...
254198092Srdivacky      //
255198092Srdivacky      //   the class-name-or-namespace-name is looked up in global scope as a
256198092Srdivacky      //   class-name or namespace-name.
257198092Srdivacky      //
258198092Srdivacky      // To implement this, we clear out the object type as soon as we've
259198092Srdivacky      // seen a leading '::' or part of a nested-name-specifier.
260212904Sdim      ObjectType = ParsedType();
261198092Srdivacky
262198092Srdivacky      if (Tok.is(tok::code_completion)) {
263198092Srdivacky        // Code completion for a nested-name-specifier, where the code
264198092Srdivacky        // code completion token follows the '::'.
265210299Sed        Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext);
266221345Sdim        // Include code completion token into the range of the scope otherwise
267221345Sdim        // when we try to annotate the scope tokens the dangling code completion
268221345Sdim        // token will cause assertion in
269221345Sdim        // Preprocessor::AnnotatePreviousCachedTokens.
270226633Sdim        SS.setEndLoc(Tok.getLocation());
271226633Sdim        cutOffParsing();
272226633Sdim        return true;
273198092Srdivacky      }
274198092Srdivacky    }
275198092Srdivacky
276193326Sed    // nested-name-specifier:
277195099Sed    //   nested-name-specifier 'template'[opt] simple-template-id '::'
278195099Sed
279195099Sed    // Parse the optional 'template' keyword, then make sure we have
280195099Sed    // 'identifier <' after it.
281195099Sed    if (Tok.is(tok::kw_template)) {
282198092Srdivacky      // If we don't have a scope specifier or an object type, this isn't a
283198092Srdivacky      // nested-name-specifier, since they aren't allowed to start with
284198092Srdivacky      // 'template'.
285198092Srdivacky      if (!HasScopeSpecifier && !ObjectType)
286198092Srdivacky        break;
287198092Srdivacky
288199482Srdivacky      TentativeParsingAction TPA(*this);
289195099Sed      SourceLocation TemplateKWLoc = ConsumeToken();
290198893Srdivacky
291198893Srdivacky      UnqualifiedId TemplateName;
292198893Srdivacky      if (Tok.is(tok::identifier)) {
293199482Srdivacky        // Consume the identifier.
294198893Srdivacky        TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
295198893Srdivacky        ConsumeToken();
296198893Srdivacky      } else if (Tok.is(tok::kw_operator)) {
297198893Srdivacky        if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType,
298199482Srdivacky                                       TemplateName)) {
299199482Srdivacky          TPA.Commit();
300198893Srdivacky          break;
301199482Srdivacky        }
302198893Srdivacky
303199990Srdivacky        if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId &&
304199990Srdivacky            TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) {
305198893Srdivacky          Diag(TemplateName.getSourceRange().getBegin(),
306198893Srdivacky               diag::err_id_after_template_in_nested_name_spec)
307198893Srdivacky            << TemplateName.getSourceRange();
308199482Srdivacky          TPA.Commit();
309198893Srdivacky          break;
310198893Srdivacky        }
311198893Srdivacky      } else {
312199482Srdivacky        TPA.Revert();
313195099Sed        break;
314193326Sed      }
315198092Srdivacky
316199482Srdivacky      // If the next token is not '<', we have a qualified-id that refers
317199482Srdivacky      // to a template name, such as T::template apply, but is not a
318199482Srdivacky      // template-id.
319199482Srdivacky      if (Tok.isNot(tok::less)) {
320199482Srdivacky        TPA.Revert();
321199482Srdivacky        break;
322199482Srdivacky      }
323199482Srdivacky
324199482Srdivacky      // Commit to parsing the template-id.
325199482Srdivacky      TPA.Commit();
326210299Sed      TemplateTy Template;
327234353Sdim      if (TemplateNameKind TNK
328234353Sdim          = Actions.ActOnDependentTemplateName(getCurScope(),
329234353Sdim                                               SS, TemplateKWLoc, TemplateName,
330234353Sdim                                               ObjectType, EnteringContext,
331234353Sdim                                               Template)) {
332234353Sdim        if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc,
333234353Sdim                                    TemplateName, false))
334210299Sed          return true;
335210299Sed      } else
336204643Srdivacky        return true;
337198092Srdivacky
338193326Sed      continue;
339193326Sed    }
340198092Srdivacky
341193326Sed    if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
342198092Srdivacky      // We have
343193326Sed      //
344193326Sed      //   simple-template-id '::'
345193326Sed      //
346193326Sed      // So we need to check whether the simple-template-id is of the
347193326Sed      // right kind (it should name a type or be dependent), and then
348193326Sed      // convert it into a type within the nested-name-specifier.
349224145Sdim      TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
350204643Srdivacky      if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {
351204643Srdivacky        *MayBePseudoDestructor = true;
352204643Srdivacky        return false;
353204643Srdivacky      }
354193326Sed
355249423Sdim      if (LastII)
356249423Sdim        *LastII = TemplateId->Name;
357249423Sdim
358221345Sdim      // Consume the template-id token.
359221345Sdim      ConsumeToken();
360221345Sdim
361221345Sdim      assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
362221345Sdim      SourceLocation CCLoc = ConsumeToken();
363193326Sed
364234353Sdim      HasScopeSpecifier = true;
365221345Sdim
366243830Sdim      ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
367221345Sdim                                         TemplateId->NumArgs);
368221345Sdim
369221345Sdim      if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(),
370234353Sdim                                              SS,
371234353Sdim                                              TemplateId->TemplateKWLoc,
372221345Sdim                                              TemplateId->Template,
373221345Sdim                                              TemplateId->TemplateNameLoc,
374221345Sdim                                              TemplateId->LAngleLoc,
375221345Sdim                                              TemplateArgsPtr,
376221345Sdim                                              TemplateId->RAngleLoc,
377221345Sdim                                              CCLoc,
378221345Sdim                                              EnteringContext)) {
379221345Sdim        SourceLocation StartLoc
380221345Sdim          = SS.getBeginLoc().isValid()? SS.getBeginLoc()
381221345Sdim                                      : TemplateId->TemplateNameLoc;
382221345Sdim        SS.SetInvalid(SourceRange(StartLoc, CCLoc));
383195099Sed      }
384223017Sdim
385221345Sdim      continue;
386193326Sed    }
387193326Sed
388195099Sed
389195099Sed    // The rest of the nested-name-specifier possibilities start with
390195099Sed    // tok::identifier.
391195099Sed    if (Tok.isNot(tok::identifier))
392195099Sed      break;
393195099Sed
394195099Sed    IdentifierInfo &II = *Tok.getIdentifierInfo();
395195099Sed
396195099Sed    // nested-name-specifier:
397195099Sed    //   type-name '::'
398195099Sed    //   namespace-name '::'
399195099Sed    //   nested-name-specifier identifier '::'
400195099Sed    Token Next = NextToken();
401200583Srdivacky
402200583Srdivacky    // If we get foo:bar, this is almost certainly a typo for foo::bar.  Recover
403200583Srdivacky    // and emit a fixit hint for it.
404204643Srdivacky    if (Next.is(tok::colon) && !ColonIsSacred) {
405219077Sdim      if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, II,
406219077Sdim                                            Tok.getLocation(),
407219077Sdim                                            Next.getLocation(), ObjectType,
408204643Srdivacky                                            EnteringContext) &&
409204643Srdivacky          // If the token after the colon isn't an identifier, it's still an
410204643Srdivacky          // error, but they probably meant something else strange so don't
411204643Srdivacky          // recover like this.
412204643Srdivacky          PP.LookAhead(1).is(tok::identifier)) {
413204643Srdivacky        Diag(Next, diag::err_unexected_colon_in_nested_name_spec)
414206084Srdivacky          << FixItHint::CreateReplacement(Next.getLocation(), "::");
415204643Srdivacky
416204643Srdivacky        // Recover as if the user wrote '::'.
417204643Srdivacky        Next.setKind(tok::coloncolon);
418204643Srdivacky      }
419200583Srdivacky    }
420200583Srdivacky
421195099Sed    if (Next.is(tok::coloncolon)) {
422204643Srdivacky      if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) &&
423210299Sed          !Actions.isNonTypeNestedNameSpecifier(getCurScope(), SS, Tok.getLocation(),
424204643Srdivacky                                                II, ObjectType)) {
425204643Srdivacky        *MayBePseudoDestructor = true;
426204643Srdivacky        return false;
427204643Srdivacky      }
428204643Srdivacky
429249423Sdim      if (LastII)
430249423Sdim        *LastII = &II;
431249423Sdim
432195099Sed      // We have an identifier followed by a '::'. Lookup this name
433195099Sed      // as the name in a nested-name-specifier.
434195099Sed      SourceLocation IdLoc = ConsumeToken();
435200583Srdivacky      assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) &&
436200583Srdivacky             "NextToken() not working properly!");
437195099Sed      SourceLocation CCLoc = ConsumeToken();
438198092Srdivacky
439243830Sdim      CheckForLParenAfterColonColon();
440243830Sdim
441219077Sdim      HasScopeSpecifier = true;
442219077Sdim      if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc,
443219077Sdim                                              ObjectType, EnteringContext, SS))
444219077Sdim        SS.SetInvalid(SourceRange(IdLoc, CCLoc));
445219077Sdim
446195099Sed      continue;
447195099Sed    }
448198092Srdivacky
449226633Sdim    CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS);
450221345Sdim
451195099Sed    // nested-name-specifier:
452195099Sed    //   type-name '<'
453195099Sed    if (Next.is(tok::less)) {
454195099Sed      TemplateTy Template;
455198893Srdivacky      UnqualifiedId TemplateName;
456198893Srdivacky      TemplateName.setIdentifier(&II, Tok.getLocation());
457208600Srdivacky      bool MemberOfUnknownSpecialization;
458210299Sed      if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS,
459212904Sdim                                              /*hasTemplateKeyword=*/false,
460198893Srdivacky                                                        TemplateName,
461198092Srdivacky                                                        ObjectType,
462198092Srdivacky                                                        EnteringContext,
463208600Srdivacky                                                        Template,
464208600Srdivacky                                              MemberOfUnknownSpecialization)) {
465234353Sdim        // We have found a template name, so annotate this token
466195099Sed        // with a template-id annotation. We do not permit the
467195099Sed        // template-id to be translated into a type annotation,
468195099Sed        // because some clients (e.g., the parsing of class template
469195099Sed        // specializations) still want to see the original template-id
470195099Sed        // token.
471198893Srdivacky        ConsumeToken();
472234353Sdim        if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
473234353Sdim                                    TemplateName, false))
474204643Srdivacky          return true;
475195099Sed        continue;
476263508Sdim      }
477263508Sdim
478208600Srdivacky      if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) &&
479221345Sdim          (IsTypename || IsTemplateArgumentList(1))) {
480208600Srdivacky        // We have something like t::getAs<T>, where getAs is a
481208600Srdivacky        // member of an unknown specialization. However, this will only
482208600Srdivacky        // parse correctly as a template, so suggest the keyword 'template'
483208600Srdivacky        // before 'getAs' and treat this as a dependent template name.
484221345Sdim        unsigned DiagID = diag::err_missing_dependent_template_keyword;
485234353Sdim        if (getLangOpts().MicrosoftExt)
486221345Sdim          DiagID = diag::warn_missing_dependent_template_keyword;
487221345Sdim
488221345Sdim        Diag(Tok.getLocation(), DiagID)
489208600Srdivacky          << II.getName()
490208600Srdivacky          << FixItHint::CreateInsertion(Tok.getLocation(), "template ");
491208600Srdivacky
492210299Sed        if (TemplateNameKind TNK
493210299Sed              = Actions.ActOnDependentTemplateName(getCurScope(),
494234353Sdim                                                   SS, SourceLocation(),
495210299Sed                                                   TemplateName, ObjectType,
496210299Sed                                                   EnteringContext, Template)) {
497210299Sed          // Consume the identifier.
498210299Sed          ConsumeToken();
499234353Sdim          if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
500234353Sdim                                      TemplateName, false))
501234353Sdim            return true;
502210299Sed        }
503210299Sed        else
504208600Srdivacky          return true;
505210299Sed
506208600Srdivacky        continue;
507195099Sed      }
508195099Sed    }
509195099Sed
510193326Sed    // We don't have any tokens that form the beginning of a
511193326Sed    // nested-name-specifier, so we're done.
512193326Sed    break;
513193326Sed  }
514198092Srdivacky
515204643Srdivacky  // Even if we didn't see any pieces of a nested-name-specifier, we
516204643Srdivacky  // still check whether there is a tilde in this position, which
517204643Srdivacky  // indicates a potential pseudo-destructor.
518204643Srdivacky  if (CheckForDestructor && Tok.is(tok::tilde))
519204643Srdivacky    *MayBePseudoDestructor = true;
520204643Srdivacky
521204643Srdivacky  return false;
522193326Sed}
523193326Sed
524193326Sed/// ParseCXXIdExpression - Handle id-expression.
525193326Sed///
526193326Sed///       id-expression:
527193326Sed///         unqualified-id
528193326Sed///         qualified-id
529193326Sed///
530193326Sed///       qualified-id:
531193326Sed///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
532193326Sed///         '::' identifier
533193326Sed///         '::' operator-function-id
534195341Sed///         '::' template-id
535193326Sed///
536193326Sed/// NOTE: The standard specifies that, for qualified-id, the parser does not
537193326Sed/// expect:
538193326Sed///
539193326Sed///   '::' conversion-function-id
540193326Sed///   '::' '~' class-name
541193326Sed///
542193326Sed/// This may cause a slight inconsistency on diagnostics:
543193326Sed///
544193326Sed/// class C {};
545193326Sed/// namespace A {}
546193326Sed/// void f() {
547193326Sed///   :: A :: ~ C(); // Some Sema error about using destructor with a
548193326Sed///                  // namespace.
549193326Sed///   :: ~ C(); // Some Parser error like 'unexpected ~'.
550193326Sed/// }
551193326Sed///
552193326Sed/// We simplify the parser a bit and make it work like:
553193326Sed///
554193326Sed///       qualified-id:
555193326Sed///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
556193326Sed///         '::' unqualified-id
557193326Sed///
558193326Sed/// That way Sema can handle and report similar errors for namespaces and the
559193326Sed/// global scope.
560193326Sed///
561193326Sed/// The isAddressOfOperand parameter indicates that this id-expression is a
562193326Sed/// direct operand of the address-of operator. This is, besides member contexts,
563193326Sed/// the only place where a qualified-id naming a non-static class member may
564193326Sed/// appear.
565193326Sed///
566212904SdimExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
567193326Sed  // qualified-id:
568193326Sed  //   '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
569193326Sed  //   '::' unqualified-id
570193326Sed  //
571193326Sed  CXXScopeSpec SS;
572234353Sdim  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
573234353Sdim
574234353Sdim  SourceLocation TemplateKWLoc;
575198893Srdivacky  UnqualifiedId Name;
576234353Sdim  if (ParseUnqualifiedId(SS,
577234353Sdim                         /*EnteringContext=*/false,
578234353Sdim                         /*AllowDestructorName=*/false,
579234353Sdim                         /*AllowConstructorName=*/false,
580212904Sdim                         /*ObjectType=*/ ParsedType(),
581234353Sdim                         TemplateKWLoc,
582198893Srdivacky                         Name))
583193326Sed    return ExprError();
584199990Srdivacky
585199990Srdivacky  // This is only the direct operand of an & operator if it is not
586199990Srdivacky  // followed by a postfix-expression suffix.
587212904Sdim  if (isAddressOfOperand && isPostfixExpressionSuffixStart())
588212904Sdim    isAddressOfOperand = false;
589234353Sdim
590234353Sdim  return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name,
591234353Sdim                                   Tok.is(tok::l_paren), isAddressOfOperand);
592193326Sed}
593193326Sed
594263508Sdim/// ParseLambdaExpression - Parse a C++11 lambda expression.
595226633Sdim///
596226633Sdim///       lambda-expression:
597226633Sdim///         lambda-introducer lambda-declarator[opt] compound-statement
598226633Sdim///
599226633Sdim///       lambda-introducer:
600226633Sdim///         '[' lambda-capture[opt] ']'
601226633Sdim///
602226633Sdim///       lambda-capture:
603226633Sdim///         capture-default
604226633Sdim///         capture-list
605226633Sdim///         capture-default ',' capture-list
606226633Sdim///
607226633Sdim///       capture-default:
608226633Sdim///         '&'
609226633Sdim///         '='
610226633Sdim///
611226633Sdim///       capture-list:
612226633Sdim///         capture
613226633Sdim///         capture-list ',' capture
614226633Sdim///
615226633Sdim///       capture:
616263508Sdim///         simple-capture
617263508Sdim///         init-capture     [C++1y]
618263508Sdim///
619263508Sdim///       simple-capture:
620226633Sdim///         identifier
621226633Sdim///         '&' identifier
622226633Sdim///         'this'
623226633Sdim///
624263508Sdim///       init-capture:      [C++1y]
625263508Sdim///         identifier initializer
626263508Sdim///         '&' identifier initializer
627263508Sdim///
628226633Sdim///       lambda-declarator:
629226633Sdim///         '(' parameter-declaration-clause ')' attribute-specifier[opt]
630226633Sdim///           'mutable'[opt] exception-specification[opt]
631226633Sdim///           trailing-return-type[opt]
632226633Sdim///
633226633SdimExprResult Parser::ParseLambdaExpression() {
634226633Sdim  // Parse lambda-introducer.
635226633Sdim  LambdaIntroducer Intro;
636263508Sdim  Optional<unsigned> DiagID = ParseLambdaIntroducer(Intro);
637226633Sdim  if (DiagID) {
638226633Sdim    Diag(Tok, DiagID.getValue());
639263508Sdim    SkipUntil(tok::r_square, StopAtSemi);
640263508Sdim    SkipUntil(tok::l_brace, StopAtSemi);
641263508Sdim    SkipUntil(tok::r_brace, StopAtSemi);
642234353Sdim    return ExprError();
643226633Sdim  }
644226633Sdim
645226633Sdim  return ParseLambdaExpressionAfterIntroducer(Intro);
646226633Sdim}
647226633Sdim
648226633Sdim/// TryParseLambdaExpression - Use lookahead and potentially tentative
649226633Sdim/// parsing to determine if we are looking at a C++0x lambda expression, and parse
650226633Sdim/// it if we are.
651226633Sdim///
652226633Sdim/// If we are not looking at a lambda expression, returns ExprError().
653226633SdimExprResult Parser::TryParseLambdaExpression() {
654249423Sdim  assert(getLangOpts().CPlusPlus11
655226633Sdim         && Tok.is(tok::l_square)
656226633Sdim         && "Not at the start of a possible lambda expression.");
657226633Sdim
658226633Sdim  const Token Next = NextToken(), After = GetLookAheadToken(2);
659226633Sdim
660226633Sdim  // If lookahead indicates this is a lambda...
661226633Sdim  if (Next.is(tok::r_square) ||     // []
662226633Sdim      Next.is(tok::equal) ||        // [=
663226633Sdim      (Next.is(tok::amp) &&         // [&] or [&,
664226633Sdim       (After.is(tok::r_square) ||
665226633Sdim        After.is(tok::comma))) ||
666226633Sdim      (Next.is(tok::identifier) &&  // [identifier]
667226633Sdim       After.is(tok::r_square))) {
668226633Sdim    return ParseLambdaExpression();
669226633Sdim  }
670226633Sdim
671234353Sdim  // If lookahead indicates an ObjC message send...
672234353Sdim  // [identifier identifier
673226633Sdim  if (Next.is(tok::identifier) && After.is(tok::identifier)) {
674234353Sdim    return ExprEmpty();
675226633Sdim  }
676263508Sdim
677234353Sdim  // Here, we're stuck: lambda introducers and Objective-C message sends are
678234353Sdim  // unambiguous, but it requires arbitrary lookhead.  [a,b,c,d,e,f,g] is a
679234353Sdim  // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send.  Instead of
680234353Sdim  // writing two routines to parse a lambda introducer, just try to parse
681234353Sdim  // a lambda introducer first, and fall back if that fails.
682234353Sdim  // (TryParseLambdaIntroducer never produces any diagnostic output.)
683226633Sdim  LambdaIntroducer Intro;
684226633Sdim  if (TryParseLambdaIntroducer(Intro))
685234353Sdim    return ExprEmpty();
686263508Sdim
687226633Sdim  return ParseLambdaExpressionAfterIntroducer(Intro);
688226633Sdim}
689226633Sdim
690263508Sdim/// \brief Parse a lambda introducer.
691263508Sdim/// \param Intro A LambdaIntroducer filled in with information about the
692263508Sdim///        contents of the lambda-introducer.
693263508Sdim/// \param SkippedInits If non-null, we are disambiguating between an Obj-C
694263508Sdim///        message send and a lambda expression. In this mode, we will
695263508Sdim///        sometimes skip the initializers for init-captures and not fully
696263508Sdim///        populate \p Intro. This flag will be set to \c true if we do so.
697263508Sdim/// \return A DiagnosticID if it hit something unexpected. The location for
698263508Sdim///         for the diagnostic is that of the current token.
699263508SdimOptional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
700263508Sdim                                                 bool *SkippedInits) {
701249423Sdim  typedef Optional<unsigned> DiagResult;
702226633Sdim
703226633Sdim  assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");
704226633Sdim  BalancedDelimiterTracker T(*this, tok::l_square);
705226633Sdim  T.consumeOpen();
706226633Sdim
707226633Sdim  Intro.Range.setBegin(T.getOpenLocation());
708226633Sdim
709226633Sdim  bool first = true;
710226633Sdim
711226633Sdim  // Parse capture-default.
712226633Sdim  if (Tok.is(tok::amp) &&
713226633Sdim      (NextToken().is(tok::comma) || NextToken().is(tok::r_square))) {
714226633Sdim    Intro.Default = LCD_ByRef;
715234353Sdim    Intro.DefaultLoc = ConsumeToken();
716226633Sdim    first = false;
717226633Sdim  } else if (Tok.is(tok::equal)) {
718226633Sdim    Intro.Default = LCD_ByCopy;
719234353Sdim    Intro.DefaultLoc = ConsumeToken();
720226633Sdim    first = false;
721226633Sdim  }
722226633Sdim
723226633Sdim  while (Tok.isNot(tok::r_square)) {
724226633Sdim    if (!first) {
725234353Sdim      if (Tok.isNot(tok::comma)) {
726239462Sdim        // Provide a completion for a lambda introducer here. Except
727239462Sdim        // in Objective-C, where this is Almost Surely meant to be a message
728239462Sdim        // send. In that case, fail here and let the ObjC message
729239462Sdim        // expression parser perform the completion.
730239462Sdim        if (Tok.is(tok::code_completion) &&
731239462Sdim            !(getLangOpts().ObjC1 && Intro.Default == LCD_None &&
732239462Sdim              !Intro.Captures.empty())) {
733234353Sdim          Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
734234353Sdim                                               /*AfterAmpersand=*/false);
735234353Sdim          ConsumeCodeCompletionToken();
736234353Sdim          break;
737234353Sdim        }
738234353Sdim
739226633Sdim        return DiagResult(diag::err_expected_comma_or_rsquare);
740234353Sdim      }
741226633Sdim      ConsumeToken();
742226633Sdim    }
743226633Sdim
744234353Sdim    if (Tok.is(tok::code_completion)) {
745234353Sdim      // If we're in Objective-C++ and we have a bare '[', then this is more
746234353Sdim      // likely to be a message receiver.
747234353Sdim      if (getLangOpts().ObjC1 && first)
748234353Sdim        Actions.CodeCompleteObjCMessageReceiver(getCurScope());
749234353Sdim      else
750234353Sdim        Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
751234353Sdim                                             /*AfterAmpersand=*/false);
752234353Sdim      ConsumeCodeCompletionToken();
753234353Sdim      break;
754234353Sdim    }
755234353Sdim
756226633Sdim    first = false;
757234353Sdim
758226633Sdim    // Parse capture.
759226633Sdim    LambdaCaptureKind Kind = LCK_ByCopy;
760226633Sdim    SourceLocation Loc;
761226633Sdim    IdentifierInfo* Id = 0;
762234353Sdim    SourceLocation EllipsisLoc;
763263508Sdim    ExprResult Init;
764234353Sdim
765226633Sdim    if (Tok.is(tok::kw_this)) {
766226633Sdim      Kind = LCK_This;
767226633Sdim      Loc = ConsumeToken();
768226633Sdim    } else {
769226633Sdim      if (Tok.is(tok::amp)) {
770226633Sdim        Kind = LCK_ByRef;
771226633Sdim        ConsumeToken();
772234353Sdim
773234353Sdim        if (Tok.is(tok::code_completion)) {
774234353Sdim          Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
775234353Sdim                                               /*AfterAmpersand=*/true);
776234353Sdim          ConsumeCodeCompletionToken();
777234353Sdim          break;
778234353Sdim        }
779226633Sdim      }
780226633Sdim
781226633Sdim      if (Tok.is(tok::identifier)) {
782226633Sdim        Id = Tok.getIdentifierInfo();
783226633Sdim        Loc = ConsumeToken();
784226633Sdim      } else if (Tok.is(tok::kw_this)) {
785226633Sdim        // FIXME: If we want to suggest a fixit here, will need to return more
786226633Sdim        // than just DiagnosticID. Perhaps full DiagnosticBuilder that can be
787226633Sdim        // Clear()ed to prevent emission in case of tentative parsing?
788226633Sdim        return DiagResult(diag::err_this_captured_by_reference);
789226633Sdim      } else {
790226633Sdim        return DiagResult(diag::err_expected_capture);
791226633Sdim      }
792263508Sdim
793263508Sdim      if (Tok.is(tok::l_paren)) {
794263508Sdim        BalancedDelimiterTracker Parens(*this, tok::l_paren);
795263508Sdim        Parens.consumeOpen();
796263508Sdim
797263508Sdim        ExprVector Exprs;
798263508Sdim        CommaLocsTy Commas;
799263508Sdim        if (SkippedInits) {
800263508Sdim          Parens.skipToEnd();
801263508Sdim          *SkippedInits = true;
802263508Sdim        } else if (ParseExpressionList(Exprs, Commas)) {
803263508Sdim          Parens.skipToEnd();
804263508Sdim          Init = ExprError();
805263508Sdim        } else {
806263508Sdim          Parens.consumeClose();
807263508Sdim          Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(),
808263508Sdim                                            Parens.getCloseLocation(),
809263508Sdim                                            Exprs);
810263508Sdim        }
811263508Sdim      } else if (Tok.is(tok::l_brace) || Tok.is(tok::equal)) {
812263508Sdim        // Each lambda init-capture forms its own full expression, which clears
813263508Sdim        // Actions.MaybeODRUseExprs. So create an expression evaluation context
814263508Sdim        // to save the necessary state, and restore it later.
815263508Sdim        EnterExpressionEvaluationContext EC(Actions,
816263508Sdim                                            Sema::PotentiallyEvaluated);
817263508Sdim        if (Tok.is(tok::equal))
818263508Sdim          ConsumeToken();
819263508Sdim
820263508Sdim        if (!SkippedInits)
821263508Sdim          Init = ParseInitializer();
822263508Sdim        else if (Tok.is(tok::l_brace)) {
823263508Sdim          BalancedDelimiterTracker Braces(*this, tok::l_brace);
824263508Sdim          Braces.consumeOpen();
825263508Sdim          Braces.skipToEnd();
826263508Sdim          *SkippedInits = true;
827263508Sdim        } else {
828263508Sdim          // We're disambiguating this:
829263508Sdim          //
830263508Sdim          //   [..., x = expr
831263508Sdim          //
832263508Sdim          // We need to find the end of the following expression in order to
833263508Sdim          // determine whether this is an Obj-C message send's receiver, or a
834263508Sdim          // lambda init-capture.
835263508Sdim          //
836263508Sdim          // Parse the expression to find where it ends, and annotate it back
837263508Sdim          // onto the tokens. We would have parsed this expression the same way
838263508Sdim          // in either case: both the RHS of an init-capture and the RHS of an
839263508Sdim          // assignment expression are parsed as an initializer-clause, and in
840263508Sdim          // neither case can anything be added to the scope between the '[' and
841263508Sdim          // here.
842263508Sdim          //
843263508Sdim          // FIXME: This is horrible. Adding a mechanism to skip an expression
844263508Sdim          // would be much cleaner.
845263508Sdim          // FIXME: If there is a ',' before the next ']' or ':', we can skip to
846263508Sdim          // that instead. (And if we see a ':' with no matching '?', we can
847263508Sdim          // classify this as an Obj-C message send.)
848263508Sdim          SourceLocation StartLoc = Tok.getLocation();
849263508Sdim          InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true);
850263508Sdim          Init = ParseInitializer();
851263508Sdim
852263508Sdim          if (Tok.getLocation() != StartLoc) {
853263508Sdim            // Back out the lexing of the token after the initializer.
854263508Sdim            PP.RevertCachedTokens(1);
855263508Sdim
856263508Sdim            // Replace the consumed tokens with an appropriate annotation.
857263508Sdim            Tok.setLocation(StartLoc);
858263508Sdim            Tok.setKind(tok::annot_primary_expr);
859263508Sdim            setExprAnnotation(Tok, Init);
860263508Sdim            Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation());
861263508Sdim            PP.AnnotateCachedTokens(Tok);
862263508Sdim
863263508Sdim            // Consume the annotated initializer.
864263508Sdim            ConsumeToken();
865263508Sdim          }
866263508Sdim        }
867263508Sdim      } else if (Tok.is(tok::ellipsis))
868263508Sdim        EllipsisLoc = ConsumeToken();
869226633Sdim    }
870263508Sdim    // If this is an init capture, process the initialization expression
871263508Sdim    // right away.  For lambda init-captures such as the following:
872263508Sdim    // const int x = 10;
873263508Sdim    //  auto L = [i = x+1](int a) {
874263508Sdim    //    return [j = x+2,
875263508Sdim    //           &k = x](char b) { };
876263508Sdim    //  };
877263508Sdim    // keep in mind that each lambda init-capture has to have:
878263508Sdim    //  - its initialization expression executed in the context
879263508Sdim    //    of the enclosing/parent decl-context.
880263508Sdim    //  - but the variable itself has to be 'injected' into the
881263508Sdim    //    decl-context of its lambda's call-operator (which has
882263508Sdim    //    not yet been created).
883263508Sdim    // Each init-expression is a full-expression that has to get
884263508Sdim    // Sema-analyzed (for capturing etc.) before its lambda's
885263508Sdim    // call-operator's decl-context, scope & scopeinfo are pushed on their
886263508Sdim    // respective stacks.  Thus if any variable is odr-used in the init-capture
887263508Sdim    // it will correctly get captured in the enclosing lambda, if one exists.
888263508Sdim    // The init-variables above are created later once the lambdascope and
889263508Sdim    // call-operators decl-context is pushed onto its respective stack.
890226633Sdim
891263508Sdim    // Since the lambda init-capture's initializer expression occurs in the
892263508Sdim    // context of the enclosing function or lambda, therefore we can not wait
893263508Sdim    // till a lambda scope has been pushed on before deciding whether the
894263508Sdim    // variable needs to be captured.  We also need to process all
895263508Sdim    // lvalue-to-rvalue conversions and discarded-value conversions,
896263508Sdim    // so that we can avoid capturing certain constant variables.
897263508Sdim    // For e.g.,
898263508Sdim    //  void test() {
899263508Sdim    //   const int x = 10;
900263508Sdim    //   auto L = [&z = x](char a) { <-- don't capture by the current lambda
901263508Sdim    //     return [y = x](int i) { <-- don't capture by enclosing lambda
902263508Sdim    //          return y;
903263508Sdim    //     }
904263508Sdim    //   };
905263508Sdim    // If x was not const, the second use would require 'L' to capture, and
906263508Sdim    // that would be an error.
907263508Sdim
908263508Sdim    ParsedType InitCaptureParsedType;
909263508Sdim    if (Init.isUsable()) {
910263508Sdim      // Get the pointer and store it in an lvalue, so we can use it as an
911263508Sdim      // out argument.
912263508Sdim      Expr *InitExpr = Init.get();
913263508Sdim      // This performs any lvalue-to-rvalue conversions if necessary, which
914263508Sdim      // can affect what gets captured in the containing decl-context.
915263508Sdim      QualType InitCaptureType = Actions.performLambdaInitCaptureInitialization(
916263508Sdim        Loc, Kind == LCK_ByRef, Id, InitExpr);
917263508Sdim      Init = InitExpr;
918263508Sdim      InitCaptureParsedType.set(InitCaptureType);
919263508Sdim    }
920263508Sdim    Intro.addCapture(Kind, Loc, Id, EllipsisLoc, Init, InitCaptureParsedType);
921226633Sdim  }
922226633Sdim
923226633Sdim  T.consumeClose();
924226633Sdim  Intro.Range.setEnd(T.getCloseLocation());
925226633Sdim  return DiagResult();
926226633Sdim}
927226633Sdim
928234353Sdim/// TryParseLambdaIntroducer - Tentatively parse a lambda introducer.
929226633Sdim///
930226633Sdim/// Returns true if it hit something unexpected.
931226633Sdimbool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) {
932226633Sdim  TentativeParsingAction PA(*this);
933226633Sdim
934263508Sdim  bool SkippedInits = false;
935263508Sdim  Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits));
936226633Sdim
937226633Sdim  if (DiagID) {
938226633Sdim    PA.Revert();
939226633Sdim    return true;
940226633Sdim  }
941226633Sdim
942263508Sdim  if (SkippedInits) {
943263508Sdim    // Parse it again, but this time parse the init-captures too.
944263508Sdim    PA.Revert();
945263508Sdim    Intro = LambdaIntroducer();
946263508Sdim    DiagID = ParseLambdaIntroducer(Intro);
947263508Sdim    assert(!DiagID && "parsing lambda-introducer failed on reparse");
948263508Sdim    return false;
949263508Sdim  }
950263508Sdim
951226633Sdim  PA.Commit();
952226633Sdim  return false;
953226633Sdim}
954226633Sdim
955226633Sdim/// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda
956226633Sdim/// expression.
957226633SdimExprResult Parser::ParseLambdaExpressionAfterIntroducer(
958226633Sdim                     LambdaIntroducer &Intro) {
959234353Sdim  SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
960234353Sdim  Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda);
961234353Sdim
962234353Sdim  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
963234353Sdim                                "lambda expression parsing");
964234353Sdim
965263508Sdim
966263508Sdim
967263508Sdim  // FIXME: Call into Actions to add any init-capture declarations to the
968263508Sdim  // scope while parsing the lambda-declarator and compound-statement.
969263508Sdim
970226633Sdim  // Parse lambda-declarator[opt].
971226633Sdim  DeclSpec DS(AttrFactory);
972234353Sdim  Declarator D(DS, Declarator::LambdaExprContext);
973263508Sdim  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
974263508Sdim  Actions.PushLambdaScope();
975226633Sdim
976226633Sdim  if (Tok.is(tok::l_paren)) {
977226633Sdim    ParseScope PrototypeScope(this,
978226633Sdim                              Scope::FunctionPrototypeScope |
979249423Sdim                              Scope::FunctionDeclarationScope |
980226633Sdim                              Scope::DeclScope);
981226633Sdim
982243830Sdim    SourceLocation DeclEndLoc;
983226633Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
984226633Sdim    T.consumeOpen();
985243830Sdim    SourceLocation LParenLoc = T.getOpenLocation();
986226633Sdim
987226633Sdim    // Parse parameter-declaration-clause.
988226633Sdim    ParsedAttributes Attr(AttrFactory);
989249423Sdim    SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
990226633Sdim    SourceLocation EllipsisLoc;
991226633Sdim
992263508Sdim
993263508Sdim    if (Tok.isNot(tok::r_paren)) {
994263508Sdim      Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth);
995226633Sdim      ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc);
996263508Sdim      // For a generic lambda, each 'auto' within the parameter declaration
997263508Sdim      // clause creates a template type parameter, so increment the depth.
998263508Sdim      if (Actions.getCurGenericLambda())
999263508Sdim        ++CurTemplateDepthTracker;
1000263508Sdim    }
1001226633Sdim    T.consumeClose();
1002243830Sdim    SourceLocation RParenLoc = T.getCloseLocation();
1003243830Sdim    DeclEndLoc = RParenLoc;
1004226633Sdim
1005226633Sdim    // Parse 'mutable'[opt].
1006226633Sdim    SourceLocation MutableLoc;
1007226633Sdim    if (Tok.is(tok::kw_mutable)) {
1008226633Sdim      MutableLoc = ConsumeToken();
1009226633Sdim      DeclEndLoc = MutableLoc;
1010226633Sdim    }
1011226633Sdim
1012226633Sdim    // Parse exception-specification[opt].
1013226633Sdim    ExceptionSpecificationType ESpecType = EST_None;
1014226633Sdim    SourceRange ESpecRange;
1015249423Sdim    SmallVector<ParsedType, 2> DynamicExceptions;
1016249423Sdim    SmallVector<SourceRange, 2> DynamicExceptionRanges;
1017226633Sdim    ExprResult NoexceptExpr;
1018235864Sdim    ESpecType = tryParseExceptionSpecification(ESpecRange,
1019234982Sdim                                               DynamicExceptions,
1020234982Sdim                                               DynamicExceptionRanges,
1021235864Sdim                                               NoexceptExpr);
1022226633Sdim
1023226633Sdim    if (ESpecType != EST_None)
1024226633Sdim      DeclEndLoc = ESpecRange.getEnd();
1025226633Sdim
1026226633Sdim    // Parse attribute-specifier[opt].
1027249423Sdim    MaybeParseCXX11Attributes(Attr, &DeclEndLoc);
1028226633Sdim
1029243830Sdim    SourceLocation FunLocalRangeEnd = DeclEndLoc;
1030243830Sdim
1031226633Sdim    // Parse trailing-return-type[opt].
1032239462Sdim    TypeResult TrailingReturnType;
1033226633Sdim    if (Tok.is(tok::arrow)) {
1034243830Sdim      FunLocalRangeEnd = Tok.getLocation();
1035226633Sdim      SourceRange Range;
1036239462Sdim      TrailingReturnType = ParseTrailingReturnType(Range);
1037226633Sdim      if (Range.getEnd().isValid())
1038226633Sdim        DeclEndLoc = Range.getEnd();
1039226633Sdim    }
1040226633Sdim
1041226633Sdim    PrototypeScope.Exit();
1042226633Sdim
1043243830Sdim    SourceLocation NoLoc;
1044226633Sdim    D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
1045243830Sdim                                           /*isAmbiguous=*/false,
1046243830Sdim                                           LParenLoc,
1047226633Sdim                                           ParamInfo.data(), ParamInfo.size(),
1048243830Sdim                                           EllipsisLoc, RParenLoc,
1049226633Sdim                                           DS.getTypeQualifiers(),
1050226633Sdim                                           /*RefQualifierIsLValueRef=*/true,
1051243830Sdim                                           /*RefQualifierLoc=*/NoLoc,
1052243830Sdim                                           /*ConstQualifierLoc=*/NoLoc,
1053243830Sdim                                           /*VolatileQualifierLoc=*/NoLoc,
1054226633Sdim                                           MutableLoc,
1055226633Sdim                                           ESpecType, ESpecRange.getBegin(),
1056226633Sdim                                           DynamicExceptions.data(),
1057226633Sdim                                           DynamicExceptionRanges.data(),
1058226633Sdim                                           DynamicExceptions.size(),
1059226633Sdim                                           NoexceptExpr.isUsable() ?
1060226633Sdim                                             NoexceptExpr.get() : 0,
1061243830Sdim                                           LParenLoc, FunLocalRangeEnd, D,
1062226633Sdim                                           TrailingReturnType),
1063226633Sdim                  Attr, DeclEndLoc);
1064234353Sdim  } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow)) {
1065234353Sdim    // It's common to forget that one needs '()' before 'mutable' or the
1066234353Sdim    // result type. Deal with this.
1067234353Sdim    Diag(Tok, diag::err_lambda_missing_parens)
1068234353Sdim      << Tok.is(tok::arrow)
1069234353Sdim      << FixItHint::CreateInsertion(Tok.getLocation(), "() ");
1070234353Sdim    SourceLocation DeclLoc = Tok.getLocation();
1071234353Sdim    SourceLocation DeclEndLoc = DeclLoc;
1072234353Sdim
1073234353Sdim    // Parse 'mutable', if it's there.
1074234353Sdim    SourceLocation MutableLoc;
1075234353Sdim    if (Tok.is(tok::kw_mutable)) {
1076234353Sdim      MutableLoc = ConsumeToken();
1077234353Sdim      DeclEndLoc = MutableLoc;
1078234353Sdim    }
1079234353Sdim
1080234353Sdim    // Parse the return type, if there is one.
1081239462Sdim    TypeResult TrailingReturnType;
1082234353Sdim    if (Tok.is(tok::arrow)) {
1083234353Sdim      SourceRange Range;
1084239462Sdim      TrailingReturnType = ParseTrailingReturnType(Range);
1085234353Sdim      if (Range.getEnd().isValid())
1086234353Sdim        DeclEndLoc = Range.getEnd();
1087234353Sdim    }
1088234353Sdim
1089234353Sdim    ParsedAttributes Attr(AttrFactory);
1090243830Sdim    SourceLocation NoLoc;
1091234353Sdim    D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
1092243830Sdim                                               /*isAmbiguous=*/false,
1093243830Sdim                                               /*LParenLoc=*/NoLoc,
1094243830Sdim                                               /*Params=*/0,
1095243830Sdim                                               /*NumParams=*/0,
1096243830Sdim                                               /*EllipsisLoc=*/NoLoc,
1097243830Sdim                                               /*RParenLoc=*/NoLoc,
1098243830Sdim                                               /*TypeQuals=*/0,
1099243830Sdim                                               /*RefQualifierIsLValueRef=*/true,
1100243830Sdim                                               /*RefQualifierLoc=*/NoLoc,
1101243830Sdim                                               /*ConstQualifierLoc=*/NoLoc,
1102243830Sdim                                               /*VolatileQualifierLoc=*/NoLoc,
1103243830Sdim                                               MutableLoc,
1104243830Sdim                                               EST_None,
1105243830Sdim                                               /*ESpecLoc=*/NoLoc,
1106243830Sdim                                               /*Exceptions=*/0,
1107243830Sdim                                               /*ExceptionRanges=*/0,
1108243830Sdim                                               /*NumExceptions=*/0,
1109243830Sdim                                               /*NoexceptExpr=*/0,
1110243830Sdim                                               DeclLoc, DeclEndLoc, D,
1111243830Sdim                                               TrailingReturnType),
1112234353Sdim                  Attr, DeclEndLoc);
1113226633Sdim  }
1114234353Sdim
1115226633Sdim
1116234353Sdim  // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
1117234353Sdim  // it.
1118234353Sdim  unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope;
1119234353Sdim  ParseScope BodyScope(this, ScopeFlags);
1120226633Sdim
1121234353Sdim  Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope());
1122226633Sdim
1123234353Sdim  // Parse compound-statement.
1124234353Sdim  if (!Tok.is(tok::l_brace)) {
1125226633Sdim    Diag(Tok, diag::err_expected_lambda_body);
1126234353Sdim    Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
1127234353Sdim    return ExprError();
1128226633Sdim  }
1129226633Sdim
1130234353Sdim  StmtResult Stmt(ParseCompoundStatementBody());
1131234353Sdim  BodyScope.Exit();
1132234353Sdim
1133234353Sdim  if (!Stmt.isInvalid())
1134234353Sdim    return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.take(), getCurScope());
1135234353Sdim
1136234353Sdim  Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
1137234353Sdim  return ExprError();
1138226633Sdim}
1139226633Sdim
1140193326Sed/// ParseCXXCasts - This handles the various ways to cast expressions to another
1141193326Sed/// type.
1142193326Sed///
1143193326Sed///       postfix-expression: [C++ 5.2p1]
1144193326Sed///         'dynamic_cast' '<' type-name '>' '(' expression ')'
1145193326Sed///         'static_cast' '<' type-name '>' '(' expression ')'
1146193326Sed///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
1147193326Sed///         'const_cast' '<' type-name '>' '(' expression ')'
1148193326Sed///
1149212904SdimExprResult Parser::ParseCXXCasts() {
1150193326Sed  tok::TokenKind Kind = Tok.getKind();
1151193326Sed  const char *CastName = 0;     // For error messages
1152193326Sed
1153193326Sed  switch (Kind) {
1154226633Sdim  default: llvm_unreachable("Unknown C++ cast!");
1155193326Sed  case tok::kw_const_cast:       CastName = "const_cast";       break;
1156193326Sed  case tok::kw_dynamic_cast:     CastName = "dynamic_cast";     break;
1157193326Sed  case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
1158193326Sed  case tok::kw_static_cast:      CastName = "static_cast";      break;
1159193326Sed  }
1160193326Sed
1161193326Sed  SourceLocation OpLoc = ConsumeToken();
1162193326Sed  SourceLocation LAngleBracketLoc = Tok.getLocation();
1163193326Sed
1164221345Sdim  // Check for "<::" which is parsed as "[:".  If found, fix token stream,
1165221345Sdim  // diagnose error, suggest fix, and recover parsing.
1166243830Sdim  if (Tok.is(tok::l_square) && Tok.getLength() == 2) {
1167243830Sdim    Token Next = NextToken();
1168243830Sdim    if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next))
1169243830Sdim      FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true);
1170243830Sdim  }
1171221345Sdim
1172193326Sed  if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
1173193326Sed    return ExprError();
1174193326Sed
1175224145Sdim  // Parse the common declaration-specifiers piece.
1176224145Sdim  DeclSpec DS(AttrFactory);
1177224145Sdim  ParseSpecifierQualifierList(DS);
1178224145Sdim
1179224145Sdim  // Parse the abstract-declarator, if present.
1180224145Sdim  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1181224145Sdim  ParseDeclarator(DeclaratorInfo);
1182224145Sdim
1183193326Sed  SourceLocation RAngleBracketLoc = Tok.getLocation();
1184193326Sed
1185193326Sed  if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
1186193326Sed    return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
1187193326Sed
1188226633Sdim  SourceLocation LParenLoc, RParenLoc;
1189226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
1190193326Sed
1191226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen_after, CastName))
1192193326Sed    return ExprError();
1193193326Sed
1194212904Sdim  ExprResult Result = ParseExpression();
1195198092Srdivacky
1196193326Sed  // Match the ')'.
1197226633Sdim  T.consumeClose();
1198198092Srdivacky
1199224145Sdim  if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType())
1200193326Sed    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
1201224145Sdim                                       LAngleBracketLoc, DeclaratorInfo,
1202193326Sed                                       RAngleBracketLoc,
1203226633Sdim                                       T.getOpenLocation(), Result.take(),
1204226633Sdim                                       T.getCloseLocation());
1205193326Sed
1206243830Sdim  return Result;
1207193326Sed}
1208193326Sed
1209193326Sed/// ParseCXXTypeid - This handles the C++ typeid expression.
1210193326Sed///
1211193326Sed///       postfix-expression: [C++ 5.2p1]
1212193326Sed///         'typeid' '(' expression ')'
1213193326Sed///         'typeid' '(' type-id ')'
1214193326Sed///
1215212904SdimExprResult Parser::ParseCXXTypeid() {
1216193326Sed  assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
1217193326Sed
1218193326Sed  SourceLocation OpLoc = ConsumeToken();
1219226633Sdim  SourceLocation LParenLoc, RParenLoc;
1220226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
1221193326Sed
1222193326Sed  // typeid expressions are always parenthesized.
1223226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid"))
1224193326Sed    return ExprError();
1225226633Sdim  LParenLoc = T.getOpenLocation();
1226193326Sed
1227212904Sdim  ExprResult Result;
1228193326Sed
1229243830Sdim  // C++0x [expr.typeid]p3:
1230243830Sdim  //   When typeid is applied to an expression other than an lvalue of a
1231243830Sdim  //   polymorphic class type [...] The expression is an unevaluated
1232243830Sdim  //   operand (Clause 5).
1233243830Sdim  //
1234243830Sdim  // Note that we can't tell whether the expression is an lvalue of a
1235243830Sdim  // polymorphic class type until after we've parsed the expression; we
1236243830Sdim  // speculatively assume the subexpression is unevaluated, and fix it up
1237243830Sdim  // later.
1238243830Sdim  //
1239243830Sdim  // We enter the unevaluated context before trying to determine whether we
1240243830Sdim  // have a type-id, because the tentative parse logic will try to resolve
1241243830Sdim  // names, and must treat them as unevaluated.
1242243830Sdim  EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
1243243830Sdim                                               Sema::ReuseLambdaContextDecl);
1244243830Sdim
1245193326Sed  if (isTypeIdInParens()) {
1246193326Sed    TypeResult Ty = ParseTypeName();
1247193326Sed
1248193326Sed    // Match the ')'.
1249226633Sdim    T.consumeClose();
1250226633Sdim    RParenLoc = T.getCloseLocation();
1251218893Sdim    if (Ty.isInvalid() || RParenLoc.isInvalid())
1252193326Sed      return ExprError();
1253193326Sed
1254193326Sed    Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
1255212904Sdim                                    Ty.get().getAsOpaquePtr(), RParenLoc);
1256193326Sed  } else {
1257193326Sed    Result = ParseExpression();
1258193326Sed
1259193326Sed    // Match the ')'.
1260193326Sed    if (Result.isInvalid())
1261263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
1262193326Sed    else {
1263226633Sdim      T.consumeClose();
1264226633Sdim      RParenLoc = T.getCloseLocation();
1265218893Sdim      if (RParenLoc.isInvalid())
1266218893Sdim        return ExprError();
1267221345Sdim
1268193326Sed      Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
1269193326Sed                                      Result.release(), RParenLoc);
1270193326Sed    }
1271193326Sed  }
1272193326Sed
1273243830Sdim  return Result;
1274193326Sed}
1275193326Sed
1276218893Sdim/// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.
1277218893Sdim///
1278218893Sdim///         '__uuidof' '(' expression ')'
1279218893Sdim///         '__uuidof' '(' type-id ')'
1280218893Sdim///
1281218893SdimExprResult Parser::ParseCXXUuidof() {
1282218893Sdim  assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");
1283218893Sdim
1284218893Sdim  SourceLocation OpLoc = ConsumeToken();
1285226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
1286218893Sdim
1287218893Sdim  // __uuidof expressions are always parenthesized.
1288226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof"))
1289218893Sdim    return ExprError();
1290218893Sdim
1291218893Sdim  ExprResult Result;
1292218893Sdim
1293218893Sdim  if (isTypeIdInParens()) {
1294218893Sdim    TypeResult Ty = ParseTypeName();
1295218893Sdim
1296218893Sdim    // Match the ')'.
1297226633Sdim    T.consumeClose();
1298218893Sdim
1299218893Sdim    if (Ty.isInvalid())
1300218893Sdim      return ExprError();
1301218893Sdim
1302226633Sdim    Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true,
1303226633Sdim                                    Ty.get().getAsOpaquePtr(),
1304226633Sdim                                    T.getCloseLocation());
1305218893Sdim  } else {
1306218893Sdim    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
1307218893Sdim    Result = ParseExpression();
1308218893Sdim
1309218893Sdim    // Match the ')'.
1310218893Sdim    if (Result.isInvalid())
1311263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
1312218893Sdim    else {
1313226633Sdim      T.consumeClose();
1314218893Sdim
1315226633Sdim      Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(),
1316226633Sdim                                      /*isType=*/false,
1317226633Sdim                                      Result.release(), T.getCloseLocation());
1318218893Sdim    }
1319218893Sdim  }
1320218893Sdim
1321243830Sdim  return Result;
1322218893Sdim}
1323218893Sdim
1324204643Srdivacky/// \brief Parse a C++ pseudo-destructor expression after the base,
1325204643Srdivacky/// . or -> operator, and nested-name-specifier have already been
1326204643Srdivacky/// parsed.
1327204643Srdivacky///
1328204643Srdivacky///       postfix-expression: [C++ 5.2]
1329204643Srdivacky///         postfix-expression . pseudo-destructor-name
1330204643Srdivacky///         postfix-expression -> pseudo-destructor-name
1331204643Srdivacky///
1332204643Srdivacky///       pseudo-destructor-name:
1333204643Srdivacky///         ::[opt] nested-name-specifier[opt] type-name :: ~type-name
1334204643Srdivacky///         ::[opt] nested-name-specifier template simple-template-id ::
1335204643Srdivacky///                 ~type-name
1336204643Srdivacky///         ::[opt] nested-name-specifier[opt] ~type-name
1337204643Srdivacky///
1338212904SdimExprResult
1339204643SrdivackyParser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
1340204643Srdivacky                                 tok::TokenKind OpKind,
1341204643Srdivacky                                 CXXScopeSpec &SS,
1342212904Sdim                                 ParsedType ObjectType) {
1343204643Srdivacky  // We're parsing either a pseudo-destructor-name or a dependent
1344204643Srdivacky  // member access that has the same form as a
1345204643Srdivacky  // pseudo-destructor-name. We parse both in the same way and let
1346204643Srdivacky  // the action model sort them out.
1347204643Srdivacky  //
1348204643Srdivacky  // Note that the ::[opt] nested-name-specifier[opt] has already
1349204643Srdivacky  // been parsed, and if there was a simple-template-id, it has
1350204643Srdivacky  // been coalesced into a template-id annotation token.
1351204643Srdivacky  UnqualifiedId FirstTypeName;
1352204643Srdivacky  SourceLocation CCLoc;
1353204643Srdivacky  if (Tok.is(tok::identifier)) {
1354204643Srdivacky    FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1355204643Srdivacky    ConsumeToken();
1356204643Srdivacky    assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
1357204643Srdivacky    CCLoc = ConsumeToken();
1358204643Srdivacky  } else if (Tok.is(tok::annot_template_id)) {
1359234353Sdim    // FIXME: retrieve TemplateKWLoc from template-id annotation and
1360234353Sdim    // store it in the pseudo-dtor node (to be used when instantiating it).
1361204643Srdivacky    FirstTypeName.setTemplateId(
1362204643Srdivacky                              (TemplateIdAnnotation *)Tok.getAnnotationValue());
1363204643Srdivacky    ConsumeToken();
1364204643Srdivacky    assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
1365204643Srdivacky    CCLoc = ConsumeToken();
1366204643Srdivacky  } else {
1367204643Srdivacky    FirstTypeName.setIdentifier(0, SourceLocation());
1368204643Srdivacky  }
1369204643Srdivacky
1370204643Srdivacky  // Parse the tilde.
1371204643Srdivacky  assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");
1372204643Srdivacky  SourceLocation TildeLoc = ConsumeToken();
1373234353Sdim
1374234353Sdim  if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid() && SS.isEmpty()) {
1375234353Sdim    DeclSpec DS(AttrFactory);
1376234353Sdim    ParseDecltypeSpecifier(DS);
1377234353Sdim    if (DS.getTypeSpecType() == TST_error)
1378234353Sdim      return ExprError();
1379234353Sdim    return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc,
1380234353Sdim                                             OpKind, TildeLoc, DS,
1381234353Sdim                                             Tok.is(tok::l_paren));
1382234353Sdim  }
1383234353Sdim
1384204643Srdivacky  if (!Tok.is(tok::identifier)) {
1385204643Srdivacky    Diag(Tok, diag::err_destructor_tilde_identifier);
1386204643Srdivacky    return ExprError();
1387204643Srdivacky  }
1388204643Srdivacky
1389204643Srdivacky  // Parse the second type.
1390204643Srdivacky  UnqualifiedId SecondTypeName;
1391204643Srdivacky  IdentifierInfo *Name = Tok.getIdentifierInfo();
1392204643Srdivacky  SourceLocation NameLoc = ConsumeToken();
1393204643Srdivacky  SecondTypeName.setIdentifier(Name, NameLoc);
1394204643Srdivacky
1395204643Srdivacky  // If there is a '<', the second type name is a template-id. Parse
1396204643Srdivacky  // it as such.
1397204643Srdivacky  if (Tok.is(tok::less) &&
1398234353Sdim      ParseUnqualifiedIdTemplateId(SS, SourceLocation(),
1399234353Sdim                                   Name, NameLoc,
1400234353Sdim                                   false, ObjectType, SecondTypeName,
1401234353Sdim                                   /*AssumeTemplateName=*/true))
1402204643Srdivacky    return ExprError();
1403204643Srdivacky
1404212904Sdim  return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base,
1405212904Sdim                                           OpLoc, OpKind,
1406204643Srdivacky                                           SS, FirstTypeName, CCLoc,
1407204643Srdivacky                                           TildeLoc, SecondTypeName,
1408204643Srdivacky                                           Tok.is(tok::l_paren));
1409204643Srdivacky}
1410204643Srdivacky
1411193326Sed/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
1412193326Sed///
1413193326Sed///       boolean-literal: [C++ 2.13.5]
1414193326Sed///         'true'
1415193326Sed///         'false'
1416212904SdimExprResult Parser::ParseCXXBoolLiteral() {
1417193326Sed  tok::TokenKind Kind = Tok.getKind();
1418193326Sed  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
1419193326Sed}
1420193326Sed
1421193326Sed/// ParseThrowExpression - This handles the C++ throw expression.
1422193326Sed///
1423193326Sed///       throw-expression: [C++ 15]
1424193326Sed///         'throw' assignment-expression[opt]
1425212904SdimExprResult Parser::ParseThrowExpression() {
1426193326Sed  assert(Tok.is(tok::kw_throw) && "Not throw!");
1427193326Sed  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
1428193326Sed
1429193326Sed  // If the current token isn't the start of an assignment-expression,
1430193326Sed  // then the expression is not present.  This handles things like:
1431193326Sed  //   "C ? throw : (void)42", which is crazy but legal.
1432193326Sed  switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
1433193326Sed  case tok::semi:
1434193326Sed  case tok::r_paren:
1435193326Sed  case tok::r_square:
1436193326Sed  case tok::r_brace:
1437193326Sed  case tok::colon:
1438193326Sed  case tok::comma:
1439224145Sdim    return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, 0);
1440193326Sed
1441193326Sed  default:
1442212904Sdim    ExprResult Expr(ParseAssignmentExpression());
1443243830Sdim    if (Expr.isInvalid()) return Expr;
1444224145Sdim    return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.take());
1445193326Sed  }
1446193326Sed}
1447193326Sed
1448193326Sed/// ParseCXXThis - This handles the C++ 'this' pointer.
1449193326Sed///
1450193326Sed/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
1451193326Sed/// a non-lvalue expression whose value is the address of the object for which
1452193326Sed/// the function is called.
1453212904SdimExprResult Parser::ParseCXXThis() {
1454193326Sed  assert(Tok.is(tok::kw_this) && "Not 'this'!");
1455193326Sed  SourceLocation ThisLoc = ConsumeToken();
1456193326Sed  return Actions.ActOnCXXThis(ThisLoc);
1457193326Sed}
1458193326Sed
1459193326Sed/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
1460193326Sed/// Can be interpreted either as function-style casting ("int(x)")
1461193326Sed/// or class type construction ("ClassType(x,y,z)")
1462193326Sed/// or creation of a value-initialized type ("int()").
1463223017Sdim/// See [C++ 5.2.3].
1464193326Sed///
1465193326Sed///       postfix-expression: [C++ 5.2p1]
1466223017Sdim///         simple-type-specifier '(' expression-list[opt] ')'
1467223017Sdim/// [C++0x] simple-type-specifier braced-init-list
1468223017Sdim///         typename-specifier '(' expression-list[opt] ')'
1469223017Sdim/// [C++0x] typename-specifier braced-init-list
1470193326Sed///
1471212904SdimExprResult
1472193326SedParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
1473193326Sed  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1474212904Sdim  ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
1475193326Sed
1476223017Sdim  assert((Tok.is(tok::l_paren) ||
1477249423Sdim          (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)))
1478223017Sdim         && "Expected '(' or '{'!");
1479218893Sdim
1480223017Sdim  if (Tok.is(tok::l_brace)) {
1481234353Sdim    ExprResult Init = ParseBraceInitializer();
1482234353Sdim    if (Init.isInvalid())
1483234353Sdim      return Init;
1484234353Sdim    Expr *InitList = Init.take();
1485234353Sdim    return Actions.ActOnCXXTypeConstructExpr(TypeRep, SourceLocation(),
1486234353Sdim                                             MultiExprArg(&InitList, 1),
1487234353Sdim                                             SourceLocation());
1488223017Sdim  } else {
1489226633Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
1490226633Sdim    T.consumeOpen();
1491223017Sdim
1492243830Sdim    ExprVector Exprs;
1493223017Sdim    CommaLocsTy CommaLocs;
1494223017Sdim
1495223017Sdim    if (Tok.isNot(tok::r_paren)) {
1496223017Sdim      if (ParseExpressionList(Exprs, CommaLocs)) {
1497263508Sdim        SkipUntil(tok::r_paren, StopAtSemi);
1498223017Sdim        return ExprError();
1499223017Sdim      }
1500193326Sed    }
1501193326Sed
1502223017Sdim    // Match the ')'.
1503226633Sdim    T.consumeClose();
1504193326Sed
1505223017Sdim    // TypeRep could be null, if it references an invalid typedef.
1506223017Sdim    if (!TypeRep)
1507223017Sdim      return ExprError();
1508198092Srdivacky
1509223017Sdim    assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
1510223017Sdim           "Unexpected number of commas!");
1511226633Sdim    return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(),
1512243830Sdim                                             Exprs,
1513226633Sdim                                             T.getCloseLocation());
1514223017Sdim  }
1515193326Sed}
1516193326Sed
1517199990Srdivacky/// ParseCXXCondition - if/switch/while condition expression.
1518193326Sed///
1519193326Sed///       condition:
1520193326Sed///         expression
1521193326Sed///         type-specifier-seq declarator '=' assignment-expression
1522234353Sdim/// [C++11] type-specifier-seq declarator '=' initializer-clause
1523234353Sdim/// [C++11] type-specifier-seq declarator braced-init-list
1524193326Sed/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
1525193326Sed///             '=' assignment-expression
1526193326Sed///
1527243830Sdim/// \param ExprOut if the condition was parsed as an expression, the parsed
1528243830Sdim/// expression.
1529199990Srdivacky///
1530243830Sdim/// \param DeclOut if the condition was parsed as a declaration, the parsed
1531243830Sdim/// declaration.
1532199990Srdivacky///
1533208600Srdivacky/// \param Loc The location of the start of the statement that requires this
1534208600Srdivacky/// condition, e.g., the "for" in a for loop.
1535208600Srdivacky///
1536208600Srdivacky/// \param ConvertToBoolean Whether the condition expression should be
1537208600Srdivacky/// converted to a boolean value.
1538208600Srdivacky///
1539199990Srdivacky/// \returns true if there was a parsing, false otherwise.
1540212904Sdimbool Parser::ParseCXXCondition(ExprResult &ExprOut,
1541212904Sdim                               Decl *&DeclOut,
1542208600Srdivacky                               SourceLocation Loc,
1543208600Srdivacky                               bool ConvertToBoolean) {
1544202379Srdivacky  if (Tok.is(tok::code_completion)) {
1545212904Sdim    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
1546226633Sdim    cutOffParsing();
1547226633Sdim    return true;
1548202379Srdivacky  }
1549202379Srdivacky
1550239462Sdim  ParsedAttributesWithRange attrs(AttrFactory);
1551249423Sdim  MaybeParseCXX11Attributes(attrs);
1552239462Sdim
1553199990Srdivacky  if (!isCXXConditionDeclaration()) {
1554239462Sdim    ProhibitAttributes(attrs);
1555239462Sdim
1556208600Srdivacky    // Parse the expression.
1557212904Sdim    ExprOut = ParseExpression(); // expression
1558212904Sdim    DeclOut = 0;
1559212904Sdim    if (ExprOut.isInvalid())
1560208600Srdivacky      return true;
1561208600Srdivacky
1562208600Srdivacky    // If required, convert to a boolean value.
1563208600Srdivacky    if (ConvertToBoolean)
1564212904Sdim      ExprOut
1565212904Sdim        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get());
1566212904Sdim    return ExprOut.isInvalid();
1567199990Srdivacky  }
1568193326Sed
1569193326Sed  // type-specifier-seq
1570221345Sdim  DeclSpec DS(AttrFactory);
1571249423Sdim  DS.takeAttributesFrom(attrs);
1572193326Sed  ParseSpecifierQualifierList(DS);
1573193326Sed
1574193326Sed  // declarator
1575193326Sed  Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
1576193326Sed  ParseDeclarator(DeclaratorInfo);
1577193326Sed
1578193326Sed  // simple-asm-expr[opt]
1579193326Sed  if (Tok.is(tok::kw_asm)) {
1580193326Sed    SourceLocation Loc;
1581212904Sdim    ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1582193326Sed    if (AsmLabel.isInvalid()) {
1583263508Sdim      SkipUntil(tok::semi, StopAtSemi);
1584199990Srdivacky      return true;
1585193326Sed    }
1586193326Sed    DeclaratorInfo.setAsmLabel(AsmLabel.release());
1587193326Sed    DeclaratorInfo.SetRangeEnd(Loc);
1588193326Sed  }
1589193326Sed
1590193326Sed  // If attributes are present, parse them.
1591218893Sdim  MaybeParseGNUAttributes(DeclaratorInfo);
1592193326Sed
1593199990Srdivacky  // Type-check the declaration itself.
1594212904Sdim  DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),
1595218893Sdim                                                        DeclaratorInfo);
1596212904Sdim  DeclOut = Dcl.get();
1597212904Sdim  ExprOut = ExprError();
1598218893Sdim
1599193326Sed  // '=' assignment-expression
1600234353Sdim  // If a '==' or '+=' is found, suggest a fixit to '='.
1601234353Sdim  bool CopyInitialization = isTokenEqualOrEqualTypo();
1602234353Sdim  if (CopyInitialization)
1603218893Sdim    ConsumeToken();
1604234353Sdim
1605234353Sdim  ExprResult InitExpr = ExprError();
1606249423Sdim  if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
1607234353Sdim    Diag(Tok.getLocation(),
1608234353Sdim         diag::warn_cxx98_compat_generalized_initializer_lists);
1609234353Sdim    InitExpr = ParseBraceInitializer();
1610234353Sdim  } else if (CopyInitialization) {
1611234353Sdim    InitExpr = ParseAssignmentExpression();
1612234353Sdim  } else if (Tok.is(tok::l_paren)) {
1613234353Sdim    // This was probably an attempt to initialize the variable.
1614234353Sdim    SourceLocation LParen = ConsumeParen(), RParen = LParen;
1615263508Sdim    if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch))
1616234353Sdim      RParen = ConsumeParen();
1617234353Sdim    Diag(DeclOut ? DeclOut->getLocation() : LParen,
1618234353Sdim         diag::err_expected_init_in_condition_lparen)
1619234353Sdim      << SourceRange(LParen, RParen);
1620199990Srdivacky  } else {
1621234353Sdim    Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(),
1622234353Sdim         diag::err_expected_init_in_condition);
1623199990Srdivacky  }
1624234353Sdim
1625234353Sdim  if (!InitExpr.isInvalid())
1626234353Sdim    Actions.AddInitializerToDecl(DeclOut, InitExpr.take(), !CopyInitialization,
1627251662Sdim                                 DS.containsPlaceholderType());
1628251662Sdim  else
1629251662Sdim    Actions.ActOnInitializerError(DeclOut);
1630234353Sdim
1631208600Srdivacky  // FIXME: Build a reference to this declaration? Convert it to bool?
1632208600Srdivacky  // (This is currently handled by Sema).
1633219077Sdim
1634219077Sdim  Actions.FinalizeDeclaration(DeclOut);
1635208600Srdivacky
1636199990Srdivacky  return false;
1637193326Sed}
1638193326Sed
1639193326Sed/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
1640193326Sed/// This should only be called when the current token is known to be part of
1641193326Sed/// simple-type-specifier.
1642193326Sed///
1643193326Sed///       simple-type-specifier:
1644193326Sed///         '::'[opt] nested-name-specifier[opt] type-name
1645193326Sed///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
1646193326Sed///         char
1647193326Sed///         wchar_t
1648193326Sed///         bool
1649193326Sed///         short
1650193326Sed///         int
1651193326Sed///         long
1652193326Sed///         signed
1653193326Sed///         unsigned
1654193326Sed///         float
1655193326Sed///         double
1656193326Sed///         void
1657193326Sed/// [GNU]   typeof-specifier
1658193326Sed/// [C++0x] auto               [TODO]
1659193326Sed///
1660193326Sed///       type-name:
1661193326Sed///         class-name
1662193326Sed///         enum-name
1663193326Sed///         typedef-name
1664193326Sed///
1665193326Sedvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
1666193326Sed  DS.SetRangeStart(Tok.getLocation());
1667193326Sed  const char *PrevSpec;
1668198092Srdivacky  unsigned DiagID;
1669193326Sed  SourceLocation Loc = Tok.getLocation();
1670198092Srdivacky
1671193326Sed  switch (Tok.getKind()) {
1672193326Sed  case tok::identifier:   // foo::bar
1673193326Sed  case tok::coloncolon:   // ::foo::bar
1674226633Sdim    llvm_unreachable("Annotation token should already be formed!");
1675198092Srdivacky  default:
1676226633Sdim    llvm_unreachable("Not a simple-type-specifier token!");
1677193326Sed
1678193326Sed  // type-name
1679193326Sed  case tok::annot_typename: {
1680218893Sdim    if (getTypeAnnotation(Tok))
1681218893Sdim      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
1682218893Sdim                         getTypeAnnotation(Tok));
1683218893Sdim    else
1684218893Sdim      DS.SetTypeSpecError();
1685218893Sdim
1686218893Sdim    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
1687218893Sdim    ConsumeToken();
1688218893Sdim
1689218893Sdim    // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
1690218893Sdim    // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
1691218893Sdim    // Objective-C interface.  If we don't have Objective-C or a '<', this is
1692218893Sdim    // just a normal reference to a typedef name.
1693234353Sdim    if (Tok.is(tok::less) && getLangOpts().ObjC1)
1694218893Sdim      ParseObjCProtocolQualifiers(DS);
1695218893Sdim
1696218893Sdim    DS.Finish(Diags, PP);
1697218893Sdim    return;
1698193326Sed  }
1699198092Srdivacky
1700193326Sed  // builtin types
1701193326Sed  case tok::kw_short:
1702198092Srdivacky    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
1703193326Sed    break;
1704193326Sed  case tok::kw_long:
1705198092Srdivacky    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID);
1706193326Sed    break;
1707221345Sdim  case tok::kw___int64:
1708221345Sdim    DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, DiagID);
1709221345Sdim    break;
1710193326Sed  case tok::kw_signed:
1711198092Srdivacky    DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
1712193326Sed    break;
1713193326Sed  case tok::kw_unsigned:
1714198092Srdivacky    DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID);
1715193326Sed    break;
1716193326Sed  case tok::kw_void:
1717198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
1718193326Sed    break;
1719193326Sed  case tok::kw_char:
1720198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
1721193326Sed    break;
1722193326Sed  case tok::kw_int:
1723198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
1724193326Sed    break;
1725234353Sdim  case tok::kw___int128:
1726234353Sdim    DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID);
1727234353Sdim    break;
1728226633Sdim  case tok::kw_half:
1729226633Sdim    DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID);
1730226633Sdim    break;
1731193326Sed  case tok::kw_float:
1732198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
1733193326Sed    break;
1734193326Sed  case tok::kw_double:
1735198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
1736193326Sed    break;
1737193326Sed  case tok::kw_wchar_t:
1738198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
1739193326Sed    break;
1740198092Srdivacky  case tok::kw_char16_t:
1741198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
1742198092Srdivacky    break;
1743198092Srdivacky  case tok::kw_char32_t:
1744198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
1745198092Srdivacky    break;
1746193326Sed  case tok::kw_bool:
1747198092Srdivacky    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
1748193326Sed    break;
1749234353Sdim  case tok::annot_decltype:
1750234353Sdim  case tok::kw_decltype:
1751234353Sdim    DS.SetRangeEnd(ParseDecltypeSpecifier(DS));
1752234353Sdim    return DS.Finish(Diags, PP);
1753198092Srdivacky
1754193326Sed  // GNU typeof support.
1755193326Sed  case tok::kw_typeof:
1756193326Sed    ParseTypeofSpecifier(DS);
1757193326Sed    DS.Finish(Diags, PP);
1758193326Sed    return;
1759193326Sed  }
1760193326Sed  if (Tok.is(tok::annot_typename))
1761193326Sed    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
1762193326Sed  else
1763193326Sed    DS.SetRangeEnd(Tok.getLocation());
1764193326Sed  ConsumeToken();
1765193326Sed  DS.Finish(Diags, PP);
1766193326Sed}
1767193326Sed
1768193326Sed/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
1769193326Sed/// [dcl.name]), which is a non-empty sequence of type-specifiers,
1770193326Sed/// e.g., "const short int". Note that the DeclSpec is *not* finished
1771193326Sed/// by parsing the type-specifier-seq, because these sequences are
1772193326Sed/// typically followed by some form of declarator. Returns true and
1773193326Sed/// emits diagnostics if this is not a type-specifier-seq, false
1774193326Sed/// otherwise.
1775193326Sed///
1776193326Sed///   type-specifier-seq: [C++ 8.1]
1777193326Sed///     type-specifier type-specifier-seq[opt]
1778193326Sed///
1779193326Sedbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
1780234353Sdim  ParseSpecifierQualifierList(DS, AS_none, DSC_type_specifier);
1781204643Srdivacky  DS.Finish(Diags, PP);
1782193326Sed  return false;
1783193326Sed}
1784193326Sed
1785198893Srdivacky/// \brief Finish parsing a C++ unqualified-id that is a template-id of
1786198893Srdivacky/// some form.
1787198893Srdivacky///
1788198893Srdivacky/// This routine is invoked when a '<' is encountered after an identifier or
1789198893Srdivacky/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine
1790198893Srdivacky/// whether the unqualified-id is actually a template-id. This routine will
1791198893Srdivacky/// then parse the template arguments and form the appropriate template-id to
1792198893Srdivacky/// return to the caller.
1793198893Srdivacky///
1794198893Srdivacky/// \param SS the nested-name-specifier that precedes this template-id, if
1795198893Srdivacky/// we're actually parsing a qualified-id.
1796198893Srdivacky///
1797198893Srdivacky/// \param Name for constructor and destructor names, this is the actual
1798198893Srdivacky/// identifier that may be a template-name.
1799198893Srdivacky///
1800198893Srdivacky/// \param NameLoc the location of the class-name in a constructor or
1801198893Srdivacky/// destructor.
1802198893Srdivacky///
1803198893Srdivacky/// \param EnteringContext whether we're entering the scope of the
1804198893Srdivacky/// nested-name-specifier.
1805198893Srdivacky///
1806198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access
1807198893Srdivacky/// expression, the type of the base object whose member is being accessed.
1808198893Srdivacky///
1809198893Srdivacky/// \param Id as input, describes the template-name or operator-function-id
1810198893Srdivacky/// that precedes the '<'. If template arguments were parsed successfully,
1811198893Srdivacky/// will be updated with the template-id.
1812198893Srdivacky///
1813204643Srdivacky/// \param AssumeTemplateId When true, this routine will assume that the name
1814204643Srdivacky/// refers to a template without performing name lookup to verify.
1815204643Srdivacky///
1816198893Srdivacky/// \returns true if a parse error occurred, false otherwise.
1817198893Srdivackybool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
1818234353Sdim                                          SourceLocation TemplateKWLoc,
1819198893Srdivacky                                          IdentifierInfo *Name,
1820198893Srdivacky                                          SourceLocation NameLoc,
1821198893Srdivacky                                          bool EnteringContext,
1822212904Sdim                                          ParsedType ObjectType,
1823204643Srdivacky                                          UnqualifiedId &Id,
1824234353Sdim                                          bool AssumeTemplateId) {
1825208600Srdivacky  assert((AssumeTemplateId || Tok.is(tok::less)) &&
1826208600Srdivacky         "Expected '<' to finish parsing a template-id");
1827198893Srdivacky
1828198893Srdivacky  TemplateTy Template;
1829198893Srdivacky  TemplateNameKind TNK = TNK_Non_template;
1830198893Srdivacky  switch (Id.getKind()) {
1831198893Srdivacky  case UnqualifiedId::IK_Identifier:
1832198893Srdivacky  case UnqualifiedId::IK_OperatorFunctionId:
1833199990Srdivacky  case UnqualifiedId::IK_LiteralOperatorId:
1834204643Srdivacky    if (AssumeTemplateId) {
1835234353Sdim      TNK = Actions.ActOnDependentTemplateName(getCurScope(), SS, TemplateKWLoc,
1836210299Sed                                               Id, ObjectType, EnteringContext,
1837210299Sed                                               Template);
1838210299Sed      if (TNK == TNK_Non_template)
1839210299Sed        return true;
1840208600Srdivacky    } else {
1841208600Srdivacky      bool MemberOfUnknownSpecialization;
1842212904Sdim      TNK = Actions.isTemplateName(getCurScope(), SS,
1843212904Sdim                                   TemplateKWLoc.isValid(), Id,
1844212904Sdim                                   ObjectType, EnteringContext, Template,
1845208600Srdivacky                                   MemberOfUnknownSpecialization);
1846208600Srdivacky
1847208600Srdivacky      if (TNK == TNK_Non_template && MemberOfUnknownSpecialization &&
1848208600Srdivacky          ObjectType && IsTemplateArgumentList()) {
1849208600Srdivacky        // We have something like t->getAs<T>(), where getAs is a
1850208600Srdivacky        // member of an unknown specialization. However, this will only
1851208600Srdivacky        // parse correctly as a template, so suggest the keyword 'template'
1852208600Srdivacky        // before 'getAs' and treat this as a dependent template name.
1853208600Srdivacky        std::string Name;
1854208600Srdivacky        if (Id.getKind() == UnqualifiedId::IK_Identifier)
1855208600Srdivacky          Name = Id.Identifier->getName();
1856208600Srdivacky        else {
1857208600Srdivacky          Name = "operator ";
1858208600Srdivacky          if (Id.getKind() == UnqualifiedId::IK_OperatorFunctionId)
1859208600Srdivacky            Name += getOperatorSpelling(Id.OperatorFunctionId.Operator);
1860208600Srdivacky          else
1861208600Srdivacky            Name += Id.Identifier->getName();
1862208600Srdivacky        }
1863208600Srdivacky        Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)
1864208600Srdivacky          << Name
1865208600Srdivacky          << FixItHint::CreateInsertion(Id.StartLocation, "template ");
1866234353Sdim        TNK = Actions.ActOnDependentTemplateName(getCurScope(),
1867234353Sdim                                                 SS, TemplateKWLoc, Id,
1868234353Sdim                                                 ObjectType, EnteringContext,
1869234353Sdim                                                 Template);
1870210299Sed        if (TNK == TNK_Non_template)
1871208600Srdivacky          return true;
1872208600Srdivacky      }
1873208600Srdivacky    }
1874198893Srdivacky    break;
1875198893Srdivacky
1876198893Srdivacky  case UnqualifiedId::IK_ConstructorName: {
1877198893Srdivacky    UnqualifiedId TemplateName;
1878208600Srdivacky    bool MemberOfUnknownSpecialization;
1879198893Srdivacky    TemplateName.setIdentifier(Name, NameLoc);
1880212904Sdim    TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(),
1881212904Sdim                                 TemplateName, ObjectType,
1882208600Srdivacky                                 EnteringContext, Template,
1883208600Srdivacky                                 MemberOfUnknownSpecialization);
1884198893Srdivacky    break;
1885198893Srdivacky  }
1886198893Srdivacky
1887198893Srdivacky  case UnqualifiedId::IK_DestructorName: {
1888198893Srdivacky    UnqualifiedId TemplateName;
1889208600Srdivacky    bool MemberOfUnknownSpecialization;
1890198893Srdivacky    TemplateName.setIdentifier(Name, NameLoc);
1891198893Srdivacky    if (ObjectType) {
1892234353Sdim      TNK = Actions.ActOnDependentTemplateName(getCurScope(),
1893234353Sdim                                               SS, TemplateKWLoc, TemplateName,
1894234353Sdim                                               ObjectType, EnteringContext,
1895234353Sdim                                               Template);
1896210299Sed      if (TNK == TNK_Non_template)
1897198893Srdivacky        return true;
1898198893Srdivacky    } else {
1899212904Sdim      TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(),
1900212904Sdim                                   TemplateName, ObjectType,
1901208600Srdivacky                                   EnteringContext, Template,
1902208600Srdivacky                                   MemberOfUnknownSpecialization);
1903198893Srdivacky
1904212904Sdim      if (TNK == TNK_Non_template && !Id.DestructorName.get()) {
1905204643Srdivacky        Diag(NameLoc, diag::err_destructor_template_id)
1906204643Srdivacky          << Name << SS.getRange();
1907198893Srdivacky        return true;
1908198893Srdivacky      }
1909198893Srdivacky    }
1910198893Srdivacky    break;
1911198893Srdivacky  }
1912198893Srdivacky
1913198893Srdivacky  default:
1914198893Srdivacky    return false;
1915198893Srdivacky  }
1916198893Srdivacky
1917198893Srdivacky  if (TNK == TNK_Non_template)
1918198893Srdivacky    return false;
1919198893Srdivacky
1920198893Srdivacky  // Parse the enclosed template argument list.
1921198893Srdivacky  SourceLocation LAngleLoc, RAngleLoc;
1922198893Srdivacky  TemplateArgList TemplateArgs;
1923208600Srdivacky  if (Tok.is(tok::less) &&
1924208600Srdivacky      ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
1925221345Sdim                                       SS, true, LAngleLoc,
1926198893Srdivacky                                       TemplateArgs,
1927198893Srdivacky                                       RAngleLoc))
1928198893Srdivacky    return true;
1929198893Srdivacky
1930198893Srdivacky  if (Id.getKind() == UnqualifiedId::IK_Identifier ||
1931199990Srdivacky      Id.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
1932199990Srdivacky      Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
1933198893Srdivacky    // Form a parsed representation of the template-id to be stored in the
1934198893Srdivacky    // UnqualifiedId.
1935198893Srdivacky    TemplateIdAnnotation *TemplateId
1936234982Sdim      = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
1937198893Srdivacky
1938198893Srdivacky    if (Id.getKind() == UnqualifiedId::IK_Identifier) {
1939198893Srdivacky      TemplateId->Name = Id.Identifier;
1940198893Srdivacky      TemplateId->Operator = OO_None;
1941198893Srdivacky      TemplateId->TemplateNameLoc = Id.StartLocation;
1942198893Srdivacky    } else {
1943198893Srdivacky      TemplateId->Name = 0;
1944198893Srdivacky      TemplateId->Operator = Id.OperatorFunctionId.Operator;
1945198893Srdivacky      TemplateId->TemplateNameLoc = Id.StartLocation;
1946198893Srdivacky    }
1947198893Srdivacky
1948221345Sdim    TemplateId->SS = SS;
1949234353Sdim    TemplateId->TemplateKWLoc = TemplateKWLoc;
1950212904Sdim    TemplateId->Template = Template;
1951198893Srdivacky    TemplateId->Kind = TNK;
1952198893Srdivacky    TemplateId->LAngleLoc = LAngleLoc;
1953198893Srdivacky    TemplateId->RAngleLoc = RAngleLoc;
1954199482Srdivacky    ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
1955198893Srdivacky    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size();
1956199482Srdivacky         Arg != ArgEnd; ++Arg)
1957198893Srdivacky      Args[Arg] = TemplateArgs[Arg];
1958198893Srdivacky
1959198893Srdivacky    Id.setTemplateId(TemplateId);
1960198893Srdivacky    return false;
1961198893Srdivacky  }
1962198893Srdivacky
1963198893Srdivacky  // Bundle the template arguments together.
1964243830Sdim  ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs);
1965234353Sdim
1966198893Srdivacky  // Constructor and destructor names.
1967212904Sdim  TypeResult Type
1968234353Sdim    = Actions.ActOnTemplateIdType(SS, TemplateKWLoc,
1969234353Sdim                                  Template, NameLoc,
1970234353Sdim                                  LAngleLoc, TemplateArgsPtr, RAngleLoc,
1971234353Sdim                                  /*IsCtorOrDtorName=*/true);
1972198893Srdivacky  if (Type.isInvalid())
1973198893Srdivacky    return true;
1974198893Srdivacky
1975198893Srdivacky  if (Id.getKind() == UnqualifiedId::IK_ConstructorName)
1976198893Srdivacky    Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);
1977198893Srdivacky  else
1978198893Srdivacky    Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);
1979198893Srdivacky
1980198893Srdivacky  return false;
1981198893Srdivacky}
1982198893Srdivacky
1983198893Srdivacky/// \brief Parse an operator-function-id or conversion-function-id as part
1984198893Srdivacky/// of a C++ unqualified-id.
1985198893Srdivacky///
1986198893Srdivacky/// This routine is responsible only for parsing the operator-function-id or
1987198893Srdivacky/// conversion-function-id; it does not handle template arguments in any way.
1988198893Srdivacky///
1989198893Srdivacky/// \code
1990198893Srdivacky///       operator-function-id: [C++ 13.5]
1991198893Srdivacky///         'operator' operator
1992198893Srdivacky///
1993198893Srdivacky///       operator: one of
1994198893Srdivacky///            new   delete  new[]   delete[]
1995198893Srdivacky///            +     -    *  /    %  ^    &   |   ~
1996198893Srdivacky///            !     =    <  >    += -=   *=  /=  %=
1997198893Srdivacky///            ^=    &=   |= <<   >> >>= <<=  ==  !=
1998198893Srdivacky///            <=    >=   && ||   ++ --   ,   ->* ->
1999198893Srdivacky///            ()    []
2000198893Srdivacky///
2001198893Srdivacky///       conversion-function-id: [C++ 12.3.2]
2002198893Srdivacky///         operator conversion-type-id
2003198893Srdivacky///
2004198893Srdivacky///       conversion-type-id:
2005198893Srdivacky///         type-specifier-seq conversion-declarator[opt]
2006198893Srdivacky///
2007198893Srdivacky///       conversion-declarator:
2008198893Srdivacky///         ptr-operator conversion-declarator[opt]
2009198893Srdivacky/// \endcode
2010198893Srdivacky///
2011243830Sdim/// \param SS The nested-name-specifier that preceded this unqualified-id. If
2012198893Srdivacky/// non-empty, then we are parsing the unqualified-id of a qualified-id.
2013198893Srdivacky///
2014198893Srdivacky/// \param EnteringContext whether we are entering the scope of the
2015198893Srdivacky/// nested-name-specifier.
2016198893Srdivacky///
2017198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access
2018198893Srdivacky/// expression, the type of the base object whose member is being accessed.
2019198893Srdivacky///
2020198893Srdivacky/// \param Result on a successful parse, contains the parsed unqualified-id.
2021198893Srdivacky///
2022198893Srdivacky/// \returns true if parsing fails, false otherwise.
2023198893Srdivackybool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
2024212904Sdim                                        ParsedType ObjectType,
2025198893Srdivacky                                        UnqualifiedId &Result) {
2026198893Srdivacky  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
2027198893Srdivacky
2028198893Srdivacky  // Consume the 'operator' keyword.
2029198893Srdivacky  SourceLocation KeywordLoc = ConsumeToken();
2030198893Srdivacky
2031198893Srdivacky  // Determine what kind of operator name we have.
2032198893Srdivacky  unsigned SymbolIdx = 0;
2033198893Srdivacky  SourceLocation SymbolLocations[3];
2034198893Srdivacky  OverloadedOperatorKind Op = OO_None;
2035198893Srdivacky  switch (Tok.getKind()) {
2036198893Srdivacky    case tok::kw_new:
2037198893Srdivacky    case tok::kw_delete: {
2038198893Srdivacky      bool isNew = Tok.getKind() == tok::kw_new;
2039198893Srdivacky      // Consume the 'new' or 'delete'.
2040198893Srdivacky      SymbolLocations[SymbolIdx++] = ConsumeToken();
2041234353Sdim      // Check for array new/delete.
2042234353Sdim      if (Tok.is(tok::l_square) &&
2043249423Sdim          (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))) {
2044226633Sdim        // Consume the '[' and ']'.
2045226633Sdim        BalancedDelimiterTracker T(*this, tok::l_square);
2046226633Sdim        T.consumeOpen();
2047226633Sdim        T.consumeClose();
2048226633Sdim        if (T.getCloseLocation().isInvalid())
2049198893Srdivacky          return true;
2050198893Srdivacky
2051226633Sdim        SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2052226633Sdim        SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2053198893Srdivacky        Op = isNew? OO_Array_New : OO_Array_Delete;
2054198893Srdivacky      } else {
2055198893Srdivacky        Op = isNew? OO_New : OO_Delete;
2056198893Srdivacky      }
2057198893Srdivacky      break;
2058198893Srdivacky    }
2059198893Srdivacky
2060198893Srdivacky#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2061198893Srdivacky    case tok::Token:                                                     \
2062198893Srdivacky      SymbolLocations[SymbolIdx++] = ConsumeToken();                     \
2063198893Srdivacky      Op = OO_##Name;                                                    \
2064198893Srdivacky      break;
2065198893Srdivacky#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
2066198893Srdivacky#include "clang/Basic/OperatorKinds.def"
2067198893Srdivacky
2068198893Srdivacky    case tok::l_paren: {
2069226633Sdim      // Consume the '(' and ')'.
2070226633Sdim      BalancedDelimiterTracker T(*this, tok::l_paren);
2071226633Sdim      T.consumeOpen();
2072226633Sdim      T.consumeClose();
2073226633Sdim      if (T.getCloseLocation().isInvalid())
2074198893Srdivacky        return true;
2075198893Srdivacky
2076226633Sdim      SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2077226633Sdim      SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2078198893Srdivacky      Op = OO_Call;
2079198893Srdivacky      break;
2080198893Srdivacky    }
2081198893Srdivacky
2082198893Srdivacky    case tok::l_square: {
2083226633Sdim      // Consume the '[' and ']'.
2084226633Sdim      BalancedDelimiterTracker T(*this, tok::l_square);
2085226633Sdim      T.consumeOpen();
2086226633Sdim      T.consumeClose();
2087226633Sdim      if (T.getCloseLocation().isInvalid())
2088198893Srdivacky        return true;
2089198893Srdivacky
2090226633Sdim      SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2091226633Sdim      SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2092198893Srdivacky      Op = OO_Subscript;
2093198893Srdivacky      break;
2094198893Srdivacky    }
2095198893Srdivacky
2096198893Srdivacky    case tok::code_completion: {
2097198893Srdivacky      // Code completion for the operator name.
2098210299Sed      Actions.CodeCompleteOperatorName(getCurScope());
2099226633Sdim      cutOffParsing();
2100198893Srdivacky      // Don't try to parse any further.
2101198893Srdivacky      return true;
2102198893Srdivacky    }
2103198893Srdivacky
2104198893Srdivacky    default:
2105198893Srdivacky      break;
2106198893Srdivacky  }
2107198893Srdivacky
2108198893Srdivacky  if (Op != OO_None) {
2109198893Srdivacky    // We have parsed an operator-function-id.
2110198893Srdivacky    Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);
2111198893Srdivacky    return false;
2112198893Srdivacky  }
2113199990Srdivacky
2114199990Srdivacky  // Parse a literal-operator-id.
2115199990Srdivacky  //
2116243830Sdim  //   literal-operator-id: C++11 [over.literal]
2117243830Sdim  //     operator string-literal identifier
2118243830Sdim  //     operator user-defined-string-literal
2119199990Srdivacky
2120249423Sdim  if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) {
2121234353Sdim    Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);
2122199990Srdivacky
2123234353Sdim    SourceLocation DiagLoc;
2124234353Sdim    unsigned DiagId = 0;
2125234353Sdim
2126234353Sdim    // We're past translation phase 6, so perform string literal concatenation
2127234353Sdim    // before checking for "".
2128249423Sdim    SmallVector<Token, 4> Toks;
2129249423Sdim    SmallVector<SourceLocation, 4> TokLocs;
2130234353Sdim    while (isTokenStringLiteral()) {
2131234353Sdim      if (!Tok.is(tok::string_literal) && !DiagId) {
2132243830Sdim        // C++11 [over.literal]p1:
2133243830Sdim        //   The string-literal or user-defined-string-literal in a
2134243830Sdim        //   literal-operator-id shall have no encoding-prefix [...].
2135234353Sdim        DiagLoc = Tok.getLocation();
2136234353Sdim        DiagId = diag::err_literal_operator_string_prefix;
2137234353Sdim      }
2138234353Sdim      Toks.push_back(Tok);
2139234353Sdim      TokLocs.push_back(ConsumeStringToken());
2140234353Sdim    }
2141234353Sdim
2142234353Sdim    StringLiteralParser Literal(Toks.data(), Toks.size(), PP);
2143234353Sdim    if (Literal.hadError)
2144234353Sdim      return true;
2145234353Sdim
2146234353Sdim    // Grab the literal operator's suffix, which will be either the next token
2147234353Sdim    // or a ud-suffix from the string literal.
2148234353Sdim    IdentifierInfo *II = 0;
2149234353Sdim    SourceLocation SuffixLoc;
2150234353Sdim    if (!Literal.getUDSuffix().empty()) {
2151234353Sdim      II = &PP.getIdentifierTable().get(Literal.getUDSuffix());
2152234353Sdim      SuffixLoc =
2153234353Sdim        Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()],
2154234353Sdim                                       Literal.getUDSuffixOffset(),
2155234353Sdim                                       PP.getSourceManager(), getLangOpts());
2156234353Sdim    } else if (Tok.is(tok::identifier)) {
2157234353Sdim      II = Tok.getIdentifierInfo();
2158234353Sdim      SuffixLoc = ConsumeToken();
2159234353Sdim      TokLocs.push_back(SuffixLoc);
2160234353Sdim    } else {
2161199990Srdivacky      Diag(Tok.getLocation(), diag::err_expected_ident);
2162199990Srdivacky      return true;
2163199990Srdivacky    }
2164199990Srdivacky
2165234353Sdim    // The string literal must be empty.
2166234353Sdim    if (!Literal.GetString().empty() || Literal.Pascal) {
2167243830Sdim      // C++11 [over.literal]p1:
2168243830Sdim      //   The string-literal or user-defined-string-literal in a
2169243830Sdim      //   literal-operator-id shall [...] contain no characters
2170243830Sdim      //   other than the implicit terminating '\0'.
2171234353Sdim      DiagLoc = TokLocs.front();
2172234353Sdim      DiagId = diag::err_literal_operator_string_not_empty;
2173234353Sdim    }
2174234353Sdim
2175234353Sdim    if (DiagId) {
2176234353Sdim      // This isn't a valid literal-operator-id, but we think we know
2177234353Sdim      // what the user meant. Tell them what they should have written.
2178249423Sdim      SmallString<32> Str;
2179234353Sdim      Str += "\"\" ";
2180234353Sdim      Str += II->getName();
2181234353Sdim      Diag(DiagLoc, DiagId) << FixItHint::CreateReplacement(
2182234353Sdim          SourceRange(TokLocs.front(), TokLocs.back()), Str);
2183234353Sdim    }
2184234353Sdim
2185234353Sdim    Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc);
2186199990Srdivacky    return false;
2187199990Srdivacky  }
2188198893Srdivacky
2189198893Srdivacky  // Parse a conversion-function-id.
2190198893Srdivacky  //
2191198893Srdivacky  //   conversion-function-id: [C++ 12.3.2]
2192198893Srdivacky  //     operator conversion-type-id
2193198893Srdivacky  //
2194198893Srdivacky  //   conversion-type-id:
2195198893Srdivacky  //     type-specifier-seq conversion-declarator[opt]
2196198893Srdivacky  //
2197198893Srdivacky  //   conversion-declarator:
2198198893Srdivacky  //     ptr-operator conversion-declarator[opt]
2199198893Srdivacky
2200198893Srdivacky  // Parse the type-specifier-seq.
2201221345Sdim  DeclSpec DS(AttrFactory);
2202199990Srdivacky  if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
2203198893Srdivacky    return true;
2204198893Srdivacky
2205198893Srdivacky  // Parse the conversion-declarator, which is merely a sequence of
2206198893Srdivacky  // ptr-operators.
2207251662Sdim  Declarator D(DS, Declarator::ConversionIdContext);
2208198893Srdivacky  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
2209198893Srdivacky
2210198893Srdivacky  // Finish up the type.
2211212904Sdim  TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D);
2212198893Srdivacky  if (Ty.isInvalid())
2213198893Srdivacky    return true;
2214198893Srdivacky
2215198893Srdivacky  // Note that this is a conversion-function-id.
2216198893Srdivacky  Result.setConversionFunctionId(KeywordLoc, Ty.get(),
2217198893Srdivacky                                 D.getSourceRange().getEnd());
2218198893Srdivacky  return false;
2219198893Srdivacky}
2220198893Srdivacky
2221198893Srdivacky/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the
2222198893Srdivacky/// name of an entity.
2223198893Srdivacky///
2224198893Srdivacky/// \code
2225198893Srdivacky///       unqualified-id: [C++ expr.prim.general]
2226198893Srdivacky///         identifier
2227198893Srdivacky///         operator-function-id
2228198893Srdivacky///         conversion-function-id
2229198893Srdivacky/// [C++0x] literal-operator-id [TODO]
2230198893Srdivacky///         ~ class-name
2231198893Srdivacky///         template-id
2232198893Srdivacky///
2233198893Srdivacky/// \endcode
2234198893Srdivacky///
2235243830Sdim/// \param SS The nested-name-specifier that preceded this unqualified-id. If
2236198893Srdivacky/// non-empty, then we are parsing the unqualified-id of a qualified-id.
2237198893Srdivacky///
2238198893Srdivacky/// \param EnteringContext whether we are entering the scope of the
2239198893Srdivacky/// nested-name-specifier.
2240198893Srdivacky///
2241198893Srdivacky/// \param AllowDestructorName whether we allow parsing of a destructor name.
2242198893Srdivacky///
2243198893Srdivacky/// \param AllowConstructorName whether we allow parsing a constructor name.
2244198893Srdivacky///
2245198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access
2246198893Srdivacky/// expression, the type of the base object whose member is being accessed.
2247198893Srdivacky///
2248198893Srdivacky/// \param Result on a successful parse, contains the parsed unqualified-id.
2249198893Srdivacky///
2250198893Srdivacky/// \returns true if parsing fails, false otherwise.
2251198893Srdivackybool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
2252198893Srdivacky                                bool AllowDestructorName,
2253198893Srdivacky                                bool AllowConstructorName,
2254212904Sdim                                ParsedType ObjectType,
2255234353Sdim                                SourceLocation& TemplateKWLoc,
2256198893Srdivacky                                UnqualifiedId &Result) {
2257208600Srdivacky
2258208600Srdivacky  // Handle 'A::template B'. This is for template-ids which have not
2259208600Srdivacky  // already been annotated by ParseOptionalCXXScopeSpecifier().
2260208600Srdivacky  bool TemplateSpecified = false;
2261234353Sdim  if (getLangOpts().CPlusPlus && Tok.is(tok::kw_template) &&
2262208600Srdivacky      (ObjectType || SS.isSet())) {
2263208600Srdivacky    TemplateSpecified = true;
2264208600Srdivacky    TemplateKWLoc = ConsumeToken();
2265208600Srdivacky  }
2266208600Srdivacky
2267198893Srdivacky  // unqualified-id:
2268198893Srdivacky  //   identifier
2269198893Srdivacky  //   template-id (when it hasn't already been annotated)
2270198893Srdivacky  if (Tok.is(tok::identifier)) {
2271198893Srdivacky    // Consume the identifier.
2272198893Srdivacky    IdentifierInfo *Id = Tok.getIdentifierInfo();
2273198893Srdivacky    SourceLocation IdLoc = ConsumeToken();
2274198893Srdivacky
2275234353Sdim    if (!getLangOpts().CPlusPlus) {
2276202379Srdivacky      // If we're not in C++, only identifiers matter. Record the
2277202379Srdivacky      // identifier and return.
2278202379Srdivacky      Result.setIdentifier(Id, IdLoc);
2279202379Srdivacky      return false;
2280202379Srdivacky    }
2281202379Srdivacky
2282198893Srdivacky    if (AllowConstructorName &&
2283210299Sed        Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {
2284198893Srdivacky      // We have parsed a constructor name.
2285234353Sdim      ParsedType Ty = Actions.getTypeName(*Id, IdLoc, getCurScope(),
2286234353Sdim                                          &SS, false, false,
2287234353Sdim                                          ParsedType(),
2288234353Sdim                                          /*IsCtorOrDtorName=*/true,
2289234353Sdim                                          /*NonTrivialTypeSourceInfo=*/true);
2290234353Sdim      Result.setConstructorName(Ty, IdLoc, IdLoc);
2291198893Srdivacky    } else {
2292198893Srdivacky      // We have parsed an identifier.
2293198893Srdivacky      Result.setIdentifier(Id, IdLoc);
2294198893Srdivacky    }
2295198893Srdivacky
2296198893Srdivacky    // If the next token is a '<', we may have a template.
2297208600Srdivacky    if (TemplateSpecified || Tok.is(tok::less))
2298234353Sdim      return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, Id, IdLoc,
2299234353Sdim                                          EnteringContext, ObjectType,
2300234353Sdim                                          Result, TemplateSpecified);
2301198893Srdivacky
2302198893Srdivacky    return false;
2303198893Srdivacky  }
2304198893Srdivacky
2305198893Srdivacky  // unqualified-id:
2306198893Srdivacky  //   template-id (already parsed and annotated)
2307198893Srdivacky  if (Tok.is(tok::annot_template_id)) {
2308224145Sdim    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2309202379Srdivacky
2310202379Srdivacky    // If the template-name names the current class, then this is a constructor
2311202379Srdivacky    if (AllowConstructorName && TemplateId->Name &&
2312210299Sed        Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
2313202379Srdivacky      if (SS.isSet()) {
2314202379Srdivacky        // C++ [class.qual]p2 specifies that a qualified template-name
2315202379Srdivacky        // is taken as the constructor name where a constructor can be
2316202379Srdivacky        // declared. Thus, the template arguments are extraneous, so
2317202379Srdivacky        // complain about them and remove them entirely.
2318202379Srdivacky        Diag(TemplateId->TemplateNameLoc,
2319202379Srdivacky             diag::err_out_of_line_constructor_template_id)
2320202379Srdivacky          << TemplateId->Name
2321206084Srdivacky          << FixItHint::CreateRemoval(
2322202379Srdivacky                    SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
2323234353Sdim        ParsedType Ty = Actions.getTypeName(*TemplateId->Name,
2324234353Sdim                                            TemplateId->TemplateNameLoc,
2325234353Sdim                                            getCurScope(),
2326234353Sdim                                            &SS, false, false,
2327234353Sdim                                            ParsedType(),
2328234353Sdim                                            /*IsCtorOrDtorName=*/true,
2329234353Sdim                                            /*NontrivialTypeSourceInfo=*/true);
2330234353Sdim        Result.setConstructorName(Ty, TemplateId->TemplateNameLoc,
2331202379Srdivacky                                  TemplateId->RAngleLoc);
2332202379Srdivacky        ConsumeToken();
2333202379Srdivacky        return false;
2334202379Srdivacky      }
2335202379Srdivacky
2336202379Srdivacky      Result.setConstructorTemplateId(TemplateId);
2337202379Srdivacky      ConsumeToken();
2338202379Srdivacky      return false;
2339202379Srdivacky    }
2340202379Srdivacky
2341198893Srdivacky    // We have already parsed a template-id; consume the annotation token as
2342198893Srdivacky    // our unqualified-id.
2343202379Srdivacky    Result.setTemplateId(TemplateId);
2344234353Sdim    TemplateKWLoc = TemplateId->TemplateKWLoc;
2345198893Srdivacky    ConsumeToken();
2346198893Srdivacky    return false;
2347198893Srdivacky  }
2348198893Srdivacky
2349198893Srdivacky  // unqualified-id:
2350198893Srdivacky  //   operator-function-id
2351198893Srdivacky  //   conversion-function-id
2352198893Srdivacky  if (Tok.is(tok::kw_operator)) {
2353198893Srdivacky    if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result))
2354198893Srdivacky      return true;
2355198893Srdivacky
2356199990Srdivacky    // If we have an operator-function-id or a literal-operator-id and the next
2357199990Srdivacky    // token is a '<', we may have a
2358198893Srdivacky    //
2359198893Srdivacky    //   template-id:
2360198893Srdivacky    //     operator-function-id < template-argument-list[opt] >
2361199990Srdivacky    if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
2362199990Srdivacky         Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) &&
2363208600Srdivacky        (TemplateSpecified || Tok.is(tok::less)))
2364234353Sdim      return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
2365234353Sdim                                          0, SourceLocation(),
2366234353Sdim                                          EnteringContext, ObjectType,
2367234353Sdim                                          Result, TemplateSpecified);
2368198893Srdivacky
2369198893Srdivacky    return false;
2370198893Srdivacky  }
2371198893Srdivacky
2372234353Sdim  if (getLangOpts().CPlusPlus &&
2373202379Srdivacky      (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {
2374198893Srdivacky    // C++ [expr.unary.op]p10:
2375198893Srdivacky    //   There is an ambiguity in the unary-expression ~X(), where X is a
2376198893Srdivacky    //   class-name. The ambiguity is resolved in favor of treating ~ as a
2377198893Srdivacky    //    unary complement rather than treating ~X as referring to a destructor.
2378198893Srdivacky
2379198893Srdivacky    // Parse the '~'.
2380198893Srdivacky    SourceLocation TildeLoc = ConsumeToken();
2381234353Sdim
2382234353Sdim    if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {
2383234353Sdim      DeclSpec DS(AttrFactory);
2384234353Sdim      SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
2385234353Sdim      if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) {
2386234353Sdim        Result.setDestructorName(TildeLoc, Type, EndLoc);
2387234353Sdim        return false;
2388234353Sdim      }
2389234353Sdim      return true;
2390234353Sdim    }
2391198893Srdivacky
2392198893Srdivacky    // Parse the class-name.
2393198893Srdivacky    if (Tok.isNot(tok::identifier)) {
2394204643Srdivacky      Diag(Tok, diag::err_destructor_tilde_identifier);
2395198893Srdivacky      return true;
2396198893Srdivacky    }
2397198893Srdivacky
2398198893Srdivacky    // Parse the class-name (or template-name in a simple-template-id).
2399198893Srdivacky    IdentifierInfo *ClassName = Tok.getIdentifierInfo();
2400198893Srdivacky    SourceLocation ClassNameLoc = ConsumeToken();
2401198893Srdivacky
2402208600Srdivacky    if (TemplateSpecified || Tok.is(tok::less)) {
2403212904Sdim      Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc);
2404234353Sdim      return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
2405234353Sdim                                          ClassName, ClassNameLoc,
2406234353Sdim                                          EnteringContext, ObjectType,
2407234353Sdim                                          Result, TemplateSpecified);
2408198893Srdivacky    }
2409198893Srdivacky
2410198893Srdivacky    // Note that this is a destructor name.
2411212904Sdim    ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName,
2412212904Sdim                                              ClassNameLoc, getCurScope(),
2413212904Sdim                                              SS, ObjectType,
2414212904Sdim                                              EnteringContext);
2415204643Srdivacky    if (!Ty)
2416198893Srdivacky      return true;
2417204643Srdivacky
2418198893Srdivacky    Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
2419198893Srdivacky    return false;
2420198893Srdivacky  }
2421198893Srdivacky
2422198893Srdivacky  Diag(Tok, diag::err_expected_unqualified_id)
2423234353Sdim    << getLangOpts().CPlusPlus;
2424198893Srdivacky  return true;
2425198893Srdivacky}
2426198893Srdivacky
2427193326Sed/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
2428193326Sed/// memory in a typesafe manner and call constructors.
2429198092Srdivacky///
2430193326Sed/// This method is called to parse the new expression after the optional :: has
2431193326Sed/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
2432193326Sed/// is its location.  Otherwise, "Start" is the location of the 'new' token.
2433193326Sed///
2434193326Sed///        new-expression:
2435193326Sed///                   '::'[opt] 'new' new-placement[opt] new-type-id
2436193326Sed///                                     new-initializer[opt]
2437193326Sed///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
2438193326Sed///                                     new-initializer[opt]
2439193326Sed///
2440193326Sed///        new-placement:
2441193326Sed///                   '(' expression-list ')'
2442193326Sed///
2443193326Sed///        new-type-id:
2444193326Sed///                   type-specifier-seq new-declarator[opt]
2445221345Sdim/// [GNU]             attributes type-specifier-seq new-declarator[opt]
2446193326Sed///
2447193326Sed///        new-declarator:
2448193326Sed///                   ptr-operator new-declarator[opt]
2449193326Sed///                   direct-new-declarator
2450193326Sed///
2451193326Sed///        new-initializer:
2452193326Sed///                   '(' expression-list[opt] ')'
2453223017Sdim/// [C++0x]           braced-init-list
2454193326Sed///
2455212904SdimExprResult
2456193326SedParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
2457193326Sed  assert(Tok.is(tok::kw_new) && "expected 'new' token");
2458193326Sed  ConsumeToken();   // Consume 'new'
2459193326Sed
2460193326Sed  // A '(' now can be a new-placement or the '(' wrapping the type-id in the
2461193326Sed  // second form of new-expression. It can't be a new-type-id.
2462193326Sed
2463243830Sdim  ExprVector PlacementArgs;
2464193326Sed  SourceLocation PlacementLParen, PlacementRParen;
2465193326Sed
2466210299Sed  SourceRange TypeIdParens;
2467221345Sdim  DeclSpec DS(AttrFactory);
2468224145Sdim  Declarator DeclaratorInfo(DS, Declarator::CXXNewContext);
2469193326Sed  if (Tok.is(tok::l_paren)) {
2470193326Sed    // If it turns out to be a placement, we change the type location.
2471226633Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
2472226633Sdim    T.consumeOpen();
2473226633Sdim    PlacementLParen = T.getOpenLocation();
2474193326Sed    if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
2475263508Sdim      SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2476193326Sed      return ExprError();
2477193326Sed    }
2478193326Sed
2479226633Sdim    T.consumeClose();
2480226633Sdim    PlacementRParen = T.getCloseLocation();
2481193326Sed    if (PlacementRParen.isInvalid()) {
2482263508Sdim      SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2483193326Sed      return ExprError();
2484193326Sed    }
2485193326Sed
2486193326Sed    if (PlacementArgs.empty()) {
2487193326Sed      // Reset the placement locations. There was no placement.
2488226633Sdim      TypeIdParens = T.getRange();
2489193326Sed      PlacementLParen = PlacementRParen = SourceLocation();
2490193326Sed    } else {
2491193326Sed      // We still need the type.
2492193326Sed      if (Tok.is(tok::l_paren)) {
2493226633Sdim        BalancedDelimiterTracker T(*this, tok::l_paren);
2494226633Sdim        T.consumeOpen();
2495221345Sdim        MaybeParseGNUAttributes(DeclaratorInfo);
2496193326Sed        ParseSpecifierQualifierList(DS);
2497193326Sed        DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2498193326Sed        ParseDeclarator(DeclaratorInfo);
2499226633Sdim        T.consumeClose();
2500226633Sdim        TypeIdParens = T.getRange();
2501193326Sed      } else {
2502221345Sdim        MaybeParseGNUAttributes(DeclaratorInfo);
2503193326Sed        if (ParseCXXTypeSpecifierSeq(DS))
2504193326Sed          DeclaratorInfo.setInvalidType(true);
2505193326Sed        else {
2506193326Sed          DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2507193326Sed          ParseDeclaratorInternal(DeclaratorInfo,
2508193326Sed                                  &Parser::ParseDirectNewDeclarator);
2509193326Sed        }
2510193326Sed      }
2511193326Sed    }
2512193326Sed  } else {
2513193326Sed    // A new-type-id is a simplified type-id, where essentially the
2514193326Sed    // direct-declarator is replaced by a direct-new-declarator.
2515221345Sdim    MaybeParseGNUAttributes(DeclaratorInfo);
2516193326Sed    if (ParseCXXTypeSpecifierSeq(DS))
2517193326Sed      DeclaratorInfo.setInvalidType(true);
2518193326Sed    else {
2519193326Sed      DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2520193326Sed      ParseDeclaratorInternal(DeclaratorInfo,
2521193326Sed                              &Parser::ParseDirectNewDeclarator);
2522193326Sed    }
2523193326Sed  }
2524193326Sed  if (DeclaratorInfo.isInvalidType()) {
2525263508Sdim    SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2526193326Sed    return ExprError();
2527193326Sed  }
2528193326Sed
2529234353Sdim  ExprResult Initializer;
2530193326Sed
2531193326Sed  if (Tok.is(tok::l_paren)) {
2532234353Sdim    SourceLocation ConstructorLParen, ConstructorRParen;
2533243830Sdim    ExprVector ConstructorArgs;
2534226633Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
2535226633Sdim    T.consumeOpen();
2536226633Sdim    ConstructorLParen = T.getOpenLocation();
2537193326Sed    if (Tok.isNot(tok::r_paren)) {
2538193326Sed      CommaLocsTy CommaLocs;
2539193326Sed      if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
2540263508Sdim        SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2541193326Sed        return ExprError();
2542193326Sed      }
2543193326Sed    }
2544226633Sdim    T.consumeClose();
2545226633Sdim    ConstructorRParen = T.getCloseLocation();
2546193326Sed    if (ConstructorRParen.isInvalid()) {
2547263508Sdim      SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2548193326Sed      return ExprError();
2549193326Sed    }
2550234353Sdim    Initializer = Actions.ActOnParenListExpr(ConstructorLParen,
2551234353Sdim                                             ConstructorRParen,
2552243830Sdim                                             ConstructorArgs);
2553249423Sdim  } else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) {
2554234353Sdim    Diag(Tok.getLocation(),
2555234353Sdim         diag::warn_cxx98_compat_generalized_initializer_lists);
2556234353Sdim    Initializer = ParseBraceInitializer();
2557193326Sed  }
2558234353Sdim  if (Initializer.isInvalid())
2559234353Sdim    return Initializer;
2560193326Sed
2561193326Sed  return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
2562243830Sdim                             PlacementArgs, PlacementRParen,
2563234353Sdim                             TypeIdParens, DeclaratorInfo, Initializer.take());
2564193326Sed}
2565193326Sed
2566193326Sed/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
2567193326Sed/// passed to ParseDeclaratorInternal.
2568193326Sed///
2569193326Sed///        direct-new-declarator:
2570193326Sed///                   '[' expression ']'
2571193326Sed///                   direct-new-declarator '[' constant-expression ']'
2572193326Sed///
2573193326Sedvoid Parser::ParseDirectNewDeclarator(Declarator &D) {
2574193326Sed  // Parse the array dimensions.
2575193326Sed  bool first = true;
2576193326Sed  while (Tok.is(tok::l_square)) {
2577234353Sdim    // An array-size expression can't start with a lambda.
2578234353Sdim    if (CheckProhibitedCXX11Attribute())
2579234353Sdim      continue;
2580234353Sdim
2581226633Sdim    BalancedDelimiterTracker T(*this, tok::l_square);
2582226633Sdim    T.consumeOpen();
2583226633Sdim
2584212904Sdim    ExprResult Size(first ? ParseExpression()
2585193326Sed                                : ParseConstantExpression());
2586193326Sed    if (Size.isInvalid()) {
2587193326Sed      // Recover
2588263508Sdim      SkipUntil(tok::r_square, StopAtSemi);
2589193326Sed      return;
2590193326Sed    }
2591193326Sed    first = false;
2592193326Sed
2593226633Sdim    T.consumeClose();
2594221345Sdim
2595234353Sdim    // Attributes here appertain to the array type. C++11 [expr.new]p5.
2596234353Sdim    ParsedAttributes Attrs(AttrFactory);
2597249423Sdim    MaybeParseCXX11Attributes(Attrs);
2598234353Sdim
2599221345Sdim    D.AddTypeInfo(DeclaratorChunk::getArray(0,
2600218893Sdim                                            /*static=*/false, /*star=*/false,
2601226633Sdim                                            Size.release(),
2602226633Sdim                                            T.getOpenLocation(),
2603226633Sdim                                            T.getCloseLocation()),
2604234353Sdim                  Attrs, T.getCloseLocation());
2605193326Sed
2606226633Sdim    if (T.getCloseLocation().isInvalid())
2607193326Sed      return;
2608193326Sed  }
2609193326Sed}
2610193326Sed
2611193326Sed/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
2612193326Sed/// This ambiguity appears in the syntax of the C++ new operator.
2613193326Sed///
2614193326Sed///        new-expression:
2615193326Sed///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
2616193326Sed///                                     new-initializer[opt]
2617193326Sed///
2618193326Sed///        new-placement:
2619193326Sed///                   '(' expression-list ')'
2620193326Sed///
2621212904Sdimbool Parser::ParseExpressionListOrTypeId(
2622226633Sdim                                   SmallVectorImpl<Expr*> &PlacementArgs,
2623193326Sed                                         Declarator &D) {
2624193326Sed  // The '(' was already consumed.
2625193326Sed  if (isTypeIdInParens()) {
2626193326Sed    ParseSpecifierQualifierList(D.getMutableDeclSpec());
2627193326Sed    D.SetSourceRange(D.getDeclSpec().getSourceRange());
2628193326Sed    ParseDeclarator(D);
2629193326Sed    return D.isInvalidType();
2630193326Sed  }
2631193326Sed
2632193326Sed  // It's not a type, it has to be an expression list.
2633193326Sed  // Discard the comma locations - ActOnCXXNew has enough parameters.
2634193326Sed  CommaLocsTy CommaLocs;
2635193326Sed  return ParseExpressionList(PlacementArgs, CommaLocs);
2636193326Sed}
2637193326Sed
2638193326Sed/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
2639193326Sed/// to free memory allocated by new.
2640193326Sed///
2641193326Sed/// This method is called to parse the 'delete' expression after the optional
2642193326Sed/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
2643193326Sed/// and "Start" is its location.  Otherwise, "Start" is the location of the
2644193326Sed/// 'delete' token.
2645193326Sed///
2646193326Sed///        delete-expression:
2647193326Sed///                   '::'[opt] 'delete' cast-expression
2648193326Sed///                   '::'[opt] 'delete' '[' ']' cast-expression
2649212904SdimExprResult
2650193326SedParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
2651193326Sed  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
2652193326Sed  ConsumeToken(); // Consume 'delete'
2653193326Sed
2654193326Sed  // Array delete?
2655193326Sed  bool ArrayDelete = false;
2656234353Sdim  if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {
2657239462Sdim    // C++11 [expr.delete]p1:
2658239462Sdim    //   Whenever the delete keyword is followed by empty square brackets, it
2659239462Sdim    //   shall be interpreted as [array delete].
2660239462Sdim    //   [Footnote: A lambda expression with a lambda-introducer that consists
2661239462Sdim    //              of empty square brackets can follow the delete keyword if
2662239462Sdim    //              the lambda expression is enclosed in parentheses.]
2663239462Sdim    // FIXME: Produce a better diagnostic if the '[]' is unambiguously a
2664239462Sdim    //        lambda-introducer.
2665193326Sed    ArrayDelete = true;
2666226633Sdim    BalancedDelimiterTracker T(*this, tok::l_square);
2667226633Sdim
2668226633Sdim    T.consumeOpen();
2669226633Sdim    T.consumeClose();
2670226633Sdim    if (T.getCloseLocation().isInvalid())
2671193326Sed      return ExprError();
2672193326Sed  }
2673193326Sed
2674212904Sdim  ExprResult Operand(ParseCastExpression(false));
2675193326Sed  if (Operand.isInvalid())
2676243830Sdim    return Operand;
2677193326Sed
2678212904Sdim  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take());
2679193326Sed}
2680193326Sed
2681198092Srdivackystatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
2682193326Sed  switch(kind) {
2683226633Sdim  default: llvm_unreachable("Not a known unary type trait.");
2684193326Sed  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
2685249423Sdim  case tok::kw___has_nothrow_move_assign: return UTT_HasNothrowMoveAssign;
2686193326Sed  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
2687221345Sdim  case tok::kw___has_nothrow_copy:           return UTT_HasNothrowCopy;
2688193326Sed  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
2689249423Sdim  case tok::kw___has_trivial_move_assign: return UTT_HasTrivialMoveAssign;
2690223017Sdim  case tok::kw___has_trivial_constructor:
2691223017Sdim                                    return UTT_HasTrivialDefaultConstructor;
2692249423Sdim  case tok::kw___has_trivial_move_constructor:
2693249423Sdim                                    return UTT_HasTrivialMoveConstructor;
2694221345Sdim  case tok::kw___has_trivial_copy:           return UTT_HasTrivialCopy;
2695193326Sed  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
2696193326Sed  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
2697193326Sed  case tok::kw___is_abstract:             return UTT_IsAbstract;
2698221345Sdim  case tok::kw___is_arithmetic:              return UTT_IsArithmetic;
2699221345Sdim  case tok::kw___is_array:                   return UTT_IsArray;
2700193326Sed  case tok::kw___is_class:                return UTT_IsClass;
2701221345Sdim  case tok::kw___is_complete_type:           return UTT_IsCompleteType;
2702221345Sdim  case tok::kw___is_compound:                return UTT_IsCompound;
2703221345Sdim  case tok::kw___is_const:                   return UTT_IsConst;
2704193326Sed  case tok::kw___is_empty:                return UTT_IsEmpty;
2705193326Sed  case tok::kw___is_enum:                 return UTT_IsEnum;
2706234353Sdim  case tok::kw___is_final:                 return UTT_IsFinal;
2707221345Sdim  case tok::kw___is_floating_point:          return UTT_IsFloatingPoint;
2708221345Sdim  case tok::kw___is_function:                return UTT_IsFunction;
2709221345Sdim  case tok::kw___is_fundamental:             return UTT_IsFundamental;
2710221345Sdim  case tok::kw___is_integral:                return UTT_IsIntegral;
2711243830Sdim  case tok::kw___is_interface_class:         return UTT_IsInterfaceClass;
2712221345Sdim  case tok::kw___is_lvalue_reference:        return UTT_IsLvalueReference;
2713221345Sdim  case tok::kw___is_member_function_pointer: return UTT_IsMemberFunctionPointer;
2714221345Sdim  case tok::kw___is_member_object_pointer:   return UTT_IsMemberObjectPointer;
2715221345Sdim  case tok::kw___is_member_pointer:          return UTT_IsMemberPointer;
2716221345Sdim  case tok::kw___is_object:                  return UTT_IsObject;
2717221345Sdim  case tok::kw___is_literal:              return UTT_IsLiteral;
2718221345Sdim  case tok::kw___is_literal_type:         return UTT_IsLiteral;
2719193326Sed  case tok::kw___is_pod:                  return UTT_IsPOD;
2720221345Sdim  case tok::kw___is_pointer:                 return UTT_IsPointer;
2721193326Sed  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
2722221345Sdim  case tok::kw___is_reference:               return UTT_IsReference;
2723221345Sdim  case tok::kw___is_rvalue_reference:        return UTT_IsRvalueReference;
2724221345Sdim  case tok::kw___is_scalar:                  return UTT_IsScalar;
2725263508Sdim  case tok::kw___is_sealed:                  return UTT_IsSealed;
2726221345Sdim  case tok::kw___is_signed:                  return UTT_IsSigned;
2727221345Sdim  case tok::kw___is_standard_layout:         return UTT_IsStandardLayout;
2728221345Sdim  case tok::kw___is_trivial:                 return UTT_IsTrivial;
2729223017Sdim  case tok::kw___is_trivially_copyable:      return UTT_IsTriviallyCopyable;
2730193326Sed  case tok::kw___is_union:                return UTT_IsUnion;
2731221345Sdim  case tok::kw___is_unsigned:                return UTT_IsUnsigned;
2732221345Sdim  case tok::kw___is_void:                    return UTT_IsVoid;
2733221345Sdim  case tok::kw___is_volatile:                return UTT_IsVolatile;
2734193326Sed  }
2735193326Sed}
2736193326Sed
2737218893Sdimstatic BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) {
2738218893Sdim  switch(kind) {
2739218893Sdim  default: llvm_unreachable("Not a known binary type trait");
2740218893Sdim  case tok::kw___is_base_of:                 return BTT_IsBaseOf;
2741221345Sdim  case tok::kw___is_convertible:             return BTT_IsConvertible;
2742221345Sdim  case tok::kw___is_same:                    return BTT_IsSame;
2743218893Sdim  case tok::kw___builtin_types_compatible_p: return BTT_TypeCompatible;
2744218893Sdim  case tok::kw___is_convertible_to:          return BTT_IsConvertibleTo;
2745234353Sdim  case tok::kw___is_trivially_assignable:    return BTT_IsTriviallyAssignable;
2746218893Sdim  }
2747218893Sdim}
2748218893Sdim
2749234353Sdimstatic TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
2750234353Sdim  switch (kind) {
2751234353Sdim  default: llvm_unreachable("Not a known type trait");
2752234353Sdim  case tok::kw___is_trivially_constructible:
2753234353Sdim    return TT_IsTriviallyConstructible;
2754234353Sdim  }
2755234353Sdim}
2756234353Sdim
2757221345Sdimstatic ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) {
2758221345Sdim  switch(kind) {
2759221345Sdim  default: llvm_unreachable("Not a known binary type trait");
2760221345Sdim  case tok::kw___array_rank:                 return ATT_ArrayRank;
2761221345Sdim  case tok::kw___array_extent:               return ATT_ArrayExtent;
2762221345Sdim  }
2763221345Sdim}
2764221345Sdim
2765221345Sdimstatic ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) {
2766221345Sdim  switch(kind) {
2767226633Sdim  default: llvm_unreachable("Not a known unary expression trait.");
2768221345Sdim  case tok::kw___is_lvalue_expr:             return ET_IsLValueExpr;
2769221345Sdim  case tok::kw___is_rvalue_expr:             return ET_IsRValueExpr;
2770221345Sdim  }
2771221345Sdim}
2772221345Sdim
2773193326Sed/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
2774193326Sed/// pseudo-functions that allow implementation of the TR1/C++0x type traits
2775193326Sed/// templates.
2776193326Sed///
2777193326Sed///       primary-expression:
2778193326Sed/// [GNU]             unary-type-trait '(' type-id ')'
2779193326Sed///
2780212904SdimExprResult Parser::ParseUnaryTypeTrait() {
2781193326Sed  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
2782193326Sed  SourceLocation Loc = ConsumeToken();
2783193326Sed
2784226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
2785226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen))
2786193326Sed    return ExprError();
2787193326Sed
2788193326Sed  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
2789193326Sed  // there will be cryptic errors about mismatched parentheses and missing
2790193326Sed  // specifiers.
2791193326Sed  TypeResult Ty = ParseTypeName();
2792193326Sed
2793226633Sdim  T.consumeClose();
2794193326Sed
2795193326Sed  if (Ty.isInvalid())
2796193326Sed    return ExprError();
2797193326Sed
2798226633Sdim  return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), T.getCloseLocation());
2799193326Sed}
2800193326Sed
2801218893Sdim/// ParseBinaryTypeTrait - Parse the built-in binary type-trait
2802218893Sdim/// pseudo-functions that allow implementation of the TR1/C++0x type traits
2803218893Sdim/// templates.
2804218893Sdim///
2805218893Sdim///       primary-expression:
2806218893Sdim/// [GNU]             binary-type-trait '(' type-id ',' type-id ')'
2807218893Sdim///
2808218893SdimExprResult Parser::ParseBinaryTypeTrait() {
2809218893Sdim  BinaryTypeTrait BTT = BinaryTypeTraitFromTokKind(Tok.getKind());
2810218893Sdim  SourceLocation Loc = ConsumeToken();
2811218893Sdim
2812226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
2813226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen))
2814218893Sdim    return ExprError();
2815218893Sdim
2816218893Sdim  TypeResult LhsTy = ParseTypeName();
2817218893Sdim  if (LhsTy.isInvalid()) {
2818263508Sdim    SkipUntil(tok::r_paren, StopAtSemi);
2819218893Sdim    return ExprError();
2820218893Sdim  }
2821218893Sdim
2822218893Sdim  if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
2823263508Sdim    SkipUntil(tok::r_paren, StopAtSemi);
2824218893Sdim    return ExprError();
2825218893Sdim  }
2826218893Sdim
2827218893Sdim  TypeResult RhsTy = ParseTypeName();
2828218893Sdim  if (RhsTy.isInvalid()) {
2829263508Sdim    SkipUntil(tok::r_paren, StopAtSemi);
2830218893Sdim    return ExprError();
2831218893Sdim  }
2832218893Sdim
2833226633Sdim  T.consumeClose();
2834218893Sdim
2835226633Sdim  return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(),
2836226633Sdim                                      T.getCloseLocation());
2837218893Sdim}
2838218893Sdim
2839234353Sdim/// \brief Parse the built-in type-trait pseudo-functions that allow
2840234353Sdim/// implementation of the TR1/C++11 type traits templates.
2841234353Sdim///
2842234353Sdim///       primary-expression:
2843234353Sdim///          type-trait '(' type-id-seq ')'
2844234353Sdim///
2845234353Sdim///       type-id-seq:
2846234353Sdim///          type-id ...[opt] type-id-seq[opt]
2847234353Sdim///
2848234353SdimExprResult Parser::ParseTypeTrait() {
2849234353Sdim  TypeTrait Kind = TypeTraitFromTokKind(Tok.getKind());
2850234353Sdim  SourceLocation Loc = ConsumeToken();
2851234353Sdim
2852234353Sdim  BalancedDelimiterTracker Parens(*this, tok::l_paren);
2853234353Sdim  if (Parens.expectAndConsume(diag::err_expected_lparen))
2854234353Sdim    return ExprError();
2855234353Sdim
2856249423Sdim  SmallVector<ParsedType, 2> Args;
2857234353Sdim  do {
2858234353Sdim    // Parse the next type.
2859234353Sdim    TypeResult Ty = ParseTypeName();
2860234353Sdim    if (Ty.isInvalid()) {
2861234353Sdim      Parens.skipToEnd();
2862234353Sdim      return ExprError();
2863234353Sdim    }
2864234353Sdim
2865234353Sdim    // Parse the ellipsis, if present.
2866234353Sdim    if (Tok.is(tok::ellipsis)) {
2867234353Sdim      Ty = Actions.ActOnPackExpansion(Ty.get(), ConsumeToken());
2868234353Sdim      if (Ty.isInvalid()) {
2869234353Sdim        Parens.skipToEnd();
2870234353Sdim        return ExprError();
2871234353Sdim      }
2872234353Sdim    }
2873234353Sdim
2874234353Sdim    // Add this type to the list of arguments.
2875234353Sdim    Args.push_back(Ty.get());
2876234353Sdim
2877234353Sdim    if (Tok.is(tok::comma)) {
2878234353Sdim      ConsumeToken();
2879234353Sdim      continue;
2880234353Sdim    }
2881234353Sdim
2882234353Sdim    break;
2883234353Sdim  } while (true);
2884234353Sdim
2885234353Sdim  if (Parens.consumeClose())
2886234353Sdim    return ExprError();
2887234353Sdim
2888234353Sdim  return Actions.ActOnTypeTrait(Kind, Loc, Args, Parens.getCloseLocation());
2889234353Sdim}
2890234353Sdim
2891221345Sdim/// ParseArrayTypeTrait - Parse the built-in array type-trait
2892221345Sdim/// pseudo-functions.
2893221345Sdim///
2894221345Sdim///       primary-expression:
2895221345Sdim/// [Embarcadero]     '__array_rank' '(' type-id ')'
2896221345Sdim/// [Embarcadero]     '__array_extent' '(' type-id ',' expression ')'
2897221345Sdim///
2898221345SdimExprResult Parser::ParseArrayTypeTrait() {
2899221345Sdim  ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind());
2900221345Sdim  SourceLocation Loc = ConsumeToken();
2901221345Sdim
2902226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
2903226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen))
2904221345Sdim    return ExprError();
2905221345Sdim
2906221345Sdim  TypeResult Ty = ParseTypeName();
2907221345Sdim  if (Ty.isInvalid()) {
2908263508Sdim    SkipUntil(tok::comma, StopAtSemi);
2909263508Sdim    SkipUntil(tok::r_paren, StopAtSemi);
2910221345Sdim    return ExprError();
2911221345Sdim  }
2912221345Sdim
2913221345Sdim  switch (ATT) {
2914221345Sdim  case ATT_ArrayRank: {
2915226633Sdim    T.consumeClose();
2916226633Sdim    return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL,
2917226633Sdim                                       T.getCloseLocation());
2918221345Sdim  }
2919221345Sdim  case ATT_ArrayExtent: {
2920221345Sdim    if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
2921263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
2922221345Sdim      return ExprError();
2923221345Sdim    }
2924221345Sdim
2925221345Sdim    ExprResult DimExpr = ParseExpression();
2926226633Sdim    T.consumeClose();
2927221345Sdim
2928226633Sdim    return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(),
2929226633Sdim                                       T.getCloseLocation());
2930221345Sdim  }
2931221345Sdim  }
2932234353Sdim  llvm_unreachable("Invalid ArrayTypeTrait!");
2933221345Sdim}
2934221345Sdim
2935221345Sdim/// ParseExpressionTrait - Parse built-in expression-trait
2936221345Sdim/// pseudo-functions like __is_lvalue_expr( xxx ).
2937221345Sdim///
2938221345Sdim///       primary-expression:
2939221345Sdim/// [Embarcadero]     expression-trait '(' expression ')'
2940221345Sdim///
2941221345SdimExprResult Parser::ParseExpressionTrait() {
2942221345Sdim  ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind());
2943221345Sdim  SourceLocation Loc = ConsumeToken();
2944221345Sdim
2945226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
2946226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen))
2947221345Sdim    return ExprError();
2948221345Sdim
2949221345Sdim  ExprResult Expr = ParseExpression();
2950221345Sdim
2951226633Sdim  T.consumeClose();
2952221345Sdim
2953226633Sdim  return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(),
2954226633Sdim                                      T.getCloseLocation());
2955221345Sdim}
2956221345Sdim
2957221345Sdim
2958193326Sed/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
2959193326Sed/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
2960193326Sed/// based on the context past the parens.
2961212904SdimExprResult
2962193326SedParser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
2963212904Sdim                                         ParsedType &CastTy,
2964226633Sdim                                         BalancedDelimiterTracker &Tracker) {
2965234353Sdim  assert(getLangOpts().CPlusPlus && "Should only be called for C++!");
2966193326Sed  assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
2967193326Sed  assert(isTypeIdInParens() && "Not a type-id!");
2968193326Sed
2969212904Sdim  ExprResult Result(true);
2970212904Sdim  CastTy = ParsedType();
2971193326Sed
2972193326Sed  // We need to disambiguate a very ugly part of the C++ syntax:
2973193326Sed  //
2974193326Sed  // (T())x;  - type-id
2975193326Sed  // (T())*x; - type-id
2976193326Sed  // (T())/x; - expression
2977193326Sed  // (T());   - expression
2978193326Sed  //
2979193326Sed  // The bad news is that we cannot use the specialized tentative parser, since
2980193326Sed  // it can only verify that the thing inside the parens can be parsed as
2981193326Sed  // type-id, it is not useful for determining the context past the parens.
2982193326Sed  //
2983193326Sed  // The good news is that the parser can disambiguate this part without
2984193326Sed  // making any unnecessary Action calls.
2985193326Sed  //
2986193326Sed  // It uses a scheme similar to parsing inline methods. The parenthesized
2987193326Sed  // tokens are cached, the context that follows is determined (possibly by
2988193326Sed  // parsing a cast-expression), and then we re-introduce the cached tokens
2989193326Sed  // into the token stream and parse them appropriately.
2990193326Sed
2991198092Srdivacky  ParenParseOption ParseAs;
2992193326Sed  CachedTokens Toks;
2993193326Sed
2994193326Sed  // Store the tokens of the parentheses. We will parse them after we determine
2995193326Sed  // the context that follows them.
2996207619Srdivacky  if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) {
2997193326Sed    // We didn't find the ')' we expected.
2998226633Sdim    Tracker.consumeClose();
2999193326Sed    return ExprError();
3000193326Sed  }
3001193326Sed
3002193326Sed  if (Tok.is(tok::l_brace)) {
3003193326Sed    ParseAs = CompoundLiteral;
3004193326Sed  } else {
3005193326Sed    bool NotCastExpr;
3006193326Sed    // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
3007193326Sed    if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
3008193326Sed      NotCastExpr = true;
3009193326Sed    } else {
3010193326Sed      // Try parsing the cast-expression that may follow.
3011193326Sed      // If it is not a cast-expression, NotCastExpr will be true and no token
3012193326Sed      // will be consumed.
3013193326Sed      Result = ParseCastExpression(false/*isUnaryExpression*/,
3014193326Sed                                   false/*isAddressofOperand*/,
3015212904Sdim                                   NotCastExpr,
3016224145Sdim                                   // type-id has priority.
3017234353Sdim                                   IsTypeCast);
3018193326Sed    }
3019193326Sed
3020193326Sed    // If we parsed a cast-expression, it's really a type-id, otherwise it's
3021193326Sed    // an expression.
3022193326Sed    ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
3023193326Sed  }
3024193326Sed
3025198092Srdivacky  // The current token should go after the cached tokens.
3026193326Sed  Toks.push_back(Tok);
3027193326Sed  // Re-enter the stored parenthesized tokens into the token stream, so we may
3028193326Sed  // parse them now.
3029193326Sed  PP.EnterTokenStream(Toks.data(), Toks.size(),
3030193326Sed                      true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
3031193326Sed  // Drop the current token and bring the first cached one. It's the same token
3032193326Sed  // as when we entered this function.
3033193326Sed  ConsumeAnyToken();
3034193326Sed
3035193326Sed  if (ParseAs >= CompoundLiteral) {
3036224145Sdim    // Parse the type declarator.
3037224145Sdim    DeclSpec DS(AttrFactory);
3038224145Sdim    ParseSpecifierQualifierList(DS);
3039224145Sdim    Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
3040224145Sdim    ParseDeclarator(DeclaratorInfo);
3041193326Sed
3042193326Sed    // Match the ')'.
3043226633Sdim    Tracker.consumeClose();
3044193326Sed
3045193326Sed    if (ParseAs == CompoundLiteral) {
3046193326Sed      ExprType = CompoundLiteral;
3047224145Sdim      TypeResult Ty = ParseTypeName();
3048226633Sdim       return ParseCompoundLiteralExpression(Ty.get(),
3049226633Sdim                                            Tracker.getOpenLocation(),
3050226633Sdim                                            Tracker.getCloseLocation());
3051193326Sed    }
3052198092Srdivacky
3053193326Sed    // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
3054193326Sed    assert(ParseAs == CastExpr);
3055193326Sed
3056224145Sdim    if (DeclaratorInfo.isInvalidType())
3057193326Sed      return ExprError();
3058193326Sed
3059193326Sed    // Result is what ParseCastExpression returned earlier.
3060193326Sed    if (!Result.isInvalid())
3061226633Sdim      Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(),
3062226633Sdim                                    DeclaratorInfo, CastTy,
3063226633Sdim                                    Tracker.getCloseLocation(), Result.take());
3064243830Sdim    return Result;
3065193326Sed  }
3066198092Srdivacky
3067193326Sed  // Not a compound literal, and not followed by a cast-expression.
3068193326Sed  assert(ParseAs == SimpleExpr);
3069193326Sed
3070193326Sed  ExprType = SimpleExpr;
3071193326Sed  Result = ParseExpression();
3072193326Sed  if (!Result.isInvalid() && Tok.is(tok::r_paren))
3073226633Sdim    Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(),
3074226633Sdim                                    Tok.getLocation(), Result.take());
3075193326Sed
3076193326Sed  // Match the ')'.
3077193326Sed  if (Result.isInvalid()) {
3078263508Sdim    SkipUntil(tok::r_paren, StopAtSemi);
3079193326Sed    return ExprError();
3080193326Sed  }
3081198092Srdivacky
3082226633Sdim  Tracker.consumeClose();
3083243830Sdim  return Result;
3084193326Sed}
3085