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