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