blob: dc7974135d3ca520fe32e92171534e2f7f1e30f3 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Expression parsing implementation for C++.
11//
12//===----------------------------------------------------------------------===//
13
Chris Lattner500d3292009-01-29 05:15:15 +000014#include "clang/Parse/ParseDiagnostic.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000015#include "clang/Parse/Parser.h"
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000016#include "clang/Parse/DeclSpec.h"
Douglas Gregor3f9a0562009-11-03 01:35:08 +000017#include "llvm/Support/ErrorHandling.h"
18
Reid Spencer5f016e22007-07-11 17:01:13 +000019using namespace clang;
20
Mike Stump1eb44332009-09-09 15:08:12 +000021/// \brief Parse global scope or nested-name-specifier if present.
Douglas Gregor2dd078a2009-09-02 22:59:36 +000022///
23/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
Mike Stump1eb44332009-09-09 15:08:12 +000024/// may be preceded by '::'). Note that this routine will not parse ::new or
Douglas Gregor2dd078a2009-09-02 22:59:36 +000025/// ::delete; it will just leave them in the token stream.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000026///
27/// '::'[opt] nested-name-specifier
28/// '::'
29///
30/// nested-name-specifier:
31/// type-name '::'
32/// namespace-name '::'
33/// nested-name-specifier identifier '::'
Douglas Gregor2dd078a2009-09-02 22:59:36 +000034/// nested-name-specifier 'template'[opt] simple-template-id '::'
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000035///
Douglas Gregor2dd078a2009-09-02 22:59:36 +000036///
Mike Stump1eb44332009-09-09 15:08:12 +000037/// \param SS the scope specifier that will be set to the parsed
Douglas Gregor2dd078a2009-09-02 22:59:36 +000038/// nested-name-specifier (or empty)
39///
Mike Stump1eb44332009-09-09 15:08:12 +000040/// \param ObjectType if this nested-name-specifier is being parsed following
Douglas Gregor2dd078a2009-09-02 22:59:36 +000041/// the "." or "->" of a member access expression, this parameter provides the
42/// type of the object whose members are being accessed.
43///
44/// \param EnteringContext whether we will be entering into the context of
45/// the nested-name-specifier after parsing it.
46///
47/// \returns true if a scope specifier was parsed.
Douglas Gregor495c35d2009-08-25 22:51:20 +000048bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
Douglas Gregor2dd078a2009-09-02 22:59:36 +000049 Action::TypeTy *ObjectType,
Douglas Gregor495c35d2009-08-25 22:51:20 +000050 bool EnteringContext) {
Argyrios Kyrtzidis4bdd91c2008-11-26 21:41:52 +000051 assert(getLang().CPlusPlus &&
Chris Lattner7452c6f2009-01-05 01:24:05 +000052 "Call sites of this function should be guarded by checking for C++");
Mike Stump1eb44332009-09-09 15:08:12 +000053
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000054 if (Tok.is(tok::annot_cxxscope)) {
Douglas Gregor35073692009-03-26 23:56:24 +000055 SS.setScopeRep(Tok.getAnnotationValue());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000056 SS.setRange(Tok.getAnnotationRange());
57 ConsumeToken();
Argyrios Kyrtzidis4bdd91c2008-11-26 21:41:52 +000058 return true;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000059 }
Chris Lattnere607e802009-01-04 21:14:15 +000060
Douglas Gregor39a8de12009-02-25 19:37:18 +000061 bool HasScopeSpecifier = false;
62
Chris Lattner5b454732009-01-05 03:55:46 +000063 if (Tok.is(tok::coloncolon)) {
64 // ::new and ::delete aren't nested-name-specifiers.
65 tok::TokenKind NextKind = NextToken().getKind();
66 if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
67 return false;
Mike Stump1eb44332009-09-09 15:08:12 +000068
Chris Lattner55a7cef2009-01-05 00:13:00 +000069 // '::' - Global scope qualifier.
Chris Lattner357089d2009-01-05 02:07:19 +000070 SourceLocation CCLoc = ConsumeToken();
Chris Lattner357089d2009-01-05 02:07:19 +000071 SS.setBeginLoc(CCLoc);
Douglas Gregor35073692009-03-26 23:56:24 +000072 SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
Chris Lattner357089d2009-01-05 02:07:19 +000073 SS.setEndLoc(CCLoc);
Douglas Gregor39a8de12009-02-25 19:37:18 +000074 HasScopeSpecifier = true;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000075 }
76
Douglas Gregor39a8de12009-02-25 19:37:18 +000077 while (true) {
Douglas Gregor2dd078a2009-09-02 22:59:36 +000078 if (HasScopeSpecifier) {
79 // C++ [basic.lookup.classref]p5:
80 // If the qualified-id has the form
Douglas Gregor3b6afbb2009-09-09 00:23:06 +000081 //
Douglas Gregor2dd078a2009-09-02 22:59:36 +000082 // ::class-name-or-namespace-name::...
Douglas Gregor3b6afbb2009-09-09 00:23:06 +000083 //
Douglas Gregor2dd078a2009-09-02 22:59:36 +000084 // the class-name-or-namespace-name is looked up in global scope as a
85 // class-name or namespace-name.
86 //
87 // To implement this, we clear out the object type as soon as we've
88 // seen a leading '::' or part of a nested-name-specifier.
89 ObjectType = 0;
Douglas Gregor81b747b2009-09-17 21:32:03 +000090
91 if (Tok.is(tok::code_completion)) {
92 // Code completion for a nested-name-specifier, where the code
93 // code completion token follows the '::'.
94 Actions.CodeCompleteQualifiedId(CurScope, SS, EnteringContext);
95 ConsumeToken();
96 }
Douglas Gregor2dd078a2009-09-02 22:59:36 +000097 }
Mike Stump1eb44332009-09-09 15:08:12 +000098
Douglas Gregor39a8de12009-02-25 19:37:18 +000099 // nested-name-specifier:
Chris Lattner77cf72a2009-06-26 03:47:46 +0000100 // nested-name-specifier 'template'[opt] simple-template-id '::'
101
102 // Parse the optional 'template' keyword, then make sure we have
103 // 'identifier <' after it.
104 if (Tok.is(tok::kw_template)) {
Douglas Gregor2dd078a2009-09-02 22:59:36 +0000105 // If we don't have a scope specifier or an object type, this isn't a
Eli Friedmaneab975d2009-08-29 04:08:08 +0000106 // nested-name-specifier, since they aren't allowed to start with
107 // 'template'.
Douglas Gregor2dd078a2009-09-02 22:59:36 +0000108 if (!HasScopeSpecifier && !ObjectType)
Eli Friedmaneab975d2009-08-29 04:08:08 +0000109 break;
110
Chris Lattner77cf72a2009-06-26 03:47:46 +0000111 SourceLocation TemplateKWLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +0000112
Chris Lattner77cf72a2009-06-26 03:47:46 +0000113 if (Tok.isNot(tok::identifier)) {
Mike Stump1eb44332009-09-09 15:08:12 +0000114 Diag(Tok.getLocation(),
Chris Lattner77cf72a2009-06-26 03:47:46 +0000115 diag::err_id_after_template_in_nested_name_spec)
116 << SourceRange(TemplateKWLoc);
117 break;
118 }
Mike Stump1eb44332009-09-09 15:08:12 +0000119
Chris Lattner77cf72a2009-06-26 03:47:46 +0000120 if (NextToken().isNot(tok::less)) {
121 Diag(NextToken().getLocation(),
122 diag::err_less_after_template_name_in_nested_name_spec)
123 << Tok.getIdentifierInfo()->getName()
124 << SourceRange(TemplateKWLoc, Tok.getLocation());
125 break;
126 }
Mike Stump1eb44332009-09-09 15:08:12 +0000127
128 TemplateTy Template
Chris Lattner77cf72a2009-06-26 03:47:46 +0000129 = Actions.ActOnDependentTemplateName(TemplateKWLoc,
130 *Tok.getIdentifierInfo(),
Douglas Gregor2dd078a2009-09-02 22:59:36 +0000131 Tok.getLocation(), SS,
132 ObjectType);
Eli Friedmaneab975d2009-08-29 04:08:08 +0000133 if (!Template)
134 break;
Chris Lattnerc8e27cc2009-06-26 04:27:47 +0000135 if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
136 &SS, TemplateKWLoc, false))
137 break;
Mike Stump1eb44332009-09-09 15:08:12 +0000138
Chris Lattner77cf72a2009-06-26 03:47:46 +0000139 continue;
140 }
Mike Stump1eb44332009-09-09 15:08:12 +0000141
Douglas Gregor39a8de12009-02-25 19:37:18 +0000142 if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
Mike Stump1eb44332009-09-09 15:08:12 +0000143 // We have
Douglas Gregor39a8de12009-02-25 19:37:18 +0000144 //
145 // simple-template-id '::'
146 //
147 // So we need to check whether the simple-template-id is of the
Douglas Gregorc45c2322009-03-31 00:43:58 +0000148 // right kind (it should name a type or be dependent), and then
149 // convert it into a type within the nested-name-specifier.
Mike Stump1eb44332009-09-09 15:08:12 +0000150 TemplateIdAnnotation *TemplateId
Douglas Gregor39a8de12009-02-25 19:37:18 +0000151 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
152
Mike Stump1eb44332009-09-09 15:08:12 +0000153 if (TemplateId->Kind == TNK_Type_template ||
Douglas Gregorc45c2322009-03-31 00:43:58 +0000154 TemplateId->Kind == TNK_Dependent_template_name) {
Douglas Gregor31a19b62009-04-01 21:51:26 +0000155 AnnotateTemplateIdTokenAsType(&SS);
Douglas Gregor39a8de12009-02-25 19:37:18 +0000156
Mike Stump1eb44332009-09-09 15:08:12 +0000157 assert(Tok.is(tok::annot_typename) &&
Douglas Gregor39a8de12009-02-25 19:37:18 +0000158 "AnnotateTemplateIdTokenAsType isn't working");
Douglas Gregor39a8de12009-02-25 19:37:18 +0000159 Token TypeToken = Tok;
160 ConsumeToken();
161 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
162 SourceLocation CCLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +0000163
Douglas Gregor39a8de12009-02-25 19:37:18 +0000164 if (!HasScopeSpecifier) {
165 SS.setBeginLoc(TypeToken.getLocation());
166 HasScopeSpecifier = true;
167 }
Mike Stump1eb44332009-09-09 15:08:12 +0000168
Douglas Gregor31a19b62009-04-01 21:51:26 +0000169 if (TypeToken.getAnnotationValue())
170 SS.setScopeRep(
Mike Stump1eb44332009-09-09 15:08:12 +0000171 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
Douglas Gregor31a19b62009-04-01 21:51:26 +0000172 TypeToken.getAnnotationValue(),
173 TypeToken.getAnnotationRange(),
174 CCLoc));
175 else
176 SS.setScopeRep(0);
Douglas Gregor39a8de12009-02-25 19:37:18 +0000177 SS.setEndLoc(CCLoc);
178 continue;
Chris Lattner67b9e832009-06-26 03:45:46 +0000179 }
Mike Stump1eb44332009-09-09 15:08:12 +0000180
Chris Lattner67b9e832009-06-26 03:45:46 +0000181 assert(false && "FIXME: Only type template names supported here");
Douglas Gregor39a8de12009-02-25 19:37:18 +0000182 }
183
Chris Lattner5c7f7862009-06-26 03:52:38 +0000184
185 // The rest of the nested-name-specifier possibilities start with
186 // tok::identifier.
187 if (Tok.isNot(tok::identifier))
188 break;
189
190 IdentifierInfo &II = *Tok.getIdentifierInfo();
191
192 // nested-name-specifier:
193 // type-name '::'
194 // namespace-name '::'
195 // nested-name-specifier identifier '::'
196 Token Next = NextToken();
197 if (Next.is(tok::coloncolon)) {
198 // We have an identifier followed by a '::'. Lookup this name
199 // as the name in a nested-name-specifier.
200 SourceLocation IdLoc = ConsumeToken();
201 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
202 SourceLocation CCLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +0000203
Chris Lattner5c7f7862009-06-26 03:52:38 +0000204 if (!HasScopeSpecifier) {
205 SS.setBeginLoc(IdLoc);
206 HasScopeSpecifier = true;
207 }
Mike Stump1eb44332009-09-09 15:08:12 +0000208
Chris Lattner5c7f7862009-06-26 03:52:38 +0000209 if (SS.isInvalid())
210 continue;
Mike Stump1eb44332009-09-09 15:08:12 +0000211
Chris Lattner5c7f7862009-06-26 03:52:38 +0000212 SS.setScopeRep(
Douglas Gregor495c35d2009-08-25 22:51:20 +0000213 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, II,
Douglas Gregor2dd078a2009-09-02 22:59:36 +0000214 ObjectType, EnteringContext));
Chris Lattner5c7f7862009-06-26 03:52:38 +0000215 SS.setEndLoc(CCLoc);
216 continue;
217 }
Mike Stump1eb44332009-09-09 15:08:12 +0000218
Chris Lattner5c7f7862009-06-26 03:52:38 +0000219 // nested-name-specifier:
220 // type-name '<'
221 if (Next.is(tok::less)) {
222 TemplateTy Template;
Douglas Gregor2dd078a2009-09-02 22:59:36 +0000223 if (TemplateNameKind TNK = Actions.isTemplateName(CurScope, II,
224 Tok.getLocation(),
225 &SS,
226 ObjectType,
Douglas Gregor495c35d2009-08-25 22:51:20 +0000227 EnteringContext,
228 Template)) {
Chris Lattner5c7f7862009-06-26 03:52:38 +0000229 // We have found a template name, so annotate this this token
230 // with a template-id annotation. We do not permit the
231 // template-id to be translated into a type annotation,
232 // because some clients (e.g., the parsing of class template
233 // specializations) still want to see the original template-id
234 // token.
Chris Lattnerc8e27cc2009-06-26 04:27:47 +0000235 if (AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(),
236 false))
237 break;
Chris Lattner5c7f7862009-06-26 03:52:38 +0000238 continue;
239 }
240 }
241
Douglas Gregor39a8de12009-02-25 19:37:18 +0000242 // We don't have any tokens that form the beginning of a
243 // nested-name-specifier, so we're done.
244 break;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000245 }
Mike Stump1eb44332009-09-09 15:08:12 +0000246
Douglas Gregor39a8de12009-02-25 19:37:18 +0000247 return HasScopeSpecifier;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000248}
249
250/// ParseCXXIdExpression - Handle id-expression.
251///
252/// id-expression:
253/// unqualified-id
254/// qualified-id
255///
256/// unqualified-id:
257/// identifier
258/// operator-function-id
259/// conversion-function-id [TODO]
260/// '~' class-name [TODO]
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000261/// template-id
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000262///
263/// qualified-id:
264/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
265/// '::' identifier
266/// '::' operator-function-id
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000267/// '::' template-id
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000268///
269/// nested-name-specifier:
270/// type-name '::'
271/// namespace-name '::'
272/// nested-name-specifier identifier '::'
273/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
274///
275/// NOTE: The standard specifies that, for qualified-id, the parser does not
276/// expect:
277///
278/// '::' conversion-function-id
279/// '::' '~' class-name
280///
281/// This may cause a slight inconsistency on diagnostics:
282///
283/// class C {};
284/// namespace A {}
285/// void f() {
286/// :: A :: ~ C(); // Some Sema error about using destructor with a
287/// // namespace.
288/// :: ~ C(); // Some Parser error like 'unexpected ~'.
289/// }
290///
291/// We simplify the parser a bit and make it work like:
292///
293/// qualified-id:
294/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
295/// '::' unqualified-id
296///
297/// That way Sema can handle and report similar errors for namespaces and the
298/// global scope.
299///
Sebastian Redlebc07d52009-02-03 20:19:35 +0000300/// The isAddressOfOperand parameter indicates that this id-expression is a
301/// direct operand of the address-of operator. This is, besides member contexts,
302/// the only place where a qualified-id naming a non-static class member may
303/// appear.
304///
305Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000306 // qualified-id:
307 // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
308 // '::' unqualified-id
309 //
310 CXXScopeSpec SS;
Douglas Gregor2dd078a2009-09-02 22:59:36 +0000311 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000312
313 // unqualified-id:
314 // identifier
315 // operator-function-id
Douglas Gregor2def4832008-11-17 20:34:05 +0000316 // conversion-function-id
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000317 // '~' class-name [TODO]
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000318 // template-id
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000319 //
320 switch (Tok.getKind()) {
321 default:
Sebastian Redl20df9b72008-12-11 22:51:44 +0000322 return ExprError(Diag(Tok, diag::err_expected_unqualified_id));
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000323
324 case tok::identifier: {
325 // Consume the identifier so that we can see if it is followed by a '('.
326 IdentifierInfo &II = *Tok.getIdentifierInfo();
327 SourceLocation L = ConsumeToken();
Sebastian Redlebc07d52009-02-03 20:19:35 +0000328 return Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren),
329 &SS, isAddressOfOperand);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000330 }
331
332 case tok::kw_operator: {
333 SourceLocation OperatorLoc = Tok.getLocation();
Chris Lattner7452c6f2009-01-05 01:24:05 +0000334 if (OverloadedOperatorKind Op = TryParseOperatorFunctionId())
Sebastian Redlcd965b92009-01-18 18:53:16 +0000335 return Actions.ActOnCXXOperatorFunctionIdExpr(
Sebastian Redlebc07d52009-02-03 20:19:35 +0000336 CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS,
337 isAddressOfOperand);
Chris Lattner7452c6f2009-01-05 01:24:05 +0000338 if (TypeTy *Type = ParseConversionFunctionId())
Sebastian Redlcd965b92009-01-18 18:53:16 +0000339 return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type,
Sebastian Redlebc07d52009-02-03 20:19:35 +0000340 Tok.is(tok::l_paren), SS,
341 isAddressOfOperand);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000342
Douglas Gregor2def4832008-11-17 20:34:05 +0000343 // We already complained about a bad conversion-function-id,
344 // above.
Sebastian Redl20df9b72008-12-11 22:51:44 +0000345 return ExprError();
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000346 }
347
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000348 case tok::annot_template_id: {
Mike Stump1eb44332009-09-09 15:08:12 +0000349 TemplateIdAnnotation *TemplateId
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000350 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
351 assert((TemplateId->Kind == TNK_Function_template ||
352 TemplateId->Kind == TNK_Dependent_template_name) &&
353 "A template type name is not an ID expression");
354
Mike Stump1eb44332009-09-09 15:08:12 +0000355 ASTTemplateArgsPtr TemplateArgsPtr(Actions,
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000356 TemplateId->getTemplateArgs(),
357 TemplateId->getTemplateArgIsType(),
358 TemplateId->NumArgs);
Mike Stump1eb44332009-09-09 15:08:12 +0000359
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000360 OwningExprResult Result
Douglas Gregorf17bb742009-10-22 17:20:55 +0000361 = Actions.ActOnTemplateIdExpr(SS,
362 TemplateTy::make(TemplateId->Template),
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000363 TemplateId->TemplateNameLoc,
364 TemplateId->LAngleLoc,
365 TemplateArgsPtr,
366 TemplateId->getTemplateArgLocations(),
367 TemplateId->RAngleLoc);
368 ConsumeToken(); // Consume the template-id token
369 return move(Result);
370 }
371
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000372 } // switch.
373
374 assert(0 && "The switch was supposed to take care everything.");
375}
376
Reid Spencer5f016e22007-07-11 17:01:13 +0000377/// ParseCXXCasts - This handles the various ways to cast expressions to another
378/// type.
379///
380/// postfix-expression: [C++ 5.2p1]
381/// 'dynamic_cast' '<' type-name '>' '(' expression ')'
382/// 'static_cast' '<' type-name '>' '(' expression ')'
383/// 'reinterpret_cast' '<' type-name '>' '(' expression ')'
384/// 'const_cast' '<' type-name '>' '(' expression ')'
385///
Sebastian Redl20df9b72008-12-11 22:51:44 +0000386Parser::OwningExprResult Parser::ParseCXXCasts() {
Reid Spencer5f016e22007-07-11 17:01:13 +0000387 tok::TokenKind Kind = Tok.getKind();
388 const char *CastName = 0; // For error messages
389
390 switch (Kind) {
391 default: assert(0 && "Unknown C++ cast!"); abort();
392 case tok::kw_const_cast: CastName = "const_cast"; break;
393 case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break;
394 case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
395 case tok::kw_static_cast: CastName = "static_cast"; break;
396 }
397
398 SourceLocation OpLoc = ConsumeToken();
399 SourceLocation LAngleBracketLoc = Tok.getLocation();
400
401 if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
Sebastian Redl20df9b72008-12-11 22:51:44 +0000402 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000403
Douglas Gregor809070a2009-02-18 17:45:20 +0000404 TypeResult CastTy = ParseTypeName();
Reid Spencer5f016e22007-07-11 17:01:13 +0000405 SourceLocation RAngleBracketLoc = Tok.getLocation();
406
Chris Lattner1ab3b962008-11-18 07:48:38 +0000407 if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
Sebastian Redl20df9b72008-12-11 22:51:44 +0000408 return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
Reid Spencer5f016e22007-07-11 17:01:13 +0000409
410 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
411
Argyrios Kyrtzidis21e7ad22009-05-22 10:23:16 +0000412 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName))
413 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000414
Argyrios Kyrtzidis21e7ad22009-05-22 10:23:16 +0000415 OwningExprResult Result = ParseExpression();
Mike Stump1eb44332009-09-09 15:08:12 +0000416
Argyrios Kyrtzidis21e7ad22009-05-22 10:23:16 +0000417 // Match the ')'.
418 if (Result.isInvalid())
419 SkipUntil(tok::r_paren);
Mike Stump1eb44332009-09-09 15:08:12 +0000420
Argyrios Kyrtzidis21e7ad22009-05-22 10:23:16 +0000421 if (Tok.is(tok::r_paren))
422 RParenLoc = ConsumeParen();
423 else
424 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000425
Douglas Gregor809070a2009-02-18 17:45:20 +0000426 if (!Result.isInvalid() && !CastTy.isInvalid())
Douglas Gregor49badde2008-10-27 19:41:14 +0000427 Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
Sebastian Redlf53597f2009-03-15 17:47:39 +0000428 LAngleBracketLoc, CastTy.get(),
Douglas Gregor809070a2009-02-18 17:45:20 +0000429 RAngleBracketLoc,
Sebastian Redlf53597f2009-03-15 17:47:39 +0000430 LParenLoc, move(Result), RParenLoc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000431
Sebastian Redl20df9b72008-12-11 22:51:44 +0000432 return move(Result);
Reid Spencer5f016e22007-07-11 17:01:13 +0000433}
434
Sebastian Redlc42e1182008-11-11 11:37:55 +0000435/// ParseCXXTypeid - This handles the C++ typeid expression.
436///
437/// postfix-expression: [C++ 5.2p1]
438/// 'typeid' '(' expression ')'
439/// 'typeid' '(' type-id ')'
440///
Sebastian Redl20df9b72008-12-11 22:51:44 +0000441Parser::OwningExprResult Parser::ParseCXXTypeid() {
Sebastian Redlc42e1182008-11-11 11:37:55 +0000442 assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
443
444 SourceLocation OpLoc = ConsumeToken();
445 SourceLocation LParenLoc = Tok.getLocation();
446 SourceLocation RParenLoc;
447
448 // typeid expressions are always parenthesized.
449 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
450 "typeid"))
Sebastian Redl20df9b72008-12-11 22:51:44 +0000451 return ExprError();
Sebastian Redlc42e1182008-11-11 11:37:55 +0000452
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000453 OwningExprResult Result(Actions);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000454
455 if (isTypeIdInParens()) {
Douglas Gregor809070a2009-02-18 17:45:20 +0000456 TypeResult Ty = ParseTypeName();
Sebastian Redlc42e1182008-11-11 11:37:55 +0000457
458 // Match the ')'.
459 MatchRHSPunctuation(tok::r_paren, LParenLoc);
460
Douglas Gregor809070a2009-02-18 17:45:20 +0000461 if (Ty.isInvalid())
Sebastian Redl20df9b72008-12-11 22:51:44 +0000462 return ExprError();
Sebastian Redlc42e1182008-11-11 11:37:55 +0000463
464 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
Douglas Gregor809070a2009-02-18 17:45:20 +0000465 Ty.get(), RParenLoc);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000466 } else {
Douglas Gregore0762c92009-06-19 23:52:42 +0000467 // C++0x [expr.typeid]p3:
Mike Stump1eb44332009-09-09 15:08:12 +0000468 // When typeid is applied to an expression other than an lvalue of a
469 // polymorphic class type [...] The expression is an unevaluated
Douglas Gregore0762c92009-06-19 23:52:42 +0000470 // operand (Clause 5).
471 //
Mike Stump1eb44332009-09-09 15:08:12 +0000472 // Note that we can't tell whether the expression is an lvalue of a
Douglas Gregore0762c92009-06-19 23:52:42 +0000473 // polymorphic class type until after we've parsed the expression, so
Douglas Gregorac7610d2009-06-22 20:57:11 +0000474 // we the expression is potentially potentially evaluated.
475 EnterExpressionEvaluationContext Unevaluated(Actions,
476 Action::PotentiallyPotentiallyEvaluated);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000477 Result = ParseExpression();
478
479 // Match the ')'.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000480 if (Result.isInvalid())
Sebastian Redlc42e1182008-11-11 11:37:55 +0000481 SkipUntil(tok::r_paren);
482 else {
483 MatchRHSPunctuation(tok::r_paren, LParenLoc);
484
485 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
Sebastian Redleffa8d12008-12-10 00:02:53 +0000486 Result.release(), RParenLoc);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000487 }
488 }
489
Sebastian Redl20df9b72008-12-11 22:51:44 +0000490 return move(Result);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000491}
492
Reid Spencer5f016e22007-07-11 17:01:13 +0000493/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
494///
495/// boolean-literal: [C++ 2.13.5]
496/// 'true'
497/// 'false'
Sebastian Redl20df9b72008-12-11 22:51:44 +0000498Parser::OwningExprResult Parser::ParseCXXBoolLiteral() {
Reid Spencer5f016e22007-07-11 17:01:13 +0000499 tok::TokenKind Kind = Tok.getKind();
Sebastian Redlf53597f2009-03-15 17:47:39 +0000500 return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
Reid Spencer5f016e22007-07-11 17:01:13 +0000501}
Chris Lattner50dd2892008-02-26 00:51:44 +0000502
503/// ParseThrowExpression - This handles the C++ throw expression.
504///
505/// throw-expression: [C++ 15]
506/// 'throw' assignment-expression[opt]
Sebastian Redl20df9b72008-12-11 22:51:44 +0000507Parser::OwningExprResult Parser::ParseThrowExpression() {
Chris Lattner50dd2892008-02-26 00:51:44 +0000508 assert(Tok.is(tok::kw_throw) && "Not throw!");
Chris Lattner50dd2892008-02-26 00:51:44 +0000509 SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token.
Sebastian Redl20df9b72008-12-11 22:51:44 +0000510
Chris Lattner2a2819a2008-04-06 06:02:23 +0000511 // If the current token isn't the start of an assignment-expression,
512 // then the expression is not present. This handles things like:
513 // "C ? throw : (void)42", which is crazy but legal.
514 switch (Tok.getKind()) { // FIXME: move this predicate somewhere common.
515 case tok::semi:
516 case tok::r_paren:
517 case tok::r_square:
518 case tok::r_brace:
519 case tok::colon:
520 case tok::comma:
Sebastian Redlf53597f2009-03-15 17:47:39 +0000521 return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
Chris Lattner50dd2892008-02-26 00:51:44 +0000522
Chris Lattner2a2819a2008-04-06 06:02:23 +0000523 default:
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000524 OwningExprResult Expr(ParseAssignmentExpression());
Sebastian Redl20df9b72008-12-11 22:51:44 +0000525 if (Expr.isInvalid()) return move(Expr);
Sebastian Redlf53597f2009-03-15 17:47:39 +0000526 return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
Chris Lattner2a2819a2008-04-06 06:02:23 +0000527 }
Chris Lattner50dd2892008-02-26 00:51:44 +0000528}
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000529
530/// ParseCXXThis - This handles the C++ 'this' pointer.
531///
532/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
533/// a non-lvalue expression whose value is the address of the object for which
534/// the function is called.
Sebastian Redl20df9b72008-12-11 22:51:44 +0000535Parser::OwningExprResult Parser::ParseCXXThis() {
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000536 assert(Tok.is(tok::kw_this) && "Not 'this'!");
537 SourceLocation ThisLoc = ConsumeToken();
Sebastian Redlf53597f2009-03-15 17:47:39 +0000538 return Actions.ActOnCXXThis(ThisLoc);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000539}
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000540
541/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
542/// Can be interpreted either as function-style casting ("int(x)")
543/// or class type construction ("ClassType(x,y,z)")
544/// or creation of a value-initialized type ("int()").
545///
546/// postfix-expression: [C++ 5.2p1]
547/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
548/// typename-specifier '(' expression-list[opt] ')' [TODO]
549///
Sebastian Redl20df9b72008-12-11 22:51:44 +0000550Parser::OwningExprResult
551Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000552 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +0000553 TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000554
555 assert(Tok.is(tok::l_paren) && "Expected '('!");
556 SourceLocation LParenLoc = ConsumeParen();
557
Sebastian Redla55e52c2008-11-25 22:21:31 +0000558 ExprVector Exprs(Actions);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000559 CommaLocsTy CommaLocs;
560
561 if (Tok.isNot(tok::r_paren)) {
562 if (ParseExpressionList(Exprs, CommaLocs)) {
563 SkipUntil(tok::r_paren);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000564 return ExprError();
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000565 }
566 }
567
568 // Match the ')'.
569 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
570
Sebastian Redlef0cb8e2009-07-29 13:50:23 +0000571 // TypeRep could be null, if it references an invalid typedef.
572 if (!TypeRep)
573 return ExprError();
574
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000575 assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
576 "Unexpected number of commas!");
Sebastian Redlf53597f2009-03-15 17:47:39 +0000577 return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
578 LParenLoc, move_arg(Exprs),
Jay Foadbeaaccd2009-05-21 09:52:38 +0000579 CommaLocs.data(), RParenLoc);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000580}
581
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000582/// ParseCXXCondition - if/switch/while/for condition expression.
583///
584/// condition:
585/// expression
586/// type-specifier-seq declarator '=' assignment-expression
587/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
588/// '=' assignment-expression
589///
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000590Parser::OwningExprResult Parser::ParseCXXCondition() {
Argyrios Kyrtzidisa8a45982008-10-05 15:03:47 +0000591 if (!isCXXConditionDeclaration())
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000592 return ParseExpression(); // expression
593
594 SourceLocation StartLoc = Tok.getLocation();
595
596 // type-specifier-seq
597 DeclSpec DS;
598 ParseSpecifierQualifierList(DS);
599
600 // declarator
601 Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
602 ParseDeclarator(DeclaratorInfo);
603
604 // simple-asm-expr[opt]
605 if (Tok.is(tok::kw_asm)) {
Sebastian Redlab197ba2009-02-09 18:23:29 +0000606 SourceLocation Loc;
607 OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000608 if (AsmLabel.isInvalid()) {
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000609 SkipUntil(tok::semi);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000610 return ExprError();
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000611 }
Sebastian Redleffa8d12008-12-10 00:02:53 +0000612 DeclaratorInfo.setAsmLabel(AsmLabel.release());
Sebastian Redlab197ba2009-02-09 18:23:29 +0000613 DeclaratorInfo.SetRangeEnd(Loc);
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000614 }
615
616 // If attributes are present, parse them.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000617 if (Tok.is(tok::kw___attribute)) {
618 SourceLocation Loc;
619 AttributeList *AttrList = ParseAttributes(&Loc);
620 DeclaratorInfo.AddAttributes(AttrList, Loc);
621 }
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000622
623 // '=' assignment-expression
624 if (Tok.isNot(tok::equal))
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000625 return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator));
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000626 SourceLocation EqualLoc = ConsumeToken();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000627 OwningExprResult AssignExpr(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000628 if (AssignExpr.isInvalid())
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000629 return ExprError();
630
Sebastian Redlf53597f2009-03-15 17:47:39 +0000631 return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
632 DeclaratorInfo,EqualLoc,
633 move(AssignExpr));
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000634}
635
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000636/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
637/// This should only be called when the current token is known to be part of
638/// simple-type-specifier.
639///
640/// simple-type-specifier:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000641/// '::'[opt] nested-name-specifier[opt] type-name
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000642/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
643/// char
644/// wchar_t
645/// bool
646/// short
647/// int
648/// long
649/// signed
650/// unsigned
651/// float
652/// double
653/// void
654/// [GNU] typeof-specifier
655/// [C++0x] auto [TODO]
656///
657/// type-name:
658/// class-name
659/// enum-name
660/// typedef-name
661///
662void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
663 DS.SetRangeStart(Tok.getLocation());
664 const char *PrevSpec;
John McCallfec54012009-08-03 20:12:06 +0000665 unsigned DiagID;
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000666 SourceLocation Loc = Tok.getLocation();
Mike Stump1eb44332009-09-09 15:08:12 +0000667
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000668 switch (Tok.getKind()) {
Chris Lattner55a7cef2009-01-05 00:13:00 +0000669 case tok::identifier: // foo::bar
670 case tok::coloncolon: // ::foo::bar
671 assert(0 && "Annotation token should already be formed!");
Mike Stump1eb44332009-09-09 15:08:12 +0000672 default:
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000673 assert(0 && "Not a simple-type-specifier token!");
674 abort();
Chris Lattner55a7cef2009-01-05 00:13:00 +0000675
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000676 // type-name
Chris Lattnerb31757b2009-01-06 05:06:21 +0000677 case tok::annot_typename: {
John McCallfec54012009-08-03 20:12:06 +0000678 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000679 Tok.getAnnotationValue());
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000680 break;
681 }
Mike Stump1eb44332009-09-09 15:08:12 +0000682
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000683 // builtin types
684 case tok::kw_short:
John McCallfec54012009-08-03 20:12:06 +0000685 DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000686 break;
687 case tok::kw_long:
John McCallfec54012009-08-03 20:12:06 +0000688 DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000689 break;
690 case tok::kw_signed:
John McCallfec54012009-08-03 20:12:06 +0000691 DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000692 break;
693 case tok::kw_unsigned:
John McCallfec54012009-08-03 20:12:06 +0000694 DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000695 break;
696 case tok::kw_void:
John McCallfec54012009-08-03 20:12:06 +0000697 DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000698 break;
699 case tok::kw_char:
John McCallfec54012009-08-03 20:12:06 +0000700 DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000701 break;
702 case tok::kw_int:
John McCallfec54012009-08-03 20:12:06 +0000703 DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000704 break;
705 case tok::kw_float:
John McCallfec54012009-08-03 20:12:06 +0000706 DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000707 break;
708 case tok::kw_double:
John McCallfec54012009-08-03 20:12:06 +0000709 DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000710 break;
711 case tok::kw_wchar_t:
John McCallfec54012009-08-03 20:12:06 +0000712 DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000713 break;
Alisdair Meredithf5c209d2009-07-14 06:30:34 +0000714 case tok::kw_char16_t:
John McCallfec54012009-08-03 20:12:06 +0000715 DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +0000716 break;
717 case tok::kw_char32_t:
John McCallfec54012009-08-03 20:12:06 +0000718 DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +0000719 break;
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000720 case tok::kw_bool:
John McCallfec54012009-08-03 20:12:06 +0000721 DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000722 break;
Mike Stump1eb44332009-09-09 15:08:12 +0000723
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000724 // GNU typeof support.
725 case tok::kw_typeof:
726 ParseTypeofSpecifier(DS);
Douglas Gregor9b3064b2009-04-01 22:41:11 +0000727 DS.Finish(Diags, PP);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000728 return;
729 }
Chris Lattnerb31757b2009-01-06 05:06:21 +0000730 if (Tok.is(tok::annot_typename))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000731 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
732 else
733 DS.SetRangeEnd(Tok.getLocation());
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000734 ConsumeToken();
Douglas Gregor9b3064b2009-04-01 22:41:11 +0000735 DS.Finish(Diags, PP);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000736}
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000737
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000738/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
739/// [dcl.name]), which is a non-empty sequence of type-specifiers,
740/// e.g., "const short int". Note that the DeclSpec is *not* finished
741/// by parsing the type-specifier-seq, because these sequences are
742/// typically followed by some form of declarator. Returns true and
743/// emits diagnostics if this is not a type-specifier-seq, false
744/// otherwise.
745///
746/// type-specifier-seq: [C++ 8.1]
747/// type-specifier type-specifier-seq[opt]
748///
749bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
750 DS.SetRangeStart(Tok.getLocation());
751 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +0000752 unsigned DiagID;
753 bool isInvalid = 0;
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000754
755 // Parse one or more of the type specifiers.
John McCallfec54012009-08-03 20:12:06 +0000756 if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +0000757 Diag(Tok, diag::err_operator_missing_type_specifier);
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000758 return true;
759 }
Mike Stump1eb44332009-09-09 15:08:12 +0000760
John McCallfec54012009-08-03 20:12:06 +0000761 while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) ;
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000762
763 return false;
764}
765
Douglas Gregor3f9a0562009-11-03 01:35:08 +0000766/// \brief Finish parsing a C++ unqualified-id that is a template-id of
767/// some form.
768///
769/// This routine is invoked when a '<' is encountered after an identifier or
770/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine
771/// whether the unqualified-id is actually a template-id. This routine will
772/// then parse the template arguments and form the appropriate template-id to
773/// return to the caller.
774///
775/// \param SS the nested-name-specifier that precedes this template-id, if
776/// we're actually parsing a qualified-id.
777///
778/// \param Name for constructor and destructor names, this is the actual
779/// identifier that may be a template-name.
780///
781/// \param NameLoc the location of the class-name in a constructor or
782/// destructor.
783///
784/// \param EnteringContext whether we're entering the scope of the
785/// nested-name-specifier.
786///
787/// \param Id as input, describes the template-name or operator-function-id
788/// that precedes the '<'. If template arguments were parsed successfully,
789/// will be updated with the template-id.
790///
791/// \returns true if a parse error occurred, false otherwise.
792bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
793 IdentifierInfo *Name,
794 SourceLocation NameLoc,
795 bool EnteringContext,
796 UnqualifiedId &Id) {
797 assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
798
799 TemplateTy Template;
800 TemplateNameKind TNK = TNK_Non_template;
801 switch (Id.getKind()) {
802 case UnqualifiedId::IK_Identifier:
803 TNK = Actions.isTemplateName(CurScope, *Id.Identifier, Id.StartLocation,
804 &SS, /*ObjectType=*/0, EnteringContext,
805 Template);
806 break;
807
808 case UnqualifiedId::IK_OperatorFunctionId: {
809 // FIXME: Temporary hack: warn that we are completely ignoring the
810 // template arguments for now.
811 // Parse the enclosed template argument list.
812 SourceLocation LAngleLoc, RAngleLoc;
813 TemplateArgList TemplateArgs;
814 TemplateArgIsTypeList TemplateArgIsType;
815 TemplateArgLocationList TemplateArgLocations;
816 if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
817 &SS, true, LAngleLoc,
818 TemplateArgs,
819 TemplateArgIsType,
820 TemplateArgLocations,
821 RAngleLoc))
822 return true;
823
824 Diag(Id.StartLocation, diag::warn_operator_template_id_ignores_args)
825 << SourceRange(LAngleLoc, RAngleLoc);
826 break;
827 }
828
829 case UnqualifiedId::IK_ConstructorName:
830 TNK = Actions.isTemplateName(CurScope, *Name, NameLoc,
831 &SS, /*ObjectType=*/0, EnteringContext,
832 Template);
833 break;
834
835 case UnqualifiedId::IK_DestructorName:
836 TNK = Actions.isTemplateName(CurScope, *Name, NameLoc,
837 &SS, /*ObjectType=*/0, EnteringContext,
838 Template);
839 break;
840
841 default:
842 return false;
843 }
844
845 if (TNK == TNK_Non_template)
846 return false;
847
848 // Parse the enclosed template argument list.
849 SourceLocation LAngleLoc, RAngleLoc;
850 TemplateArgList TemplateArgs;
851 TemplateArgIsTypeList TemplateArgIsType;
852 TemplateArgLocationList TemplateArgLocations;
853 if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
854 &SS, true, LAngleLoc,
855 TemplateArgs,
856 TemplateArgIsType,
857 TemplateArgLocations,
858 RAngleLoc))
859 return true;
860
861 if (Id.getKind() == UnqualifiedId::IK_Identifier ||
862 Id.getKind() == UnqualifiedId::IK_OperatorFunctionId) {
863 // Form a parsed representation of the template-id to be stored in the
864 // UnqualifiedId.
865 TemplateIdAnnotation *TemplateId
866 = TemplateIdAnnotation::Allocate(TemplateArgs.size());
867
868 if (Id.getKind() == UnqualifiedId::IK_Identifier) {
869 TemplateId->Name = Id.Identifier;
870 TemplateId->TemplateNameLoc = Id.StartLocation;
871 } else {
872 // FIXME: Handle IK_OperatorFunctionId
873 }
874
875 TemplateId->Template = Template.getAs<void*>();
876 TemplateId->Kind = TNK;
877 TemplateId->LAngleLoc = LAngleLoc;
878 TemplateId->RAngleLoc = RAngleLoc;
879 void **Args = TemplateId->getTemplateArgs();
880 bool *ArgIsType = TemplateId->getTemplateArgIsType();
881 SourceLocation *ArgLocs = TemplateId->getTemplateArgLocations();
882 for (unsigned Arg = 0, ArgEnd = TemplateArgs.size();
883 Arg != ArgEnd; ++Arg) {
884 Args[Arg] = TemplateArgs[Arg];
885 ArgIsType[Arg] = TemplateArgIsType[Arg];
886 ArgLocs[Arg] = TemplateArgLocations[Arg];
887 }
888
889 Id.setTemplateId(TemplateId);
890 return false;
891 }
892
893 // Bundle the template arguments together.
894 ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
895 TemplateArgIsType.data(),
896 TemplateArgs.size());
897
898 // Constructor and destructor names.
899 Action::TypeResult Type
900 = Actions.ActOnTemplateIdType(Template, NameLoc,
901 LAngleLoc, TemplateArgsPtr,
902 &TemplateArgLocations[0],
903 RAngleLoc);
904 if (Type.isInvalid())
905 return true;
906
907 if (Id.getKind() == UnqualifiedId::IK_ConstructorName)
908 Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);
909 else
910 Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);
911
912 return false;
913}
914
915/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the
916/// name of an entity.
917///
918/// \code
919/// unqualified-id: [C++ expr.prim.general]
920/// identifier
921/// operator-function-id
922/// conversion-function-id
923/// [C++0x] literal-operator-id [TODO]
924/// ~ class-name
925/// template-id
926///
927/// operator-function-id: [C++ 13.5]
928/// 'operator' operator
929///
930/// operator: one of
931/// new delete new[] delete[]
932/// + - * / % ^ & | ~
933/// ! = < > += -= *= /= %=
934/// ^= &= |= << >> >>= <<= == !=
935/// <= >= && || ++ -- , ->* ->
936/// () []
937///
938/// conversion-function-id: [C++ 12.3.2]
939/// operator conversion-type-id
940///
941/// conversion-type-id:
942/// type-specifier-seq conversion-declarator[opt]
943///
944/// conversion-declarator:
945/// ptr-operator conversion-declarator[opt]
946/// \endcode
947///
948/// \param The nested-name-specifier that preceded this unqualified-id. If
949/// non-empty, then we are parsing the unqualified-id of a qualified-id.
950///
951/// \param EnteringContext whether we are entering the scope of the
952/// nested-name-specifier.
953///
954/// \param AllowDestructorName whether we allow parsing of a destructor name.
955///
956/// \param AllowConstructorName whether we allow parsing a constructor name.
957///
958/// \param Result on a successful parse, contains the parsed unqualified-id.
959///
960/// \returns true if parsing fails, false otherwise.
961bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
962 bool AllowDestructorName,
963 bool AllowConstructorName,
964 UnqualifiedId &Result) {
965 // unqualified-id:
966 // identifier
967 // template-id (when it hasn't already been annotated)
968 if (Tok.is(tok::identifier)) {
969 // Consume the identifier.
970 IdentifierInfo *Id = Tok.getIdentifierInfo();
971 SourceLocation IdLoc = ConsumeToken();
972
973 if (AllowConstructorName &&
974 Actions.isCurrentClassName(*Id, CurScope, &SS)) {
975 // We have parsed a constructor name.
976 Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, CurScope,
977 &SS, false),
978 IdLoc, IdLoc);
979 } else {
980 // We have parsed an identifier.
981 Result.setIdentifier(Id, IdLoc);
982 }
983
984 // If the next token is a '<', we may have a template.
985 if (Tok.is(tok::less))
986 return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext,
987 Result);
988
989 return false;
990 }
991
992 // unqualified-id:
993 // template-id (already parsed and annotated)
994 if (Tok.is(tok::annot_template_id)) {
995 // FIXME: Could this be a constructor name???
996
997 // We have already parsed a template-id; consume the annotation token as
998 // our unqualified-id.
999 Result.setTemplateId(
1000 static_cast<TemplateIdAnnotation*>(Tok.getAnnotationValue()));
1001 ConsumeToken();
1002 return false;
1003 }
1004
1005 // unqualified-id:
1006 // operator-function-id
1007 // conversion-function-id
1008 if (Tok.is(tok::kw_operator)) {
1009 // Consume the 'operator' keyword.
1010 SourceLocation KeywordLoc = ConsumeToken();
1011
1012 // Determine what kind of operator name we have.
1013 unsigned SymbolIdx = 0;
1014 SourceLocation SymbolLocations[3];
1015 OverloadedOperatorKind Op = OO_None;
1016 switch (Tok.getKind()) {
1017 case tok::kw_new:
1018 case tok::kw_delete: {
1019 bool isNew = Tok.getKind() == tok::kw_new;
1020 // Consume the 'new' or 'delete'.
1021 SymbolLocations[SymbolIdx++] = ConsumeToken();
1022 if (Tok.is(tok::l_square)) {
1023 // Consume the '['.
1024 SourceLocation LBracketLoc = ConsumeBracket();
1025 // Consume the ']'.
1026 SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square,
1027 LBracketLoc);
1028 if (RBracketLoc.isInvalid())
1029 return true;
1030
1031 SymbolLocations[SymbolIdx++] = LBracketLoc;
1032 SymbolLocations[SymbolIdx++] = RBracketLoc;
1033 Op = isNew? OO_Array_New : OO_Array_Delete;
1034 } else {
1035 Op = isNew? OO_New : OO_Delete;
1036 }
1037 break;
1038 }
1039
1040 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1041 case tok::Token: \
1042 SymbolLocations[SymbolIdx++] = ConsumeToken(); \
1043 Op = OO_##Name; \
1044 break;
1045 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
1046 #include "clang/Basic/OperatorKinds.def"
1047
1048 case tok::l_paren: {
1049 // Consume the '('.
1050 SourceLocation LParenLoc = ConsumeParen();
1051 // Consume the ')'.
1052 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren,
1053 LParenLoc);
1054 if (RParenLoc.isInvalid())
1055 return true;
1056
1057 SymbolLocations[SymbolIdx++] = LParenLoc;
1058 SymbolLocations[SymbolIdx++] = RParenLoc;
1059 Op = OO_Call;
1060 break;
1061 }
1062
1063 case tok::l_square: {
1064 // Consume the '['.
1065 SourceLocation LBracketLoc = ConsumeBracket();
1066 // Consume the ']'.
1067 SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square,
1068 LBracketLoc);
1069 if (RBracketLoc.isInvalid())
1070 return true;
1071
1072 SymbolLocations[SymbolIdx++] = LBracketLoc;
1073 SymbolLocations[SymbolIdx++] = RBracketLoc;
1074 Op = OO_Subscript;
1075 break;
1076 }
1077
1078 case tok::code_completion: {
1079 // Code completion for the operator name.
1080 Actions.CodeCompleteOperatorName(CurScope);
1081
1082 // Consume the operator token.
1083 ConsumeToken();
1084
1085 // Don't try to parse any further.
1086 return true;
1087 }
1088
1089 default:
1090 break;
1091 }
1092
1093 if (Op != OO_None) {
1094 // We have parsed an operator-function-id.
1095 Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);
1096
1097 // If the next token is a '<', we may have a template.
1098 if (Tok.is(tok::less))
1099 return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(),
1100 EnteringContext, Result);
1101
1102 return false;
1103 }
1104
1105 // Parse a conversion-function-id.
1106 //
1107 // conversion-function-id: [C++ 12.3.2]
1108 // operator conversion-type-id
1109 //
1110 // conversion-type-id:
1111 // type-specifier-seq conversion-declarator[opt]
1112 //
1113 // conversion-declarator:
1114 // ptr-operator conversion-declarator[opt]
1115
1116 // Parse the type-specifier-seq.
1117 DeclSpec DS;
1118 if (ParseCXXTypeSpecifierSeq(DS))
1119 return true;
1120
1121 // Parse the conversion-declarator, which is merely a sequence of
1122 // ptr-operators.
1123 Declarator D(DS, Declarator::TypeNameContext);
1124 ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
1125
1126 // Finish up the type.
1127 Action::TypeResult Ty = Actions.ActOnTypeName(CurScope, D);
1128 if (Ty.isInvalid())
1129 return true;
1130
1131 // Note that this is a conversion-function-id.
1132 Result.setConversionFunctionId(KeywordLoc, Ty.get(),
1133 D.getSourceRange().getEnd());
1134 return false;
1135 }
1136
1137 if ((AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {
1138 // C++ [expr.unary.op]p10:
1139 // There is an ambiguity in the unary-expression ~X(), where X is a
1140 // class-name. The ambiguity is resolved in favor of treating ~ as a
1141 // unary complement rather than treating ~X as referring to a destructor.
1142
1143 // Parse the '~'.
1144 SourceLocation TildeLoc = ConsumeToken();
1145
1146 // Parse the class-name.
1147 if (Tok.isNot(tok::identifier)) {
1148 Diag(Tok, diag::err_destructor_class_name);
1149 return true;
1150 }
1151
1152 // Parse the class-name (or template-name in a simple-template-id).
1153 IdentifierInfo *ClassName = Tok.getIdentifierInfo();
1154 SourceLocation ClassNameLoc = ConsumeToken();
1155
1156 // Note that this is a destructor name.
1157 Action::TypeTy *Ty = Actions.getTypeName(*ClassName, ClassNameLoc,
1158 CurScope, &SS);
1159 if (!Ty) {
1160 Diag(ClassNameLoc, diag::err_destructor_class_name);
1161 return true;
1162 }
1163
1164 Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
1165
1166 if (Tok.is(tok::less))
1167 return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
1168 EnteringContext, Result);
1169
1170 return false;
1171 }
1172
1173 Diag(Tok, diag::err_expected_unqualified_id);
1174 return true;
1175}
1176
Douglas Gregor43c7bad2008-11-17 16:14:12 +00001177/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001178/// operator name (C++ [over.oper]). If successful, returns the
1179/// predefined identifier that corresponds to that overloaded
1180/// operator. Otherwise, returns NULL and does not consume any tokens.
1181///
1182/// operator-function-id: [C++ 13.5]
1183/// 'operator' operator
1184///
1185/// operator: one of
1186/// new delete new[] delete[]
1187/// + - * / % ^ & | ~
1188/// ! = < > += -= *= /= %=
1189/// ^= &= |= << >> >>= <<= == !=
1190/// <= >= && || ++ -- , ->* ->
1191/// () []
Sebastian Redlab197ba2009-02-09 18:23:29 +00001192OverloadedOperatorKind
1193Parser::TryParseOperatorFunctionId(SourceLocation *EndLoc) {
Argyrios Kyrtzidis9057a812008-11-07 15:54:02 +00001194 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
Sebastian Redlab197ba2009-02-09 18:23:29 +00001195 SourceLocation Loc;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001196
1197 OverloadedOperatorKind Op = OO_None;
1198 switch (NextToken().getKind()) {
1199 case tok::kw_new:
1200 ConsumeToken(); // 'operator'
Sebastian Redlab197ba2009-02-09 18:23:29 +00001201 Loc = ConsumeToken(); // 'new'
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001202 if (Tok.is(tok::l_square)) {
1203 ConsumeBracket(); // '['
Sebastian Redlab197ba2009-02-09 18:23:29 +00001204 Loc = Tok.getLocation();
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001205 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
1206 Op = OO_Array_New;
1207 } else {
1208 Op = OO_New;
1209 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00001210 if (EndLoc)
1211 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +00001212 return Op;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001213
1214 case tok::kw_delete:
1215 ConsumeToken(); // 'operator'
Sebastian Redlab197ba2009-02-09 18:23:29 +00001216 Loc = ConsumeToken(); // 'delete'
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001217 if (Tok.is(tok::l_square)) {
1218 ConsumeBracket(); // '['
Sebastian Redlab197ba2009-02-09 18:23:29 +00001219 Loc = Tok.getLocation();
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001220 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
1221 Op = OO_Array_Delete;
1222 } else {
1223 Op = OO_Delete;
1224 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00001225 if (EndLoc)
1226 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +00001227 return Op;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001228
Douglas Gregor02bcd4c2008-11-10 13:38:07 +00001229#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001230 case tok::Token: Op = OO_##Name; break;
Douglas Gregor02bcd4c2008-11-10 13:38:07 +00001231#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001232#include "clang/Basic/OperatorKinds.def"
1233
1234 case tok::l_paren:
1235 ConsumeToken(); // 'operator'
1236 ConsumeParen(); // '('
Sebastian Redlab197ba2009-02-09 18:23:29 +00001237 Loc = Tok.getLocation();
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001238 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
Sebastian Redlab197ba2009-02-09 18:23:29 +00001239 if (EndLoc)
1240 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +00001241 return OO_Call;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001242
1243 case tok::l_square:
1244 ConsumeToken(); // 'operator'
1245 ConsumeBracket(); // '['
Sebastian Redlab197ba2009-02-09 18:23:29 +00001246 Loc = Tok.getLocation();
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001247 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
Sebastian Redlab197ba2009-02-09 18:23:29 +00001248 if (EndLoc)
1249 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +00001250 return OO_Subscript;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001251
Douglas Gregored8d3222009-09-18 20:05:18 +00001252 case tok::code_completion: {
1253 // Code completion for the operator name.
1254 Actions.CodeCompleteOperatorName(CurScope);
1255
1256 // Consume the 'operator' token, then replace the code-completion token
1257 // with an 'operator' token and try again.
1258 SourceLocation OperatorLoc = ConsumeToken();
1259 Tok.setLocation(OperatorLoc);
1260 Tok.setKind(tok::kw_operator);
1261 return TryParseOperatorFunctionId(EndLoc);
1262 }
1263
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001264 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +00001265 return OO_None;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001266 }
1267
Douglas Gregor43c7bad2008-11-17 16:14:12 +00001268 ConsumeToken(); // 'operator'
Sebastian Redlab197ba2009-02-09 18:23:29 +00001269 Loc = ConsumeAnyToken(); // the operator itself
1270 if (EndLoc)
1271 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +00001272 return Op;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001273}
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001274
1275/// ParseConversionFunctionId - Parse a C++ conversion-function-id,
1276/// which expresses the name of a user-defined conversion operator
1277/// (C++ [class.conv.fct]p1). Returns the type that this operator is
1278/// specifying a conversion for, or NULL if there was an error.
1279///
1280/// conversion-function-id: [C++ 12.3.2]
1281/// operator conversion-type-id
1282///
1283/// conversion-type-id:
1284/// type-specifier-seq conversion-declarator[opt]
1285///
1286/// conversion-declarator:
1287/// ptr-operator conversion-declarator[opt]
Sebastian Redlab197ba2009-02-09 18:23:29 +00001288Parser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) {
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001289 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
1290 ConsumeToken(); // 'operator'
1291
1292 // Parse the type-specifier-seq.
1293 DeclSpec DS;
1294 if (ParseCXXTypeSpecifierSeq(DS))
1295 return 0;
1296
1297 // Parse the conversion-declarator, which is merely a sequence of
1298 // ptr-operators.
1299 Declarator D(DS, Declarator::TypeNameContext);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001300 ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001301 if (EndLoc)
1302 *EndLoc = D.getSourceRange().getEnd();
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001303
1304 // Finish up the type.
1305 Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +00001306 if (Result.isInvalid())
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001307 return 0;
1308 else
Douglas Gregor5ac8aff2009-01-26 22:44:13 +00001309 return Result.get();
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001310}
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001311
1312/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
1313/// memory in a typesafe manner and call constructors.
Mike Stump1eb44332009-09-09 15:08:12 +00001314///
Chris Lattner59232d32009-01-04 21:25:24 +00001315/// This method is called to parse the new expression after the optional :: has
1316/// been already parsed. If the :: was present, "UseGlobal" is true and "Start"
1317/// is its location. Otherwise, "Start" is the location of the 'new' token.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001318///
1319/// new-expression:
1320/// '::'[opt] 'new' new-placement[opt] new-type-id
1321/// new-initializer[opt]
1322/// '::'[opt] 'new' new-placement[opt] '(' type-id ')'
1323/// new-initializer[opt]
1324///
1325/// new-placement:
1326/// '(' expression-list ')'
1327///
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001328/// new-type-id:
1329/// type-specifier-seq new-declarator[opt]
1330///
1331/// new-declarator:
1332/// ptr-operator new-declarator[opt]
1333/// direct-new-declarator
1334///
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001335/// new-initializer:
1336/// '(' expression-list[opt] ')'
1337/// [C++0x] braced-init-list [TODO]
1338///
Chris Lattner59232d32009-01-04 21:25:24 +00001339Parser::OwningExprResult
1340Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
1341 assert(Tok.is(tok::kw_new) && "expected 'new' token");
1342 ConsumeToken(); // Consume 'new'
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001343
1344 // A '(' now can be a new-placement or the '(' wrapping the type-id in the
1345 // second form of new-expression. It can't be a new-type-id.
1346
Sebastian Redla55e52c2008-11-25 22:21:31 +00001347 ExprVector PlacementArgs(Actions);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001348 SourceLocation PlacementLParen, PlacementRParen;
1349
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001350 bool ParenTypeId;
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001351 DeclSpec DS;
1352 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001353 if (Tok.is(tok::l_paren)) {
1354 // If it turns out to be a placement, we change the type location.
1355 PlacementLParen = ConsumeParen();
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001356 if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
1357 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +00001358 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001359 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001360
1361 PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001362 if (PlacementRParen.isInvalid()) {
1363 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +00001364 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001365 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001366
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001367 if (PlacementArgs.empty()) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001368 // Reset the placement locations. There was no placement.
1369 PlacementLParen = PlacementRParen = SourceLocation();
1370 ParenTypeId = true;
1371 } else {
1372 // We still need the type.
1373 if (Tok.is(tok::l_paren)) {
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001374 SourceLocation LParen = ConsumeParen();
1375 ParseSpecifierQualifierList(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001376 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001377 ParseDeclarator(DeclaratorInfo);
1378 MatchRHSPunctuation(tok::r_paren, LParen);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001379 ParenTypeId = true;
1380 } else {
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001381 if (ParseCXXTypeSpecifierSeq(DS))
1382 DeclaratorInfo.setInvalidType(true);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001383 else {
1384 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001385 ParseDeclaratorInternal(DeclaratorInfo,
1386 &Parser::ParseDirectNewDeclarator);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001387 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001388 ParenTypeId = false;
1389 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001390 }
1391 } else {
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001392 // A new-type-id is a simplified type-id, where essentially the
1393 // direct-declarator is replaced by a direct-new-declarator.
1394 if (ParseCXXTypeSpecifierSeq(DS))
1395 DeclaratorInfo.setInvalidType(true);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001396 else {
1397 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001398 ParseDeclaratorInternal(DeclaratorInfo,
1399 &Parser::ParseDirectNewDeclarator);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001400 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001401 ParenTypeId = false;
1402 }
Chris Lattnereaaebc72009-04-25 08:06:05 +00001403 if (DeclaratorInfo.isInvalidType()) {
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001404 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +00001405 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001406 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001407
Sebastian Redla55e52c2008-11-25 22:21:31 +00001408 ExprVector ConstructorArgs(Actions);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001409 SourceLocation ConstructorLParen, ConstructorRParen;
1410
1411 if (Tok.is(tok::l_paren)) {
1412 ConstructorLParen = ConsumeParen();
1413 if (Tok.isNot(tok::r_paren)) {
1414 CommaLocsTy CommaLocs;
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001415 if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
1416 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +00001417 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001418 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001419 }
1420 ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001421 if (ConstructorRParen.isInvalid()) {
1422 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +00001423 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001424 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001425 }
1426
Sebastian Redlf53597f2009-03-15 17:47:39 +00001427 return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
1428 move_arg(PlacementArgs), PlacementRParen,
1429 ParenTypeId, DeclaratorInfo, ConstructorLParen,
1430 move_arg(ConstructorArgs), ConstructorRParen);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001431}
1432
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001433/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
1434/// passed to ParseDeclaratorInternal.
1435///
1436/// direct-new-declarator:
1437/// '[' expression ']'
1438/// direct-new-declarator '[' constant-expression ']'
1439///
Chris Lattner59232d32009-01-04 21:25:24 +00001440void Parser::ParseDirectNewDeclarator(Declarator &D) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001441 // Parse the array dimensions.
1442 bool first = true;
1443 while (Tok.is(tok::l_square)) {
1444 SourceLocation LLoc = ConsumeBracket();
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001445 OwningExprResult Size(first ? ParseExpression()
1446 : ParseConstantExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001447 if (Size.isInvalid()) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001448 // Recover
1449 SkipUntil(tok::r_square);
1450 return;
1451 }
1452 first = false;
1453
Sebastian Redlab197ba2009-02-09 18:23:29 +00001454 SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001455 D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00001456 Size.release(), LLoc, RLoc),
Sebastian Redlab197ba2009-02-09 18:23:29 +00001457 RLoc);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001458
Sebastian Redlab197ba2009-02-09 18:23:29 +00001459 if (RLoc.isInvalid())
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001460 return;
1461 }
1462}
1463
1464/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
1465/// This ambiguity appears in the syntax of the C++ new operator.
1466///
1467/// new-expression:
1468/// '::'[opt] 'new' new-placement[opt] '(' type-id ')'
1469/// new-initializer[opt]
1470///
1471/// new-placement:
1472/// '(' expression-list ')'
1473///
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001474bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
Chris Lattner59232d32009-01-04 21:25:24 +00001475 Declarator &D) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001476 // The '(' was already consumed.
1477 if (isTypeIdInParens()) {
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001478 ParseSpecifierQualifierList(D.getMutableDeclSpec());
Sebastian Redlab197ba2009-02-09 18:23:29 +00001479 D.SetSourceRange(D.getDeclSpec().getSourceRange());
Sebastian Redlcee63fb2008-12-02 14:43:59 +00001480 ParseDeclarator(D);
Chris Lattnereaaebc72009-04-25 08:06:05 +00001481 return D.isInvalidType();
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001482 }
1483
1484 // It's not a type, it has to be an expression list.
1485 // Discard the comma locations - ActOnCXXNew has enough parameters.
1486 CommaLocsTy CommaLocs;
1487 return ParseExpressionList(PlacementArgs, CommaLocs);
1488}
1489
1490/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
1491/// to free memory allocated by new.
1492///
Chris Lattner59232d32009-01-04 21:25:24 +00001493/// This method is called to parse the 'delete' expression after the optional
1494/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true
1495/// and "Start" is its location. Otherwise, "Start" is the location of the
1496/// 'delete' token.
1497///
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001498/// delete-expression:
1499/// '::'[opt] 'delete' cast-expression
1500/// '::'[opt] 'delete' '[' ']' cast-expression
Chris Lattner59232d32009-01-04 21:25:24 +00001501Parser::OwningExprResult
1502Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
1503 assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
1504 ConsumeToken(); // Consume 'delete'
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001505
1506 // Array delete?
1507 bool ArrayDelete = false;
1508 if (Tok.is(tok::l_square)) {
1509 ArrayDelete = true;
1510 SourceLocation LHS = ConsumeBracket();
1511 SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
1512 if (RHS.isInvalid())
Sebastian Redl20df9b72008-12-11 22:51:44 +00001513 return ExprError();
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001514 }
1515
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001516 OwningExprResult Operand(ParseCastExpression(false));
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001517 if (Operand.isInvalid())
Sebastian Redl20df9b72008-12-11 22:51:44 +00001518 return move(Operand);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001519
Sebastian Redlf53597f2009-03-15 17:47:39 +00001520 return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001521}
Sebastian Redl64b45f72009-01-05 20:52:13 +00001522
Mike Stump1eb44332009-09-09 15:08:12 +00001523static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
Sebastian Redl64b45f72009-01-05 20:52:13 +00001524 switch(kind) {
1525 default: assert(false && "Not a known unary type trait.");
1526 case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign;
1527 case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy;
1528 case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
1529 case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign;
1530 case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy;
1531 case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
1532 case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor;
1533 case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor;
1534 case tok::kw___is_abstract: return UTT_IsAbstract;
1535 case tok::kw___is_class: return UTT_IsClass;
1536 case tok::kw___is_empty: return UTT_IsEmpty;
1537 case tok::kw___is_enum: return UTT_IsEnum;
1538 case tok::kw___is_pod: return UTT_IsPOD;
1539 case tok::kw___is_polymorphic: return UTT_IsPolymorphic;
1540 case tok::kw___is_union: return UTT_IsUnion;
1541 }
1542}
1543
1544/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
1545/// pseudo-functions that allow implementation of the TR1/C++0x type traits
1546/// templates.
1547///
1548/// primary-expression:
1549/// [GNU] unary-type-trait '(' type-id ')'
1550///
Mike Stump1eb44332009-09-09 15:08:12 +00001551Parser::OwningExprResult Parser::ParseUnaryTypeTrait() {
Sebastian Redl64b45f72009-01-05 20:52:13 +00001552 UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
1553 SourceLocation Loc = ConsumeToken();
1554
1555 SourceLocation LParen = Tok.getLocation();
1556 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
1557 return ExprError();
1558
1559 // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
1560 // there will be cryptic errors about mismatched parentheses and missing
1561 // specifiers.
Douglas Gregor809070a2009-02-18 17:45:20 +00001562 TypeResult Ty = ParseTypeName();
Sebastian Redl64b45f72009-01-05 20:52:13 +00001563
1564 SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
1565
Douglas Gregor809070a2009-02-18 17:45:20 +00001566 if (Ty.isInvalid())
1567 return ExprError();
1568
1569 return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
Sebastian Redl64b45f72009-01-05 20:52:13 +00001570}
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001571
1572/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
1573/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
1574/// based on the context past the parens.
1575Parser::OwningExprResult
1576Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
1577 TypeTy *&CastTy,
1578 SourceLocation LParenLoc,
1579 SourceLocation &RParenLoc) {
1580 assert(getLang().CPlusPlus && "Should only be called for C++!");
1581 assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
1582 assert(isTypeIdInParens() && "Not a type-id!");
1583
1584 OwningExprResult Result(Actions, true);
1585 CastTy = 0;
1586
1587 // We need to disambiguate a very ugly part of the C++ syntax:
1588 //
1589 // (T())x; - type-id
1590 // (T())*x; - type-id
1591 // (T())/x; - expression
1592 // (T()); - expression
1593 //
1594 // The bad news is that we cannot use the specialized tentative parser, since
1595 // it can only verify that the thing inside the parens can be parsed as
1596 // type-id, it is not useful for determining the context past the parens.
1597 //
1598 // The good news is that the parser can disambiguate this part without
Argyrios Kyrtzidisa558a892009-05-22 15:12:46 +00001599 // making any unnecessary Action calls.
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001600 //
1601 // It uses a scheme similar to parsing inline methods. The parenthesized
1602 // tokens are cached, the context that follows is determined (possibly by
1603 // parsing a cast-expression), and then we re-introduce the cached tokens
1604 // into the token stream and parse them appropriately.
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001605
Mike Stump1eb44332009-09-09 15:08:12 +00001606 ParenParseOption ParseAs;
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001607 CachedTokens Toks;
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001608
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001609 // Store the tokens of the parentheses. We will parse them after we determine
1610 // the context that follows them.
1611 if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) {
1612 // We didn't find the ')' we expected.
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001613 MatchRHSPunctuation(tok::r_paren, LParenLoc);
1614 return ExprError();
1615 }
1616
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001617 if (Tok.is(tok::l_brace)) {
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001618 ParseAs = CompoundLiteral;
1619 } else {
1620 bool NotCastExpr;
Eli Friedmanb53f08a2009-05-25 19:41:42 +00001621 // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
1622 if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
1623 NotCastExpr = true;
1624 } else {
1625 // Try parsing the cast-expression that may follow.
1626 // If it is not a cast-expression, NotCastExpr will be true and no token
1627 // will be consumed.
1628 Result = ParseCastExpression(false/*isUnaryExpression*/,
1629 false/*isAddressofOperand*/,
Nate Begeman2ef13e52009-08-10 23:49:36 +00001630 NotCastExpr, false);
Eli Friedmanb53f08a2009-05-25 19:41:42 +00001631 }
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001632
1633 // If we parsed a cast-expression, it's really a type-id, otherwise it's
1634 // an expression.
1635 ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001636 }
1637
Mike Stump1eb44332009-09-09 15:08:12 +00001638 // The current token should go after the cached tokens.
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001639 Toks.push_back(Tok);
1640 // Re-enter the stored parenthesized tokens into the token stream, so we may
1641 // parse them now.
1642 PP.EnterTokenStream(Toks.data(), Toks.size(),
1643 true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
1644 // Drop the current token and bring the first cached one. It's the same token
1645 // as when we entered this function.
1646 ConsumeAnyToken();
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001647
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001648 if (ParseAs >= CompoundLiteral) {
1649 TypeResult Ty = ParseTypeName();
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001650
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001651 // Match the ')'.
1652 if (Tok.is(tok::r_paren))
1653 RParenLoc = ConsumeParen();
1654 else
1655 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001656
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001657 if (ParseAs == CompoundLiteral) {
1658 ExprType = CompoundLiteral;
1659 return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
1660 }
Mike Stump1eb44332009-09-09 15:08:12 +00001661
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001662 // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
1663 assert(ParseAs == CastExpr);
1664
1665 if (Ty.isInvalid())
1666 return ExprError();
1667
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001668 CastTy = Ty.get();
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001669
1670 // Result is what ParseCastExpression returned earlier.
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001671 if (!Result.isInvalid())
Mike Stump1eb44332009-09-09 15:08:12 +00001672 Result = Actions.ActOnCastExpr(CurScope, LParenLoc, CastTy, RParenLoc,
Nate Begeman2ef13e52009-08-10 23:49:36 +00001673 move(Result));
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001674 return move(Result);
1675 }
Mike Stump1eb44332009-09-09 15:08:12 +00001676
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001677 // Not a compound literal, and not followed by a cast-expression.
1678 assert(ParseAs == SimpleExpr);
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001679
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001680 ExprType = SimpleExpr;
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001681 Result = ParseExpression();
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001682 if (!Result.isInvalid() && Tok.is(tok::r_paren))
1683 Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
1684
1685 // Match the ')'.
1686 if (Result.isInvalid()) {
1687 SkipUntil(tok::r_paren);
1688 return ExprError();
1689 }
Mike Stump1eb44332009-09-09 15:08:12 +00001690
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001691 if (Tok.is(tok::r_paren))
1692 RParenLoc = ConsumeParen();
1693 else
1694 MatchRHSPunctuation(tok::r_paren, LParenLoc);
1695
1696 return move(Result);
1697}