1f4a2713aSLionel Sambuc //===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the Expression parsing implementation for C++.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13*0a6a1f1dSLionel Sambuc #include "clang/AST/ASTContext.h"
14f4a2713aSLionel Sambuc #include "RAIIObjectsForParser.h"
15*0a6a1f1dSLionel Sambuc #include "clang/AST/DeclTemplate.h"
16f4a2713aSLionel Sambuc #include "clang/Basic/PrettyStackTrace.h"
17f4a2713aSLionel Sambuc #include "clang/Lex/LiteralSupport.h"
18f4a2713aSLionel Sambuc #include "clang/Parse/ParseDiagnostic.h"
19*0a6a1f1dSLionel Sambuc #include "clang/Parse/Parser.h"
20f4a2713aSLionel Sambuc #include "clang/Sema/DeclSpec.h"
21f4a2713aSLionel Sambuc #include "clang/Sema/ParsedTemplate.h"
22f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc 
26f4a2713aSLionel Sambuc using namespace clang;
27f4a2713aSLionel Sambuc 
SelectDigraphErrorMessage(tok::TokenKind Kind)28f4a2713aSLionel Sambuc static int SelectDigraphErrorMessage(tok::TokenKind Kind) {
29f4a2713aSLionel Sambuc   switch (Kind) {
30*0a6a1f1dSLionel Sambuc     // template name
31*0a6a1f1dSLionel Sambuc     case tok::unknown:             return 0;
32*0a6a1f1dSLionel Sambuc     // casts
33f4a2713aSLionel Sambuc     case tok::kw_const_cast:       return 1;
34f4a2713aSLionel Sambuc     case tok::kw_dynamic_cast:     return 2;
35f4a2713aSLionel Sambuc     case tok::kw_reinterpret_cast: return 3;
36f4a2713aSLionel Sambuc     case tok::kw_static_cast:      return 4;
37f4a2713aSLionel Sambuc     default:
38f4a2713aSLionel Sambuc       llvm_unreachable("Unknown type for digraph error message.");
39f4a2713aSLionel Sambuc   }
40f4a2713aSLionel Sambuc }
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc // Are the two tokens adjacent in the same source file?
areTokensAdjacent(const Token & First,const Token & Second)43f4a2713aSLionel Sambuc bool Parser::areTokensAdjacent(const Token &First, const Token &Second) {
44f4a2713aSLionel Sambuc   SourceManager &SM = PP.getSourceManager();
45f4a2713aSLionel Sambuc   SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation());
46f4a2713aSLionel Sambuc   SourceLocation FirstEnd = FirstLoc.getLocWithOffset(First.getLength());
47f4a2713aSLionel Sambuc   return FirstEnd == SM.getSpellingLoc(Second.getLocation());
48f4a2713aSLionel Sambuc }
49f4a2713aSLionel Sambuc 
50f4a2713aSLionel Sambuc // Suggest fixit for "<::" after a cast.
FixDigraph(Parser & P,Preprocessor & PP,Token & DigraphToken,Token & ColonToken,tok::TokenKind Kind,bool AtDigraph)51f4a2713aSLionel Sambuc static void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken,
52f4a2713aSLionel Sambuc                        Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) {
53f4a2713aSLionel Sambuc   // Pull '<:' and ':' off token stream.
54f4a2713aSLionel Sambuc   if (!AtDigraph)
55f4a2713aSLionel Sambuc     PP.Lex(DigraphToken);
56f4a2713aSLionel Sambuc   PP.Lex(ColonToken);
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc   SourceRange Range;
59f4a2713aSLionel Sambuc   Range.setBegin(DigraphToken.getLocation());
60f4a2713aSLionel Sambuc   Range.setEnd(ColonToken.getLocation());
61f4a2713aSLionel Sambuc   P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph)
62f4a2713aSLionel Sambuc       << SelectDigraphErrorMessage(Kind)
63f4a2713aSLionel Sambuc       << FixItHint::CreateReplacement(Range, "< ::");
64f4a2713aSLionel Sambuc 
65f4a2713aSLionel Sambuc   // Update token information to reflect their change in token type.
66f4a2713aSLionel Sambuc   ColonToken.setKind(tok::coloncolon);
67f4a2713aSLionel Sambuc   ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(-1));
68f4a2713aSLionel Sambuc   ColonToken.setLength(2);
69f4a2713aSLionel Sambuc   DigraphToken.setKind(tok::less);
70f4a2713aSLionel Sambuc   DigraphToken.setLength(1);
71f4a2713aSLionel Sambuc 
72f4a2713aSLionel Sambuc   // Push new tokens back to token stream.
73f4a2713aSLionel Sambuc   PP.EnterToken(ColonToken);
74f4a2713aSLionel Sambuc   if (!AtDigraph)
75f4a2713aSLionel Sambuc     PP.EnterToken(DigraphToken);
76f4a2713aSLionel Sambuc }
77f4a2713aSLionel Sambuc 
78f4a2713aSLionel Sambuc // Check for '<::' which should be '< ::' instead of '[:' when following
79f4a2713aSLionel Sambuc // a template name.
CheckForTemplateAndDigraph(Token & Next,ParsedType ObjectType,bool EnteringContext,IdentifierInfo & II,CXXScopeSpec & SS)80f4a2713aSLionel Sambuc void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
81f4a2713aSLionel Sambuc                                         bool EnteringContext,
82f4a2713aSLionel Sambuc                                         IdentifierInfo &II, CXXScopeSpec &SS) {
83f4a2713aSLionel Sambuc   if (!Next.is(tok::l_square) || Next.getLength() != 2)
84f4a2713aSLionel Sambuc     return;
85f4a2713aSLionel Sambuc 
86f4a2713aSLionel Sambuc   Token SecondToken = GetLookAheadToken(2);
87f4a2713aSLionel Sambuc   if (!SecondToken.is(tok::colon) || !areTokensAdjacent(Next, SecondToken))
88f4a2713aSLionel Sambuc     return;
89f4a2713aSLionel Sambuc 
90f4a2713aSLionel Sambuc   TemplateTy Template;
91f4a2713aSLionel Sambuc   UnqualifiedId TemplateName;
92f4a2713aSLionel Sambuc   TemplateName.setIdentifier(&II, Tok.getLocation());
93f4a2713aSLionel Sambuc   bool MemberOfUnknownSpecialization;
94f4a2713aSLionel Sambuc   if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false,
95f4a2713aSLionel Sambuc                               TemplateName, ObjectType, EnteringContext,
96f4a2713aSLionel Sambuc                               Template, MemberOfUnknownSpecialization))
97f4a2713aSLionel Sambuc     return;
98f4a2713aSLionel Sambuc 
99*0a6a1f1dSLionel Sambuc   FixDigraph(*this, PP, Next, SecondToken, tok::unknown,
100f4a2713aSLionel Sambuc              /*AtDigraph*/false);
101f4a2713aSLionel Sambuc }
102f4a2713aSLionel Sambuc 
103f4a2713aSLionel Sambuc /// \brief Emits an error for a left parentheses after a double colon.
104f4a2713aSLionel Sambuc ///
105f4a2713aSLionel Sambuc /// When a '(' is found after a '::', emit an error.  Attempt to fix the token
106f4a2713aSLionel Sambuc /// stream by removing the '(', and the matching ')' if found.
CheckForLParenAfterColonColon()107f4a2713aSLionel Sambuc void Parser::CheckForLParenAfterColonColon() {
108f4a2713aSLionel Sambuc   if (!Tok.is(tok::l_paren))
109f4a2713aSLionel Sambuc     return;
110f4a2713aSLionel Sambuc 
111*0a6a1f1dSLionel Sambuc   Token LParen = Tok;
112*0a6a1f1dSLionel Sambuc   Token NextTok = GetLookAheadToken(1);
113*0a6a1f1dSLionel Sambuc   Token StarTok = NextTok;
114*0a6a1f1dSLionel Sambuc   // Check for (identifier or (*identifier
115*0a6a1f1dSLionel Sambuc   Token IdentifierTok = StarTok.is(tok::star) ? GetLookAheadToken(2) : StarTok;
116*0a6a1f1dSLionel Sambuc   if (IdentifierTok.isNot(tok::identifier))
117f4a2713aSLionel Sambuc     return;
118*0a6a1f1dSLionel Sambuc   // Eat the '('.
119*0a6a1f1dSLionel Sambuc   ConsumeParen();
120*0a6a1f1dSLionel Sambuc   Token RParen;
121*0a6a1f1dSLionel Sambuc   // Do we have a ')' ?
122*0a6a1f1dSLionel Sambuc   NextTok = StarTok.is(tok::star) ? GetLookAheadToken(2) : GetLookAheadToken(1);
123*0a6a1f1dSLionel Sambuc   if (NextTok.is(tok::r_paren)) {
124*0a6a1f1dSLionel Sambuc     RParen = NextTok;
125*0a6a1f1dSLionel Sambuc     // Eat the '*' if it is present.
126*0a6a1f1dSLionel Sambuc     if (StarTok.is(tok::star))
127f4a2713aSLionel Sambuc       ConsumeToken();
128*0a6a1f1dSLionel Sambuc     // Eat the identifier.
129f4a2713aSLionel Sambuc     ConsumeToken();
130*0a6a1f1dSLionel Sambuc     // Add the identifier token back.
131*0a6a1f1dSLionel Sambuc     PP.EnterToken(IdentifierTok);
132*0a6a1f1dSLionel Sambuc     // Add the '*' back if it was present.
133*0a6a1f1dSLionel Sambuc     if (StarTok.is(tok::star))
134*0a6a1f1dSLionel Sambuc       PP.EnterToken(StarTok);
135*0a6a1f1dSLionel Sambuc     // Eat the ')'.
136*0a6a1f1dSLionel Sambuc     ConsumeParen();
137f4a2713aSLionel Sambuc   }
138f4a2713aSLionel Sambuc 
139*0a6a1f1dSLionel Sambuc   Diag(LParen.getLocation(), diag::err_paren_after_colon_colon)
140*0a6a1f1dSLionel Sambuc       << FixItHint::CreateRemoval(LParen.getLocation())
141*0a6a1f1dSLionel Sambuc       << FixItHint::CreateRemoval(RParen.getLocation());
142f4a2713aSLionel Sambuc }
143f4a2713aSLionel Sambuc 
144f4a2713aSLionel Sambuc /// \brief Parse global scope or nested-name-specifier if present.
145f4a2713aSLionel Sambuc ///
146f4a2713aSLionel Sambuc /// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
147f4a2713aSLionel Sambuc /// may be preceded by '::'). Note that this routine will not parse ::new or
148f4a2713aSLionel Sambuc /// ::delete; it will just leave them in the token stream.
149f4a2713aSLionel Sambuc ///
150f4a2713aSLionel Sambuc ///       '::'[opt] nested-name-specifier
151f4a2713aSLionel Sambuc ///       '::'
152f4a2713aSLionel Sambuc ///
153f4a2713aSLionel Sambuc ///       nested-name-specifier:
154f4a2713aSLionel Sambuc ///         type-name '::'
155f4a2713aSLionel Sambuc ///         namespace-name '::'
156f4a2713aSLionel Sambuc ///         nested-name-specifier identifier '::'
157f4a2713aSLionel Sambuc ///         nested-name-specifier 'template'[opt] simple-template-id '::'
158f4a2713aSLionel Sambuc ///
159f4a2713aSLionel Sambuc ///
160f4a2713aSLionel Sambuc /// \param SS the scope specifier that will be set to the parsed
161f4a2713aSLionel Sambuc /// nested-name-specifier (or empty)
162f4a2713aSLionel Sambuc ///
163f4a2713aSLionel Sambuc /// \param ObjectType if this nested-name-specifier is being parsed following
164f4a2713aSLionel Sambuc /// the "." or "->" of a member access expression, this parameter provides the
165f4a2713aSLionel Sambuc /// type of the object whose members are being accessed.
166f4a2713aSLionel Sambuc ///
167f4a2713aSLionel Sambuc /// \param EnteringContext whether we will be entering into the context of
168f4a2713aSLionel Sambuc /// the nested-name-specifier after parsing it.
169f4a2713aSLionel Sambuc ///
170f4a2713aSLionel Sambuc /// \param MayBePseudoDestructor When non-NULL, points to a flag that
171f4a2713aSLionel Sambuc /// indicates whether this nested-name-specifier may be part of a
172f4a2713aSLionel Sambuc /// pseudo-destructor name. In this case, the flag will be set false
173f4a2713aSLionel Sambuc /// if we don't actually end up parsing a destructor name. Moreorover,
174f4a2713aSLionel Sambuc /// if we do end up determining that we are parsing a destructor name,
175f4a2713aSLionel Sambuc /// the last component of the nested-name-specifier is not parsed as
176f4a2713aSLionel Sambuc /// part of the scope specifier.
177f4a2713aSLionel Sambuc ///
178f4a2713aSLionel Sambuc /// \param IsTypename If \c true, this nested-name-specifier is known to be
179f4a2713aSLionel Sambuc /// part of a type name. This is used to improve error recovery.
180f4a2713aSLionel Sambuc ///
181f4a2713aSLionel Sambuc /// \param LastII When non-NULL, points to an IdentifierInfo* that will be
182f4a2713aSLionel Sambuc /// filled in with the leading identifier in the last component of the
183f4a2713aSLionel Sambuc /// nested-name-specifier, if any.
184f4a2713aSLionel Sambuc ///
185f4a2713aSLionel Sambuc /// \returns true if there was an error parsing a scope specifier
ParseOptionalCXXScopeSpecifier(CXXScopeSpec & SS,ParsedType ObjectType,bool EnteringContext,bool * MayBePseudoDestructor,bool IsTypename,IdentifierInfo ** LastII)186f4a2713aSLionel Sambuc bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
187f4a2713aSLionel Sambuc                                             ParsedType ObjectType,
188f4a2713aSLionel Sambuc                                             bool EnteringContext,
189f4a2713aSLionel Sambuc                                             bool *MayBePseudoDestructor,
190f4a2713aSLionel Sambuc                                             bool IsTypename,
191f4a2713aSLionel Sambuc                                             IdentifierInfo **LastII) {
192f4a2713aSLionel Sambuc   assert(getLangOpts().CPlusPlus &&
193f4a2713aSLionel Sambuc          "Call sites of this function should be guarded by checking for C++");
194f4a2713aSLionel Sambuc 
195f4a2713aSLionel Sambuc   if (Tok.is(tok::annot_cxxscope)) {
196f4a2713aSLionel Sambuc     assert(!LastII && "want last identifier but have already annotated scope");
197f4a2713aSLionel Sambuc     Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
198f4a2713aSLionel Sambuc                                                  Tok.getAnnotationRange(),
199f4a2713aSLionel Sambuc                                                  SS);
200f4a2713aSLionel Sambuc     ConsumeToken();
201f4a2713aSLionel Sambuc     return false;
202f4a2713aSLionel Sambuc   }
203f4a2713aSLionel Sambuc 
204f4a2713aSLionel Sambuc   if (Tok.is(tok::annot_template_id)) {
205f4a2713aSLionel Sambuc     // If the current token is an annotated template id, it may already have
206f4a2713aSLionel Sambuc     // a scope specifier. Restore it.
207f4a2713aSLionel Sambuc     TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
208f4a2713aSLionel Sambuc     SS = TemplateId->SS;
209f4a2713aSLionel Sambuc   }
210f4a2713aSLionel Sambuc 
211f4a2713aSLionel Sambuc   if (LastII)
212*0a6a1f1dSLionel Sambuc     *LastII = nullptr;
213f4a2713aSLionel Sambuc 
214f4a2713aSLionel Sambuc   bool HasScopeSpecifier = false;
215f4a2713aSLionel Sambuc 
216f4a2713aSLionel Sambuc   if (Tok.is(tok::coloncolon)) {
217f4a2713aSLionel Sambuc     // ::new and ::delete aren't nested-name-specifiers.
218f4a2713aSLionel Sambuc     tok::TokenKind NextKind = NextToken().getKind();
219f4a2713aSLionel Sambuc     if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
220f4a2713aSLionel Sambuc       return false;
221f4a2713aSLionel Sambuc 
222*0a6a1f1dSLionel Sambuc     if (NextKind == tok::l_brace) {
223*0a6a1f1dSLionel Sambuc       // It is invalid to have :: {, consume the scope qualifier and pretend
224*0a6a1f1dSLionel Sambuc       // like we never saw it.
225*0a6a1f1dSLionel Sambuc       Diag(ConsumeToken(), diag::err_expected) << tok::identifier;
226*0a6a1f1dSLionel Sambuc     } else {
227f4a2713aSLionel Sambuc       // '::' - Global scope qualifier.
228*0a6a1f1dSLionel Sambuc       if (Actions.ActOnCXXGlobalScopeSpecifier(ConsumeToken(), SS))
229f4a2713aSLionel Sambuc         return true;
230f4a2713aSLionel Sambuc 
231f4a2713aSLionel Sambuc       CheckForLParenAfterColonColon();
232f4a2713aSLionel Sambuc 
233f4a2713aSLionel Sambuc       HasScopeSpecifier = true;
234f4a2713aSLionel Sambuc     }
235*0a6a1f1dSLionel Sambuc   }
236*0a6a1f1dSLionel Sambuc 
237*0a6a1f1dSLionel Sambuc   if (Tok.is(tok::kw___super)) {
238*0a6a1f1dSLionel Sambuc     SourceLocation SuperLoc = ConsumeToken();
239*0a6a1f1dSLionel Sambuc     if (!Tok.is(tok::coloncolon)) {
240*0a6a1f1dSLionel Sambuc       Diag(Tok.getLocation(), diag::err_expected_coloncolon_after_super);
241*0a6a1f1dSLionel Sambuc       return true;
242*0a6a1f1dSLionel Sambuc     }
243*0a6a1f1dSLionel Sambuc 
244*0a6a1f1dSLionel Sambuc     return Actions.ActOnSuperScopeSpecifier(SuperLoc, ConsumeToken(), SS);
245*0a6a1f1dSLionel Sambuc   }
246f4a2713aSLionel Sambuc 
247f4a2713aSLionel Sambuc   bool CheckForDestructor = false;
248f4a2713aSLionel Sambuc   if (MayBePseudoDestructor && *MayBePseudoDestructor) {
249f4a2713aSLionel Sambuc     CheckForDestructor = true;
250f4a2713aSLionel Sambuc     *MayBePseudoDestructor = false;
251f4a2713aSLionel Sambuc   }
252f4a2713aSLionel Sambuc 
253*0a6a1f1dSLionel Sambuc   if (!HasScopeSpecifier &&
254*0a6a1f1dSLionel Sambuc       (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype))) {
255f4a2713aSLionel Sambuc     DeclSpec DS(AttrFactory);
256f4a2713aSLionel Sambuc     SourceLocation DeclLoc = Tok.getLocation();
257f4a2713aSLionel Sambuc     SourceLocation EndLoc  = ParseDecltypeSpecifier(DS);
258*0a6a1f1dSLionel Sambuc 
259*0a6a1f1dSLionel Sambuc     SourceLocation CCLoc;
260*0a6a1f1dSLionel Sambuc     if (!TryConsumeToken(tok::coloncolon, CCLoc)) {
261f4a2713aSLionel Sambuc       AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc);
262f4a2713aSLionel Sambuc       return false;
263f4a2713aSLionel Sambuc     }
264f4a2713aSLionel Sambuc 
265f4a2713aSLionel Sambuc     if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, CCLoc))
266f4a2713aSLionel Sambuc       SS.SetInvalid(SourceRange(DeclLoc, CCLoc));
267f4a2713aSLionel Sambuc 
268f4a2713aSLionel Sambuc     HasScopeSpecifier = true;
269f4a2713aSLionel Sambuc   }
270f4a2713aSLionel Sambuc 
271f4a2713aSLionel Sambuc   while (true) {
272f4a2713aSLionel Sambuc     if (HasScopeSpecifier) {
273f4a2713aSLionel Sambuc       // C++ [basic.lookup.classref]p5:
274f4a2713aSLionel Sambuc       //   If the qualified-id has the form
275f4a2713aSLionel Sambuc       //
276f4a2713aSLionel Sambuc       //       ::class-name-or-namespace-name::...
277f4a2713aSLionel Sambuc       //
278f4a2713aSLionel Sambuc       //   the class-name-or-namespace-name is looked up in global scope as a
279f4a2713aSLionel Sambuc       //   class-name or namespace-name.
280f4a2713aSLionel Sambuc       //
281f4a2713aSLionel Sambuc       // To implement this, we clear out the object type as soon as we've
282f4a2713aSLionel Sambuc       // seen a leading '::' or part of a nested-name-specifier.
283f4a2713aSLionel Sambuc       ObjectType = ParsedType();
284f4a2713aSLionel Sambuc 
285f4a2713aSLionel Sambuc       if (Tok.is(tok::code_completion)) {
286f4a2713aSLionel Sambuc         // Code completion for a nested-name-specifier, where the code
287f4a2713aSLionel Sambuc         // code completion token follows the '::'.
288f4a2713aSLionel Sambuc         Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext);
289f4a2713aSLionel Sambuc         // Include code completion token into the range of the scope otherwise
290f4a2713aSLionel Sambuc         // when we try to annotate the scope tokens the dangling code completion
291f4a2713aSLionel Sambuc         // token will cause assertion in
292f4a2713aSLionel Sambuc         // Preprocessor::AnnotatePreviousCachedTokens.
293f4a2713aSLionel Sambuc         SS.setEndLoc(Tok.getLocation());
294f4a2713aSLionel Sambuc         cutOffParsing();
295f4a2713aSLionel Sambuc         return true;
296f4a2713aSLionel Sambuc       }
297f4a2713aSLionel Sambuc     }
298f4a2713aSLionel Sambuc 
299f4a2713aSLionel Sambuc     // nested-name-specifier:
300f4a2713aSLionel Sambuc     //   nested-name-specifier 'template'[opt] simple-template-id '::'
301f4a2713aSLionel Sambuc 
302f4a2713aSLionel Sambuc     // Parse the optional 'template' keyword, then make sure we have
303f4a2713aSLionel Sambuc     // 'identifier <' after it.
304f4a2713aSLionel Sambuc     if (Tok.is(tok::kw_template)) {
305f4a2713aSLionel Sambuc       // If we don't have a scope specifier or an object type, this isn't a
306f4a2713aSLionel Sambuc       // nested-name-specifier, since they aren't allowed to start with
307f4a2713aSLionel Sambuc       // 'template'.
308f4a2713aSLionel Sambuc       if (!HasScopeSpecifier && !ObjectType)
309f4a2713aSLionel Sambuc         break;
310f4a2713aSLionel Sambuc 
311f4a2713aSLionel Sambuc       TentativeParsingAction TPA(*this);
312f4a2713aSLionel Sambuc       SourceLocation TemplateKWLoc = ConsumeToken();
313f4a2713aSLionel Sambuc 
314f4a2713aSLionel Sambuc       UnqualifiedId TemplateName;
315f4a2713aSLionel Sambuc       if (Tok.is(tok::identifier)) {
316f4a2713aSLionel Sambuc         // Consume the identifier.
317f4a2713aSLionel Sambuc         TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
318f4a2713aSLionel Sambuc         ConsumeToken();
319f4a2713aSLionel Sambuc       } else if (Tok.is(tok::kw_operator)) {
320*0a6a1f1dSLionel Sambuc         // We don't need to actually parse the unqualified-id in this case,
321*0a6a1f1dSLionel Sambuc         // because a simple-template-id cannot start with 'operator', but
322*0a6a1f1dSLionel Sambuc         // go ahead and parse it anyway for consistency with the case where
323*0a6a1f1dSLionel Sambuc         // we already annotated the template-id.
324f4a2713aSLionel Sambuc         if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType,
325f4a2713aSLionel Sambuc                                        TemplateName)) {
326f4a2713aSLionel Sambuc           TPA.Commit();
327f4a2713aSLionel Sambuc           break;
328f4a2713aSLionel Sambuc         }
329f4a2713aSLionel Sambuc 
330f4a2713aSLionel Sambuc         if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId &&
331f4a2713aSLionel Sambuc             TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) {
332f4a2713aSLionel Sambuc           Diag(TemplateName.getSourceRange().getBegin(),
333f4a2713aSLionel Sambuc                diag::err_id_after_template_in_nested_name_spec)
334f4a2713aSLionel Sambuc             << TemplateName.getSourceRange();
335f4a2713aSLionel Sambuc           TPA.Commit();
336f4a2713aSLionel Sambuc           break;
337f4a2713aSLionel Sambuc         }
338f4a2713aSLionel Sambuc       } else {
339f4a2713aSLionel Sambuc         TPA.Revert();
340f4a2713aSLionel Sambuc         break;
341f4a2713aSLionel Sambuc       }
342f4a2713aSLionel Sambuc 
343f4a2713aSLionel Sambuc       // If the next token is not '<', we have a qualified-id that refers
344f4a2713aSLionel Sambuc       // to a template name, such as T::template apply, but is not a
345f4a2713aSLionel Sambuc       // template-id.
346f4a2713aSLionel Sambuc       if (Tok.isNot(tok::less)) {
347f4a2713aSLionel Sambuc         TPA.Revert();
348f4a2713aSLionel Sambuc         break;
349f4a2713aSLionel Sambuc       }
350f4a2713aSLionel Sambuc 
351f4a2713aSLionel Sambuc       // Commit to parsing the template-id.
352f4a2713aSLionel Sambuc       TPA.Commit();
353f4a2713aSLionel Sambuc       TemplateTy Template;
354f4a2713aSLionel Sambuc       if (TemplateNameKind TNK
355f4a2713aSLionel Sambuc           = Actions.ActOnDependentTemplateName(getCurScope(),
356f4a2713aSLionel Sambuc                                                SS, TemplateKWLoc, TemplateName,
357f4a2713aSLionel Sambuc                                                ObjectType, EnteringContext,
358f4a2713aSLionel Sambuc                                                Template)) {
359f4a2713aSLionel Sambuc         if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc,
360f4a2713aSLionel Sambuc                                     TemplateName, false))
361f4a2713aSLionel Sambuc           return true;
362f4a2713aSLionel Sambuc       } else
363f4a2713aSLionel Sambuc         return true;
364f4a2713aSLionel Sambuc 
365f4a2713aSLionel Sambuc       continue;
366f4a2713aSLionel Sambuc     }
367f4a2713aSLionel Sambuc 
368f4a2713aSLionel Sambuc     if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
369f4a2713aSLionel Sambuc       // We have
370f4a2713aSLionel Sambuc       //
371*0a6a1f1dSLionel Sambuc       //   template-id '::'
372f4a2713aSLionel Sambuc       //
373*0a6a1f1dSLionel Sambuc       // So we need to check whether the template-id is a simple-template-id of
374*0a6a1f1dSLionel Sambuc       // the right kind (it should name a type or be dependent), and then
375f4a2713aSLionel Sambuc       // convert it into a type within the nested-name-specifier.
376f4a2713aSLionel Sambuc       TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
377f4a2713aSLionel Sambuc       if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {
378f4a2713aSLionel Sambuc         *MayBePseudoDestructor = true;
379f4a2713aSLionel Sambuc         return false;
380f4a2713aSLionel Sambuc       }
381f4a2713aSLionel Sambuc 
382f4a2713aSLionel Sambuc       if (LastII)
383f4a2713aSLionel Sambuc         *LastII = TemplateId->Name;
384f4a2713aSLionel Sambuc 
385f4a2713aSLionel Sambuc       // Consume the template-id token.
386f4a2713aSLionel Sambuc       ConsumeToken();
387f4a2713aSLionel Sambuc 
388f4a2713aSLionel Sambuc       assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
389f4a2713aSLionel Sambuc       SourceLocation CCLoc = ConsumeToken();
390f4a2713aSLionel Sambuc 
391f4a2713aSLionel Sambuc       HasScopeSpecifier = true;
392f4a2713aSLionel Sambuc 
393f4a2713aSLionel Sambuc       ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
394f4a2713aSLionel Sambuc                                          TemplateId->NumArgs);
395f4a2713aSLionel Sambuc 
396f4a2713aSLionel Sambuc       if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(),
397f4a2713aSLionel Sambuc                                               SS,
398f4a2713aSLionel Sambuc                                               TemplateId->TemplateKWLoc,
399f4a2713aSLionel Sambuc                                               TemplateId->Template,
400f4a2713aSLionel Sambuc                                               TemplateId->TemplateNameLoc,
401f4a2713aSLionel Sambuc                                               TemplateId->LAngleLoc,
402f4a2713aSLionel Sambuc                                               TemplateArgsPtr,
403f4a2713aSLionel Sambuc                                               TemplateId->RAngleLoc,
404f4a2713aSLionel Sambuc                                               CCLoc,
405f4a2713aSLionel Sambuc                                               EnteringContext)) {
406f4a2713aSLionel Sambuc         SourceLocation StartLoc
407f4a2713aSLionel Sambuc           = SS.getBeginLoc().isValid()? SS.getBeginLoc()
408f4a2713aSLionel Sambuc                                       : TemplateId->TemplateNameLoc;
409f4a2713aSLionel Sambuc         SS.SetInvalid(SourceRange(StartLoc, CCLoc));
410f4a2713aSLionel Sambuc       }
411f4a2713aSLionel Sambuc 
412f4a2713aSLionel Sambuc       continue;
413f4a2713aSLionel Sambuc     }
414f4a2713aSLionel Sambuc 
415f4a2713aSLionel Sambuc     // The rest of the nested-name-specifier possibilities start with
416f4a2713aSLionel Sambuc     // tok::identifier.
417f4a2713aSLionel Sambuc     if (Tok.isNot(tok::identifier))
418f4a2713aSLionel Sambuc       break;
419f4a2713aSLionel Sambuc 
420f4a2713aSLionel Sambuc     IdentifierInfo &II = *Tok.getIdentifierInfo();
421f4a2713aSLionel Sambuc 
422f4a2713aSLionel Sambuc     // nested-name-specifier:
423f4a2713aSLionel Sambuc     //   type-name '::'
424f4a2713aSLionel Sambuc     //   namespace-name '::'
425f4a2713aSLionel Sambuc     //   nested-name-specifier identifier '::'
426f4a2713aSLionel Sambuc     Token Next = NextToken();
427f4a2713aSLionel Sambuc 
428f4a2713aSLionel Sambuc     // If we get foo:bar, this is almost certainly a typo for foo::bar.  Recover
429f4a2713aSLionel Sambuc     // and emit a fixit hint for it.
430f4a2713aSLionel Sambuc     if (Next.is(tok::colon) && !ColonIsSacred) {
431f4a2713aSLionel Sambuc       if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, II,
432f4a2713aSLionel Sambuc                                             Tok.getLocation(),
433f4a2713aSLionel Sambuc                                             Next.getLocation(), ObjectType,
434f4a2713aSLionel Sambuc                                             EnteringContext) &&
435f4a2713aSLionel Sambuc           // If the token after the colon isn't an identifier, it's still an
436f4a2713aSLionel Sambuc           // error, but they probably meant something else strange so don't
437f4a2713aSLionel Sambuc           // recover like this.
438f4a2713aSLionel Sambuc           PP.LookAhead(1).is(tok::identifier)) {
439*0a6a1f1dSLionel Sambuc         Diag(Next, diag::err_unexpected_colon_in_nested_name_spec)
440f4a2713aSLionel Sambuc           << FixItHint::CreateReplacement(Next.getLocation(), "::");
441f4a2713aSLionel Sambuc         // Recover as if the user wrote '::'.
442f4a2713aSLionel Sambuc         Next.setKind(tok::coloncolon);
443f4a2713aSLionel Sambuc       }
444f4a2713aSLionel Sambuc     }
445f4a2713aSLionel Sambuc 
446*0a6a1f1dSLionel Sambuc     if (Next.is(tok::coloncolon) && GetLookAheadToken(2).is(tok::l_brace)) {
447*0a6a1f1dSLionel Sambuc       // It is invalid to have :: {, consume the scope qualifier and pretend
448*0a6a1f1dSLionel Sambuc       // like we never saw it.
449*0a6a1f1dSLionel Sambuc       Token Identifier = Tok; // Stash away the identifier.
450*0a6a1f1dSLionel Sambuc       ConsumeToken();         // Eat the identifier, current token is now '::'.
451*0a6a1f1dSLionel Sambuc       Diag(PP.getLocForEndOfToken(ConsumeToken()), diag::err_expected)
452*0a6a1f1dSLionel Sambuc           << tok::identifier;
453*0a6a1f1dSLionel Sambuc       UnconsumeToken(Identifier); // Stick the identifier back.
454*0a6a1f1dSLionel Sambuc       Next = NextToken();         // Point Next at the '{' token.
455*0a6a1f1dSLionel Sambuc     }
456*0a6a1f1dSLionel Sambuc 
457f4a2713aSLionel Sambuc     if (Next.is(tok::coloncolon)) {
458f4a2713aSLionel Sambuc       if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) &&
459*0a6a1f1dSLionel Sambuc           !Actions.isNonTypeNestedNameSpecifier(
460*0a6a1f1dSLionel Sambuc               getCurScope(), SS, Tok.getLocation(), II, ObjectType)) {
461f4a2713aSLionel Sambuc         *MayBePseudoDestructor = true;
462f4a2713aSLionel Sambuc         return false;
463f4a2713aSLionel Sambuc       }
464f4a2713aSLionel Sambuc 
465*0a6a1f1dSLionel Sambuc       if (ColonIsSacred) {
466*0a6a1f1dSLionel Sambuc         const Token &Next2 = GetLookAheadToken(2);
467*0a6a1f1dSLionel Sambuc         if (Next2.is(tok::kw_private) || Next2.is(tok::kw_protected) ||
468*0a6a1f1dSLionel Sambuc             Next2.is(tok::kw_public) || Next2.is(tok::kw_virtual)) {
469*0a6a1f1dSLionel Sambuc           Diag(Next2, diag::err_unexpected_token_in_nested_name_spec)
470*0a6a1f1dSLionel Sambuc               << Next2.getName()
471*0a6a1f1dSLionel Sambuc               << FixItHint::CreateReplacement(Next.getLocation(), ":");
472*0a6a1f1dSLionel Sambuc           Token ColonColon;
473*0a6a1f1dSLionel Sambuc           PP.Lex(ColonColon);
474*0a6a1f1dSLionel Sambuc           ColonColon.setKind(tok::colon);
475*0a6a1f1dSLionel Sambuc           PP.EnterToken(ColonColon);
476*0a6a1f1dSLionel Sambuc           break;
477*0a6a1f1dSLionel Sambuc         }
478*0a6a1f1dSLionel Sambuc       }
479*0a6a1f1dSLionel Sambuc 
480f4a2713aSLionel Sambuc       if (LastII)
481f4a2713aSLionel Sambuc         *LastII = &II;
482f4a2713aSLionel Sambuc 
483f4a2713aSLionel Sambuc       // We have an identifier followed by a '::'. Lookup this name
484f4a2713aSLionel Sambuc       // as the name in a nested-name-specifier.
485*0a6a1f1dSLionel Sambuc       Token Identifier = Tok;
486f4a2713aSLionel Sambuc       SourceLocation IdLoc = ConsumeToken();
487f4a2713aSLionel Sambuc       assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) &&
488f4a2713aSLionel Sambuc              "NextToken() not working properly!");
489*0a6a1f1dSLionel Sambuc       Token ColonColon = Tok;
490f4a2713aSLionel Sambuc       SourceLocation CCLoc = ConsumeToken();
491f4a2713aSLionel Sambuc 
492f4a2713aSLionel Sambuc       CheckForLParenAfterColonColon();
493f4a2713aSLionel Sambuc 
494*0a6a1f1dSLionel Sambuc       bool IsCorrectedToColon = false;
495*0a6a1f1dSLionel Sambuc       bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;
496f4a2713aSLionel Sambuc       if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc,
497*0a6a1f1dSLionel Sambuc                                               ObjectType, EnteringContext, SS,
498*0a6a1f1dSLionel Sambuc                                               false, CorrectionFlagPtr)) {
499*0a6a1f1dSLionel Sambuc         // Identifier is not recognized as a nested name, but we can have
500*0a6a1f1dSLionel Sambuc         // mistyped '::' instead of ':'.
501*0a6a1f1dSLionel Sambuc         if (CorrectionFlagPtr && IsCorrectedToColon) {
502*0a6a1f1dSLionel Sambuc           ColonColon.setKind(tok::colon);
503*0a6a1f1dSLionel Sambuc           PP.EnterToken(Tok);
504*0a6a1f1dSLionel Sambuc           PP.EnterToken(ColonColon);
505*0a6a1f1dSLionel Sambuc           Tok = Identifier;
506*0a6a1f1dSLionel Sambuc           break;
507*0a6a1f1dSLionel Sambuc         }
508f4a2713aSLionel Sambuc         SS.SetInvalid(SourceRange(IdLoc, CCLoc));
509*0a6a1f1dSLionel Sambuc       }
510*0a6a1f1dSLionel Sambuc       HasScopeSpecifier = true;
511f4a2713aSLionel Sambuc       continue;
512f4a2713aSLionel Sambuc     }
513f4a2713aSLionel Sambuc 
514f4a2713aSLionel Sambuc     CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS);
515f4a2713aSLionel Sambuc 
516f4a2713aSLionel Sambuc     // nested-name-specifier:
517f4a2713aSLionel Sambuc     //   type-name '<'
518f4a2713aSLionel Sambuc     if (Next.is(tok::less)) {
519f4a2713aSLionel Sambuc       TemplateTy Template;
520f4a2713aSLionel Sambuc       UnqualifiedId TemplateName;
521f4a2713aSLionel Sambuc       TemplateName.setIdentifier(&II, Tok.getLocation());
522f4a2713aSLionel Sambuc       bool MemberOfUnknownSpecialization;
523f4a2713aSLionel Sambuc       if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS,
524f4a2713aSLionel Sambuc                                               /*hasTemplateKeyword=*/false,
525f4a2713aSLionel Sambuc                                                         TemplateName,
526f4a2713aSLionel Sambuc                                                         ObjectType,
527f4a2713aSLionel Sambuc                                                         EnteringContext,
528f4a2713aSLionel Sambuc                                                         Template,
529f4a2713aSLionel Sambuc                                               MemberOfUnknownSpecialization)) {
530f4a2713aSLionel Sambuc         // We have found a template name, so annotate this token
531f4a2713aSLionel Sambuc         // with a template-id annotation. We do not permit the
532f4a2713aSLionel Sambuc         // template-id to be translated into a type annotation,
533f4a2713aSLionel Sambuc         // because some clients (e.g., the parsing of class template
534f4a2713aSLionel Sambuc         // specializations) still want to see the original template-id
535f4a2713aSLionel Sambuc         // token.
536f4a2713aSLionel Sambuc         ConsumeToken();
537f4a2713aSLionel Sambuc         if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
538f4a2713aSLionel Sambuc                                     TemplateName, false))
539f4a2713aSLionel Sambuc           return true;
540f4a2713aSLionel Sambuc         continue;
541f4a2713aSLionel Sambuc       }
542f4a2713aSLionel Sambuc 
543f4a2713aSLionel Sambuc       if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) &&
544f4a2713aSLionel Sambuc           (IsTypename || IsTemplateArgumentList(1))) {
545f4a2713aSLionel Sambuc         // We have something like t::getAs<T>, where getAs is a
546f4a2713aSLionel Sambuc         // member of an unknown specialization. However, this will only
547f4a2713aSLionel Sambuc         // parse correctly as a template, so suggest the keyword 'template'
548f4a2713aSLionel Sambuc         // before 'getAs' and treat this as a dependent template name.
549f4a2713aSLionel Sambuc         unsigned DiagID = diag::err_missing_dependent_template_keyword;
550f4a2713aSLionel Sambuc         if (getLangOpts().MicrosoftExt)
551f4a2713aSLionel Sambuc           DiagID = diag::warn_missing_dependent_template_keyword;
552f4a2713aSLionel Sambuc 
553f4a2713aSLionel Sambuc         Diag(Tok.getLocation(), DiagID)
554f4a2713aSLionel Sambuc           << II.getName()
555f4a2713aSLionel Sambuc           << FixItHint::CreateInsertion(Tok.getLocation(), "template ");
556f4a2713aSLionel Sambuc 
557f4a2713aSLionel Sambuc         if (TemplateNameKind TNK
558f4a2713aSLionel Sambuc               = Actions.ActOnDependentTemplateName(getCurScope(),
559f4a2713aSLionel Sambuc                                                    SS, SourceLocation(),
560f4a2713aSLionel Sambuc                                                    TemplateName, ObjectType,
561f4a2713aSLionel Sambuc                                                    EnteringContext, Template)) {
562f4a2713aSLionel Sambuc           // Consume the identifier.
563f4a2713aSLionel Sambuc           ConsumeToken();
564f4a2713aSLionel Sambuc           if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
565f4a2713aSLionel Sambuc                                       TemplateName, false))
566f4a2713aSLionel Sambuc             return true;
567f4a2713aSLionel Sambuc         }
568f4a2713aSLionel Sambuc         else
569f4a2713aSLionel Sambuc           return true;
570f4a2713aSLionel Sambuc 
571f4a2713aSLionel Sambuc         continue;
572f4a2713aSLionel Sambuc       }
573f4a2713aSLionel Sambuc     }
574f4a2713aSLionel Sambuc 
575f4a2713aSLionel Sambuc     // We don't have any tokens that form the beginning of a
576f4a2713aSLionel Sambuc     // nested-name-specifier, so we're done.
577f4a2713aSLionel Sambuc     break;
578f4a2713aSLionel Sambuc   }
579f4a2713aSLionel Sambuc 
580f4a2713aSLionel Sambuc   // Even if we didn't see any pieces of a nested-name-specifier, we
581f4a2713aSLionel Sambuc   // still check whether there is a tilde in this position, which
582f4a2713aSLionel Sambuc   // indicates a potential pseudo-destructor.
583f4a2713aSLionel Sambuc   if (CheckForDestructor && Tok.is(tok::tilde))
584f4a2713aSLionel Sambuc     *MayBePseudoDestructor = true;
585f4a2713aSLionel Sambuc 
586f4a2713aSLionel Sambuc   return false;
587f4a2713aSLionel Sambuc }
588f4a2713aSLionel Sambuc 
tryParseCXXIdExpression(CXXScopeSpec & SS,bool isAddressOfOperand,Token & Replacement)589*0a6a1f1dSLionel Sambuc ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOperand,
590*0a6a1f1dSLionel Sambuc                                            Token &Replacement) {
591*0a6a1f1dSLionel Sambuc   SourceLocation TemplateKWLoc;
592*0a6a1f1dSLionel Sambuc   UnqualifiedId Name;
593*0a6a1f1dSLionel Sambuc   if (ParseUnqualifiedId(SS,
594*0a6a1f1dSLionel Sambuc                          /*EnteringContext=*/false,
595*0a6a1f1dSLionel Sambuc                          /*AllowDestructorName=*/false,
596*0a6a1f1dSLionel Sambuc                          /*AllowConstructorName=*/false,
597*0a6a1f1dSLionel Sambuc                          /*ObjectType=*/ParsedType(), TemplateKWLoc, Name))
598*0a6a1f1dSLionel Sambuc     return ExprError();
599*0a6a1f1dSLionel Sambuc 
600*0a6a1f1dSLionel Sambuc   // This is only the direct operand of an & operator if it is not
601*0a6a1f1dSLionel Sambuc   // followed by a postfix-expression suffix.
602*0a6a1f1dSLionel Sambuc   if (isAddressOfOperand && isPostfixExpressionSuffixStart())
603*0a6a1f1dSLionel Sambuc     isAddressOfOperand = false;
604*0a6a1f1dSLionel Sambuc 
605*0a6a1f1dSLionel Sambuc   return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name,
606*0a6a1f1dSLionel Sambuc                                    Tok.is(tok::l_paren), isAddressOfOperand,
607*0a6a1f1dSLionel Sambuc                                    nullptr, /*IsInlineAsmIdentifier=*/false,
608*0a6a1f1dSLionel Sambuc                                    &Replacement);
609*0a6a1f1dSLionel Sambuc }
610*0a6a1f1dSLionel Sambuc 
611f4a2713aSLionel Sambuc /// ParseCXXIdExpression - Handle id-expression.
612f4a2713aSLionel Sambuc ///
613f4a2713aSLionel Sambuc ///       id-expression:
614f4a2713aSLionel Sambuc ///         unqualified-id
615f4a2713aSLionel Sambuc ///         qualified-id
616f4a2713aSLionel Sambuc ///
617f4a2713aSLionel Sambuc ///       qualified-id:
618f4a2713aSLionel Sambuc ///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
619f4a2713aSLionel Sambuc ///         '::' identifier
620f4a2713aSLionel Sambuc ///         '::' operator-function-id
621f4a2713aSLionel Sambuc ///         '::' template-id
622f4a2713aSLionel Sambuc ///
623f4a2713aSLionel Sambuc /// NOTE: The standard specifies that, for qualified-id, the parser does not
624f4a2713aSLionel Sambuc /// expect:
625f4a2713aSLionel Sambuc ///
626f4a2713aSLionel Sambuc ///   '::' conversion-function-id
627f4a2713aSLionel Sambuc ///   '::' '~' class-name
628f4a2713aSLionel Sambuc ///
629f4a2713aSLionel Sambuc /// This may cause a slight inconsistency on diagnostics:
630f4a2713aSLionel Sambuc ///
631f4a2713aSLionel Sambuc /// class C {};
632f4a2713aSLionel Sambuc /// namespace A {}
633f4a2713aSLionel Sambuc /// void f() {
634f4a2713aSLionel Sambuc ///   :: A :: ~ C(); // Some Sema error about using destructor with a
635f4a2713aSLionel Sambuc ///                  // namespace.
636f4a2713aSLionel Sambuc ///   :: ~ C(); // Some Parser error like 'unexpected ~'.
637f4a2713aSLionel Sambuc /// }
638f4a2713aSLionel Sambuc ///
639f4a2713aSLionel Sambuc /// We simplify the parser a bit and make it work like:
640f4a2713aSLionel Sambuc ///
641f4a2713aSLionel Sambuc ///       qualified-id:
642f4a2713aSLionel Sambuc ///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
643f4a2713aSLionel Sambuc ///         '::' unqualified-id
644f4a2713aSLionel Sambuc ///
645f4a2713aSLionel Sambuc /// That way Sema can handle and report similar errors for namespaces and the
646f4a2713aSLionel Sambuc /// global scope.
647f4a2713aSLionel Sambuc ///
648f4a2713aSLionel Sambuc /// The isAddressOfOperand parameter indicates that this id-expression is a
649f4a2713aSLionel Sambuc /// direct operand of the address-of operator. This is, besides member contexts,
650f4a2713aSLionel Sambuc /// the only place where a qualified-id naming a non-static class member may
651f4a2713aSLionel Sambuc /// appear.
652f4a2713aSLionel Sambuc ///
ParseCXXIdExpression(bool isAddressOfOperand)653f4a2713aSLionel Sambuc ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
654f4a2713aSLionel Sambuc   // qualified-id:
655f4a2713aSLionel Sambuc   //   '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
656f4a2713aSLionel Sambuc   //   '::' unqualified-id
657f4a2713aSLionel Sambuc   //
658f4a2713aSLionel Sambuc   CXXScopeSpec SS;
659f4a2713aSLionel Sambuc   ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
660f4a2713aSLionel Sambuc 
661*0a6a1f1dSLionel Sambuc   Token Replacement;
662*0a6a1f1dSLionel Sambuc   ExprResult Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
663*0a6a1f1dSLionel Sambuc   if (Result.isUnset()) {
664*0a6a1f1dSLionel Sambuc     // If the ExprResult is valid but null, then typo correction suggested a
665*0a6a1f1dSLionel Sambuc     // keyword replacement that needs to be reparsed.
666*0a6a1f1dSLionel Sambuc     UnconsumeToken(Replacement);
667*0a6a1f1dSLionel Sambuc     Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
668*0a6a1f1dSLionel Sambuc   }
669*0a6a1f1dSLionel Sambuc   assert(!Result.isUnset() && "Typo correction suggested a keyword replacement "
670*0a6a1f1dSLionel Sambuc                               "for a previous keyword suggestion");
671*0a6a1f1dSLionel Sambuc   return Result;
672f4a2713aSLionel Sambuc }
673f4a2713aSLionel Sambuc 
674f4a2713aSLionel Sambuc /// ParseLambdaExpression - Parse a C++11 lambda expression.
675f4a2713aSLionel Sambuc ///
676f4a2713aSLionel Sambuc ///       lambda-expression:
677f4a2713aSLionel Sambuc ///         lambda-introducer lambda-declarator[opt] compound-statement
678f4a2713aSLionel Sambuc ///
679f4a2713aSLionel Sambuc ///       lambda-introducer:
680f4a2713aSLionel Sambuc ///         '[' lambda-capture[opt] ']'
681f4a2713aSLionel Sambuc ///
682f4a2713aSLionel Sambuc ///       lambda-capture:
683f4a2713aSLionel Sambuc ///         capture-default
684f4a2713aSLionel Sambuc ///         capture-list
685f4a2713aSLionel Sambuc ///         capture-default ',' capture-list
686f4a2713aSLionel Sambuc ///
687f4a2713aSLionel Sambuc ///       capture-default:
688f4a2713aSLionel Sambuc ///         '&'
689f4a2713aSLionel Sambuc ///         '='
690f4a2713aSLionel Sambuc ///
691f4a2713aSLionel Sambuc ///       capture-list:
692f4a2713aSLionel Sambuc ///         capture
693f4a2713aSLionel Sambuc ///         capture-list ',' capture
694f4a2713aSLionel Sambuc ///
695f4a2713aSLionel Sambuc ///       capture:
696f4a2713aSLionel Sambuc ///         simple-capture
697f4a2713aSLionel Sambuc ///         init-capture     [C++1y]
698f4a2713aSLionel Sambuc ///
699f4a2713aSLionel Sambuc ///       simple-capture:
700f4a2713aSLionel Sambuc ///         identifier
701f4a2713aSLionel Sambuc ///         '&' identifier
702f4a2713aSLionel Sambuc ///         'this'
703f4a2713aSLionel Sambuc ///
704f4a2713aSLionel Sambuc ///       init-capture:      [C++1y]
705f4a2713aSLionel Sambuc ///         identifier initializer
706f4a2713aSLionel Sambuc ///         '&' identifier initializer
707f4a2713aSLionel Sambuc ///
708f4a2713aSLionel Sambuc ///       lambda-declarator:
709f4a2713aSLionel Sambuc ///         '(' parameter-declaration-clause ')' attribute-specifier[opt]
710f4a2713aSLionel Sambuc ///           'mutable'[opt] exception-specification[opt]
711f4a2713aSLionel Sambuc ///           trailing-return-type[opt]
712f4a2713aSLionel Sambuc ///
ParseLambdaExpression()713f4a2713aSLionel Sambuc ExprResult Parser::ParseLambdaExpression() {
714f4a2713aSLionel Sambuc   // Parse lambda-introducer.
715f4a2713aSLionel Sambuc   LambdaIntroducer Intro;
716*0a6a1f1dSLionel Sambuc   Optional<unsigned> DiagID = ParseLambdaIntroducer(Intro);
717f4a2713aSLionel Sambuc   if (DiagID) {
718f4a2713aSLionel Sambuc     Diag(Tok, DiagID.getValue());
719f4a2713aSLionel Sambuc     SkipUntil(tok::r_square, StopAtSemi);
720f4a2713aSLionel Sambuc     SkipUntil(tok::l_brace, StopAtSemi);
721f4a2713aSLionel Sambuc     SkipUntil(tok::r_brace, StopAtSemi);
722f4a2713aSLionel Sambuc     return ExprError();
723f4a2713aSLionel Sambuc   }
724f4a2713aSLionel Sambuc 
725f4a2713aSLionel Sambuc   return ParseLambdaExpressionAfterIntroducer(Intro);
726f4a2713aSLionel Sambuc }
727f4a2713aSLionel Sambuc 
728f4a2713aSLionel Sambuc /// TryParseLambdaExpression - Use lookahead and potentially tentative
729f4a2713aSLionel Sambuc /// parsing to determine if we are looking at a C++0x lambda expression, and parse
730f4a2713aSLionel Sambuc /// it if we are.
731f4a2713aSLionel Sambuc ///
732f4a2713aSLionel Sambuc /// If we are not looking at a lambda expression, returns ExprError().
TryParseLambdaExpression()733f4a2713aSLionel Sambuc ExprResult Parser::TryParseLambdaExpression() {
734f4a2713aSLionel Sambuc   assert(getLangOpts().CPlusPlus11
735f4a2713aSLionel Sambuc          && Tok.is(tok::l_square)
736f4a2713aSLionel Sambuc          && "Not at the start of a possible lambda expression.");
737f4a2713aSLionel Sambuc 
738f4a2713aSLionel Sambuc   const Token Next = NextToken(), After = GetLookAheadToken(2);
739f4a2713aSLionel Sambuc 
740f4a2713aSLionel Sambuc   // If lookahead indicates this is a lambda...
741f4a2713aSLionel Sambuc   if (Next.is(tok::r_square) ||     // []
742f4a2713aSLionel Sambuc       Next.is(tok::equal) ||        // [=
743f4a2713aSLionel Sambuc       (Next.is(tok::amp) &&         // [&] or [&,
744f4a2713aSLionel Sambuc        (After.is(tok::r_square) ||
745f4a2713aSLionel Sambuc         After.is(tok::comma))) ||
746f4a2713aSLionel Sambuc       (Next.is(tok::identifier) &&  // [identifier]
747f4a2713aSLionel Sambuc        After.is(tok::r_square))) {
748f4a2713aSLionel Sambuc     return ParseLambdaExpression();
749f4a2713aSLionel Sambuc   }
750f4a2713aSLionel Sambuc 
751f4a2713aSLionel Sambuc   // If lookahead indicates an ObjC message send...
752f4a2713aSLionel Sambuc   // [identifier identifier
753f4a2713aSLionel Sambuc   if (Next.is(tok::identifier) && After.is(tok::identifier)) {
754f4a2713aSLionel Sambuc     return ExprEmpty();
755f4a2713aSLionel Sambuc   }
756f4a2713aSLionel Sambuc 
757f4a2713aSLionel Sambuc   // Here, we're stuck: lambda introducers and Objective-C message sends are
758f4a2713aSLionel Sambuc   // unambiguous, but it requires arbitrary lookhead.  [a,b,c,d,e,f,g] is a
759f4a2713aSLionel Sambuc   // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send.  Instead of
760f4a2713aSLionel Sambuc   // writing two routines to parse a lambda introducer, just try to parse
761f4a2713aSLionel Sambuc   // a lambda introducer first, and fall back if that fails.
762f4a2713aSLionel Sambuc   // (TryParseLambdaIntroducer never produces any diagnostic output.)
763f4a2713aSLionel Sambuc   LambdaIntroducer Intro;
764f4a2713aSLionel Sambuc   if (TryParseLambdaIntroducer(Intro))
765f4a2713aSLionel Sambuc     return ExprEmpty();
766*0a6a1f1dSLionel Sambuc 
767f4a2713aSLionel Sambuc   return ParseLambdaExpressionAfterIntroducer(Intro);
768f4a2713aSLionel Sambuc }
769f4a2713aSLionel Sambuc 
770f4a2713aSLionel Sambuc /// \brief Parse a lambda introducer.
771f4a2713aSLionel Sambuc /// \param Intro A LambdaIntroducer filled in with information about the
772f4a2713aSLionel Sambuc ///        contents of the lambda-introducer.
773f4a2713aSLionel Sambuc /// \param SkippedInits If non-null, we are disambiguating between an Obj-C
774f4a2713aSLionel Sambuc ///        message send and a lambda expression. In this mode, we will
775f4a2713aSLionel Sambuc ///        sometimes skip the initializers for init-captures and not fully
776f4a2713aSLionel Sambuc ///        populate \p Intro. This flag will be set to \c true if we do so.
777f4a2713aSLionel Sambuc /// \return A DiagnosticID if it hit something unexpected. The location for
778f4a2713aSLionel Sambuc ///         for the diagnostic is that of the current token.
ParseLambdaIntroducer(LambdaIntroducer & Intro,bool * SkippedInits)779f4a2713aSLionel Sambuc Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
780f4a2713aSLionel Sambuc                                                  bool *SkippedInits) {
781f4a2713aSLionel Sambuc   typedef Optional<unsigned> DiagResult;
782f4a2713aSLionel Sambuc 
783f4a2713aSLionel Sambuc   assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");
784f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_square);
785f4a2713aSLionel Sambuc   T.consumeOpen();
786f4a2713aSLionel Sambuc 
787f4a2713aSLionel Sambuc   Intro.Range.setBegin(T.getOpenLocation());
788f4a2713aSLionel Sambuc 
789f4a2713aSLionel Sambuc   bool first = true;
790f4a2713aSLionel Sambuc 
791f4a2713aSLionel Sambuc   // Parse capture-default.
792f4a2713aSLionel Sambuc   if (Tok.is(tok::amp) &&
793f4a2713aSLionel Sambuc       (NextToken().is(tok::comma) || NextToken().is(tok::r_square))) {
794f4a2713aSLionel Sambuc     Intro.Default = LCD_ByRef;
795f4a2713aSLionel Sambuc     Intro.DefaultLoc = ConsumeToken();
796f4a2713aSLionel Sambuc     first = false;
797f4a2713aSLionel Sambuc   } else if (Tok.is(tok::equal)) {
798f4a2713aSLionel Sambuc     Intro.Default = LCD_ByCopy;
799f4a2713aSLionel Sambuc     Intro.DefaultLoc = ConsumeToken();
800f4a2713aSLionel Sambuc     first = false;
801f4a2713aSLionel Sambuc   }
802f4a2713aSLionel Sambuc 
803f4a2713aSLionel Sambuc   while (Tok.isNot(tok::r_square)) {
804f4a2713aSLionel Sambuc     if (!first) {
805f4a2713aSLionel Sambuc       if (Tok.isNot(tok::comma)) {
806f4a2713aSLionel Sambuc         // Provide a completion for a lambda introducer here. Except
807f4a2713aSLionel Sambuc         // in Objective-C, where this is Almost Surely meant to be a message
808f4a2713aSLionel Sambuc         // send. In that case, fail here and let the ObjC message
809f4a2713aSLionel Sambuc         // expression parser perform the completion.
810f4a2713aSLionel Sambuc         if (Tok.is(tok::code_completion) &&
811f4a2713aSLionel Sambuc             !(getLangOpts().ObjC1 && Intro.Default == LCD_None &&
812f4a2713aSLionel Sambuc               !Intro.Captures.empty())) {
813f4a2713aSLionel Sambuc           Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
814f4a2713aSLionel Sambuc                                                /*AfterAmpersand=*/false);
815*0a6a1f1dSLionel Sambuc           cutOffParsing();
816f4a2713aSLionel Sambuc           break;
817f4a2713aSLionel Sambuc         }
818f4a2713aSLionel Sambuc 
819f4a2713aSLionel Sambuc         return DiagResult(diag::err_expected_comma_or_rsquare);
820f4a2713aSLionel Sambuc       }
821f4a2713aSLionel Sambuc       ConsumeToken();
822f4a2713aSLionel Sambuc     }
823f4a2713aSLionel Sambuc 
824f4a2713aSLionel Sambuc     if (Tok.is(tok::code_completion)) {
825f4a2713aSLionel Sambuc       // If we're in Objective-C++ and we have a bare '[', then this is more
826f4a2713aSLionel Sambuc       // likely to be a message receiver.
827f4a2713aSLionel Sambuc       if (getLangOpts().ObjC1 && first)
828f4a2713aSLionel Sambuc         Actions.CodeCompleteObjCMessageReceiver(getCurScope());
829f4a2713aSLionel Sambuc       else
830f4a2713aSLionel Sambuc         Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
831f4a2713aSLionel Sambuc                                              /*AfterAmpersand=*/false);
832*0a6a1f1dSLionel Sambuc       cutOffParsing();
833f4a2713aSLionel Sambuc       break;
834f4a2713aSLionel Sambuc     }
835f4a2713aSLionel Sambuc 
836f4a2713aSLionel Sambuc     first = false;
837f4a2713aSLionel Sambuc 
838f4a2713aSLionel Sambuc     // Parse capture.
839f4a2713aSLionel Sambuc     LambdaCaptureKind Kind = LCK_ByCopy;
840f4a2713aSLionel Sambuc     SourceLocation Loc;
841*0a6a1f1dSLionel Sambuc     IdentifierInfo *Id = nullptr;
842f4a2713aSLionel Sambuc     SourceLocation EllipsisLoc;
843f4a2713aSLionel Sambuc     ExprResult Init;
844f4a2713aSLionel Sambuc 
845f4a2713aSLionel Sambuc     if (Tok.is(tok::kw_this)) {
846f4a2713aSLionel Sambuc       Kind = LCK_This;
847f4a2713aSLionel Sambuc       Loc = ConsumeToken();
848f4a2713aSLionel Sambuc     } else {
849f4a2713aSLionel Sambuc       if (Tok.is(tok::amp)) {
850f4a2713aSLionel Sambuc         Kind = LCK_ByRef;
851f4a2713aSLionel Sambuc         ConsumeToken();
852f4a2713aSLionel Sambuc 
853f4a2713aSLionel Sambuc         if (Tok.is(tok::code_completion)) {
854f4a2713aSLionel Sambuc           Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
855f4a2713aSLionel Sambuc                                                /*AfterAmpersand=*/true);
856*0a6a1f1dSLionel Sambuc           cutOffParsing();
857f4a2713aSLionel Sambuc           break;
858f4a2713aSLionel Sambuc         }
859f4a2713aSLionel Sambuc       }
860f4a2713aSLionel Sambuc 
861f4a2713aSLionel Sambuc       if (Tok.is(tok::identifier)) {
862f4a2713aSLionel Sambuc         Id = Tok.getIdentifierInfo();
863f4a2713aSLionel Sambuc         Loc = ConsumeToken();
864f4a2713aSLionel Sambuc       } else if (Tok.is(tok::kw_this)) {
865f4a2713aSLionel Sambuc         // FIXME: If we want to suggest a fixit here, will need to return more
866f4a2713aSLionel Sambuc         // than just DiagnosticID. Perhaps full DiagnosticBuilder that can be
867f4a2713aSLionel Sambuc         // Clear()ed to prevent emission in case of tentative parsing?
868f4a2713aSLionel Sambuc         return DiagResult(diag::err_this_captured_by_reference);
869f4a2713aSLionel Sambuc       } else {
870f4a2713aSLionel Sambuc         return DiagResult(diag::err_expected_capture);
871f4a2713aSLionel Sambuc       }
872f4a2713aSLionel Sambuc 
873f4a2713aSLionel Sambuc       if (Tok.is(tok::l_paren)) {
874f4a2713aSLionel Sambuc         BalancedDelimiterTracker Parens(*this, tok::l_paren);
875f4a2713aSLionel Sambuc         Parens.consumeOpen();
876f4a2713aSLionel Sambuc 
877f4a2713aSLionel Sambuc         ExprVector Exprs;
878f4a2713aSLionel Sambuc         CommaLocsTy Commas;
879f4a2713aSLionel Sambuc         if (SkippedInits) {
880f4a2713aSLionel Sambuc           Parens.skipToEnd();
881f4a2713aSLionel Sambuc           *SkippedInits = true;
882f4a2713aSLionel Sambuc         } else if (ParseExpressionList(Exprs, Commas)) {
883f4a2713aSLionel Sambuc           Parens.skipToEnd();
884f4a2713aSLionel Sambuc           Init = ExprError();
885f4a2713aSLionel Sambuc         } else {
886f4a2713aSLionel Sambuc           Parens.consumeClose();
887f4a2713aSLionel Sambuc           Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(),
888f4a2713aSLionel Sambuc                                             Parens.getCloseLocation(),
889f4a2713aSLionel Sambuc                                             Exprs);
890f4a2713aSLionel Sambuc         }
891f4a2713aSLionel Sambuc       } else if (Tok.is(tok::l_brace) || Tok.is(tok::equal)) {
892*0a6a1f1dSLionel Sambuc         // Each lambda init-capture forms its own full expression, which clears
893*0a6a1f1dSLionel Sambuc         // Actions.MaybeODRUseExprs. So create an expression evaluation context
894*0a6a1f1dSLionel Sambuc         // to save the necessary state, and restore it later.
895*0a6a1f1dSLionel Sambuc         EnterExpressionEvaluationContext EC(Actions,
896*0a6a1f1dSLionel Sambuc                                             Sema::PotentiallyEvaluated);
897*0a6a1f1dSLionel Sambuc         bool HadEquals = TryConsumeToken(tok::equal);
898f4a2713aSLionel Sambuc 
899*0a6a1f1dSLionel Sambuc         if (!SkippedInits) {
900*0a6a1f1dSLionel Sambuc           // Warn on constructs that will change meaning when we implement N3922
901*0a6a1f1dSLionel Sambuc           if (!HadEquals && Tok.is(tok::l_brace)) {
902*0a6a1f1dSLionel Sambuc             Diag(Tok, diag::warn_init_capture_direct_list_init)
903*0a6a1f1dSLionel Sambuc               << FixItHint::CreateInsertion(Tok.getLocation(), "=");
904*0a6a1f1dSLionel Sambuc           }
905f4a2713aSLionel Sambuc           Init = ParseInitializer();
906*0a6a1f1dSLionel Sambuc         } else if (Tok.is(tok::l_brace)) {
907f4a2713aSLionel Sambuc           BalancedDelimiterTracker Braces(*this, tok::l_brace);
908f4a2713aSLionel Sambuc           Braces.consumeOpen();
909f4a2713aSLionel Sambuc           Braces.skipToEnd();
910f4a2713aSLionel Sambuc           *SkippedInits = true;
911f4a2713aSLionel Sambuc         } else {
912f4a2713aSLionel Sambuc           // We're disambiguating this:
913f4a2713aSLionel Sambuc           //
914f4a2713aSLionel Sambuc           //   [..., x = expr
915f4a2713aSLionel Sambuc           //
916f4a2713aSLionel Sambuc           // We need to find the end of the following expression in order to
917*0a6a1f1dSLionel Sambuc           // determine whether this is an Obj-C message send's receiver, a
918*0a6a1f1dSLionel Sambuc           // C99 designator, or a lambda init-capture.
919f4a2713aSLionel Sambuc           //
920f4a2713aSLionel Sambuc           // Parse the expression to find where it ends, and annotate it back
921f4a2713aSLionel Sambuc           // onto the tokens. We would have parsed this expression the same way
922f4a2713aSLionel Sambuc           // in either case: both the RHS of an init-capture and the RHS of an
923f4a2713aSLionel Sambuc           // assignment expression are parsed as an initializer-clause, and in
924f4a2713aSLionel Sambuc           // neither case can anything be added to the scope between the '[' and
925f4a2713aSLionel Sambuc           // here.
926f4a2713aSLionel Sambuc           //
927f4a2713aSLionel Sambuc           // FIXME: This is horrible. Adding a mechanism to skip an expression
928f4a2713aSLionel Sambuc           // would be much cleaner.
929f4a2713aSLionel Sambuc           // FIXME: If there is a ',' before the next ']' or ':', we can skip to
930f4a2713aSLionel Sambuc           // that instead. (And if we see a ':' with no matching '?', we can
931f4a2713aSLionel Sambuc           // classify this as an Obj-C message send.)
932f4a2713aSLionel Sambuc           SourceLocation StartLoc = Tok.getLocation();
933f4a2713aSLionel Sambuc           InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true);
934f4a2713aSLionel Sambuc           Init = ParseInitializer();
935f4a2713aSLionel Sambuc 
936f4a2713aSLionel Sambuc           if (Tok.getLocation() != StartLoc) {
937f4a2713aSLionel Sambuc             // Back out the lexing of the token after the initializer.
938f4a2713aSLionel Sambuc             PP.RevertCachedTokens(1);
939f4a2713aSLionel Sambuc 
940f4a2713aSLionel Sambuc             // Replace the consumed tokens with an appropriate annotation.
941f4a2713aSLionel Sambuc             Tok.setLocation(StartLoc);
942f4a2713aSLionel Sambuc             Tok.setKind(tok::annot_primary_expr);
943f4a2713aSLionel Sambuc             setExprAnnotation(Tok, Init);
944f4a2713aSLionel Sambuc             Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation());
945f4a2713aSLionel Sambuc             PP.AnnotateCachedTokens(Tok);
946f4a2713aSLionel Sambuc 
947f4a2713aSLionel Sambuc             // Consume the annotated initializer.
948f4a2713aSLionel Sambuc             ConsumeToken();
949f4a2713aSLionel Sambuc           }
950f4a2713aSLionel Sambuc         }
951*0a6a1f1dSLionel Sambuc       } else
952*0a6a1f1dSLionel Sambuc         TryConsumeToken(tok::ellipsis, EllipsisLoc);
953f4a2713aSLionel Sambuc     }
954*0a6a1f1dSLionel Sambuc     // If this is an init capture, process the initialization expression
955*0a6a1f1dSLionel Sambuc     // right away.  For lambda init-captures such as the following:
956*0a6a1f1dSLionel Sambuc     // const int x = 10;
957*0a6a1f1dSLionel Sambuc     //  auto L = [i = x+1](int a) {
958*0a6a1f1dSLionel Sambuc     //    return [j = x+2,
959*0a6a1f1dSLionel Sambuc     //           &k = x](char b) { };
960*0a6a1f1dSLionel Sambuc     //  };
961*0a6a1f1dSLionel Sambuc     // keep in mind that each lambda init-capture has to have:
962*0a6a1f1dSLionel Sambuc     //  - its initialization expression executed in the context
963*0a6a1f1dSLionel Sambuc     //    of the enclosing/parent decl-context.
964*0a6a1f1dSLionel Sambuc     //  - but the variable itself has to be 'injected' into the
965*0a6a1f1dSLionel Sambuc     //    decl-context of its lambda's call-operator (which has
966*0a6a1f1dSLionel Sambuc     //    not yet been created).
967*0a6a1f1dSLionel Sambuc     // Each init-expression is a full-expression that has to get
968*0a6a1f1dSLionel Sambuc     // Sema-analyzed (for capturing etc.) before its lambda's
969*0a6a1f1dSLionel Sambuc     // call-operator's decl-context, scope & scopeinfo are pushed on their
970*0a6a1f1dSLionel Sambuc     // respective stacks.  Thus if any variable is odr-used in the init-capture
971*0a6a1f1dSLionel Sambuc     // it will correctly get captured in the enclosing lambda, if one exists.
972*0a6a1f1dSLionel Sambuc     // The init-variables above are created later once the lambdascope and
973*0a6a1f1dSLionel Sambuc     // call-operators decl-context is pushed onto its respective stack.
974f4a2713aSLionel Sambuc 
975*0a6a1f1dSLionel Sambuc     // Since the lambda init-capture's initializer expression occurs in the
976*0a6a1f1dSLionel Sambuc     // context of the enclosing function or lambda, therefore we can not wait
977*0a6a1f1dSLionel Sambuc     // till a lambda scope has been pushed on before deciding whether the
978*0a6a1f1dSLionel Sambuc     // variable needs to be captured.  We also need to process all
979*0a6a1f1dSLionel Sambuc     // lvalue-to-rvalue conversions and discarded-value conversions,
980*0a6a1f1dSLionel Sambuc     // so that we can avoid capturing certain constant variables.
981*0a6a1f1dSLionel Sambuc     // For e.g.,
982*0a6a1f1dSLionel Sambuc     //  void test() {
983*0a6a1f1dSLionel Sambuc     //   const int x = 10;
984*0a6a1f1dSLionel Sambuc     //   auto L = [&z = x](char a) { <-- don't capture by the current lambda
985*0a6a1f1dSLionel Sambuc     //     return [y = x](int i) { <-- don't capture by enclosing lambda
986*0a6a1f1dSLionel Sambuc     //          return y;
987*0a6a1f1dSLionel Sambuc     //     }
988*0a6a1f1dSLionel Sambuc     //   };
989*0a6a1f1dSLionel Sambuc     // If x was not const, the second use would require 'L' to capture, and
990*0a6a1f1dSLionel Sambuc     // that would be an error.
991*0a6a1f1dSLionel Sambuc 
992*0a6a1f1dSLionel Sambuc     ParsedType InitCaptureParsedType;
993*0a6a1f1dSLionel Sambuc     if (Init.isUsable()) {
994*0a6a1f1dSLionel Sambuc       // Get the pointer and store it in an lvalue, so we can use it as an
995*0a6a1f1dSLionel Sambuc       // out argument.
996*0a6a1f1dSLionel Sambuc       Expr *InitExpr = Init.get();
997*0a6a1f1dSLionel Sambuc       // This performs any lvalue-to-rvalue conversions if necessary, which
998*0a6a1f1dSLionel Sambuc       // can affect what gets captured in the containing decl-context.
999*0a6a1f1dSLionel Sambuc       QualType InitCaptureType = Actions.performLambdaInitCaptureInitialization(
1000*0a6a1f1dSLionel Sambuc         Loc, Kind == LCK_ByRef, Id, InitExpr);
1001*0a6a1f1dSLionel Sambuc       Init = InitExpr;
1002*0a6a1f1dSLionel Sambuc       InitCaptureParsedType.set(InitCaptureType);
1003*0a6a1f1dSLionel Sambuc     }
1004*0a6a1f1dSLionel Sambuc     Intro.addCapture(Kind, Loc, Id, EllipsisLoc, Init, InitCaptureParsedType);
1005f4a2713aSLionel Sambuc   }
1006f4a2713aSLionel Sambuc 
1007f4a2713aSLionel Sambuc   T.consumeClose();
1008f4a2713aSLionel Sambuc   Intro.Range.setEnd(T.getCloseLocation());
1009f4a2713aSLionel Sambuc   return DiagResult();
1010f4a2713aSLionel Sambuc }
1011f4a2713aSLionel Sambuc 
1012f4a2713aSLionel Sambuc /// TryParseLambdaIntroducer - Tentatively parse a lambda introducer.
1013f4a2713aSLionel Sambuc ///
1014f4a2713aSLionel Sambuc /// Returns true if it hit something unexpected.
TryParseLambdaIntroducer(LambdaIntroducer & Intro)1015f4a2713aSLionel Sambuc bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) {
1016f4a2713aSLionel Sambuc   TentativeParsingAction PA(*this);
1017f4a2713aSLionel Sambuc 
1018f4a2713aSLionel Sambuc   bool SkippedInits = false;
1019f4a2713aSLionel Sambuc   Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits));
1020f4a2713aSLionel Sambuc 
1021f4a2713aSLionel Sambuc   if (DiagID) {
1022f4a2713aSLionel Sambuc     PA.Revert();
1023f4a2713aSLionel Sambuc     return true;
1024f4a2713aSLionel Sambuc   }
1025f4a2713aSLionel Sambuc 
1026f4a2713aSLionel Sambuc   if (SkippedInits) {
1027f4a2713aSLionel Sambuc     // Parse it again, but this time parse the init-captures too.
1028f4a2713aSLionel Sambuc     PA.Revert();
1029f4a2713aSLionel Sambuc     Intro = LambdaIntroducer();
1030f4a2713aSLionel Sambuc     DiagID = ParseLambdaIntroducer(Intro);
1031f4a2713aSLionel Sambuc     assert(!DiagID && "parsing lambda-introducer failed on reparse");
1032f4a2713aSLionel Sambuc     return false;
1033f4a2713aSLionel Sambuc   }
1034f4a2713aSLionel Sambuc 
1035f4a2713aSLionel Sambuc   PA.Commit();
1036f4a2713aSLionel Sambuc   return false;
1037f4a2713aSLionel Sambuc }
1038f4a2713aSLionel Sambuc 
1039f4a2713aSLionel Sambuc /// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda
1040f4a2713aSLionel Sambuc /// expression.
ParseLambdaExpressionAfterIntroducer(LambdaIntroducer & Intro)1041f4a2713aSLionel Sambuc ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
1042f4a2713aSLionel Sambuc                      LambdaIntroducer &Intro) {
1043f4a2713aSLionel Sambuc   SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
1044f4a2713aSLionel Sambuc   Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda);
1045f4a2713aSLionel Sambuc 
1046f4a2713aSLionel Sambuc   PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
1047f4a2713aSLionel Sambuc                                 "lambda expression parsing");
1048f4a2713aSLionel Sambuc 
1049f4a2713aSLionel Sambuc 
1050f4a2713aSLionel Sambuc 
1051f4a2713aSLionel Sambuc   // FIXME: Call into Actions to add any init-capture declarations to the
1052f4a2713aSLionel Sambuc   // scope while parsing the lambda-declarator and compound-statement.
1053f4a2713aSLionel Sambuc 
1054f4a2713aSLionel Sambuc   // Parse lambda-declarator[opt].
1055f4a2713aSLionel Sambuc   DeclSpec DS(AttrFactory);
1056f4a2713aSLionel Sambuc   Declarator D(DS, Declarator::LambdaExprContext);
1057f4a2713aSLionel Sambuc   TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1058f4a2713aSLionel Sambuc   Actions.PushLambdaScope();
1059f4a2713aSLionel Sambuc 
1060*0a6a1f1dSLionel Sambuc   TypeResult TrailingReturnType;
1061f4a2713aSLionel Sambuc   if (Tok.is(tok::l_paren)) {
1062f4a2713aSLionel Sambuc     ParseScope PrototypeScope(this,
1063f4a2713aSLionel Sambuc                               Scope::FunctionPrototypeScope |
1064f4a2713aSLionel Sambuc                               Scope::FunctionDeclarationScope |
1065f4a2713aSLionel Sambuc                               Scope::DeclScope);
1066f4a2713aSLionel Sambuc 
1067f4a2713aSLionel Sambuc     SourceLocation DeclEndLoc;
1068f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_paren);
1069f4a2713aSLionel Sambuc     T.consumeOpen();
1070f4a2713aSLionel Sambuc     SourceLocation LParenLoc = T.getOpenLocation();
1071f4a2713aSLionel Sambuc 
1072f4a2713aSLionel Sambuc     // Parse parameter-declaration-clause.
1073f4a2713aSLionel Sambuc     ParsedAttributes Attr(AttrFactory);
1074f4a2713aSLionel Sambuc     SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
1075f4a2713aSLionel Sambuc     SourceLocation EllipsisLoc;
1076f4a2713aSLionel Sambuc 
1077f4a2713aSLionel Sambuc     if (Tok.isNot(tok::r_paren)) {
1078f4a2713aSLionel Sambuc       Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth);
1079f4a2713aSLionel Sambuc       ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc);
1080f4a2713aSLionel Sambuc       // For a generic lambda, each 'auto' within the parameter declaration
1081f4a2713aSLionel Sambuc       // clause creates a template type parameter, so increment the depth.
1082f4a2713aSLionel Sambuc       if (Actions.getCurGenericLambda())
1083f4a2713aSLionel Sambuc         ++CurTemplateDepthTracker;
1084f4a2713aSLionel Sambuc     }
1085f4a2713aSLionel Sambuc     T.consumeClose();
1086f4a2713aSLionel Sambuc     SourceLocation RParenLoc = T.getCloseLocation();
1087f4a2713aSLionel Sambuc     DeclEndLoc = RParenLoc;
1088f4a2713aSLionel Sambuc 
1089*0a6a1f1dSLionel Sambuc     // GNU-style attributes must be parsed before the mutable specifier to be
1090*0a6a1f1dSLionel Sambuc     // compatible with GCC.
1091*0a6a1f1dSLionel Sambuc     MaybeParseGNUAttributes(Attr, &DeclEndLoc);
1092*0a6a1f1dSLionel Sambuc 
1093f4a2713aSLionel Sambuc     // Parse 'mutable'[opt].
1094f4a2713aSLionel Sambuc     SourceLocation MutableLoc;
1095*0a6a1f1dSLionel Sambuc     if (TryConsumeToken(tok::kw_mutable, MutableLoc))
1096f4a2713aSLionel Sambuc       DeclEndLoc = MutableLoc;
1097f4a2713aSLionel Sambuc 
1098f4a2713aSLionel Sambuc     // Parse exception-specification[opt].
1099f4a2713aSLionel Sambuc     ExceptionSpecificationType ESpecType = EST_None;
1100f4a2713aSLionel Sambuc     SourceRange ESpecRange;
1101f4a2713aSLionel Sambuc     SmallVector<ParsedType, 2> DynamicExceptions;
1102f4a2713aSLionel Sambuc     SmallVector<SourceRange, 2> DynamicExceptionRanges;
1103f4a2713aSLionel Sambuc     ExprResult NoexceptExpr;
1104*0a6a1f1dSLionel Sambuc     CachedTokens *ExceptionSpecTokens;
1105*0a6a1f1dSLionel Sambuc     ESpecType = tryParseExceptionSpecification(/*Delayed=*/false,
1106*0a6a1f1dSLionel Sambuc                                                ESpecRange,
1107f4a2713aSLionel Sambuc                                                DynamicExceptions,
1108f4a2713aSLionel Sambuc                                                DynamicExceptionRanges,
1109*0a6a1f1dSLionel Sambuc                                                NoexceptExpr,
1110*0a6a1f1dSLionel Sambuc                                                ExceptionSpecTokens);
1111f4a2713aSLionel Sambuc 
1112f4a2713aSLionel Sambuc     if (ESpecType != EST_None)
1113f4a2713aSLionel Sambuc       DeclEndLoc = ESpecRange.getEnd();
1114f4a2713aSLionel Sambuc 
1115f4a2713aSLionel Sambuc     // Parse attribute-specifier[opt].
1116f4a2713aSLionel Sambuc     MaybeParseCXX11Attributes(Attr, &DeclEndLoc);
1117f4a2713aSLionel Sambuc 
1118f4a2713aSLionel Sambuc     SourceLocation FunLocalRangeEnd = DeclEndLoc;
1119f4a2713aSLionel Sambuc 
1120f4a2713aSLionel Sambuc     // Parse trailing-return-type[opt].
1121f4a2713aSLionel Sambuc     if (Tok.is(tok::arrow)) {
1122f4a2713aSLionel Sambuc       FunLocalRangeEnd = Tok.getLocation();
1123f4a2713aSLionel Sambuc       SourceRange Range;
1124f4a2713aSLionel Sambuc       TrailingReturnType = ParseTrailingReturnType(Range);
1125f4a2713aSLionel Sambuc       if (Range.getEnd().isValid())
1126f4a2713aSLionel Sambuc         DeclEndLoc = Range.getEnd();
1127f4a2713aSLionel Sambuc     }
1128f4a2713aSLionel Sambuc 
1129f4a2713aSLionel Sambuc     PrototypeScope.Exit();
1130f4a2713aSLionel Sambuc 
1131f4a2713aSLionel Sambuc     SourceLocation NoLoc;
1132f4a2713aSLionel Sambuc     D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
1133f4a2713aSLionel Sambuc                                            /*isAmbiguous=*/false,
1134f4a2713aSLionel Sambuc                                            LParenLoc,
1135f4a2713aSLionel Sambuc                                            ParamInfo.data(), ParamInfo.size(),
1136f4a2713aSLionel Sambuc                                            EllipsisLoc, RParenLoc,
1137f4a2713aSLionel Sambuc                                            DS.getTypeQualifiers(),
1138f4a2713aSLionel Sambuc                                            /*RefQualifierIsLValueRef=*/true,
1139f4a2713aSLionel Sambuc                                            /*RefQualifierLoc=*/NoLoc,
1140f4a2713aSLionel Sambuc                                            /*ConstQualifierLoc=*/NoLoc,
1141f4a2713aSLionel Sambuc                                            /*VolatileQualifierLoc=*/NoLoc,
1142*0a6a1f1dSLionel Sambuc                                            /*RestrictQualifierLoc=*/NoLoc,
1143f4a2713aSLionel Sambuc                                            MutableLoc,
1144f4a2713aSLionel Sambuc                                            ESpecType, ESpecRange.getBegin(),
1145f4a2713aSLionel Sambuc                                            DynamicExceptions.data(),
1146f4a2713aSLionel Sambuc                                            DynamicExceptionRanges.data(),
1147f4a2713aSLionel Sambuc                                            DynamicExceptions.size(),
1148f4a2713aSLionel Sambuc                                            NoexceptExpr.isUsable() ?
1149*0a6a1f1dSLionel Sambuc                                              NoexceptExpr.get() : nullptr,
1150*0a6a1f1dSLionel Sambuc                                            /*ExceptionSpecTokens*/nullptr,
1151f4a2713aSLionel Sambuc                                            LParenLoc, FunLocalRangeEnd, D,
1152f4a2713aSLionel Sambuc                                            TrailingReturnType),
1153f4a2713aSLionel Sambuc                   Attr, DeclEndLoc);
1154*0a6a1f1dSLionel Sambuc   } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow) ||
1155*0a6a1f1dSLionel Sambuc              Tok.is(tok::kw___attribute) ||
1156*0a6a1f1dSLionel Sambuc              (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) {
1157*0a6a1f1dSLionel Sambuc     // It's common to forget that one needs '()' before 'mutable', an attribute
1158*0a6a1f1dSLionel Sambuc     // specifier, or the result type. Deal with this.
1159*0a6a1f1dSLionel Sambuc     unsigned TokKind = 0;
1160*0a6a1f1dSLionel Sambuc     switch (Tok.getKind()) {
1161*0a6a1f1dSLionel Sambuc     case tok::kw_mutable: TokKind = 0; break;
1162*0a6a1f1dSLionel Sambuc     case tok::arrow: TokKind = 1; break;
1163*0a6a1f1dSLionel Sambuc     case tok::kw___attribute:
1164*0a6a1f1dSLionel Sambuc     case tok::l_square: TokKind = 2; break;
1165*0a6a1f1dSLionel Sambuc     default: llvm_unreachable("Unknown token kind");
1166*0a6a1f1dSLionel Sambuc     }
1167*0a6a1f1dSLionel Sambuc 
1168f4a2713aSLionel Sambuc     Diag(Tok, diag::err_lambda_missing_parens)
1169*0a6a1f1dSLionel Sambuc       << TokKind
1170f4a2713aSLionel Sambuc       << FixItHint::CreateInsertion(Tok.getLocation(), "() ");
1171f4a2713aSLionel Sambuc     SourceLocation DeclLoc = Tok.getLocation();
1172f4a2713aSLionel Sambuc     SourceLocation DeclEndLoc = DeclLoc;
1173f4a2713aSLionel Sambuc 
1174*0a6a1f1dSLionel Sambuc     // GNU-style attributes must be parsed before the mutable specifier to be
1175*0a6a1f1dSLionel Sambuc     // compatible with GCC.
1176*0a6a1f1dSLionel Sambuc     ParsedAttributes Attr(AttrFactory);
1177*0a6a1f1dSLionel Sambuc     MaybeParseGNUAttributes(Attr, &DeclEndLoc);
1178*0a6a1f1dSLionel Sambuc 
1179f4a2713aSLionel Sambuc     // Parse 'mutable', if it's there.
1180f4a2713aSLionel Sambuc     SourceLocation MutableLoc;
1181f4a2713aSLionel Sambuc     if (Tok.is(tok::kw_mutable)) {
1182f4a2713aSLionel Sambuc       MutableLoc = ConsumeToken();
1183f4a2713aSLionel Sambuc       DeclEndLoc = MutableLoc;
1184f4a2713aSLionel Sambuc     }
1185f4a2713aSLionel Sambuc 
1186*0a6a1f1dSLionel Sambuc     // Parse attribute-specifier[opt].
1187*0a6a1f1dSLionel Sambuc     MaybeParseCXX11Attributes(Attr, &DeclEndLoc);
1188*0a6a1f1dSLionel Sambuc 
1189f4a2713aSLionel Sambuc     // Parse the return type, if there is one.
1190f4a2713aSLionel Sambuc     if (Tok.is(tok::arrow)) {
1191f4a2713aSLionel Sambuc       SourceRange Range;
1192f4a2713aSLionel Sambuc       TrailingReturnType = ParseTrailingReturnType(Range);
1193f4a2713aSLionel Sambuc       if (Range.getEnd().isValid())
1194f4a2713aSLionel Sambuc         DeclEndLoc = Range.getEnd();
1195f4a2713aSLionel Sambuc     }
1196f4a2713aSLionel Sambuc 
1197f4a2713aSLionel Sambuc     SourceLocation NoLoc;
1198f4a2713aSLionel Sambuc     D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
1199f4a2713aSLionel Sambuc                                                /*isAmbiguous=*/false,
1200f4a2713aSLionel Sambuc                                                /*LParenLoc=*/NoLoc,
1201*0a6a1f1dSLionel Sambuc                                                /*Params=*/nullptr,
1202f4a2713aSLionel Sambuc                                                /*NumParams=*/0,
1203f4a2713aSLionel Sambuc                                                /*EllipsisLoc=*/NoLoc,
1204f4a2713aSLionel Sambuc                                                /*RParenLoc=*/NoLoc,
1205f4a2713aSLionel Sambuc                                                /*TypeQuals=*/0,
1206f4a2713aSLionel Sambuc                                                /*RefQualifierIsLValueRef=*/true,
1207f4a2713aSLionel Sambuc                                                /*RefQualifierLoc=*/NoLoc,
1208f4a2713aSLionel Sambuc                                                /*ConstQualifierLoc=*/NoLoc,
1209f4a2713aSLionel Sambuc                                                /*VolatileQualifierLoc=*/NoLoc,
1210*0a6a1f1dSLionel Sambuc                                                /*RestrictQualifierLoc=*/NoLoc,
1211f4a2713aSLionel Sambuc                                                MutableLoc,
1212f4a2713aSLionel Sambuc                                                EST_None,
1213f4a2713aSLionel Sambuc                                                /*ESpecLoc=*/NoLoc,
1214*0a6a1f1dSLionel Sambuc                                                /*Exceptions=*/nullptr,
1215*0a6a1f1dSLionel Sambuc                                                /*ExceptionRanges=*/nullptr,
1216f4a2713aSLionel Sambuc                                                /*NumExceptions=*/0,
1217*0a6a1f1dSLionel Sambuc                                                /*NoexceptExpr=*/nullptr,
1218*0a6a1f1dSLionel Sambuc                                                /*ExceptionSpecTokens=*/nullptr,
1219f4a2713aSLionel Sambuc                                                DeclLoc, DeclEndLoc, D,
1220f4a2713aSLionel Sambuc                                                TrailingReturnType),
1221f4a2713aSLionel Sambuc                   Attr, DeclEndLoc);
1222f4a2713aSLionel Sambuc   }
1223f4a2713aSLionel Sambuc 
1224f4a2713aSLionel Sambuc 
1225f4a2713aSLionel Sambuc   // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
1226f4a2713aSLionel Sambuc   // it.
1227f4a2713aSLionel Sambuc   unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope;
1228f4a2713aSLionel Sambuc   ParseScope BodyScope(this, ScopeFlags);
1229f4a2713aSLionel Sambuc 
1230f4a2713aSLionel Sambuc   Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope());
1231f4a2713aSLionel Sambuc 
1232f4a2713aSLionel Sambuc   // Parse compound-statement.
1233f4a2713aSLionel Sambuc   if (!Tok.is(tok::l_brace)) {
1234f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_lambda_body);
1235f4a2713aSLionel Sambuc     Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
1236f4a2713aSLionel Sambuc     return ExprError();
1237f4a2713aSLionel Sambuc   }
1238f4a2713aSLionel Sambuc 
1239f4a2713aSLionel Sambuc   StmtResult Stmt(ParseCompoundStatementBody());
1240f4a2713aSLionel Sambuc   BodyScope.Exit();
1241f4a2713aSLionel Sambuc 
1242*0a6a1f1dSLionel Sambuc   if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid())
1243*0a6a1f1dSLionel Sambuc     return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get(), getCurScope());
1244f4a2713aSLionel Sambuc 
1245f4a2713aSLionel Sambuc   Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
1246f4a2713aSLionel Sambuc   return ExprError();
1247f4a2713aSLionel Sambuc }
1248f4a2713aSLionel Sambuc 
1249f4a2713aSLionel Sambuc /// ParseCXXCasts - This handles the various ways to cast expressions to another
1250f4a2713aSLionel Sambuc /// type.
1251f4a2713aSLionel Sambuc ///
1252f4a2713aSLionel Sambuc ///       postfix-expression: [C++ 5.2p1]
1253f4a2713aSLionel Sambuc ///         'dynamic_cast' '<' type-name '>' '(' expression ')'
1254f4a2713aSLionel Sambuc ///         'static_cast' '<' type-name '>' '(' expression ')'
1255f4a2713aSLionel Sambuc ///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
1256f4a2713aSLionel Sambuc ///         'const_cast' '<' type-name '>' '(' expression ')'
1257f4a2713aSLionel Sambuc ///
ParseCXXCasts()1258f4a2713aSLionel Sambuc ExprResult Parser::ParseCXXCasts() {
1259f4a2713aSLionel Sambuc   tok::TokenKind Kind = Tok.getKind();
1260*0a6a1f1dSLionel Sambuc   const char *CastName = nullptr; // For error messages
1261f4a2713aSLionel Sambuc 
1262f4a2713aSLionel Sambuc   switch (Kind) {
1263f4a2713aSLionel Sambuc   default: llvm_unreachable("Unknown C++ cast!");
1264f4a2713aSLionel Sambuc   case tok::kw_const_cast:       CastName = "const_cast";       break;
1265f4a2713aSLionel Sambuc   case tok::kw_dynamic_cast:     CastName = "dynamic_cast";     break;
1266f4a2713aSLionel Sambuc   case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
1267f4a2713aSLionel Sambuc   case tok::kw_static_cast:      CastName = "static_cast";      break;
1268f4a2713aSLionel Sambuc   }
1269f4a2713aSLionel Sambuc 
1270f4a2713aSLionel Sambuc   SourceLocation OpLoc = ConsumeToken();
1271f4a2713aSLionel Sambuc   SourceLocation LAngleBracketLoc = Tok.getLocation();
1272f4a2713aSLionel Sambuc 
1273f4a2713aSLionel Sambuc   // Check for "<::" which is parsed as "[:".  If found, fix token stream,
1274f4a2713aSLionel Sambuc   // diagnose error, suggest fix, and recover parsing.
1275f4a2713aSLionel Sambuc   if (Tok.is(tok::l_square) && Tok.getLength() == 2) {
1276f4a2713aSLionel Sambuc     Token Next = NextToken();
1277f4a2713aSLionel Sambuc     if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next))
1278f4a2713aSLionel Sambuc       FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true);
1279f4a2713aSLionel Sambuc   }
1280f4a2713aSLionel Sambuc 
1281f4a2713aSLionel Sambuc   if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
1282f4a2713aSLionel Sambuc     return ExprError();
1283f4a2713aSLionel Sambuc 
1284f4a2713aSLionel Sambuc   // Parse the common declaration-specifiers piece.
1285f4a2713aSLionel Sambuc   DeclSpec DS(AttrFactory);
1286f4a2713aSLionel Sambuc   ParseSpecifierQualifierList(DS);
1287f4a2713aSLionel Sambuc 
1288f4a2713aSLionel Sambuc   // Parse the abstract-declarator, if present.
1289f4a2713aSLionel Sambuc   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1290f4a2713aSLionel Sambuc   ParseDeclarator(DeclaratorInfo);
1291f4a2713aSLionel Sambuc 
1292f4a2713aSLionel Sambuc   SourceLocation RAngleBracketLoc = Tok.getLocation();
1293f4a2713aSLionel Sambuc 
1294*0a6a1f1dSLionel Sambuc   if (ExpectAndConsume(tok::greater))
1295*0a6a1f1dSLionel Sambuc     return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less);
1296f4a2713aSLionel Sambuc 
1297f4a2713aSLionel Sambuc   SourceLocation LParenLoc, RParenLoc;
1298f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
1299f4a2713aSLionel Sambuc 
1300f4a2713aSLionel Sambuc   if (T.expectAndConsume(diag::err_expected_lparen_after, CastName))
1301f4a2713aSLionel Sambuc     return ExprError();
1302f4a2713aSLionel Sambuc 
1303f4a2713aSLionel Sambuc   ExprResult Result = ParseExpression();
1304f4a2713aSLionel Sambuc 
1305f4a2713aSLionel Sambuc   // Match the ')'.
1306f4a2713aSLionel Sambuc   T.consumeClose();
1307f4a2713aSLionel Sambuc 
1308f4a2713aSLionel Sambuc   if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType())
1309f4a2713aSLionel Sambuc     Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
1310f4a2713aSLionel Sambuc                                        LAngleBracketLoc, DeclaratorInfo,
1311f4a2713aSLionel Sambuc                                        RAngleBracketLoc,
1312*0a6a1f1dSLionel Sambuc                                        T.getOpenLocation(), Result.get(),
1313f4a2713aSLionel Sambuc                                        T.getCloseLocation());
1314f4a2713aSLionel Sambuc 
1315f4a2713aSLionel Sambuc   return Result;
1316f4a2713aSLionel Sambuc }
1317f4a2713aSLionel Sambuc 
1318f4a2713aSLionel Sambuc /// ParseCXXTypeid - This handles the C++ typeid expression.
1319f4a2713aSLionel Sambuc ///
1320f4a2713aSLionel Sambuc ///       postfix-expression: [C++ 5.2p1]
1321f4a2713aSLionel Sambuc ///         'typeid' '(' expression ')'
1322f4a2713aSLionel Sambuc ///         'typeid' '(' type-id ')'
1323f4a2713aSLionel Sambuc ///
ParseCXXTypeid()1324f4a2713aSLionel Sambuc ExprResult Parser::ParseCXXTypeid() {
1325f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
1326f4a2713aSLionel Sambuc 
1327f4a2713aSLionel Sambuc   SourceLocation OpLoc = ConsumeToken();
1328f4a2713aSLionel Sambuc   SourceLocation LParenLoc, RParenLoc;
1329f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
1330f4a2713aSLionel Sambuc 
1331f4a2713aSLionel Sambuc   // typeid expressions are always parenthesized.
1332f4a2713aSLionel Sambuc   if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid"))
1333f4a2713aSLionel Sambuc     return ExprError();
1334f4a2713aSLionel Sambuc   LParenLoc = T.getOpenLocation();
1335f4a2713aSLionel Sambuc 
1336f4a2713aSLionel Sambuc   ExprResult Result;
1337f4a2713aSLionel Sambuc 
1338f4a2713aSLionel Sambuc   // C++0x [expr.typeid]p3:
1339f4a2713aSLionel Sambuc   //   When typeid is applied to an expression other than an lvalue of a
1340f4a2713aSLionel Sambuc   //   polymorphic class type [...] The expression is an unevaluated
1341f4a2713aSLionel Sambuc   //   operand (Clause 5).
1342f4a2713aSLionel Sambuc   //
1343f4a2713aSLionel Sambuc   // Note that we can't tell whether the expression is an lvalue of a
1344f4a2713aSLionel Sambuc   // polymorphic class type until after we've parsed the expression; we
1345f4a2713aSLionel Sambuc   // speculatively assume the subexpression is unevaluated, and fix it up
1346f4a2713aSLionel Sambuc   // later.
1347f4a2713aSLionel Sambuc   //
1348f4a2713aSLionel Sambuc   // We enter the unevaluated context before trying to determine whether we
1349f4a2713aSLionel Sambuc   // have a type-id, because the tentative parse logic will try to resolve
1350f4a2713aSLionel Sambuc   // names, and must treat them as unevaluated.
1351f4a2713aSLionel Sambuc   EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
1352f4a2713aSLionel Sambuc                                                Sema::ReuseLambdaContextDecl);
1353f4a2713aSLionel Sambuc 
1354f4a2713aSLionel Sambuc   if (isTypeIdInParens()) {
1355f4a2713aSLionel Sambuc     TypeResult Ty = ParseTypeName();
1356f4a2713aSLionel Sambuc 
1357f4a2713aSLionel Sambuc     // Match the ')'.
1358f4a2713aSLionel Sambuc     T.consumeClose();
1359f4a2713aSLionel Sambuc     RParenLoc = T.getCloseLocation();
1360f4a2713aSLionel Sambuc     if (Ty.isInvalid() || RParenLoc.isInvalid())
1361f4a2713aSLionel Sambuc       return ExprError();
1362f4a2713aSLionel Sambuc 
1363f4a2713aSLionel Sambuc     Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
1364f4a2713aSLionel Sambuc                                     Ty.get().getAsOpaquePtr(), RParenLoc);
1365f4a2713aSLionel Sambuc   } else {
1366f4a2713aSLionel Sambuc     Result = ParseExpression();
1367f4a2713aSLionel Sambuc 
1368f4a2713aSLionel Sambuc     // Match the ')'.
1369f4a2713aSLionel Sambuc     if (Result.isInvalid())
1370f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
1371f4a2713aSLionel Sambuc     else {
1372f4a2713aSLionel Sambuc       T.consumeClose();
1373f4a2713aSLionel Sambuc       RParenLoc = T.getCloseLocation();
1374f4a2713aSLionel Sambuc       if (RParenLoc.isInvalid())
1375f4a2713aSLionel Sambuc         return ExprError();
1376f4a2713aSLionel Sambuc 
1377f4a2713aSLionel Sambuc       Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
1378*0a6a1f1dSLionel Sambuc                                       Result.get(), RParenLoc);
1379f4a2713aSLionel Sambuc     }
1380f4a2713aSLionel Sambuc   }
1381f4a2713aSLionel Sambuc 
1382f4a2713aSLionel Sambuc   return Result;
1383f4a2713aSLionel Sambuc }
1384f4a2713aSLionel Sambuc 
1385f4a2713aSLionel Sambuc /// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.
1386f4a2713aSLionel Sambuc ///
1387f4a2713aSLionel Sambuc ///         '__uuidof' '(' expression ')'
1388f4a2713aSLionel Sambuc ///         '__uuidof' '(' type-id ')'
1389f4a2713aSLionel Sambuc ///
ParseCXXUuidof()1390f4a2713aSLionel Sambuc ExprResult Parser::ParseCXXUuidof() {
1391f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");
1392f4a2713aSLionel Sambuc 
1393f4a2713aSLionel Sambuc   SourceLocation OpLoc = ConsumeToken();
1394f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
1395f4a2713aSLionel Sambuc 
1396f4a2713aSLionel Sambuc   // __uuidof expressions are always parenthesized.
1397f4a2713aSLionel Sambuc   if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof"))
1398f4a2713aSLionel Sambuc     return ExprError();
1399f4a2713aSLionel Sambuc 
1400f4a2713aSLionel Sambuc   ExprResult Result;
1401f4a2713aSLionel Sambuc 
1402f4a2713aSLionel Sambuc   if (isTypeIdInParens()) {
1403f4a2713aSLionel Sambuc     TypeResult Ty = ParseTypeName();
1404f4a2713aSLionel Sambuc 
1405f4a2713aSLionel Sambuc     // Match the ')'.
1406f4a2713aSLionel Sambuc     T.consumeClose();
1407f4a2713aSLionel Sambuc 
1408f4a2713aSLionel Sambuc     if (Ty.isInvalid())
1409f4a2713aSLionel Sambuc       return ExprError();
1410f4a2713aSLionel Sambuc 
1411f4a2713aSLionel Sambuc     Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true,
1412f4a2713aSLionel Sambuc                                     Ty.get().getAsOpaquePtr(),
1413f4a2713aSLionel Sambuc                                     T.getCloseLocation());
1414f4a2713aSLionel Sambuc   } else {
1415f4a2713aSLionel Sambuc     EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
1416f4a2713aSLionel Sambuc     Result = ParseExpression();
1417f4a2713aSLionel Sambuc 
1418f4a2713aSLionel Sambuc     // Match the ')'.
1419f4a2713aSLionel Sambuc     if (Result.isInvalid())
1420f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
1421f4a2713aSLionel Sambuc     else {
1422f4a2713aSLionel Sambuc       T.consumeClose();
1423f4a2713aSLionel Sambuc 
1424f4a2713aSLionel Sambuc       Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(),
1425f4a2713aSLionel Sambuc                                       /*isType=*/false,
1426*0a6a1f1dSLionel Sambuc                                       Result.get(), T.getCloseLocation());
1427f4a2713aSLionel Sambuc     }
1428f4a2713aSLionel Sambuc   }
1429f4a2713aSLionel Sambuc 
1430f4a2713aSLionel Sambuc   return Result;
1431f4a2713aSLionel Sambuc }
1432f4a2713aSLionel Sambuc 
1433f4a2713aSLionel Sambuc /// \brief Parse a C++ pseudo-destructor expression after the base,
1434f4a2713aSLionel Sambuc /// . or -> operator, and nested-name-specifier have already been
1435f4a2713aSLionel Sambuc /// parsed.
1436f4a2713aSLionel Sambuc ///
1437f4a2713aSLionel Sambuc ///       postfix-expression: [C++ 5.2]
1438f4a2713aSLionel Sambuc ///         postfix-expression . pseudo-destructor-name
1439f4a2713aSLionel Sambuc ///         postfix-expression -> pseudo-destructor-name
1440f4a2713aSLionel Sambuc ///
1441f4a2713aSLionel Sambuc ///       pseudo-destructor-name:
1442f4a2713aSLionel Sambuc ///         ::[opt] nested-name-specifier[opt] type-name :: ~type-name
1443f4a2713aSLionel Sambuc ///         ::[opt] nested-name-specifier template simple-template-id ::
1444f4a2713aSLionel Sambuc ///                 ~type-name
1445f4a2713aSLionel Sambuc ///         ::[opt] nested-name-specifier[opt] ~type-name
1446f4a2713aSLionel Sambuc ///
1447f4a2713aSLionel Sambuc ExprResult
ParseCXXPseudoDestructor(Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,CXXScopeSpec & SS,ParsedType ObjectType)1448*0a6a1f1dSLionel Sambuc Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
1449f4a2713aSLionel Sambuc                                  tok::TokenKind OpKind,
1450f4a2713aSLionel Sambuc                                  CXXScopeSpec &SS,
1451f4a2713aSLionel Sambuc                                  ParsedType ObjectType) {
1452f4a2713aSLionel Sambuc   // We're parsing either a pseudo-destructor-name or a dependent
1453f4a2713aSLionel Sambuc   // member access that has the same form as a
1454f4a2713aSLionel Sambuc   // pseudo-destructor-name. We parse both in the same way and let
1455f4a2713aSLionel Sambuc   // the action model sort them out.
1456f4a2713aSLionel Sambuc   //
1457f4a2713aSLionel Sambuc   // Note that the ::[opt] nested-name-specifier[opt] has already
1458f4a2713aSLionel Sambuc   // been parsed, and if there was a simple-template-id, it has
1459f4a2713aSLionel Sambuc   // been coalesced into a template-id annotation token.
1460f4a2713aSLionel Sambuc   UnqualifiedId FirstTypeName;
1461f4a2713aSLionel Sambuc   SourceLocation CCLoc;
1462f4a2713aSLionel Sambuc   if (Tok.is(tok::identifier)) {
1463f4a2713aSLionel Sambuc     FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1464f4a2713aSLionel Sambuc     ConsumeToken();
1465f4a2713aSLionel Sambuc     assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
1466f4a2713aSLionel Sambuc     CCLoc = ConsumeToken();
1467f4a2713aSLionel Sambuc   } else if (Tok.is(tok::annot_template_id)) {
1468f4a2713aSLionel Sambuc     // FIXME: retrieve TemplateKWLoc from template-id annotation and
1469f4a2713aSLionel Sambuc     // store it in the pseudo-dtor node (to be used when instantiating it).
1470f4a2713aSLionel Sambuc     FirstTypeName.setTemplateId(
1471f4a2713aSLionel Sambuc                               (TemplateIdAnnotation *)Tok.getAnnotationValue());
1472f4a2713aSLionel Sambuc     ConsumeToken();
1473f4a2713aSLionel Sambuc     assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
1474f4a2713aSLionel Sambuc     CCLoc = ConsumeToken();
1475f4a2713aSLionel Sambuc   } else {
1476*0a6a1f1dSLionel Sambuc     FirstTypeName.setIdentifier(nullptr, SourceLocation());
1477f4a2713aSLionel Sambuc   }
1478f4a2713aSLionel Sambuc 
1479f4a2713aSLionel Sambuc   // Parse the tilde.
1480f4a2713aSLionel Sambuc   assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");
1481f4a2713aSLionel Sambuc   SourceLocation TildeLoc = ConsumeToken();
1482f4a2713aSLionel Sambuc 
1483f4a2713aSLionel Sambuc   if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid() && SS.isEmpty()) {
1484f4a2713aSLionel Sambuc     DeclSpec DS(AttrFactory);
1485f4a2713aSLionel Sambuc     ParseDecltypeSpecifier(DS);
1486f4a2713aSLionel Sambuc     if (DS.getTypeSpecType() == TST_error)
1487f4a2713aSLionel Sambuc       return ExprError();
1488f4a2713aSLionel Sambuc     return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc,
1489f4a2713aSLionel Sambuc                                              OpKind, TildeLoc, DS,
1490f4a2713aSLionel Sambuc                                              Tok.is(tok::l_paren));
1491f4a2713aSLionel Sambuc   }
1492f4a2713aSLionel Sambuc 
1493f4a2713aSLionel Sambuc   if (!Tok.is(tok::identifier)) {
1494f4a2713aSLionel Sambuc     Diag(Tok, diag::err_destructor_tilde_identifier);
1495f4a2713aSLionel Sambuc     return ExprError();
1496f4a2713aSLionel Sambuc   }
1497f4a2713aSLionel Sambuc 
1498f4a2713aSLionel Sambuc   // Parse the second type.
1499f4a2713aSLionel Sambuc   UnqualifiedId SecondTypeName;
1500f4a2713aSLionel Sambuc   IdentifierInfo *Name = Tok.getIdentifierInfo();
1501f4a2713aSLionel Sambuc   SourceLocation NameLoc = ConsumeToken();
1502f4a2713aSLionel Sambuc   SecondTypeName.setIdentifier(Name, NameLoc);
1503f4a2713aSLionel Sambuc 
1504f4a2713aSLionel Sambuc   // If there is a '<', the second type name is a template-id. Parse
1505f4a2713aSLionel Sambuc   // it as such.
1506f4a2713aSLionel Sambuc   if (Tok.is(tok::less) &&
1507f4a2713aSLionel Sambuc       ParseUnqualifiedIdTemplateId(SS, SourceLocation(),
1508f4a2713aSLionel Sambuc                                    Name, NameLoc,
1509f4a2713aSLionel Sambuc                                    false, ObjectType, SecondTypeName,
1510f4a2713aSLionel Sambuc                                    /*AssumeTemplateName=*/true))
1511f4a2713aSLionel Sambuc     return ExprError();
1512f4a2713aSLionel Sambuc 
1513f4a2713aSLionel Sambuc   return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base,
1514f4a2713aSLionel Sambuc                                            OpLoc, OpKind,
1515f4a2713aSLionel Sambuc                                            SS, FirstTypeName, CCLoc,
1516f4a2713aSLionel Sambuc                                            TildeLoc, SecondTypeName,
1517f4a2713aSLionel Sambuc                                            Tok.is(tok::l_paren));
1518f4a2713aSLionel Sambuc }
1519f4a2713aSLionel Sambuc 
1520f4a2713aSLionel Sambuc /// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
1521f4a2713aSLionel Sambuc ///
1522f4a2713aSLionel Sambuc ///       boolean-literal: [C++ 2.13.5]
1523f4a2713aSLionel Sambuc ///         'true'
1524f4a2713aSLionel Sambuc ///         'false'
ParseCXXBoolLiteral()1525f4a2713aSLionel Sambuc ExprResult Parser::ParseCXXBoolLiteral() {
1526f4a2713aSLionel Sambuc   tok::TokenKind Kind = Tok.getKind();
1527f4a2713aSLionel Sambuc   return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
1528f4a2713aSLionel Sambuc }
1529f4a2713aSLionel Sambuc 
1530f4a2713aSLionel Sambuc /// ParseThrowExpression - This handles the C++ throw expression.
1531f4a2713aSLionel Sambuc ///
1532f4a2713aSLionel Sambuc ///       throw-expression: [C++ 15]
1533f4a2713aSLionel Sambuc ///         'throw' assignment-expression[opt]
ParseThrowExpression()1534f4a2713aSLionel Sambuc ExprResult Parser::ParseThrowExpression() {
1535f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw_throw) && "Not throw!");
1536f4a2713aSLionel Sambuc   SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
1537f4a2713aSLionel Sambuc 
1538f4a2713aSLionel Sambuc   // If the current token isn't the start of an assignment-expression,
1539f4a2713aSLionel Sambuc   // then the expression is not present.  This handles things like:
1540f4a2713aSLionel Sambuc   //   "C ? throw : (void)42", which is crazy but legal.
1541f4a2713aSLionel Sambuc   switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
1542f4a2713aSLionel Sambuc   case tok::semi:
1543f4a2713aSLionel Sambuc   case tok::r_paren:
1544f4a2713aSLionel Sambuc   case tok::r_square:
1545f4a2713aSLionel Sambuc   case tok::r_brace:
1546f4a2713aSLionel Sambuc   case tok::colon:
1547f4a2713aSLionel Sambuc   case tok::comma:
1548*0a6a1f1dSLionel Sambuc     return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, nullptr);
1549f4a2713aSLionel Sambuc 
1550f4a2713aSLionel Sambuc   default:
1551f4a2713aSLionel Sambuc     ExprResult Expr(ParseAssignmentExpression());
1552f4a2713aSLionel Sambuc     if (Expr.isInvalid()) return Expr;
1553*0a6a1f1dSLionel Sambuc     return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.get());
1554f4a2713aSLionel Sambuc   }
1555f4a2713aSLionel Sambuc }
1556f4a2713aSLionel Sambuc 
1557f4a2713aSLionel Sambuc /// ParseCXXThis - This handles the C++ 'this' pointer.
1558f4a2713aSLionel Sambuc ///
1559f4a2713aSLionel Sambuc /// C++ 9.3.2: In the body of a non-static member function, the keyword this is
1560f4a2713aSLionel Sambuc /// a non-lvalue expression whose value is the address of the object for which
1561f4a2713aSLionel Sambuc /// the function is called.
ParseCXXThis()1562f4a2713aSLionel Sambuc ExprResult Parser::ParseCXXThis() {
1563f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw_this) && "Not 'this'!");
1564f4a2713aSLionel Sambuc   SourceLocation ThisLoc = ConsumeToken();
1565f4a2713aSLionel Sambuc   return Actions.ActOnCXXThis(ThisLoc);
1566f4a2713aSLionel Sambuc }
1567f4a2713aSLionel Sambuc 
1568f4a2713aSLionel Sambuc /// ParseCXXTypeConstructExpression - Parse construction of a specified type.
1569f4a2713aSLionel Sambuc /// Can be interpreted either as function-style casting ("int(x)")
1570f4a2713aSLionel Sambuc /// or class type construction ("ClassType(x,y,z)")
1571f4a2713aSLionel Sambuc /// or creation of a value-initialized type ("int()").
1572f4a2713aSLionel Sambuc /// See [C++ 5.2.3].
1573f4a2713aSLionel Sambuc ///
1574f4a2713aSLionel Sambuc ///       postfix-expression: [C++ 5.2p1]
1575f4a2713aSLionel Sambuc ///         simple-type-specifier '(' expression-list[opt] ')'
1576f4a2713aSLionel Sambuc /// [C++0x] simple-type-specifier braced-init-list
1577f4a2713aSLionel Sambuc ///         typename-specifier '(' expression-list[opt] ')'
1578f4a2713aSLionel Sambuc /// [C++0x] typename-specifier braced-init-list
1579f4a2713aSLionel Sambuc ///
1580f4a2713aSLionel Sambuc ExprResult
ParseCXXTypeConstructExpression(const DeclSpec & DS)1581f4a2713aSLionel Sambuc Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
1582f4a2713aSLionel Sambuc   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1583f4a2713aSLionel Sambuc   ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
1584f4a2713aSLionel Sambuc 
1585f4a2713aSLionel Sambuc   assert((Tok.is(tok::l_paren) ||
1586f4a2713aSLionel Sambuc           (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)))
1587f4a2713aSLionel Sambuc          && "Expected '(' or '{'!");
1588f4a2713aSLionel Sambuc 
1589f4a2713aSLionel Sambuc   if (Tok.is(tok::l_brace)) {
1590f4a2713aSLionel Sambuc     ExprResult Init = ParseBraceInitializer();
1591f4a2713aSLionel Sambuc     if (Init.isInvalid())
1592f4a2713aSLionel Sambuc       return Init;
1593*0a6a1f1dSLionel Sambuc     Expr *InitList = Init.get();
1594f4a2713aSLionel Sambuc     return Actions.ActOnCXXTypeConstructExpr(TypeRep, SourceLocation(),
1595f4a2713aSLionel Sambuc                                              MultiExprArg(&InitList, 1),
1596f4a2713aSLionel Sambuc                                              SourceLocation());
1597f4a2713aSLionel Sambuc   } else {
1598f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_paren);
1599f4a2713aSLionel Sambuc     T.consumeOpen();
1600f4a2713aSLionel Sambuc 
1601f4a2713aSLionel Sambuc     ExprVector Exprs;
1602f4a2713aSLionel Sambuc     CommaLocsTy CommaLocs;
1603f4a2713aSLionel Sambuc 
1604f4a2713aSLionel Sambuc     if (Tok.isNot(tok::r_paren)) {
1605f4a2713aSLionel Sambuc       if (ParseExpressionList(Exprs, CommaLocs)) {
1606f4a2713aSLionel Sambuc         SkipUntil(tok::r_paren, StopAtSemi);
1607f4a2713aSLionel Sambuc         return ExprError();
1608f4a2713aSLionel Sambuc       }
1609f4a2713aSLionel Sambuc     }
1610f4a2713aSLionel Sambuc 
1611f4a2713aSLionel Sambuc     // Match the ')'.
1612f4a2713aSLionel Sambuc     T.consumeClose();
1613f4a2713aSLionel Sambuc 
1614f4a2713aSLionel Sambuc     // TypeRep could be null, if it references an invalid typedef.
1615f4a2713aSLionel Sambuc     if (!TypeRep)
1616f4a2713aSLionel Sambuc       return ExprError();
1617f4a2713aSLionel Sambuc 
1618f4a2713aSLionel Sambuc     assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
1619f4a2713aSLionel Sambuc            "Unexpected number of commas!");
1620f4a2713aSLionel Sambuc     return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(),
1621f4a2713aSLionel Sambuc                                              Exprs,
1622f4a2713aSLionel Sambuc                                              T.getCloseLocation());
1623f4a2713aSLionel Sambuc   }
1624f4a2713aSLionel Sambuc }
1625f4a2713aSLionel Sambuc 
1626f4a2713aSLionel Sambuc /// ParseCXXCondition - if/switch/while condition expression.
1627f4a2713aSLionel Sambuc ///
1628f4a2713aSLionel Sambuc ///       condition:
1629f4a2713aSLionel Sambuc ///         expression
1630f4a2713aSLionel Sambuc ///         type-specifier-seq declarator '=' assignment-expression
1631f4a2713aSLionel Sambuc /// [C++11] type-specifier-seq declarator '=' initializer-clause
1632f4a2713aSLionel Sambuc /// [C++11] type-specifier-seq declarator braced-init-list
1633f4a2713aSLionel Sambuc /// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
1634f4a2713aSLionel Sambuc ///             '=' assignment-expression
1635f4a2713aSLionel Sambuc ///
1636f4a2713aSLionel Sambuc /// \param ExprOut if the condition was parsed as an expression, the parsed
1637f4a2713aSLionel Sambuc /// expression.
1638f4a2713aSLionel Sambuc ///
1639f4a2713aSLionel Sambuc /// \param DeclOut if the condition was parsed as a declaration, the parsed
1640f4a2713aSLionel Sambuc /// declaration.
1641f4a2713aSLionel Sambuc ///
1642f4a2713aSLionel Sambuc /// \param Loc The location of the start of the statement that requires this
1643f4a2713aSLionel Sambuc /// condition, e.g., the "for" in a for loop.
1644f4a2713aSLionel Sambuc ///
1645f4a2713aSLionel Sambuc /// \param ConvertToBoolean Whether the condition expression should be
1646f4a2713aSLionel Sambuc /// converted to a boolean value.
1647f4a2713aSLionel Sambuc ///
1648f4a2713aSLionel Sambuc /// \returns true if there was a parsing, false otherwise.
ParseCXXCondition(ExprResult & ExprOut,Decl * & DeclOut,SourceLocation Loc,bool ConvertToBoolean)1649f4a2713aSLionel Sambuc bool Parser::ParseCXXCondition(ExprResult &ExprOut,
1650f4a2713aSLionel Sambuc                                Decl *&DeclOut,
1651f4a2713aSLionel Sambuc                                SourceLocation Loc,
1652f4a2713aSLionel Sambuc                                bool ConvertToBoolean) {
1653f4a2713aSLionel Sambuc   if (Tok.is(tok::code_completion)) {
1654f4a2713aSLionel Sambuc     Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
1655f4a2713aSLionel Sambuc     cutOffParsing();
1656f4a2713aSLionel Sambuc     return true;
1657f4a2713aSLionel Sambuc   }
1658f4a2713aSLionel Sambuc 
1659f4a2713aSLionel Sambuc   ParsedAttributesWithRange attrs(AttrFactory);
1660f4a2713aSLionel Sambuc   MaybeParseCXX11Attributes(attrs);
1661f4a2713aSLionel Sambuc 
1662f4a2713aSLionel Sambuc   if (!isCXXConditionDeclaration()) {
1663f4a2713aSLionel Sambuc     ProhibitAttributes(attrs);
1664f4a2713aSLionel Sambuc 
1665f4a2713aSLionel Sambuc     // Parse the expression.
1666f4a2713aSLionel Sambuc     ExprOut = ParseExpression(); // expression
1667*0a6a1f1dSLionel Sambuc     DeclOut = nullptr;
1668f4a2713aSLionel Sambuc     if (ExprOut.isInvalid())
1669f4a2713aSLionel Sambuc       return true;
1670f4a2713aSLionel Sambuc 
1671f4a2713aSLionel Sambuc     // If required, convert to a boolean value.
1672f4a2713aSLionel Sambuc     if (ConvertToBoolean)
1673f4a2713aSLionel Sambuc       ExprOut
1674f4a2713aSLionel Sambuc         = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get());
1675f4a2713aSLionel Sambuc     return ExprOut.isInvalid();
1676f4a2713aSLionel Sambuc   }
1677f4a2713aSLionel Sambuc 
1678f4a2713aSLionel Sambuc   // type-specifier-seq
1679f4a2713aSLionel Sambuc   DeclSpec DS(AttrFactory);
1680f4a2713aSLionel Sambuc   DS.takeAttributesFrom(attrs);
1681f4a2713aSLionel Sambuc   ParseSpecifierQualifierList(DS);
1682f4a2713aSLionel Sambuc 
1683f4a2713aSLionel Sambuc   // declarator
1684f4a2713aSLionel Sambuc   Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
1685f4a2713aSLionel Sambuc   ParseDeclarator(DeclaratorInfo);
1686f4a2713aSLionel Sambuc 
1687f4a2713aSLionel Sambuc   // simple-asm-expr[opt]
1688f4a2713aSLionel Sambuc   if (Tok.is(tok::kw_asm)) {
1689f4a2713aSLionel Sambuc     SourceLocation Loc;
1690f4a2713aSLionel Sambuc     ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1691f4a2713aSLionel Sambuc     if (AsmLabel.isInvalid()) {
1692f4a2713aSLionel Sambuc       SkipUntil(tok::semi, StopAtSemi);
1693f4a2713aSLionel Sambuc       return true;
1694f4a2713aSLionel Sambuc     }
1695*0a6a1f1dSLionel Sambuc     DeclaratorInfo.setAsmLabel(AsmLabel.get());
1696f4a2713aSLionel Sambuc     DeclaratorInfo.SetRangeEnd(Loc);
1697f4a2713aSLionel Sambuc   }
1698f4a2713aSLionel Sambuc 
1699f4a2713aSLionel Sambuc   // If attributes are present, parse them.
1700f4a2713aSLionel Sambuc   MaybeParseGNUAttributes(DeclaratorInfo);
1701f4a2713aSLionel Sambuc 
1702f4a2713aSLionel Sambuc   // Type-check the declaration itself.
1703f4a2713aSLionel Sambuc   DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),
1704f4a2713aSLionel Sambuc                                                         DeclaratorInfo);
1705f4a2713aSLionel Sambuc   DeclOut = Dcl.get();
1706f4a2713aSLionel Sambuc   ExprOut = ExprError();
1707f4a2713aSLionel Sambuc 
1708f4a2713aSLionel Sambuc   // '=' assignment-expression
1709f4a2713aSLionel Sambuc   // If a '==' or '+=' is found, suggest a fixit to '='.
1710f4a2713aSLionel Sambuc   bool CopyInitialization = isTokenEqualOrEqualTypo();
1711f4a2713aSLionel Sambuc   if (CopyInitialization)
1712f4a2713aSLionel Sambuc     ConsumeToken();
1713f4a2713aSLionel Sambuc 
1714f4a2713aSLionel Sambuc   ExprResult InitExpr = ExprError();
1715f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
1716f4a2713aSLionel Sambuc     Diag(Tok.getLocation(),
1717f4a2713aSLionel Sambuc          diag::warn_cxx98_compat_generalized_initializer_lists);
1718f4a2713aSLionel Sambuc     InitExpr = ParseBraceInitializer();
1719f4a2713aSLionel Sambuc   } else if (CopyInitialization) {
1720f4a2713aSLionel Sambuc     InitExpr = ParseAssignmentExpression();
1721f4a2713aSLionel Sambuc   } else if (Tok.is(tok::l_paren)) {
1722f4a2713aSLionel Sambuc     // This was probably an attempt to initialize the variable.
1723f4a2713aSLionel Sambuc     SourceLocation LParen = ConsumeParen(), RParen = LParen;
1724f4a2713aSLionel Sambuc     if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch))
1725f4a2713aSLionel Sambuc       RParen = ConsumeParen();
1726f4a2713aSLionel Sambuc     Diag(DeclOut ? DeclOut->getLocation() : LParen,
1727f4a2713aSLionel Sambuc          diag::err_expected_init_in_condition_lparen)
1728f4a2713aSLionel Sambuc       << SourceRange(LParen, RParen);
1729f4a2713aSLionel Sambuc   } else {
1730f4a2713aSLionel Sambuc     Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(),
1731f4a2713aSLionel Sambuc          diag::err_expected_init_in_condition);
1732f4a2713aSLionel Sambuc   }
1733f4a2713aSLionel Sambuc 
1734f4a2713aSLionel Sambuc   if (!InitExpr.isInvalid())
1735*0a6a1f1dSLionel Sambuc     Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization,
1736f4a2713aSLionel Sambuc                                  DS.containsPlaceholderType());
1737f4a2713aSLionel Sambuc   else
1738f4a2713aSLionel Sambuc     Actions.ActOnInitializerError(DeclOut);
1739f4a2713aSLionel Sambuc 
1740f4a2713aSLionel Sambuc   // FIXME: Build a reference to this declaration? Convert it to bool?
1741f4a2713aSLionel Sambuc   // (This is currently handled by Sema).
1742f4a2713aSLionel Sambuc 
1743f4a2713aSLionel Sambuc   Actions.FinalizeDeclaration(DeclOut);
1744f4a2713aSLionel Sambuc 
1745f4a2713aSLionel Sambuc   return false;
1746f4a2713aSLionel Sambuc }
1747f4a2713aSLionel Sambuc 
1748f4a2713aSLionel Sambuc /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
1749f4a2713aSLionel Sambuc /// This should only be called when the current token is known to be part of
1750f4a2713aSLionel Sambuc /// simple-type-specifier.
1751f4a2713aSLionel Sambuc ///
1752f4a2713aSLionel Sambuc ///       simple-type-specifier:
1753f4a2713aSLionel Sambuc ///         '::'[opt] nested-name-specifier[opt] type-name
1754f4a2713aSLionel Sambuc ///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
1755f4a2713aSLionel Sambuc ///         char
1756f4a2713aSLionel Sambuc ///         wchar_t
1757f4a2713aSLionel Sambuc ///         bool
1758f4a2713aSLionel Sambuc ///         short
1759f4a2713aSLionel Sambuc ///         int
1760f4a2713aSLionel Sambuc ///         long
1761f4a2713aSLionel Sambuc ///         signed
1762f4a2713aSLionel Sambuc ///         unsigned
1763f4a2713aSLionel Sambuc ///         float
1764f4a2713aSLionel Sambuc ///         double
1765f4a2713aSLionel Sambuc ///         void
1766f4a2713aSLionel Sambuc /// [GNU]   typeof-specifier
1767f4a2713aSLionel Sambuc /// [C++0x] auto               [TODO]
1768f4a2713aSLionel Sambuc ///
1769f4a2713aSLionel Sambuc ///       type-name:
1770f4a2713aSLionel Sambuc ///         class-name
1771f4a2713aSLionel Sambuc ///         enum-name
1772f4a2713aSLionel Sambuc ///         typedef-name
1773f4a2713aSLionel Sambuc ///
ParseCXXSimpleTypeSpecifier(DeclSpec & DS)1774f4a2713aSLionel Sambuc void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
1775f4a2713aSLionel Sambuc   DS.SetRangeStart(Tok.getLocation());
1776f4a2713aSLionel Sambuc   const char *PrevSpec;
1777f4a2713aSLionel Sambuc   unsigned DiagID;
1778f4a2713aSLionel Sambuc   SourceLocation Loc = Tok.getLocation();
1779*0a6a1f1dSLionel Sambuc   const clang::PrintingPolicy &Policy =
1780*0a6a1f1dSLionel Sambuc       Actions.getASTContext().getPrintingPolicy();
1781f4a2713aSLionel Sambuc 
1782f4a2713aSLionel Sambuc   switch (Tok.getKind()) {
1783f4a2713aSLionel Sambuc   case tok::identifier:   // foo::bar
1784f4a2713aSLionel Sambuc   case tok::coloncolon:   // ::foo::bar
1785f4a2713aSLionel Sambuc     llvm_unreachable("Annotation token should already be formed!");
1786f4a2713aSLionel Sambuc   default:
1787f4a2713aSLionel Sambuc     llvm_unreachable("Not a simple-type-specifier token!");
1788f4a2713aSLionel Sambuc 
1789f4a2713aSLionel Sambuc   // type-name
1790f4a2713aSLionel Sambuc   case tok::annot_typename: {
1791f4a2713aSLionel Sambuc     if (getTypeAnnotation(Tok))
1792f4a2713aSLionel Sambuc       DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
1793*0a6a1f1dSLionel Sambuc                          getTypeAnnotation(Tok), Policy);
1794f4a2713aSLionel Sambuc     else
1795f4a2713aSLionel Sambuc       DS.SetTypeSpecError();
1796f4a2713aSLionel Sambuc 
1797f4a2713aSLionel Sambuc     DS.SetRangeEnd(Tok.getAnnotationEndLoc());
1798f4a2713aSLionel Sambuc     ConsumeToken();
1799f4a2713aSLionel Sambuc 
1800f4a2713aSLionel Sambuc     // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
1801f4a2713aSLionel Sambuc     // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
1802f4a2713aSLionel Sambuc     // Objective-C interface.  If we don't have Objective-C or a '<', this is
1803f4a2713aSLionel Sambuc     // just a normal reference to a typedef name.
1804f4a2713aSLionel Sambuc     if (Tok.is(tok::less) && getLangOpts().ObjC1)
1805f4a2713aSLionel Sambuc       ParseObjCProtocolQualifiers(DS);
1806f4a2713aSLionel Sambuc 
1807*0a6a1f1dSLionel Sambuc     DS.Finish(Diags, PP, Policy);
1808f4a2713aSLionel Sambuc     return;
1809f4a2713aSLionel Sambuc   }
1810f4a2713aSLionel Sambuc 
1811f4a2713aSLionel Sambuc   // builtin types
1812f4a2713aSLionel Sambuc   case tok::kw_short:
1813*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID, Policy);
1814f4a2713aSLionel Sambuc     break;
1815f4a2713aSLionel Sambuc   case tok::kw_long:
1816*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID, Policy);
1817f4a2713aSLionel Sambuc     break;
1818f4a2713aSLionel Sambuc   case tok::kw___int64:
1819*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, DiagID, Policy);
1820f4a2713aSLionel Sambuc     break;
1821f4a2713aSLionel Sambuc   case tok::kw_signed:
1822f4a2713aSLionel Sambuc     DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
1823f4a2713aSLionel Sambuc     break;
1824f4a2713aSLionel Sambuc   case tok::kw_unsigned:
1825f4a2713aSLionel Sambuc     DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID);
1826f4a2713aSLionel Sambuc     break;
1827f4a2713aSLionel Sambuc   case tok::kw_void:
1828*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID, Policy);
1829f4a2713aSLionel Sambuc     break;
1830f4a2713aSLionel Sambuc   case tok::kw_char:
1831*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID, Policy);
1832f4a2713aSLionel Sambuc     break;
1833f4a2713aSLionel Sambuc   case tok::kw_int:
1834*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID, Policy);
1835f4a2713aSLionel Sambuc     break;
1836f4a2713aSLionel Sambuc   case tok::kw___int128:
1837*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy);
1838f4a2713aSLionel Sambuc     break;
1839f4a2713aSLionel Sambuc   case tok::kw_half:
1840*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID, Policy);
1841f4a2713aSLionel Sambuc     break;
1842f4a2713aSLionel Sambuc   case tok::kw_float:
1843*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID, Policy);
1844f4a2713aSLionel Sambuc     break;
1845f4a2713aSLionel Sambuc   case tok::kw_double:
1846*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy);
1847f4a2713aSLionel Sambuc     break;
1848f4a2713aSLionel Sambuc   case tok::kw_wchar_t:
1849*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);
1850f4a2713aSLionel Sambuc     break;
1851f4a2713aSLionel Sambuc   case tok::kw_char16_t:
1852*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID, Policy);
1853f4a2713aSLionel Sambuc     break;
1854f4a2713aSLionel Sambuc   case tok::kw_char32_t:
1855*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID, Policy);
1856f4a2713aSLionel Sambuc     break;
1857f4a2713aSLionel Sambuc   case tok::kw_bool:
1858*0a6a1f1dSLionel Sambuc     DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy);
1859f4a2713aSLionel Sambuc     break;
1860f4a2713aSLionel Sambuc   case tok::annot_decltype:
1861f4a2713aSLionel Sambuc   case tok::kw_decltype:
1862f4a2713aSLionel Sambuc     DS.SetRangeEnd(ParseDecltypeSpecifier(DS));
1863*0a6a1f1dSLionel Sambuc     return DS.Finish(Diags, PP, Policy);
1864f4a2713aSLionel Sambuc 
1865f4a2713aSLionel Sambuc   // GNU typeof support.
1866f4a2713aSLionel Sambuc   case tok::kw_typeof:
1867f4a2713aSLionel Sambuc     ParseTypeofSpecifier(DS);
1868*0a6a1f1dSLionel Sambuc     DS.Finish(Diags, PP, Policy);
1869f4a2713aSLionel Sambuc     return;
1870f4a2713aSLionel Sambuc   }
1871f4a2713aSLionel Sambuc   if (Tok.is(tok::annot_typename))
1872f4a2713aSLionel Sambuc     DS.SetRangeEnd(Tok.getAnnotationEndLoc());
1873f4a2713aSLionel Sambuc   else
1874f4a2713aSLionel Sambuc     DS.SetRangeEnd(Tok.getLocation());
1875f4a2713aSLionel Sambuc   ConsumeToken();
1876*0a6a1f1dSLionel Sambuc   DS.Finish(Diags, PP, Policy);
1877f4a2713aSLionel Sambuc }
1878f4a2713aSLionel Sambuc 
1879f4a2713aSLionel Sambuc /// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
1880f4a2713aSLionel Sambuc /// [dcl.name]), which is a non-empty sequence of type-specifiers,
1881f4a2713aSLionel Sambuc /// e.g., "const short int". Note that the DeclSpec is *not* finished
1882f4a2713aSLionel Sambuc /// by parsing the type-specifier-seq, because these sequences are
1883f4a2713aSLionel Sambuc /// typically followed by some form of declarator. Returns true and
1884f4a2713aSLionel Sambuc /// emits diagnostics if this is not a type-specifier-seq, false
1885f4a2713aSLionel Sambuc /// otherwise.
1886f4a2713aSLionel Sambuc ///
1887f4a2713aSLionel Sambuc ///   type-specifier-seq: [C++ 8.1]
1888f4a2713aSLionel Sambuc ///     type-specifier type-specifier-seq[opt]
1889f4a2713aSLionel Sambuc ///
ParseCXXTypeSpecifierSeq(DeclSpec & DS)1890f4a2713aSLionel Sambuc bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
1891f4a2713aSLionel Sambuc   ParseSpecifierQualifierList(DS, AS_none, DSC_type_specifier);
1892*0a6a1f1dSLionel Sambuc   DS.Finish(Diags, PP, Actions.getASTContext().getPrintingPolicy());
1893f4a2713aSLionel Sambuc   return false;
1894f4a2713aSLionel Sambuc }
1895f4a2713aSLionel Sambuc 
1896f4a2713aSLionel Sambuc /// \brief Finish parsing a C++ unqualified-id that is a template-id of
1897f4a2713aSLionel Sambuc /// some form.
1898f4a2713aSLionel Sambuc ///
1899f4a2713aSLionel Sambuc /// This routine is invoked when a '<' is encountered after an identifier or
1900f4a2713aSLionel Sambuc /// operator-function-id is parsed by \c ParseUnqualifiedId() to determine
1901f4a2713aSLionel Sambuc /// whether the unqualified-id is actually a template-id. This routine will
1902f4a2713aSLionel Sambuc /// then parse the template arguments and form the appropriate template-id to
1903f4a2713aSLionel Sambuc /// return to the caller.
1904f4a2713aSLionel Sambuc ///
1905f4a2713aSLionel Sambuc /// \param SS the nested-name-specifier that precedes this template-id, if
1906f4a2713aSLionel Sambuc /// we're actually parsing a qualified-id.
1907f4a2713aSLionel Sambuc ///
1908f4a2713aSLionel Sambuc /// \param Name for constructor and destructor names, this is the actual
1909f4a2713aSLionel Sambuc /// identifier that may be a template-name.
1910f4a2713aSLionel Sambuc ///
1911f4a2713aSLionel Sambuc /// \param NameLoc the location of the class-name in a constructor or
1912f4a2713aSLionel Sambuc /// destructor.
1913f4a2713aSLionel Sambuc ///
1914f4a2713aSLionel Sambuc /// \param EnteringContext whether we're entering the scope of the
1915f4a2713aSLionel Sambuc /// nested-name-specifier.
1916f4a2713aSLionel Sambuc ///
1917f4a2713aSLionel Sambuc /// \param ObjectType if this unqualified-id occurs within a member access
1918f4a2713aSLionel Sambuc /// expression, the type of the base object whose member is being accessed.
1919f4a2713aSLionel Sambuc ///
1920f4a2713aSLionel Sambuc /// \param Id as input, describes the template-name or operator-function-id
1921f4a2713aSLionel Sambuc /// that precedes the '<'. If template arguments were parsed successfully,
1922f4a2713aSLionel Sambuc /// will be updated with the template-id.
1923f4a2713aSLionel Sambuc ///
1924f4a2713aSLionel Sambuc /// \param AssumeTemplateId When true, this routine will assume that the name
1925f4a2713aSLionel Sambuc /// refers to a template without performing name lookup to verify.
1926f4a2713aSLionel Sambuc ///
1927f4a2713aSLionel Sambuc /// \returns true if a parse error occurred, false otherwise.
ParseUnqualifiedIdTemplateId(CXXScopeSpec & SS,SourceLocation TemplateKWLoc,IdentifierInfo * Name,SourceLocation NameLoc,bool EnteringContext,ParsedType ObjectType,UnqualifiedId & Id,bool AssumeTemplateId)1928f4a2713aSLionel Sambuc bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
1929f4a2713aSLionel Sambuc                                           SourceLocation TemplateKWLoc,
1930f4a2713aSLionel Sambuc                                           IdentifierInfo *Name,
1931f4a2713aSLionel Sambuc                                           SourceLocation NameLoc,
1932f4a2713aSLionel Sambuc                                           bool EnteringContext,
1933f4a2713aSLionel Sambuc                                           ParsedType ObjectType,
1934f4a2713aSLionel Sambuc                                           UnqualifiedId &Id,
1935f4a2713aSLionel Sambuc                                           bool AssumeTemplateId) {
1936f4a2713aSLionel Sambuc   assert((AssumeTemplateId || Tok.is(tok::less)) &&
1937f4a2713aSLionel Sambuc          "Expected '<' to finish parsing a template-id");
1938f4a2713aSLionel Sambuc 
1939f4a2713aSLionel Sambuc   TemplateTy Template;
1940f4a2713aSLionel Sambuc   TemplateNameKind TNK = TNK_Non_template;
1941f4a2713aSLionel Sambuc   switch (Id.getKind()) {
1942f4a2713aSLionel Sambuc   case UnqualifiedId::IK_Identifier:
1943f4a2713aSLionel Sambuc   case UnqualifiedId::IK_OperatorFunctionId:
1944f4a2713aSLionel Sambuc   case UnqualifiedId::IK_LiteralOperatorId:
1945f4a2713aSLionel Sambuc     if (AssumeTemplateId) {
1946f4a2713aSLionel Sambuc       TNK = Actions.ActOnDependentTemplateName(getCurScope(), SS, TemplateKWLoc,
1947f4a2713aSLionel Sambuc                                                Id, ObjectType, EnteringContext,
1948f4a2713aSLionel Sambuc                                                Template);
1949f4a2713aSLionel Sambuc       if (TNK == TNK_Non_template)
1950f4a2713aSLionel Sambuc         return true;
1951f4a2713aSLionel Sambuc     } else {
1952f4a2713aSLionel Sambuc       bool MemberOfUnknownSpecialization;
1953f4a2713aSLionel Sambuc       TNK = Actions.isTemplateName(getCurScope(), SS,
1954f4a2713aSLionel Sambuc                                    TemplateKWLoc.isValid(), Id,
1955f4a2713aSLionel Sambuc                                    ObjectType, EnteringContext, Template,
1956f4a2713aSLionel Sambuc                                    MemberOfUnknownSpecialization);
1957f4a2713aSLionel Sambuc 
1958f4a2713aSLionel Sambuc       if (TNK == TNK_Non_template && MemberOfUnknownSpecialization &&
1959f4a2713aSLionel Sambuc           ObjectType && IsTemplateArgumentList()) {
1960f4a2713aSLionel Sambuc         // We have something like t->getAs<T>(), where getAs is a
1961f4a2713aSLionel Sambuc         // member of an unknown specialization. However, this will only
1962f4a2713aSLionel Sambuc         // parse correctly as a template, so suggest the keyword 'template'
1963f4a2713aSLionel Sambuc         // before 'getAs' and treat this as a dependent template name.
1964f4a2713aSLionel Sambuc         std::string Name;
1965f4a2713aSLionel Sambuc         if (Id.getKind() == UnqualifiedId::IK_Identifier)
1966f4a2713aSLionel Sambuc           Name = Id.Identifier->getName();
1967f4a2713aSLionel Sambuc         else {
1968f4a2713aSLionel Sambuc           Name = "operator ";
1969f4a2713aSLionel Sambuc           if (Id.getKind() == UnqualifiedId::IK_OperatorFunctionId)
1970f4a2713aSLionel Sambuc             Name += getOperatorSpelling(Id.OperatorFunctionId.Operator);
1971f4a2713aSLionel Sambuc           else
1972f4a2713aSLionel Sambuc             Name += Id.Identifier->getName();
1973f4a2713aSLionel Sambuc         }
1974f4a2713aSLionel Sambuc         Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)
1975f4a2713aSLionel Sambuc           << Name
1976f4a2713aSLionel Sambuc           << FixItHint::CreateInsertion(Id.StartLocation, "template ");
1977f4a2713aSLionel Sambuc         TNK = Actions.ActOnDependentTemplateName(getCurScope(),
1978f4a2713aSLionel Sambuc                                                  SS, TemplateKWLoc, Id,
1979f4a2713aSLionel Sambuc                                                  ObjectType, EnteringContext,
1980f4a2713aSLionel Sambuc                                                  Template);
1981f4a2713aSLionel Sambuc         if (TNK == TNK_Non_template)
1982f4a2713aSLionel Sambuc           return true;
1983f4a2713aSLionel Sambuc       }
1984f4a2713aSLionel Sambuc     }
1985f4a2713aSLionel Sambuc     break;
1986f4a2713aSLionel Sambuc 
1987f4a2713aSLionel Sambuc   case UnqualifiedId::IK_ConstructorName: {
1988f4a2713aSLionel Sambuc     UnqualifiedId TemplateName;
1989f4a2713aSLionel Sambuc     bool MemberOfUnknownSpecialization;
1990f4a2713aSLionel Sambuc     TemplateName.setIdentifier(Name, NameLoc);
1991f4a2713aSLionel Sambuc     TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(),
1992f4a2713aSLionel Sambuc                                  TemplateName, ObjectType,
1993f4a2713aSLionel Sambuc                                  EnteringContext, Template,
1994f4a2713aSLionel Sambuc                                  MemberOfUnknownSpecialization);
1995f4a2713aSLionel Sambuc     break;
1996f4a2713aSLionel Sambuc   }
1997f4a2713aSLionel Sambuc 
1998f4a2713aSLionel Sambuc   case UnqualifiedId::IK_DestructorName: {
1999f4a2713aSLionel Sambuc     UnqualifiedId TemplateName;
2000f4a2713aSLionel Sambuc     bool MemberOfUnknownSpecialization;
2001f4a2713aSLionel Sambuc     TemplateName.setIdentifier(Name, NameLoc);
2002f4a2713aSLionel Sambuc     if (ObjectType) {
2003f4a2713aSLionel Sambuc       TNK = Actions.ActOnDependentTemplateName(getCurScope(),
2004f4a2713aSLionel Sambuc                                                SS, TemplateKWLoc, TemplateName,
2005f4a2713aSLionel Sambuc                                                ObjectType, EnteringContext,
2006f4a2713aSLionel Sambuc                                                Template);
2007f4a2713aSLionel Sambuc       if (TNK == TNK_Non_template)
2008f4a2713aSLionel Sambuc         return true;
2009f4a2713aSLionel Sambuc     } else {
2010f4a2713aSLionel Sambuc       TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(),
2011f4a2713aSLionel Sambuc                                    TemplateName, ObjectType,
2012f4a2713aSLionel Sambuc                                    EnteringContext, Template,
2013f4a2713aSLionel Sambuc                                    MemberOfUnknownSpecialization);
2014f4a2713aSLionel Sambuc 
2015f4a2713aSLionel Sambuc       if (TNK == TNK_Non_template && !Id.DestructorName.get()) {
2016f4a2713aSLionel Sambuc         Diag(NameLoc, diag::err_destructor_template_id)
2017f4a2713aSLionel Sambuc           << Name << SS.getRange();
2018f4a2713aSLionel Sambuc         return true;
2019f4a2713aSLionel Sambuc       }
2020f4a2713aSLionel Sambuc     }
2021f4a2713aSLionel Sambuc     break;
2022f4a2713aSLionel Sambuc   }
2023f4a2713aSLionel Sambuc 
2024f4a2713aSLionel Sambuc   default:
2025f4a2713aSLionel Sambuc     return false;
2026f4a2713aSLionel Sambuc   }
2027f4a2713aSLionel Sambuc 
2028f4a2713aSLionel Sambuc   if (TNK == TNK_Non_template)
2029f4a2713aSLionel Sambuc     return false;
2030f4a2713aSLionel Sambuc 
2031f4a2713aSLionel Sambuc   // Parse the enclosed template argument list.
2032f4a2713aSLionel Sambuc   SourceLocation LAngleLoc, RAngleLoc;
2033f4a2713aSLionel Sambuc   TemplateArgList TemplateArgs;
2034f4a2713aSLionel Sambuc   if (Tok.is(tok::less) &&
2035f4a2713aSLionel Sambuc       ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
2036f4a2713aSLionel Sambuc                                        SS, true, LAngleLoc,
2037f4a2713aSLionel Sambuc                                        TemplateArgs,
2038f4a2713aSLionel Sambuc                                        RAngleLoc))
2039f4a2713aSLionel Sambuc     return true;
2040f4a2713aSLionel Sambuc 
2041f4a2713aSLionel Sambuc   if (Id.getKind() == UnqualifiedId::IK_Identifier ||
2042f4a2713aSLionel Sambuc       Id.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
2043f4a2713aSLionel Sambuc       Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
2044f4a2713aSLionel Sambuc     // Form a parsed representation of the template-id to be stored in the
2045f4a2713aSLionel Sambuc     // UnqualifiedId.
2046f4a2713aSLionel Sambuc     TemplateIdAnnotation *TemplateId
2047f4a2713aSLionel Sambuc       = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
2048f4a2713aSLionel Sambuc 
2049*0a6a1f1dSLionel Sambuc     // FIXME: Store name for literal operator too.
2050f4a2713aSLionel Sambuc     if (Id.getKind() == UnqualifiedId::IK_Identifier) {
2051f4a2713aSLionel Sambuc       TemplateId->Name = Id.Identifier;
2052f4a2713aSLionel Sambuc       TemplateId->Operator = OO_None;
2053f4a2713aSLionel Sambuc       TemplateId->TemplateNameLoc = Id.StartLocation;
2054f4a2713aSLionel Sambuc     } else {
2055*0a6a1f1dSLionel Sambuc       TemplateId->Name = nullptr;
2056f4a2713aSLionel Sambuc       TemplateId->Operator = Id.OperatorFunctionId.Operator;
2057f4a2713aSLionel Sambuc       TemplateId->TemplateNameLoc = Id.StartLocation;
2058f4a2713aSLionel Sambuc     }
2059f4a2713aSLionel Sambuc 
2060f4a2713aSLionel Sambuc     TemplateId->SS = SS;
2061f4a2713aSLionel Sambuc     TemplateId->TemplateKWLoc = TemplateKWLoc;
2062f4a2713aSLionel Sambuc     TemplateId->Template = Template;
2063f4a2713aSLionel Sambuc     TemplateId->Kind = TNK;
2064f4a2713aSLionel Sambuc     TemplateId->LAngleLoc = LAngleLoc;
2065f4a2713aSLionel Sambuc     TemplateId->RAngleLoc = RAngleLoc;
2066f4a2713aSLionel Sambuc     ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
2067f4a2713aSLionel Sambuc     for (unsigned Arg = 0, ArgEnd = TemplateArgs.size();
2068f4a2713aSLionel Sambuc          Arg != ArgEnd; ++Arg)
2069f4a2713aSLionel Sambuc       Args[Arg] = TemplateArgs[Arg];
2070f4a2713aSLionel Sambuc 
2071f4a2713aSLionel Sambuc     Id.setTemplateId(TemplateId);
2072f4a2713aSLionel Sambuc     return false;
2073f4a2713aSLionel Sambuc   }
2074f4a2713aSLionel Sambuc 
2075f4a2713aSLionel Sambuc   // Bundle the template arguments together.
2076f4a2713aSLionel Sambuc   ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs);
2077f4a2713aSLionel Sambuc 
2078f4a2713aSLionel Sambuc   // Constructor and destructor names.
2079f4a2713aSLionel Sambuc   TypeResult Type
2080f4a2713aSLionel Sambuc     = Actions.ActOnTemplateIdType(SS, TemplateKWLoc,
2081f4a2713aSLionel Sambuc                                   Template, NameLoc,
2082f4a2713aSLionel Sambuc                                   LAngleLoc, TemplateArgsPtr, RAngleLoc,
2083f4a2713aSLionel Sambuc                                   /*IsCtorOrDtorName=*/true);
2084f4a2713aSLionel Sambuc   if (Type.isInvalid())
2085f4a2713aSLionel Sambuc     return true;
2086f4a2713aSLionel Sambuc 
2087f4a2713aSLionel Sambuc   if (Id.getKind() == UnqualifiedId::IK_ConstructorName)
2088f4a2713aSLionel Sambuc     Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);
2089f4a2713aSLionel Sambuc   else
2090f4a2713aSLionel Sambuc     Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);
2091f4a2713aSLionel Sambuc 
2092f4a2713aSLionel Sambuc   return false;
2093f4a2713aSLionel Sambuc }
2094f4a2713aSLionel Sambuc 
2095f4a2713aSLionel Sambuc /// \brief Parse an operator-function-id or conversion-function-id as part
2096f4a2713aSLionel Sambuc /// of a C++ unqualified-id.
2097f4a2713aSLionel Sambuc ///
2098f4a2713aSLionel Sambuc /// This routine is responsible only for parsing the operator-function-id or
2099f4a2713aSLionel Sambuc /// conversion-function-id; it does not handle template arguments in any way.
2100f4a2713aSLionel Sambuc ///
2101f4a2713aSLionel Sambuc /// \code
2102f4a2713aSLionel Sambuc ///       operator-function-id: [C++ 13.5]
2103f4a2713aSLionel Sambuc ///         'operator' operator
2104f4a2713aSLionel Sambuc ///
2105f4a2713aSLionel Sambuc ///       operator: one of
2106f4a2713aSLionel Sambuc ///            new   delete  new[]   delete[]
2107f4a2713aSLionel Sambuc ///            +     -    *  /    %  ^    &   |   ~
2108f4a2713aSLionel Sambuc ///            !     =    <  >    += -=   *=  /=  %=
2109f4a2713aSLionel Sambuc ///            ^=    &=   |= <<   >> >>= <<=  ==  !=
2110f4a2713aSLionel Sambuc ///            <=    >=   && ||   ++ --   ,   ->* ->
2111f4a2713aSLionel Sambuc ///            ()    []
2112f4a2713aSLionel Sambuc ///
2113f4a2713aSLionel Sambuc ///       conversion-function-id: [C++ 12.3.2]
2114f4a2713aSLionel Sambuc ///         operator conversion-type-id
2115f4a2713aSLionel Sambuc ///
2116f4a2713aSLionel Sambuc ///       conversion-type-id:
2117f4a2713aSLionel Sambuc ///         type-specifier-seq conversion-declarator[opt]
2118f4a2713aSLionel Sambuc ///
2119f4a2713aSLionel Sambuc ///       conversion-declarator:
2120f4a2713aSLionel Sambuc ///         ptr-operator conversion-declarator[opt]
2121f4a2713aSLionel Sambuc /// \endcode
2122f4a2713aSLionel Sambuc ///
2123f4a2713aSLionel Sambuc /// \param SS The nested-name-specifier that preceded this unqualified-id. If
2124f4a2713aSLionel Sambuc /// non-empty, then we are parsing the unqualified-id of a qualified-id.
2125f4a2713aSLionel Sambuc ///
2126f4a2713aSLionel Sambuc /// \param EnteringContext whether we are entering the scope of the
2127f4a2713aSLionel Sambuc /// nested-name-specifier.
2128f4a2713aSLionel Sambuc ///
2129f4a2713aSLionel Sambuc /// \param ObjectType if this unqualified-id occurs within a member access
2130f4a2713aSLionel Sambuc /// expression, the type of the base object whose member is being accessed.
2131f4a2713aSLionel Sambuc ///
2132f4a2713aSLionel Sambuc /// \param Result on a successful parse, contains the parsed unqualified-id.
2133f4a2713aSLionel Sambuc ///
2134f4a2713aSLionel Sambuc /// \returns true if parsing fails, false otherwise.
ParseUnqualifiedIdOperator(CXXScopeSpec & SS,bool EnteringContext,ParsedType ObjectType,UnqualifiedId & Result)2135f4a2713aSLionel Sambuc bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
2136f4a2713aSLionel Sambuc                                         ParsedType ObjectType,
2137f4a2713aSLionel Sambuc                                         UnqualifiedId &Result) {
2138f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
2139f4a2713aSLionel Sambuc 
2140f4a2713aSLionel Sambuc   // Consume the 'operator' keyword.
2141f4a2713aSLionel Sambuc   SourceLocation KeywordLoc = ConsumeToken();
2142f4a2713aSLionel Sambuc 
2143f4a2713aSLionel Sambuc   // Determine what kind of operator name we have.
2144f4a2713aSLionel Sambuc   unsigned SymbolIdx = 0;
2145f4a2713aSLionel Sambuc   SourceLocation SymbolLocations[3];
2146f4a2713aSLionel Sambuc   OverloadedOperatorKind Op = OO_None;
2147f4a2713aSLionel Sambuc   switch (Tok.getKind()) {
2148f4a2713aSLionel Sambuc     case tok::kw_new:
2149f4a2713aSLionel Sambuc     case tok::kw_delete: {
2150f4a2713aSLionel Sambuc       bool isNew = Tok.getKind() == tok::kw_new;
2151f4a2713aSLionel Sambuc       // Consume the 'new' or 'delete'.
2152f4a2713aSLionel Sambuc       SymbolLocations[SymbolIdx++] = ConsumeToken();
2153f4a2713aSLionel Sambuc       // Check for array new/delete.
2154f4a2713aSLionel Sambuc       if (Tok.is(tok::l_square) &&
2155f4a2713aSLionel Sambuc           (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))) {
2156f4a2713aSLionel Sambuc         // Consume the '[' and ']'.
2157f4a2713aSLionel Sambuc         BalancedDelimiterTracker T(*this, tok::l_square);
2158f4a2713aSLionel Sambuc         T.consumeOpen();
2159f4a2713aSLionel Sambuc         T.consumeClose();
2160f4a2713aSLionel Sambuc         if (T.getCloseLocation().isInvalid())
2161f4a2713aSLionel Sambuc           return true;
2162f4a2713aSLionel Sambuc 
2163f4a2713aSLionel Sambuc         SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2164f4a2713aSLionel Sambuc         SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2165f4a2713aSLionel Sambuc         Op = isNew? OO_Array_New : OO_Array_Delete;
2166f4a2713aSLionel Sambuc       } else {
2167f4a2713aSLionel Sambuc         Op = isNew? OO_New : OO_Delete;
2168f4a2713aSLionel Sambuc       }
2169f4a2713aSLionel Sambuc       break;
2170f4a2713aSLionel Sambuc     }
2171f4a2713aSLionel Sambuc 
2172f4a2713aSLionel Sambuc #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2173f4a2713aSLionel Sambuc     case tok::Token:                                                     \
2174f4a2713aSLionel Sambuc       SymbolLocations[SymbolIdx++] = ConsumeToken();                     \
2175f4a2713aSLionel Sambuc       Op = OO_##Name;                                                    \
2176f4a2713aSLionel Sambuc       break;
2177f4a2713aSLionel Sambuc #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
2178f4a2713aSLionel Sambuc #include "clang/Basic/OperatorKinds.def"
2179f4a2713aSLionel Sambuc 
2180f4a2713aSLionel Sambuc     case tok::l_paren: {
2181f4a2713aSLionel Sambuc       // Consume the '(' and ')'.
2182f4a2713aSLionel Sambuc       BalancedDelimiterTracker T(*this, tok::l_paren);
2183f4a2713aSLionel Sambuc       T.consumeOpen();
2184f4a2713aSLionel Sambuc       T.consumeClose();
2185f4a2713aSLionel Sambuc       if (T.getCloseLocation().isInvalid())
2186f4a2713aSLionel Sambuc         return true;
2187f4a2713aSLionel Sambuc 
2188f4a2713aSLionel Sambuc       SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2189f4a2713aSLionel Sambuc       SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2190f4a2713aSLionel Sambuc       Op = OO_Call;
2191f4a2713aSLionel Sambuc       break;
2192f4a2713aSLionel Sambuc     }
2193f4a2713aSLionel Sambuc 
2194f4a2713aSLionel Sambuc     case tok::l_square: {
2195f4a2713aSLionel Sambuc       // Consume the '[' and ']'.
2196f4a2713aSLionel Sambuc       BalancedDelimiterTracker T(*this, tok::l_square);
2197f4a2713aSLionel Sambuc       T.consumeOpen();
2198f4a2713aSLionel Sambuc       T.consumeClose();
2199f4a2713aSLionel Sambuc       if (T.getCloseLocation().isInvalid())
2200f4a2713aSLionel Sambuc         return true;
2201f4a2713aSLionel Sambuc 
2202f4a2713aSLionel Sambuc       SymbolLocations[SymbolIdx++] = T.getOpenLocation();
2203f4a2713aSLionel Sambuc       SymbolLocations[SymbolIdx++] = T.getCloseLocation();
2204f4a2713aSLionel Sambuc       Op = OO_Subscript;
2205f4a2713aSLionel Sambuc       break;
2206f4a2713aSLionel Sambuc     }
2207f4a2713aSLionel Sambuc 
2208f4a2713aSLionel Sambuc     case tok::code_completion: {
2209f4a2713aSLionel Sambuc       // Code completion for the operator name.
2210f4a2713aSLionel Sambuc       Actions.CodeCompleteOperatorName(getCurScope());
2211f4a2713aSLionel Sambuc       cutOffParsing();
2212f4a2713aSLionel Sambuc       // Don't try to parse any further.
2213f4a2713aSLionel Sambuc       return true;
2214f4a2713aSLionel Sambuc     }
2215f4a2713aSLionel Sambuc 
2216f4a2713aSLionel Sambuc     default:
2217f4a2713aSLionel Sambuc       break;
2218f4a2713aSLionel Sambuc   }
2219f4a2713aSLionel Sambuc 
2220f4a2713aSLionel Sambuc   if (Op != OO_None) {
2221f4a2713aSLionel Sambuc     // We have parsed an operator-function-id.
2222f4a2713aSLionel Sambuc     Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);
2223f4a2713aSLionel Sambuc     return false;
2224f4a2713aSLionel Sambuc   }
2225f4a2713aSLionel Sambuc 
2226f4a2713aSLionel Sambuc   // Parse a literal-operator-id.
2227f4a2713aSLionel Sambuc   //
2228f4a2713aSLionel Sambuc   //   literal-operator-id: C++11 [over.literal]
2229f4a2713aSLionel Sambuc   //     operator string-literal identifier
2230f4a2713aSLionel Sambuc   //     operator user-defined-string-literal
2231f4a2713aSLionel Sambuc 
2232f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) {
2233f4a2713aSLionel Sambuc     Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);
2234f4a2713aSLionel Sambuc 
2235f4a2713aSLionel Sambuc     SourceLocation DiagLoc;
2236f4a2713aSLionel Sambuc     unsigned DiagId = 0;
2237f4a2713aSLionel Sambuc 
2238f4a2713aSLionel Sambuc     // We're past translation phase 6, so perform string literal concatenation
2239f4a2713aSLionel Sambuc     // before checking for "".
2240f4a2713aSLionel Sambuc     SmallVector<Token, 4> Toks;
2241f4a2713aSLionel Sambuc     SmallVector<SourceLocation, 4> TokLocs;
2242f4a2713aSLionel Sambuc     while (isTokenStringLiteral()) {
2243f4a2713aSLionel Sambuc       if (!Tok.is(tok::string_literal) && !DiagId) {
2244f4a2713aSLionel Sambuc         // C++11 [over.literal]p1:
2245f4a2713aSLionel Sambuc         //   The string-literal or user-defined-string-literal in a
2246f4a2713aSLionel Sambuc         //   literal-operator-id shall have no encoding-prefix [...].
2247f4a2713aSLionel Sambuc         DiagLoc = Tok.getLocation();
2248f4a2713aSLionel Sambuc         DiagId = diag::err_literal_operator_string_prefix;
2249f4a2713aSLionel Sambuc       }
2250f4a2713aSLionel Sambuc       Toks.push_back(Tok);
2251f4a2713aSLionel Sambuc       TokLocs.push_back(ConsumeStringToken());
2252f4a2713aSLionel Sambuc     }
2253f4a2713aSLionel Sambuc 
2254*0a6a1f1dSLionel Sambuc     StringLiteralParser Literal(Toks, PP);
2255f4a2713aSLionel Sambuc     if (Literal.hadError)
2256f4a2713aSLionel Sambuc       return true;
2257f4a2713aSLionel Sambuc 
2258f4a2713aSLionel Sambuc     // Grab the literal operator's suffix, which will be either the next token
2259f4a2713aSLionel Sambuc     // or a ud-suffix from the string literal.
2260*0a6a1f1dSLionel Sambuc     IdentifierInfo *II = nullptr;
2261f4a2713aSLionel Sambuc     SourceLocation SuffixLoc;
2262f4a2713aSLionel Sambuc     if (!Literal.getUDSuffix().empty()) {
2263f4a2713aSLionel Sambuc       II = &PP.getIdentifierTable().get(Literal.getUDSuffix());
2264f4a2713aSLionel Sambuc       SuffixLoc =
2265f4a2713aSLionel Sambuc         Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()],
2266f4a2713aSLionel Sambuc                                        Literal.getUDSuffixOffset(),
2267f4a2713aSLionel Sambuc                                        PP.getSourceManager(), getLangOpts());
2268f4a2713aSLionel Sambuc     } else if (Tok.is(tok::identifier)) {
2269f4a2713aSLionel Sambuc       II = Tok.getIdentifierInfo();
2270f4a2713aSLionel Sambuc       SuffixLoc = ConsumeToken();
2271f4a2713aSLionel Sambuc       TokLocs.push_back(SuffixLoc);
2272f4a2713aSLionel Sambuc     } else {
2273*0a6a1f1dSLionel Sambuc       Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
2274f4a2713aSLionel Sambuc       return true;
2275f4a2713aSLionel Sambuc     }
2276f4a2713aSLionel Sambuc 
2277f4a2713aSLionel Sambuc     // The string literal must be empty.
2278f4a2713aSLionel Sambuc     if (!Literal.GetString().empty() || Literal.Pascal) {
2279f4a2713aSLionel Sambuc       // C++11 [over.literal]p1:
2280f4a2713aSLionel Sambuc       //   The string-literal or user-defined-string-literal in a
2281f4a2713aSLionel Sambuc       //   literal-operator-id shall [...] contain no characters
2282f4a2713aSLionel Sambuc       //   other than the implicit terminating '\0'.
2283f4a2713aSLionel Sambuc       DiagLoc = TokLocs.front();
2284f4a2713aSLionel Sambuc       DiagId = diag::err_literal_operator_string_not_empty;
2285f4a2713aSLionel Sambuc     }
2286f4a2713aSLionel Sambuc 
2287f4a2713aSLionel Sambuc     if (DiagId) {
2288f4a2713aSLionel Sambuc       // This isn't a valid literal-operator-id, but we think we know
2289f4a2713aSLionel Sambuc       // what the user meant. Tell them what they should have written.
2290f4a2713aSLionel Sambuc       SmallString<32> Str;
2291f4a2713aSLionel Sambuc       Str += "\"\" ";
2292f4a2713aSLionel Sambuc       Str += II->getName();
2293f4a2713aSLionel Sambuc       Diag(DiagLoc, DiagId) << FixItHint::CreateReplacement(
2294f4a2713aSLionel Sambuc           SourceRange(TokLocs.front(), TokLocs.back()), Str);
2295f4a2713aSLionel Sambuc     }
2296f4a2713aSLionel Sambuc 
2297f4a2713aSLionel Sambuc     Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc);
2298*0a6a1f1dSLionel Sambuc 
2299*0a6a1f1dSLionel Sambuc     return Actions.checkLiteralOperatorId(SS, Result);
2300f4a2713aSLionel Sambuc   }
2301f4a2713aSLionel Sambuc 
2302f4a2713aSLionel Sambuc   // Parse a conversion-function-id.
2303f4a2713aSLionel Sambuc   //
2304f4a2713aSLionel Sambuc   //   conversion-function-id: [C++ 12.3.2]
2305f4a2713aSLionel Sambuc   //     operator conversion-type-id
2306f4a2713aSLionel Sambuc   //
2307f4a2713aSLionel Sambuc   //   conversion-type-id:
2308f4a2713aSLionel Sambuc   //     type-specifier-seq conversion-declarator[opt]
2309f4a2713aSLionel Sambuc   //
2310f4a2713aSLionel Sambuc   //   conversion-declarator:
2311f4a2713aSLionel Sambuc   //     ptr-operator conversion-declarator[opt]
2312f4a2713aSLionel Sambuc 
2313f4a2713aSLionel Sambuc   // Parse the type-specifier-seq.
2314f4a2713aSLionel Sambuc   DeclSpec DS(AttrFactory);
2315f4a2713aSLionel Sambuc   if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
2316f4a2713aSLionel Sambuc     return true;
2317f4a2713aSLionel Sambuc 
2318f4a2713aSLionel Sambuc   // Parse the conversion-declarator, which is merely a sequence of
2319f4a2713aSLionel Sambuc   // ptr-operators.
2320f4a2713aSLionel Sambuc   Declarator D(DS, Declarator::ConversionIdContext);
2321*0a6a1f1dSLionel Sambuc   ParseDeclaratorInternal(D, /*DirectDeclParser=*/nullptr);
2322f4a2713aSLionel Sambuc 
2323f4a2713aSLionel Sambuc   // Finish up the type.
2324f4a2713aSLionel Sambuc   TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D);
2325f4a2713aSLionel Sambuc   if (Ty.isInvalid())
2326f4a2713aSLionel Sambuc     return true;
2327f4a2713aSLionel Sambuc 
2328f4a2713aSLionel Sambuc   // Note that this is a conversion-function-id.
2329f4a2713aSLionel Sambuc   Result.setConversionFunctionId(KeywordLoc, Ty.get(),
2330f4a2713aSLionel Sambuc                                  D.getSourceRange().getEnd());
2331f4a2713aSLionel Sambuc   return false;
2332f4a2713aSLionel Sambuc }
2333f4a2713aSLionel Sambuc 
2334f4a2713aSLionel Sambuc /// \brief Parse a C++ unqualified-id (or a C identifier), which describes the
2335f4a2713aSLionel Sambuc /// name of an entity.
2336f4a2713aSLionel Sambuc ///
2337f4a2713aSLionel Sambuc /// \code
2338f4a2713aSLionel Sambuc ///       unqualified-id: [C++ expr.prim.general]
2339f4a2713aSLionel Sambuc ///         identifier
2340f4a2713aSLionel Sambuc ///         operator-function-id
2341f4a2713aSLionel Sambuc ///         conversion-function-id
2342f4a2713aSLionel Sambuc /// [C++0x] literal-operator-id [TODO]
2343f4a2713aSLionel Sambuc ///         ~ class-name
2344f4a2713aSLionel Sambuc ///         template-id
2345f4a2713aSLionel Sambuc ///
2346f4a2713aSLionel Sambuc /// \endcode
2347f4a2713aSLionel Sambuc ///
2348f4a2713aSLionel Sambuc /// \param SS The nested-name-specifier that preceded this unqualified-id. If
2349f4a2713aSLionel Sambuc /// non-empty, then we are parsing the unqualified-id of a qualified-id.
2350f4a2713aSLionel Sambuc ///
2351f4a2713aSLionel Sambuc /// \param EnteringContext whether we are entering the scope of the
2352f4a2713aSLionel Sambuc /// nested-name-specifier.
2353f4a2713aSLionel Sambuc ///
2354f4a2713aSLionel Sambuc /// \param AllowDestructorName whether we allow parsing of a destructor name.
2355f4a2713aSLionel Sambuc ///
2356f4a2713aSLionel Sambuc /// \param AllowConstructorName whether we allow parsing a constructor name.
2357f4a2713aSLionel Sambuc ///
2358f4a2713aSLionel Sambuc /// \param ObjectType if this unqualified-id occurs within a member access
2359f4a2713aSLionel Sambuc /// expression, the type of the base object whose member is being accessed.
2360f4a2713aSLionel Sambuc ///
2361f4a2713aSLionel Sambuc /// \param Result on a successful parse, contains the parsed unqualified-id.
2362f4a2713aSLionel Sambuc ///
2363f4a2713aSLionel Sambuc /// \returns true if parsing fails, false otherwise.
ParseUnqualifiedId(CXXScopeSpec & SS,bool EnteringContext,bool AllowDestructorName,bool AllowConstructorName,ParsedType ObjectType,SourceLocation & TemplateKWLoc,UnqualifiedId & Result)2364f4a2713aSLionel Sambuc bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
2365f4a2713aSLionel Sambuc                                 bool AllowDestructorName,
2366f4a2713aSLionel Sambuc                                 bool AllowConstructorName,
2367f4a2713aSLionel Sambuc                                 ParsedType ObjectType,
2368f4a2713aSLionel Sambuc                                 SourceLocation& TemplateKWLoc,
2369f4a2713aSLionel Sambuc                                 UnqualifiedId &Result) {
2370f4a2713aSLionel Sambuc 
2371f4a2713aSLionel Sambuc   // Handle 'A::template B'. This is for template-ids which have not
2372f4a2713aSLionel Sambuc   // already been annotated by ParseOptionalCXXScopeSpecifier().
2373f4a2713aSLionel Sambuc   bool TemplateSpecified = false;
2374f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus && Tok.is(tok::kw_template) &&
2375f4a2713aSLionel Sambuc       (ObjectType || SS.isSet())) {
2376f4a2713aSLionel Sambuc     TemplateSpecified = true;
2377f4a2713aSLionel Sambuc     TemplateKWLoc = ConsumeToken();
2378f4a2713aSLionel Sambuc   }
2379f4a2713aSLionel Sambuc 
2380f4a2713aSLionel Sambuc   // unqualified-id:
2381f4a2713aSLionel Sambuc   //   identifier
2382f4a2713aSLionel Sambuc   //   template-id (when it hasn't already been annotated)
2383f4a2713aSLionel Sambuc   if (Tok.is(tok::identifier)) {
2384f4a2713aSLionel Sambuc     // Consume the identifier.
2385f4a2713aSLionel Sambuc     IdentifierInfo *Id = Tok.getIdentifierInfo();
2386f4a2713aSLionel Sambuc     SourceLocation IdLoc = ConsumeToken();
2387f4a2713aSLionel Sambuc 
2388f4a2713aSLionel Sambuc     if (!getLangOpts().CPlusPlus) {
2389f4a2713aSLionel Sambuc       // If we're not in C++, only identifiers matter. Record the
2390f4a2713aSLionel Sambuc       // identifier and return.
2391f4a2713aSLionel Sambuc       Result.setIdentifier(Id, IdLoc);
2392f4a2713aSLionel Sambuc       return false;
2393f4a2713aSLionel Sambuc     }
2394f4a2713aSLionel Sambuc 
2395f4a2713aSLionel Sambuc     if (AllowConstructorName &&
2396f4a2713aSLionel Sambuc         Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {
2397f4a2713aSLionel Sambuc       // We have parsed a constructor name.
2398f4a2713aSLionel Sambuc       ParsedType Ty = Actions.getTypeName(*Id, IdLoc, getCurScope(),
2399f4a2713aSLionel Sambuc                                           &SS, false, false,
2400f4a2713aSLionel Sambuc                                           ParsedType(),
2401f4a2713aSLionel Sambuc                                           /*IsCtorOrDtorName=*/true,
2402f4a2713aSLionel Sambuc                                           /*NonTrivialTypeSourceInfo=*/true);
2403f4a2713aSLionel Sambuc       Result.setConstructorName(Ty, IdLoc, IdLoc);
2404f4a2713aSLionel Sambuc     } else {
2405f4a2713aSLionel Sambuc       // We have parsed an identifier.
2406f4a2713aSLionel Sambuc       Result.setIdentifier(Id, IdLoc);
2407f4a2713aSLionel Sambuc     }
2408f4a2713aSLionel Sambuc 
2409f4a2713aSLionel Sambuc     // If the next token is a '<', we may have a template.
2410f4a2713aSLionel Sambuc     if (TemplateSpecified || Tok.is(tok::less))
2411f4a2713aSLionel Sambuc       return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, Id, IdLoc,
2412f4a2713aSLionel Sambuc                                           EnteringContext, ObjectType,
2413f4a2713aSLionel Sambuc                                           Result, TemplateSpecified);
2414f4a2713aSLionel Sambuc 
2415f4a2713aSLionel Sambuc     return false;
2416f4a2713aSLionel Sambuc   }
2417f4a2713aSLionel Sambuc 
2418f4a2713aSLionel Sambuc   // unqualified-id:
2419f4a2713aSLionel Sambuc   //   template-id (already parsed and annotated)
2420f4a2713aSLionel Sambuc   if (Tok.is(tok::annot_template_id)) {
2421f4a2713aSLionel Sambuc     TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2422f4a2713aSLionel Sambuc 
2423f4a2713aSLionel Sambuc     // If the template-name names the current class, then this is a constructor
2424f4a2713aSLionel Sambuc     if (AllowConstructorName && TemplateId->Name &&
2425f4a2713aSLionel Sambuc         Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
2426f4a2713aSLionel Sambuc       if (SS.isSet()) {
2427f4a2713aSLionel Sambuc         // C++ [class.qual]p2 specifies that a qualified template-name
2428f4a2713aSLionel Sambuc         // is taken as the constructor name where a constructor can be
2429f4a2713aSLionel Sambuc         // declared. Thus, the template arguments are extraneous, so
2430f4a2713aSLionel Sambuc         // complain about them and remove them entirely.
2431f4a2713aSLionel Sambuc         Diag(TemplateId->TemplateNameLoc,
2432f4a2713aSLionel Sambuc              diag::err_out_of_line_constructor_template_id)
2433f4a2713aSLionel Sambuc           << TemplateId->Name
2434f4a2713aSLionel Sambuc           << FixItHint::CreateRemoval(
2435f4a2713aSLionel Sambuc                     SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
2436f4a2713aSLionel Sambuc         ParsedType Ty = Actions.getTypeName(*TemplateId->Name,
2437f4a2713aSLionel Sambuc                                             TemplateId->TemplateNameLoc,
2438f4a2713aSLionel Sambuc                                             getCurScope(),
2439f4a2713aSLionel Sambuc                                             &SS, false, false,
2440f4a2713aSLionel Sambuc                                             ParsedType(),
2441f4a2713aSLionel Sambuc                                             /*IsCtorOrDtorName=*/true,
2442f4a2713aSLionel Sambuc                                             /*NontrivialTypeSourceInfo=*/true);
2443f4a2713aSLionel Sambuc         Result.setConstructorName(Ty, TemplateId->TemplateNameLoc,
2444f4a2713aSLionel Sambuc                                   TemplateId->RAngleLoc);
2445f4a2713aSLionel Sambuc         ConsumeToken();
2446f4a2713aSLionel Sambuc         return false;
2447f4a2713aSLionel Sambuc       }
2448f4a2713aSLionel Sambuc 
2449f4a2713aSLionel Sambuc       Result.setConstructorTemplateId(TemplateId);
2450f4a2713aSLionel Sambuc       ConsumeToken();
2451f4a2713aSLionel Sambuc       return false;
2452f4a2713aSLionel Sambuc     }
2453f4a2713aSLionel Sambuc 
2454f4a2713aSLionel Sambuc     // We have already parsed a template-id; consume the annotation token as
2455f4a2713aSLionel Sambuc     // our unqualified-id.
2456f4a2713aSLionel Sambuc     Result.setTemplateId(TemplateId);
2457f4a2713aSLionel Sambuc     TemplateKWLoc = TemplateId->TemplateKWLoc;
2458f4a2713aSLionel Sambuc     ConsumeToken();
2459f4a2713aSLionel Sambuc     return false;
2460f4a2713aSLionel Sambuc   }
2461f4a2713aSLionel Sambuc 
2462f4a2713aSLionel Sambuc   // unqualified-id:
2463f4a2713aSLionel Sambuc   //   operator-function-id
2464f4a2713aSLionel Sambuc   //   conversion-function-id
2465f4a2713aSLionel Sambuc   if (Tok.is(tok::kw_operator)) {
2466f4a2713aSLionel Sambuc     if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result))
2467f4a2713aSLionel Sambuc       return true;
2468f4a2713aSLionel Sambuc 
2469f4a2713aSLionel Sambuc     // If we have an operator-function-id or a literal-operator-id and the next
2470f4a2713aSLionel Sambuc     // token is a '<', we may have a
2471f4a2713aSLionel Sambuc     //
2472f4a2713aSLionel Sambuc     //   template-id:
2473f4a2713aSLionel Sambuc     //     operator-function-id < template-argument-list[opt] >
2474f4a2713aSLionel Sambuc     if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
2475f4a2713aSLionel Sambuc          Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) &&
2476f4a2713aSLionel Sambuc         (TemplateSpecified || Tok.is(tok::less)))
2477f4a2713aSLionel Sambuc       return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
2478*0a6a1f1dSLionel Sambuc                                           nullptr, SourceLocation(),
2479f4a2713aSLionel Sambuc                                           EnteringContext, ObjectType,
2480f4a2713aSLionel Sambuc                                           Result, TemplateSpecified);
2481f4a2713aSLionel Sambuc 
2482f4a2713aSLionel Sambuc     return false;
2483f4a2713aSLionel Sambuc   }
2484f4a2713aSLionel Sambuc 
2485f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus &&
2486f4a2713aSLionel Sambuc       (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {
2487f4a2713aSLionel Sambuc     // C++ [expr.unary.op]p10:
2488f4a2713aSLionel Sambuc     //   There is an ambiguity in the unary-expression ~X(), where X is a
2489f4a2713aSLionel Sambuc     //   class-name. The ambiguity is resolved in favor of treating ~ as a
2490f4a2713aSLionel Sambuc     //    unary complement rather than treating ~X as referring to a destructor.
2491f4a2713aSLionel Sambuc 
2492f4a2713aSLionel Sambuc     // Parse the '~'.
2493f4a2713aSLionel Sambuc     SourceLocation TildeLoc = ConsumeToken();
2494f4a2713aSLionel Sambuc 
2495f4a2713aSLionel Sambuc     if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {
2496f4a2713aSLionel Sambuc       DeclSpec DS(AttrFactory);
2497f4a2713aSLionel Sambuc       SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
2498f4a2713aSLionel Sambuc       if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) {
2499f4a2713aSLionel Sambuc         Result.setDestructorName(TildeLoc, Type, EndLoc);
2500f4a2713aSLionel Sambuc         return false;
2501f4a2713aSLionel Sambuc       }
2502f4a2713aSLionel Sambuc       return true;
2503f4a2713aSLionel Sambuc     }
2504f4a2713aSLionel Sambuc 
2505f4a2713aSLionel Sambuc     // Parse the class-name.
2506f4a2713aSLionel Sambuc     if (Tok.isNot(tok::identifier)) {
2507f4a2713aSLionel Sambuc       Diag(Tok, diag::err_destructor_tilde_identifier);
2508f4a2713aSLionel Sambuc       return true;
2509f4a2713aSLionel Sambuc     }
2510f4a2713aSLionel Sambuc 
2511*0a6a1f1dSLionel Sambuc     // If the user wrote ~T::T, correct it to T::~T.
2512*0a6a1f1dSLionel Sambuc     if (!TemplateSpecified && NextToken().is(tok::coloncolon)) {
2513*0a6a1f1dSLionel Sambuc       if (SS.isSet()) {
2514*0a6a1f1dSLionel Sambuc         AnnotateScopeToken(SS, /*NewAnnotation*/true);
2515*0a6a1f1dSLionel Sambuc         SS.clear();
2516*0a6a1f1dSLionel Sambuc       }
2517*0a6a1f1dSLionel Sambuc       if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, EnteringContext))
2518*0a6a1f1dSLionel Sambuc         return true;
2519*0a6a1f1dSLionel Sambuc       if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon)) {
2520*0a6a1f1dSLionel Sambuc         Diag(TildeLoc, diag::err_destructor_tilde_scope);
2521*0a6a1f1dSLionel Sambuc         return true;
2522*0a6a1f1dSLionel Sambuc       }
2523*0a6a1f1dSLionel Sambuc 
2524*0a6a1f1dSLionel Sambuc       // Recover as if the tilde had been written before the identifier.
2525*0a6a1f1dSLionel Sambuc       Diag(TildeLoc, diag::err_destructor_tilde_scope)
2526*0a6a1f1dSLionel Sambuc         << FixItHint::CreateRemoval(TildeLoc)
2527*0a6a1f1dSLionel Sambuc         << FixItHint::CreateInsertion(Tok.getLocation(), "~");
2528*0a6a1f1dSLionel Sambuc     }
2529*0a6a1f1dSLionel Sambuc 
2530f4a2713aSLionel Sambuc     // Parse the class-name (or template-name in a simple-template-id).
2531f4a2713aSLionel Sambuc     IdentifierInfo *ClassName = Tok.getIdentifierInfo();
2532f4a2713aSLionel Sambuc     SourceLocation ClassNameLoc = ConsumeToken();
2533f4a2713aSLionel Sambuc 
2534f4a2713aSLionel Sambuc     if (TemplateSpecified || Tok.is(tok::less)) {
2535f4a2713aSLionel Sambuc       Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc);
2536f4a2713aSLionel Sambuc       return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
2537f4a2713aSLionel Sambuc                                           ClassName, ClassNameLoc,
2538f4a2713aSLionel Sambuc                                           EnteringContext, ObjectType,
2539f4a2713aSLionel Sambuc                                           Result, TemplateSpecified);
2540f4a2713aSLionel Sambuc     }
2541f4a2713aSLionel Sambuc 
2542f4a2713aSLionel Sambuc     // Note that this is a destructor name.
2543f4a2713aSLionel Sambuc     ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName,
2544f4a2713aSLionel Sambuc                                               ClassNameLoc, getCurScope(),
2545f4a2713aSLionel Sambuc                                               SS, ObjectType,
2546f4a2713aSLionel Sambuc                                               EnteringContext);
2547f4a2713aSLionel Sambuc     if (!Ty)
2548f4a2713aSLionel Sambuc       return true;
2549f4a2713aSLionel Sambuc 
2550f4a2713aSLionel Sambuc     Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
2551f4a2713aSLionel Sambuc     return false;
2552f4a2713aSLionel Sambuc   }
2553f4a2713aSLionel Sambuc 
2554f4a2713aSLionel Sambuc   Diag(Tok, diag::err_expected_unqualified_id)
2555f4a2713aSLionel Sambuc     << getLangOpts().CPlusPlus;
2556f4a2713aSLionel Sambuc   return true;
2557f4a2713aSLionel Sambuc }
2558f4a2713aSLionel Sambuc 
2559f4a2713aSLionel Sambuc /// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
2560f4a2713aSLionel Sambuc /// memory in a typesafe manner and call constructors.
2561f4a2713aSLionel Sambuc ///
2562f4a2713aSLionel Sambuc /// This method is called to parse the new expression after the optional :: has
2563f4a2713aSLionel Sambuc /// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
2564f4a2713aSLionel Sambuc /// is its location.  Otherwise, "Start" is the location of the 'new' token.
2565f4a2713aSLionel Sambuc ///
2566f4a2713aSLionel Sambuc ///        new-expression:
2567f4a2713aSLionel Sambuc ///                   '::'[opt] 'new' new-placement[opt] new-type-id
2568f4a2713aSLionel Sambuc ///                                     new-initializer[opt]
2569f4a2713aSLionel Sambuc ///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
2570f4a2713aSLionel Sambuc ///                                     new-initializer[opt]
2571f4a2713aSLionel Sambuc ///
2572f4a2713aSLionel Sambuc ///        new-placement:
2573f4a2713aSLionel Sambuc ///                   '(' expression-list ')'
2574f4a2713aSLionel Sambuc ///
2575f4a2713aSLionel Sambuc ///        new-type-id:
2576f4a2713aSLionel Sambuc ///                   type-specifier-seq new-declarator[opt]
2577f4a2713aSLionel Sambuc /// [GNU]             attributes type-specifier-seq new-declarator[opt]
2578f4a2713aSLionel Sambuc ///
2579f4a2713aSLionel Sambuc ///        new-declarator:
2580f4a2713aSLionel Sambuc ///                   ptr-operator new-declarator[opt]
2581f4a2713aSLionel Sambuc ///                   direct-new-declarator
2582f4a2713aSLionel Sambuc ///
2583f4a2713aSLionel Sambuc ///        new-initializer:
2584f4a2713aSLionel Sambuc ///                   '(' expression-list[opt] ')'
2585f4a2713aSLionel Sambuc /// [C++0x]           braced-init-list
2586f4a2713aSLionel Sambuc ///
2587f4a2713aSLionel Sambuc ExprResult
ParseCXXNewExpression(bool UseGlobal,SourceLocation Start)2588f4a2713aSLionel Sambuc Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
2589f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw_new) && "expected 'new' token");
2590f4a2713aSLionel Sambuc   ConsumeToken();   // Consume 'new'
2591f4a2713aSLionel Sambuc 
2592f4a2713aSLionel Sambuc   // A '(' now can be a new-placement or the '(' wrapping the type-id in the
2593f4a2713aSLionel Sambuc   // second form of new-expression. It can't be a new-type-id.
2594f4a2713aSLionel Sambuc 
2595f4a2713aSLionel Sambuc   ExprVector PlacementArgs;
2596f4a2713aSLionel Sambuc   SourceLocation PlacementLParen, PlacementRParen;
2597f4a2713aSLionel Sambuc 
2598f4a2713aSLionel Sambuc   SourceRange TypeIdParens;
2599f4a2713aSLionel Sambuc   DeclSpec DS(AttrFactory);
2600f4a2713aSLionel Sambuc   Declarator DeclaratorInfo(DS, Declarator::CXXNewContext);
2601f4a2713aSLionel Sambuc   if (Tok.is(tok::l_paren)) {
2602f4a2713aSLionel Sambuc     // If it turns out to be a placement, we change the type location.
2603f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_paren);
2604f4a2713aSLionel Sambuc     T.consumeOpen();
2605f4a2713aSLionel Sambuc     PlacementLParen = T.getOpenLocation();
2606f4a2713aSLionel Sambuc     if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
2607f4a2713aSLionel Sambuc       SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2608f4a2713aSLionel Sambuc       return ExprError();
2609f4a2713aSLionel Sambuc     }
2610f4a2713aSLionel Sambuc 
2611f4a2713aSLionel Sambuc     T.consumeClose();
2612f4a2713aSLionel Sambuc     PlacementRParen = T.getCloseLocation();
2613f4a2713aSLionel Sambuc     if (PlacementRParen.isInvalid()) {
2614f4a2713aSLionel Sambuc       SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2615f4a2713aSLionel Sambuc       return ExprError();
2616f4a2713aSLionel Sambuc     }
2617f4a2713aSLionel Sambuc 
2618f4a2713aSLionel Sambuc     if (PlacementArgs.empty()) {
2619f4a2713aSLionel Sambuc       // Reset the placement locations. There was no placement.
2620f4a2713aSLionel Sambuc       TypeIdParens = T.getRange();
2621f4a2713aSLionel Sambuc       PlacementLParen = PlacementRParen = SourceLocation();
2622f4a2713aSLionel Sambuc     } else {
2623f4a2713aSLionel Sambuc       // We still need the type.
2624f4a2713aSLionel Sambuc       if (Tok.is(tok::l_paren)) {
2625f4a2713aSLionel Sambuc         BalancedDelimiterTracker T(*this, tok::l_paren);
2626f4a2713aSLionel Sambuc         T.consumeOpen();
2627f4a2713aSLionel Sambuc         MaybeParseGNUAttributes(DeclaratorInfo);
2628f4a2713aSLionel Sambuc         ParseSpecifierQualifierList(DS);
2629f4a2713aSLionel Sambuc         DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2630f4a2713aSLionel Sambuc         ParseDeclarator(DeclaratorInfo);
2631f4a2713aSLionel Sambuc         T.consumeClose();
2632f4a2713aSLionel Sambuc         TypeIdParens = T.getRange();
2633f4a2713aSLionel Sambuc       } else {
2634f4a2713aSLionel Sambuc         MaybeParseGNUAttributes(DeclaratorInfo);
2635f4a2713aSLionel Sambuc         if (ParseCXXTypeSpecifierSeq(DS))
2636f4a2713aSLionel Sambuc           DeclaratorInfo.setInvalidType(true);
2637f4a2713aSLionel Sambuc         else {
2638f4a2713aSLionel Sambuc           DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2639f4a2713aSLionel Sambuc           ParseDeclaratorInternal(DeclaratorInfo,
2640f4a2713aSLionel Sambuc                                   &Parser::ParseDirectNewDeclarator);
2641f4a2713aSLionel Sambuc         }
2642f4a2713aSLionel Sambuc       }
2643f4a2713aSLionel Sambuc     }
2644f4a2713aSLionel Sambuc   } else {
2645f4a2713aSLionel Sambuc     // A new-type-id is a simplified type-id, where essentially the
2646f4a2713aSLionel Sambuc     // direct-declarator is replaced by a direct-new-declarator.
2647f4a2713aSLionel Sambuc     MaybeParseGNUAttributes(DeclaratorInfo);
2648f4a2713aSLionel Sambuc     if (ParseCXXTypeSpecifierSeq(DS))
2649f4a2713aSLionel Sambuc       DeclaratorInfo.setInvalidType(true);
2650f4a2713aSLionel Sambuc     else {
2651f4a2713aSLionel Sambuc       DeclaratorInfo.SetSourceRange(DS.getSourceRange());
2652f4a2713aSLionel Sambuc       ParseDeclaratorInternal(DeclaratorInfo,
2653f4a2713aSLionel Sambuc                               &Parser::ParseDirectNewDeclarator);
2654f4a2713aSLionel Sambuc     }
2655f4a2713aSLionel Sambuc   }
2656f4a2713aSLionel Sambuc   if (DeclaratorInfo.isInvalidType()) {
2657f4a2713aSLionel Sambuc     SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2658f4a2713aSLionel Sambuc     return ExprError();
2659f4a2713aSLionel Sambuc   }
2660f4a2713aSLionel Sambuc 
2661f4a2713aSLionel Sambuc   ExprResult Initializer;
2662f4a2713aSLionel Sambuc 
2663f4a2713aSLionel Sambuc   if (Tok.is(tok::l_paren)) {
2664f4a2713aSLionel Sambuc     SourceLocation ConstructorLParen, ConstructorRParen;
2665f4a2713aSLionel Sambuc     ExprVector ConstructorArgs;
2666f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_paren);
2667f4a2713aSLionel Sambuc     T.consumeOpen();
2668f4a2713aSLionel Sambuc     ConstructorLParen = T.getOpenLocation();
2669f4a2713aSLionel Sambuc     if (Tok.isNot(tok::r_paren)) {
2670f4a2713aSLionel Sambuc       CommaLocsTy CommaLocs;
2671f4a2713aSLionel Sambuc       if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
2672f4a2713aSLionel Sambuc         SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2673f4a2713aSLionel Sambuc         return ExprError();
2674f4a2713aSLionel Sambuc       }
2675f4a2713aSLionel Sambuc     }
2676f4a2713aSLionel Sambuc     T.consumeClose();
2677f4a2713aSLionel Sambuc     ConstructorRParen = T.getCloseLocation();
2678f4a2713aSLionel Sambuc     if (ConstructorRParen.isInvalid()) {
2679f4a2713aSLionel Sambuc       SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
2680f4a2713aSLionel Sambuc       return ExprError();
2681f4a2713aSLionel Sambuc     }
2682f4a2713aSLionel Sambuc     Initializer = Actions.ActOnParenListExpr(ConstructorLParen,
2683f4a2713aSLionel Sambuc                                              ConstructorRParen,
2684f4a2713aSLionel Sambuc                                              ConstructorArgs);
2685f4a2713aSLionel Sambuc   } else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) {
2686f4a2713aSLionel Sambuc     Diag(Tok.getLocation(),
2687f4a2713aSLionel Sambuc          diag::warn_cxx98_compat_generalized_initializer_lists);
2688f4a2713aSLionel Sambuc     Initializer = ParseBraceInitializer();
2689f4a2713aSLionel Sambuc   }
2690f4a2713aSLionel Sambuc   if (Initializer.isInvalid())
2691f4a2713aSLionel Sambuc     return Initializer;
2692f4a2713aSLionel Sambuc 
2693f4a2713aSLionel Sambuc   return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
2694f4a2713aSLionel Sambuc                              PlacementArgs, PlacementRParen,
2695*0a6a1f1dSLionel Sambuc                              TypeIdParens, DeclaratorInfo, Initializer.get());
2696f4a2713aSLionel Sambuc }
2697f4a2713aSLionel Sambuc 
2698f4a2713aSLionel Sambuc /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
2699f4a2713aSLionel Sambuc /// passed to ParseDeclaratorInternal.
2700f4a2713aSLionel Sambuc ///
2701f4a2713aSLionel Sambuc ///        direct-new-declarator:
2702f4a2713aSLionel Sambuc ///                   '[' expression ']'
2703f4a2713aSLionel Sambuc ///                   direct-new-declarator '[' constant-expression ']'
2704f4a2713aSLionel Sambuc ///
ParseDirectNewDeclarator(Declarator & D)2705f4a2713aSLionel Sambuc void Parser::ParseDirectNewDeclarator(Declarator &D) {
2706f4a2713aSLionel Sambuc   // Parse the array dimensions.
2707f4a2713aSLionel Sambuc   bool first = true;
2708f4a2713aSLionel Sambuc   while (Tok.is(tok::l_square)) {
2709f4a2713aSLionel Sambuc     // An array-size expression can't start with a lambda.
2710f4a2713aSLionel Sambuc     if (CheckProhibitedCXX11Attribute())
2711f4a2713aSLionel Sambuc       continue;
2712f4a2713aSLionel Sambuc 
2713f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_square);
2714f4a2713aSLionel Sambuc     T.consumeOpen();
2715f4a2713aSLionel Sambuc 
2716f4a2713aSLionel Sambuc     ExprResult Size(first ? ParseExpression()
2717f4a2713aSLionel Sambuc                                 : ParseConstantExpression());
2718f4a2713aSLionel Sambuc     if (Size.isInvalid()) {
2719f4a2713aSLionel Sambuc       // Recover
2720f4a2713aSLionel Sambuc       SkipUntil(tok::r_square, StopAtSemi);
2721f4a2713aSLionel Sambuc       return;
2722f4a2713aSLionel Sambuc     }
2723f4a2713aSLionel Sambuc     first = false;
2724f4a2713aSLionel Sambuc 
2725f4a2713aSLionel Sambuc     T.consumeClose();
2726f4a2713aSLionel Sambuc 
2727f4a2713aSLionel Sambuc     // Attributes here appertain to the array type. C++11 [expr.new]p5.
2728f4a2713aSLionel Sambuc     ParsedAttributes Attrs(AttrFactory);
2729f4a2713aSLionel Sambuc     MaybeParseCXX11Attributes(Attrs);
2730f4a2713aSLionel Sambuc 
2731f4a2713aSLionel Sambuc     D.AddTypeInfo(DeclaratorChunk::getArray(0,
2732f4a2713aSLionel Sambuc                                             /*static=*/false, /*star=*/false,
2733*0a6a1f1dSLionel Sambuc                                             Size.get(),
2734f4a2713aSLionel Sambuc                                             T.getOpenLocation(),
2735f4a2713aSLionel Sambuc                                             T.getCloseLocation()),
2736f4a2713aSLionel Sambuc                   Attrs, T.getCloseLocation());
2737f4a2713aSLionel Sambuc 
2738f4a2713aSLionel Sambuc     if (T.getCloseLocation().isInvalid())
2739f4a2713aSLionel Sambuc       return;
2740f4a2713aSLionel Sambuc   }
2741f4a2713aSLionel Sambuc }
2742f4a2713aSLionel Sambuc 
2743f4a2713aSLionel Sambuc /// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
2744f4a2713aSLionel Sambuc /// This ambiguity appears in the syntax of the C++ new operator.
2745f4a2713aSLionel Sambuc ///
2746f4a2713aSLionel Sambuc ///        new-expression:
2747f4a2713aSLionel Sambuc ///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
2748f4a2713aSLionel Sambuc ///                                     new-initializer[opt]
2749f4a2713aSLionel Sambuc ///
2750f4a2713aSLionel Sambuc ///        new-placement:
2751f4a2713aSLionel Sambuc ///                   '(' expression-list ')'
2752f4a2713aSLionel Sambuc ///
ParseExpressionListOrTypeId(SmallVectorImpl<Expr * > & PlacementArgs,Declarator & D)2753f4a2713aSLionel Sambuc bool Parser::ParseExpressionListOrTypeId(
2754f4a2713aSLionel Sambuc                                    SmallVectorImpl<Expr*> &PlacementArgs,
2755f4a2713aSLionel Sambuc                                          Declarator &D) {
2756f4a2713aSLionel Sambuc   // The '(' was already consumed.
2757f4a2713aSLionel Sambuc   if (isTypeIdInParens()) {
2758f4a2713aSLionel Sambuc     ParseSpecifierQualifierList(D.getMutableDeclSpec());
2759f4a2713aSLionel Sambuc     D.SetSourceRange(D.getDeclSpec().getSourceRange());
2760f4a2713aSLionel Sambuc     ParseDeclarator(D);
2761f4a2713aSLionel Sambuc     return D.isInvalidType();
2762f4a2713aSLionel Sambuc   }
2763f4a2713aSLionel Sambuc 
2764f4a2713aSLionel Sambuc   // It's not a type, it has to be an expression list.
2765f4a2713aSLionel Sambuc   // Discard the comma locations - ActOnCXXNew has enough parameters.
2766f4a2713aSLionel Sambuc   CommaLocsTy CommaLocs;
2767f4a2713aSLionel Sambuc   return ParseExpressionList(PlacementArgs, CommaLocs);
2768f4a2713aSLionel Sambuc }
2769f4a2713aSLionel Sambuc 
2770f4a2713aSLionel Sambuc /// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
2771f4a2713aSLionel Sambuc /// to free memory allocated by new.
2772f4a2713aSLionel Sambuc ///
2773f4a2713aSLionel Sambuc /// This method is called to parse the 'delete' expression after the optional
2774f4a2713aSLionel Sambuc /// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
2775f4a2713aSLionel Sambuc /// and "Start" is its location.  Otherwise, "Start" is the location of the
2776f4a2713aSLionel Sambuc /// 'delete' token.
2777f4a2713aSLionel Sambuc ///
2778f4a2713aSLionel Sambuc ///        delete-expression:
2779f4a2713aSLionel Sambuc ///                   '::'[opt] 'delete' cast-expression
2780f4a2713aSLionel Sambuc ///                   '::'[opt] 'delete' '[' ']' cast-expression
2781f4a2713aSLionel Sambuc ExprResult
ParseCXXDeleteExpression(bool UseGlobal,SourceLocation Start)2782f4a2713aSLionel Sambuc Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
2783f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
2784f4a2713aSLionel Sambuc   ConsumeToken(); // Consume 'delete'
2785f4a2713aSLionel Sambuc 
2786f4a2713aSLionel Sambuc   // Array delete?
2787f4a2713aSLionel Sambuc   bool ArrayDelete = false;
2788f4a2713aSLionel Sambuc   if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {
2789f4a2713aSLionel Sambuc     // C++11 [expr.delete]p1:
2790f4a2713aSLionel Sambuc     //   Whenever the delete keyword is followed by empty square brackets, it
2791f4a2713aSLionel Sambuc     //   shall be interpreted as [array delete].
2792f4a2713aSLionel Sambuc     //   [Footnote: A lambda expression with a lambda-introducer that consists
2793f4a2713aSLionel Sambuc     //              of empty square brackets can follow the delete keyword if
2794f4a2713aSLionel Sambuc     //              the lambda expression is enclosed in parentheses.]
2795f4a2713aSLionel Sambuc     // FIXME: Produce a better diagnostic if the '[]' is unambiguously a
2796f4a2713aSLionel Sambuc     //        lambda-introducer.
2797f4a2713aSLionel Sambuc     ArrayDelete = true;
2798f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_square);
2799f4a2713aSLionel Sambuc 
2800f4a2713aSLionel Sambuc     T.consumeOpen();
2801f4a2713aSLionel Sambuc     T.consumeClose();
2802f4a2713aSLionel Sambuc     if (T.getCloseLocation().isInvalid())
2803f4a2713aSLionel Sambuc       return ExprError();
2804f4a2713aSLionel Sambuc   }
2805f4a2713aSLionel Sambuc 
2806f4a2713aSLionel Sambuc   ExprResult Operand(ParseCastExpression(false));
2807f4a2713aSLionel Sambuc   if (Operand.isInvalid())
2808f4a2713aSLionel Sambuc     return Operand;
2809f4a2713aSLionel Sambuc 
2810*0a6a1f1dSLionel Sambuc   return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.get());
2811f4a2713aSLionel Sambuc }
2812f4a2713aSLionel Sambuc 
TypeTraitFromTokKind(tok::TokenKind kind)2813f4a2713aSLionel Sambuc static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
2814f4a2713aSLionel Sambuc   switch (kind) {
2815f4a2713aSLionel Sambuc   default: llvm_unreachable("Not a known type trait");
2816*0a6a1f1dSLionel Sambuc #define TYPE_TRAIT_1(Spelling, Name, Key) \
2817*0a6a1f1dSLionel Sambuc case tok::kw_ ## Spelling: return UTT_ ## Name;
2818*0a6a1f1dSLionel Sambuc #define TYPE_TRAIT_2(Spelling, Name, Key) \
2819*0a6a1f1dSLionel Sambuc case tok::kw_ ## Spelling: return BTT_ ## Name;
2820*0a6a1f1dSLionel Sambuc #include "clang/Basic/TokenKinds.def"
2821*0a6a1f1dSLionel Sambuc #define TYPE_TRAIT_N(Spelling, Name, Key) \
2822*0a6a1f1dSLionel Sambuc   case tok::kw_ ## Spelling: return TT_ ## Name;
2823*0a6a1f1dSLionel Sambuc #include "clang/Basic/TokenKinds.def"
2824f4a2713aSLionel Sambuc   }
2825f4a2713aSLionel Sambuc }
2826f4a2713aSLionel Sambuc 
ArrayTypeTraitFromTokKind(tok::TokenKind kind)2827f4a2713aSLionel Sambuc static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) {
2828f4a2713aSLionel Sambuc   switch(kind) {
2829f4a2713aSLionel Sambuc   default: llvm_unreachable("Not a known binary type trait");
2830f4a2713aSLionel Sambuc   case tok::kw___array_rank:                 return ATT_ArrayRank;
2831f4a2713aSLionel Sambuc   case tok::kw___array_extent:               return ATT_ArrayExtent;
2832f4a2713aSLionel Sambuc   }
2833f4a2713aSLionel Sambuc }
2834f4a2713aSLionel Sambuc 
ExpressionTraitFromTokKind(tok::TokenKind kind)2835f4a2713aSLionel Sambuc static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) {
2836f4a2713aSLionel Sambuc   switch(kind) {
2837f4a2713aSLionel Sambuc   default: llvm_unreachable("Not a known unary expression trait.");
2838f4a2713aSLionel Sambuc   case tok::kw___is_lvalue_expr:             return ET_IsLValueExpr;
2839f4a2713aSLionel Sambuc   case tok::kw___is_rvalue_expr:             return ET_IsRValueExpr;
2840f4a2713aSLionel Sambuc   }
2841f4a2713aSLionel Sambuc }
2842f4a2713aSLionel Sambuc 
TypeTraitArity(tok::TokenKind kind)2843*0a6a1f1dSLionel Sambuc static unsigned TypeTraitArity(tok::TokenKind kind) {
2844*0a6a1f1dSLionel Sambuc   switch (kind) {
2845*0a6a1f1dSLionel Sambuc     default: llvm_unreachable("Not a known type trait");
2846*0a6a1f1dSLionel Sambuc #define TYPE_TRAIT(N,Spelling,K) case tok::kw_##Spelling: return N;
2847*0a6a1f1dSLionel Sambuc #include "clang/Basic/TokenKinds.def"
2848f4a2713aSLionel Sambuc   }
2849f4a2713aSLionel Sambuc }
2850f4a2713aSLionel Sambuc 
2851f4a2713aSLionel Sambuc /// \brief Parse the built-in type-trait pseudo-functions that allow
2852f4a2713aSLionel Sambuc /// implementation of the TR1/C++11 type traits templates.
2853f4a2713aSLionel Sambuc ///
2854f4a2713aSLionel Sambuc ///       primary-expression:
2855*0a6a1f1dSLionel Sambuc ///          unary-type-trait '(' type-id ')'
2856*0a6a1f1dSLionel Sambuc ///          binary-type-trait '(' type-id ',' type-id ')'
2857f4a2713aSLionel Sambuc ///          type-trait '(' type-id-seq ')'
2858f4a2713aSLionel Sambuc ///
2859f4a2713aSLionel Sambuc ///       type-id-seq:
2860f4a2713aSLionel Sambuc ///          type-id ...[opt] type-id-seq[opt]
2861f4a2713aSLionel Sambuc ///
ParseTypeTrait()2862f4a2713aSLionel Sambuc ExprResult Parser::ParseTypeTrait() {
2863*0a6a1f1dSLionel Sambuc   tok::TokenKind Kind = Tok.getKind();
2864*0a6a1f1dSLionel Sambuc   unsigned Arity = TypeTraitArity(Kind);
2865*0a6a1f1dSLionel Sambuc 
2866f4a2713aSLionel Sambuc   SourceLocation Loc = ConsumeToken();
2867f4a2713aSLionel Sambuc 
2868f4a2713aSLionel Sambuc   BalancedDelimiterTracker Parens(*this, tok::l_paren);
2869*0a6a1f1dSLionel Sambuc   if (Parens.expectAndConsume())
2870f4a2713aSLionel Sambuc     return ExprError();
2871f4a2713aSLionel Sambuc 
2872f4a2713aSLionel Sambuc   SmallVector<ParsedType, 2> Args;
2873f4a2713aSLionel Sambuc   do {
2874f4a2713aSLionel Sambuc     // Parse the next type.
2875f4a2713aSLionel Sambuc     TypeResult Ty = ParseTypeName();
2876f4a2713aSLionel Sambuc     if (Ty.isInvalid()) {
2877f4a2713aSLionel Sambuc       Parens.skipToEnd();
2878f4a2713aSLionel Sambuc       return ExprError();
2879f4a2713aSLionel Sambuc     }
2880f4a2713aSLionel Sambuc 
2881f4a2713aSLionel Sambuc     // Parse the ellipsis, if present.
2882f4a2713aSLionel Sambuc     if (Tok.is(tok::ellipsis)) {
2883f4a2713aSLionel Sambuc       Ty = Actions.ActOnPackExpansion(Ty.get(), ConsumeToken());
2884f4a2713aSLionel Sambuc       if (Ty.isInvalid()) {
2885f4a2713aSLionel Sambuc         Parens.skipToEnd();
2886f4a2713aSLionel Sambuc         return ExprError();
2887f4a2713aSLionel Sambuc       }
2888f4a2713aSLionel Sambuc     }
2889f4a2713aSLionel Sambuc 
2890f4a2713aSLionel Sambuc     // Add this type to the list of arguments.
2891f4a2713aSLionel Sambuc     Args.push_back(Ty.get());
2892*0a6a1f1dSLionel Sambuc   } while (TryConsumeToken(tok::comma));
2893f4a2713aSLionel Sambuc 
2894f4a2713aSLionel Sambuc   if (Parens.consumeClose())
2895f4a2713aSLionel Sambuc     return ExprError();
2896f4a2713aSLionel Sambuc 
2897*0a6a1f1dSLionel Sambuc   SourceLocation EndLoc = Parens.getCloseLocation();
2898*0a6a1f1dSLionel Sambuc 
2899*0a6a1f1dSLionel Sambuc   if (Arity && Args.size() != Arity) {
2900*0a6a1f1dSLionel Sambuc     Diag(EndLoc, diag::err_type_trait_arity)
2901*0a6a1f1dSLionel Sambuc       << Arity << 0 << (Arity > 1) << (int)Args.size() << SourceRange(Loc);
2902*0a6a1f1dSLionel Sambuc     return ExprError();
2903*0a6a1f1dSLionel Sambuc   }
2904*0a6a1f1dSLionel Sambuc 
2905*0a6a1f1dSLionel Sambuc   if (!Arity && Args.empty()) {
2906*0a6a1f1dSLionel Sambuc     Diag(EndLoc, diag::err_type_trait_arity)
2907*0a6a1f1dSLionel Sambuc       << 1 << 1 << 1 << (int)Args.size() << SourceRange(Loc);
2908*0a6a1f1dSLionel Sambuc     return ExprError();
2909*0a6a1f1dSLionel Sambuc   }
2910*0a6a1f1dSLionel Sambuc 
2911*0a6a1f1dSLionel Sambuc   return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, EndLoc);
2912f4a2713aSLionel Sambuc }
2913f4a2713aSLionel Sambuc 
2914f4a2713aSLionel Sambuc /// ParseArrayTypeTrait - Parse the built-in array type-trait
2915f4a2713aSLionel Sambuc /// pseudo-functions.
2916f4a2713aSLionel Sambuc ///
2917f4a2713aSLionel Sambuc ///       primary-expression:
2918f4a2713aSLionel Sambuc /// [Embarcadero]     '__array_rank' '(' type-id ')'
2919f4a2713aSLionel Sambuc /// [Embarcadero]     '__array_extent' '(' type-id ',' expression ')'
2920f4a2713aSLionel Sambuc ///
ParseArrayTypeTrait()2921f4a2713aSLionel Sambuc ExprResult Parser::ParseArrayTypeTrait() {
2922f4a2713aSLionel Sambuc   ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind());
2923f4a2713aSLionel Sambuc   SourceLocation Loc = ConsumeToken();
2924f4a2713aSLionel Sambuc 
2925f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
2926*0a6a1f1dSLionel Sambuc   if (T.expectAndConsume())
2927f4a2713aSLionel Sambuc     return ExprError();
2928f4a2713aSLionel Sambuc 
2929f4a2713aSLionel Sambuc   TypeResult Ty = ParseTypeName();
2930f4a2713aSLionel Sambuc   if (Ty.isInvalid()) {
2931f4a2713aSLionel Sambuc     SkipUntil(tok::comma, StopAtSemi);
2932f4a2713aSLionel Sambuc     SkipUntil(tok::r_paren, StopAtSemi);
2933f4a2713aSLionel Sambuc     return ExprError();
2934f4a2713aSLionel Sambuc   }
2935f4a2713aSLionel Sambuc 
2936f4a2713aSLionel Sambuc   switch (ATT) {
2937f4a2713aSLionel Sambuc   case ATT_ArrayRank: {
2938f4a2713aSLionel Sambuc     T.consumeClose();
2939*0a6a1f1dSLionel Sambuc     return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), nullptr,
2940f4a2713aSLionel Sambuc                                        T.getCloseLocation());
2941f4a2713aSLionel Sambuc   }
2942f4a2713aSLionel Sambuc   case ATT_ArrayExtent: {
2943*0a6a1f1dSLionel Sambuc     if (ExpectAndConsume(tok::comma)) {
2944f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
2945f4a2713aSLionel Sambuc       return ExprError();
2946f4a2713aSLionel Sambuc     }
2947f4a2713aSLionel Sambuc 
2948f4a2713aSLionel Sambuc     ExprResult DimExpr = ParseExpression();
2949f4a2713aSLionel Sambuc     T.consumeClose();
2950f4a2713aSLionel Sambuc 
2951f4a2713aSLionel Sambuc     return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(),
2952f4a2713aSLionel Sambuc                                        T.getCloseLocation());
2953f4a2713aSLionel Sambuc   }
2954f4a2713aSLionel Sambuc   }
2955f4a2713aSLionel Sambuc   llvm_unreachable("Invalid ArrayTypeTrait!");
2956f4a2713aSLionel Sambuc }
2957f4a2713aSLionel Sambuc 
2958f4a2713aSLionel Sambuc /// ParseExpressionTrait - Parse built-in expression-trait
2959f4a2713aSLionel Sambuc /// pseudo-functions like __is_lvalue_expr( xxx ).
2960f4a2713aSLionel Sambuc ///
2961f4a2713aSLionel Sambuc ///       primary-expression:
2962f4a2713aSLionel Sambuc /// [Embarcadero]     expression-trait '(' expression ')'
2963f4a2713aSLionel Sambuc ///
ParseExpressionTrait()2964f4a2713aSLionel Sambuc ExprResult Parser::ParseExpressionTrait() {
2965f4a2713aSLionel Sambuc   ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind());
2966f4a2713aSLionel Sambuc   SourceLocation Loc = ConsumeToken();
2967f4a2713aSLionel Sambuc 
2968f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
2969*0a6a1f1dSLionel Sambuc   if (T.expectAndConsume())
2970f4a2713aSLionel Sambuc     return ExprError();
2971f4a2713aSLionel Sambuc 
2972f4a2713aSLionel Sambuc   ExprResult Expr = ParseExpression();
2973f4a2713aSLionel Sambuc 
2974f4a2713aSLionel Sambuc   T.consumeClose();
2975f4a2713aSLionel Sambuc 
2976f4a2713aSLionel Sambuc   return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(),
2977f4a2713aSLionel Sambuc                                       T.getCloseLocation());
2978f4a2713aSLionel Sambuc }
2979f4a2713aSLionel Sambuc 
2980f4a2713aSLionel Sambuc 
2981f4a2713aSLionel Sambuc /// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
2982f4a2713aSLionel Sambuc /// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
2983f4a2713aSLionel Sambuc /// based on the context past the parens.
2984f4a2713aSLionel Sambuc ExprResult
ParseCXXAmbiguousParenExpression(ParenParseOption & ExprType,ParsedType & CastTy,BalancedDelimiterTracker & Tracker,ColonProtectionRAIIObject & ColonProt)2985f4a2713aSLionel Sambuc Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
2986f4a2713aSLionel Sambuc                                          ParsedType &CastTy,
2987*0a6a1f1dSLionel Sambuc                                          BalancedDelimiterTracker &Tracker,
2988*0a6a1f1dSLionel Sambuc                                          ColonProtectionRAIIObject &ColonProt) {
2989f4a2713aSLionel Sambuc   assert(getLangOpts().CPlusPlus && "Should only be called for C++!");
2990f4a2713aSLionel Sambuc   assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
2991f4a2713aSLionel Sambuc   assert(isTypeIdInParens() && "Not a type-id!");
2992f4a2713aSLionel Sambuc 
2993f4a2713aSLionel Sambuc   ExprResult Result(true);
2994f4a2713aSLionel Sambuc   CastTy = ParsedType();
2995f4a2713aSLionel Sambuc 
2996f4a2713aSLionel Sambuc   // We need to disambiguate a very ugly part of the C++ syntax:
2997f4a2713aSLionel Sambuc   //
2998f4a2713aSLionel Sambuc   // (T())x;  - type-id
2999f4a2713aSLionel Sambuc   // (T())*x; - type-id
3000f4a2713aSLionel Sambuc   // (T())/x; - expression
3001f4a2713aSLionel Sambuc   // (T());   - expression
3002f4a2713aSLionel Sambuc   //
3003f4a2713aSLionel Sambuc   // The bad news is that we cannot use the specialized tentative parser, since
3004f4a2713aSLionel Sambuc   // it can only verify that the thing inside the parens can be parsed as
3005f4a2713aSLionel Sambuc   // type-id, it is not useful for determining the context past the parens.
3006f4a2713aSLionel Sambuc   //
3007f4a2713aSLionel Sambuc   // The good news is that the parser can disambiguate this part without
3008f4a2713aSLionel Sambuc   // making any unnecessary Action calls.
3009f4a2713aSLionel Sambuc   //
3010f4a2713aSLionel Sambuc   // It uses a scheme similar to parsing inline methods. The parenthesized
3011f4a2713aSLionel Sambuc   // tokens are cached, the context that follows is determined (possibly by
3012f4a2713aSLionel Sambuc   // parsing a cast-expression), and then we re-introduce the cached tokens
3013f4a2713aSLionel Sambuc   // into the token stream and parse them appropriately.
3014f4a2713aSLionel Sambuc 
3015f4a2713aSLionel Sambuc   ParenParseOption ParseAs;
3016f4a2713aSLionel Sambuc   CachedTokens Toks;
3017f4a2713aSLionel Sambuc 
3018f4a2713aSLionel Sambuc   // Store the tokens of the parentheses. We will parse them after we determine
3019f4a2713aSLionel Sambuc   // the context that follows them.
3020f4a2713aSLionel Sambuc   if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) {
3021f4a2713aSLionel Sambuc     // We didn't find the ')' we expected.
3022f4a2713aSLionel Sambuc     Tracker.consumeClose();
3023f4a2713aSLionel Sambuc     return ExprError();
3024f4a2713aSLionel Sambuc   }
3025f4a2713aSLionel Sambuc 
3026f4a2713aSLionel Sambuc   if (Tok.is(tok::l_brace)) {
3027f4a2713aSLionel Sambuc     ParseAs = CompoundLiteral;
3028f4a2713aSLionel Sambuc   } else {
3029f4a2713aSLionel Sambuc     bool NotCastExpr;
3030f4a2713aSLionel Sambuc     if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
3031f4a2713aSLionel Sambuc       NotCastExpr = true;
3032f4a2713aSLionel Sambuc     } else {
3033f4a2713aSLionel Sambuc       // Try parsing the cast-expression that may follow.
3034f4a2713aSLionel Sambuc       // If it is not a cast-expression, NotCastExpr will be true and no token
3035f4a2713aSLionel Sambuc       // will be consumed.
3036*0a6a1f1dSLionel Sambuc       ColonProt.restore();
3037f4a2713aSLionel Sambuc       Result = ParseCastExpression(false/*isUnaryExpression*/,
3038f4a2713aSLionel Sambuc                                    false/*isAddressofOperand*/,
3039f4a2713aSLionel Sambuc                                    NotCastExpr,
3040f4a2713aSLionel Sambuc                                    // type-id has priority.
3041f4a2713aSLionel Sambuc                                    IsTypeCast);
3042f4a2713aSLionel Sambuc     }
3043f4a2713aSLionel Sambuc 
3044f4a2713aSLionel Sambuc     // If we parsed a cast-expression, it's really a type-id, otherwise it's
3045f4a2713aSLionel Sambuc     // an expression.
3046f4a2713aSLionel Sambuc     ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
3047f4a2713aSLionel Sambuc   }
3048f4a2713aSLionel Sambuc 
3049f4a2713aSLionel Sambuc   // The current token should go after the cached tokens.
3050f4a2713aSLionel Sambuc   Toks.push_back(Tok);
3051f4a2713aSLionel Sambuc   // Re-enter the stored parenthesized tokens into the token stream, so we may
3052f4a2713aSLionel Sambuc   // parse them now.
3053f4a2713aSLionel Sambuc   PP.EnterTokenStream(Toks.data(), Toks.size(),
3054f4a2713aSLionel Sambuc                       true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
3055f4a2713aSLionel Sambuc   // Drop the current token and bring the first cached one. It's the same token
3056f4a2713aSLionel Sambuc   // as when we entered this function.
3057f4a2713aSLionel Sambuc   ConsumeAnyToken();
3058f4a2713aSLionel Sambuc 
3059f4a2713aSLionel Sambuc   if (ParseAs >= CompoundLiteral) {
3060f4a2713aSLionel Sambuc     // Parse the type declarator.
3061f4a2713aSLionel Sambuc     DeclSpec DS(AttrFactory);
3062f4a2713aSLionel Sambuc     Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
3063*0a6a1f1dSLionel Sambuc     {
3064*0a6a1f1dSLionel Sambuc       ColonProtectionRAIIObject InnerColonProtection(*this);
3065*0a6a1f1dSLionel Sambuc       ParseSpecifierQualifierList(DS);
3066f4a2713aSLionel Sambuc       ParseDeclarator(DeclaratorInfo);
3067*0a6a1f1dSLionel Sambuc     }
3068f4a2713aSLionel Sambuc 
3069f4a2713aSLionel Sambuc     // Match the ')'.
3070f4a2713aSLionel Sambuc     Tracker.consumeClose();
3071*0a6a1f1dSLionel Sambuc     ColonProt.restore();
3072f4a2713aSLionel Sambuc 
3073f4a2713aSLionel Sambuc     if (ParseAs == CompoundLiteral) {
3074f4a2713aSLionel Sambuc       ExprType = CompoundLiteral;
3075*0a6a1f1dSLionel Sambuc       if (DeclaratorInfo.isInvalidType())
3076*0a6a1f1dSLionel Sambuc         return ExprError();
3077*0a6a1f1dSLionel Sambuc 
3078*0a6a1f1dSLionel Sambuc       TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
3079f4a2713aSLionel Sambuc       return ParseCompoundLiteralExpression(Ty.get(),
3080f4a2713aSLionel Sambuc                                             Tracker.getOpenLocation(),
3081f4a2713aSLionel Sambuc                                             Tracker.getCloseLocation());
3082f4a2713aSLionel Sambuc     }
3083f4a2713aSLionel Sambuc 
3084f4a2713aSLionel Sambuc     // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
3085f4a2713aSLionel Sambuc     assert(ParseAs == CastExpr);
3086f4a2713aSLionel Sambuc 
3087f4a2713aSLionel Sambuc     if (DeclaratorInfo.isInvalidType())
3088f4a2713aSLionel Sambuc       return ExprError();
3089f4a2713aSLionel Sambuc 
3090f4a2713aSLionel Sambuc     // Result is what ParseCastExpression returned earlier.
3091f4a2713aSLionel Sambuc     if (!Result.isInvalid())
3092f4a2713aSLionel Sambuc       Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(),
3093f4a2713aSLionel Sambuc                                     DeclaratorInfo, CastTy,
3094*0a6a1f1dSLionel Sambuc                                     Tracker.getCloseLocation(), Result.get());
3095f4a2713aSLionel Sambuc     return Result;
3096f4a2713aSLionel Sambuc   }
3097f4a2713aSLionel Sambuc 
3098f4a2713aSLionel Sambuc   // Not a compound literal, and not followed by a cast-expression.
3099f4a2713aSLionel Sambuc   assert(ParseAs == SimpleExpr);
3100f4a2713aSLionel Sambuc 
3101f4a2713aSLionel Sambuc   ExprType = SimpleExpr;
3102f4a2713aSLionel Sambuc   Result = ParseExpression();
3103f4a2713aSLionel Sambuc   if (!Result.isInvalid() && Tok.is(tok::r_paren))
3104f4a2713aSLionel Sambuc     Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(),
3105*0a6a1f1dSLionel Sambuc                                     Tok.getLocation(), Result.get());
3106f4a2713aSLionel Sambuc 
3107f4a2713aSLionel Sambuc   // Match the ')'.
3108f4a2713aSLionel Sambuc   if (Result.isInvalid()) {
3109f4a2713aSLionel Sambuc     SkipUntil(tok::r_paren, StopAtSemi);
3110f4a2713aSLionel Sambuc     return ExprError();
3111f4a2713aSLionel Sambuc   }
3112f4a2713aSLionel Sambuc 
3113f4a2713aSLionel Sambuc   Tracker.consumeClose();
3114f4a2713aSLionel Sambuc   return Result;
3115f4a2713aSLionel Sambuc }
3116