blob: 77e5358b9112319204d26cdc722468b05591ef0f [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"
Reid Spencer5f016e22007-07-11 17:01:13 +000017using namespace clang;
18
Chris Lattner7a0ab5f2009-01-06 06:59:53 +000019/// ParseOptionalCXXScopeSpecifier - Parse global scope or
20/// nested-name-specifier if present. Returns true if a nested-name-specifier
21/// was parsed from the token stream. Note that this routine will not parse
22/// ::new or ::delete, it will just leave them in the token stream.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000023///
24/// '::'[opt] nested-name-specifier
25/// '::'
26///
27/// nested-name-specifier:
28/// type-name '::'
29/// namespace-name '::'
30/// nested-name-specifier identifier '::'
31/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
32///
Chris Lattner7a0ab5f2009-01-06 06:59:53 +000033bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
Argyrios Kyrtzidis4bdd91c2008-11-26 21:41:52 +000034 assert(getLang().CPlusPlus &&
Chris Lattner7452c6f2009-01-05 01:24:05 +000035 "Call sites of this function should be guarded by checking for C++");
Argyrios Kyrtzidis4bdd91c2008-11-26 21:41:52 +000036
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000037 if (Tok.is(tok::annot_cxxscope)) {
Douglas Gregor35073692009-03-26 23:56:24 +000038 SS.setScopeRep(Tok.getAnnotationValue());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000039 SS.setRange(Tok.getAnnotationRange());
40 ConsumeToken();
Argyrios Kyrtzidis4bdd91c2008-11-26 21:41:52 +000041 return true;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000042 }
Chris Lattnere607e802009-01-04 21:14:15 +000043
Douglas Gregor39a8de12009-02-25 19:37:18 +000044 bool HasScopeSpecifier = false;
45
Chris Lattner5b454732009-01-05 03:55:46 +000046 if (Tok.is(tok::coloncolon)) {
47 // ::new and ::delete aren't nested-name-specifiers.
48 tok::TokenKind NextKind = NextToken().getKind();
49 if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
50 return false;
Chris Lattner55a7cef2009-01-05 00:13:00 +000051
Chris Lattner55a7cef2009-01-05 00:13:00 +000052 // '::' - Global scope qualifier.
Chris Lattner357089d2009-01-05 02:07:19 +000053 SourceLocation CCLoc = ConsumeToken();
Chris Lattner357089d2009-01-05 02:07:19 +000054 SS.setBeginLoc(CCLoc);
Douglas Gregor35073692009-03-26 23:56:24 +000055 SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
Chris Lattner357089d2009-01-05 02:07:19 +000056 SS.setEndLoc(CCLoc);
Douglas Gregor39a8de12009-02-25 19:37:18 +000057 HasScopeSpecifier = true;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000058 }
59
Douglas Gregor39a8de12009-02-25 19:37:18 +000060 while (true) {
61 // nested-name-specifier:
62 // type-name '::'
63 // namespace-name '::'
64 // nested-name-specifier identifier '::'
65 if (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) {
66 // We have an identifier followed by a '::'. Lookup this name
67 // as the name in a nested-name-specifier.
68 IdentifierInfo *II = Tok.getIdentifierInfo();
69 SourceLocation IdLoc = ConsumeToken();
70 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
71 SourceLocation CCLoc = ConsumeToken();
72
73 if (!HasScopeSpecifier) {
74 SS.setBeginLoc(IdLoc);
75 HasScopeSpecifier = true;
76 }
77
78 if (SS.isInvalid())
79 continue;
80
Douglas Gregor35073692009-03-26 23:56:24 +000081 SS.setScopeRep(
Douglas Gregor39a8de12009-02-25 19:37:18 +000082 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
83 SS.setEndLoc(CCLoc);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000084 continue;
Douglas Gregor39a8de12009-02-25 19:37:18 +000085 }
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +000086
Chris Lattner67b9e832009-06-26 03:45:46 +000087
88 // Parse the optional 'template' keyword, then make sure we have
89 // 'identifier <' after it.
90 if (Tok.is(tok::kw_template)) {
91 SourceLocation TemplateKWLoc = ConsumeToken();
92
93 if (Tok.isNot(tok::identifier)) {
94 Diag(Tok.getLocation(),
95 diag::err_id_after_template_in_nested_name_spec)
96 << SourceRange(TemplateKWLoc);
97 break;
98 }
99
100 if (NextToken().isNot(tok::less)) {
101 Diag(NextToken().getLocation(),
102 diag::err_less_after_template_name_in_nested_name_spec)
103 << Tok.getIdentifierInfo()->getName()
104 << SourceRange(TemplateKWLoc, Tok.getLocation());
105 break;
106 }
107
108 TemplateTy Template
109 = Actions.ActOnDependentTemplateName(TemplateKWLoc,
110 *Tok.getIdentifierInfo(),
111 Tok.getLocation(),
112 SS);
113 AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
114 &SS, TemplateKWLoc, false);
115 continue;
116 }
117
Douglas Gregor39a8de12009-02-25 19:37:18 +0000118 // nested-name-specifier:
119 // type-name '::'
120 // nested-name-specifier 'template'[opt] simple-template-id '::'
Chris Lattner67b9e832009-06-26 03:45:46 +0000121 if (Tok.is(tok::identifier) && NextToken().is(tok::less)) {
Douglas Gregor7532dc62009-03-30 22:58:21 +0000122 TemplateTy Template;
Douglas Gregorc45c2322009-03-31 00:43:58 +0000123 TemplateNameKind TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(),
124 CurScope, Template, &SS);
Douglas Gregor39a8de12009-02-25 19:37:18 +0000125 if (TNK) {
126 // We have found a template name, so annotate this this token
127 // with a template-id annotation. We do not permit the
128 // template-id to be translated into a type annotation,
129 // because some clients (e.g., the parsing of class template
130 // specializations) still want to see the original template-id
131 // token.
Douglas Gregorc45c2322009-03-31 00:43:58 +0000132 AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(), false);
Douglas Gregor39a8de12009-02-25 19:37:18 +0000133 continue;
134 }
135 }
136
137 if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
138 // We have
139 //
140 // simple-template-id '::'
141 //
142 // So we need to check whether the simple-template-id is of the
Douglas Gregorc45c2322009-03-31 00:43:58 +0000143 // right kind (it should name a type or be dependent), and then
144 // convert it into a type within the nested-name-specifier.
Douglas Gregor39a8de12009-02-25 19:37:18 +0000145 TemplateIdAnnotation *TemplateId
146 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
147
Douglas Gregorc45c2322009-03-31 00:43:58 +0000148 if (TemplateId->Kind == TNK_Type_template ||
149 TemplateId->Kind == TNK_Dependent_template_name) {
Douglas Gregor31a19b62009-04-01 21:51:26 +0000150 AnnotateTemplateIdTokenAsType(&SS);
Douglas Gregor3f5b61c2009-05-14 00:28:11 +0000151 SS.setScopeRep(0);
Douglas Gregor39a8de12009-02-25 19:37:18 +0000152
153 assert(Tok.is(tok::annot_typename) &&
154 "AnnotateTemplateIdTokenAsType isn't working");
Douglas Gregor39a8de12009-02-25 19:37:18 +0000155 Token TypeToken = Tok;
156 ConsumeToken();
157 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
158 SourceLocation CCLoc = ConsumeToken();
159
160 if (!HasScopeSpecifier) {
161 SS.setBeginLoc(TypeToken.getLocation());
162 HasScopeSpecifier = true;
163 }
Douglas Gregor31a19b62009-04-01 21:51:26 +0000164
165 if (TypeToken.getAnnotationValue())
166 SS.setScopeRep(
167 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
168 TypeToken.getAnnotationValue(),
169 TypeToken.getAnnotationRange(),
170 CCLoc));
171 else
172 SS.setScopeRep(0);
Douglas Gregor39a8de12009-02-25 19:37:18 +0000173 SS.setEndLoc(CCLoc);
174 continue;
Chris Lattner67b9e832009-06-26 03:45:46 +0000175 }
176
177 assert(false && "FIXME: Only type template names supported here");
Douglas Gregor39a8de12009-02-25 19:37:18 +0000178 }
179
180 // We don't have any tokens that form the beginning of a
181 // nested-name-specifier, so we're done.
182 break;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000183 }
Douglas Gregor39a8de12009-02-25 19:37:18 +0000184
185 return HasScopeSpecifier;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000186}
187
188/// ParseCXXIdExpression - Handle id-expression.
189///
190/// id-expression:
191/// unqualified-id
192/// qualified-id
193///
194/// unqualified-id:
195/// identifier
196/// operator-function-id
197/// conversion-function-id [TODO]
198/// '~' class-name [TODO]
199/// template-id [TODO]
200///
201/// qualified-id:
202/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
203/// '::' identifier
204/// '::' operator-function-id
205/// '::' template-id [TODO]
206///
207/// nested-name-specifier:
208/// type-name '::'
209/// namespace-name '::'
210/// nested-name-specifier identifier '::'
211/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
212///
213/// NOTE: The standard specifies that, for qualified-id, the parser does not
214/// expect:
215///
216/// '::' conversion-function-id
217/// '::' '~' class-name
218///
219/// This may cause a slight inconsistency on diagnostics:
220///
221/// class C {};
222/// namespace A {}
223/// void f() {
224/// :: A :: ~ C(); // Some Sema error about using destructor with a
225/// // namespace.
226/// :: ~ C(); // Some Parser error like 'unexpected ~'.
227/// }
228///
229/// We simplify the parser a bit and make it work like:
230///
231/// qualified-id:
232/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
233/// '::' unqualified-id
234///
235/// That way Sema can handle and report similar errors for namespaces and the
236/// global scope.
237///
Sebastian Redlebc07d52009-02-03 20:19:35 +0000238/// The isAddressOfOperand parameter indicates that this id-expression is a
239/// direct operand of the address-of operator. This is, besides member contexts,
240/// the only place where a qualified-id naming a non-static class member may
241/// appear.
242///
243Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000244 // qualified-id:
245 // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
246 // '::' unqualified-id
247 //
248 CXXScopeSpec SS;
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000249 ParseOptionalCXXScopeSpecifier(SS);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000250
251 // unqualified-id:
252 // identifier
253 // operator-function-id
Douglas Gregor2def4832008-11-17 20:34:05 +0000254 // conversion-function-id
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000255 // '~' class-name [TODO]
256 // template-id [TODO]
257 //
258 switch (Tok.getKind()) {
259 default:
Sebastian Redl20df9b72008-12-11 22:51:44 +0000260 return ExprError(Diag(Tok, diag::err_expected_unqualified_id));
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000261
262 case tok::identifier: {
263 // Consume the identifier so that we can see if it is followed by a '('.
264 IdentifierInfo &II = *Tok.getIdentifierInfo();
265 SourceLocation L = ConsumeToken();
Sebastian Redlebc07d52009-02-03 20:19:35 +0000266 return Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren),
267 &SS, isAddressOfOperand);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000268 }
269
270 case tok::kw_operator: {
271 SourceLocation OperatorLoc = Tok.getLocation();
Chris Lattner7452c6f2009-01-05 01:24:05 +0000272 if (OverloadedOperatorKind Op = TryParseOperatorFunctionId())
Sebastian Redlcd965b92009-01-18 18:53:16 +0000273 return Actions.ActOnCXXOperatorFunctionIdExpr(
Sebastian Redlebc07d52009-02-03 20:19:35 +0000274 CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS,
275 isAddressOfOperand);
Chris Lattner7452c6f2009-01-05 01:24:05 +0000276 if (TypeTy *Type = ParseConversionFunctionId())
Sebastian Redlcd965b92009-01-18 18:53:16 +0000277 return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type,
Sebastian Redlebc07d52009-02-03 20:19:35 +0000278 Tok.is(tok::l_paren), SS,
279 isAddressOfOperand);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000280
Douglas Gregor2def4832008-11-17 20:34:05 +0000281 // We already complained about a bad conversion-function-id,
282 // above.
Sebastian Redl20df9b72008-12-11 22:51:44 +0000283 return ExprError();
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000284 }
285
286 } // switch.
287
288 assert(0 && "The switch was supposed to take care everything.");
289}
290
Reid Spencer5f016e22007-07-11 17:01:13 +0000291/// ParseCXXCasts - This handles the various ways to cast expressions to another
292/// type.
293///
294/// postfix-expression: [C++ 5.2p1]
295/// 'dynamic_cast' '<' type-name '>' '(' expression ')'
296/// 'static_cast' '<' type-name '>' '(' expression ')'
297/// 'reinterpret_cast' '<' type-name '>' '(' expression ')'
298/// 'const_cast' '<' type-name '>' '(' expression ')'
299///
Sebastian Redl20df9b72008-12-11 22:51:44 +0000300Parser::OwningExprResult Parser::ParseCXXCasts() {
Reid Spencer5f016e22007-07-11 17:01:13 +0000301 tok::TokenKind Kind = Tok.getKind();
302 const char *CastName = 0; // For error messages
303
304 switch (Kind) {
305 default: assert(0 && "Unknown C++ cast!"); abort();
306 case tok::kw_const_cast: CastName = "const_cast"; break;
307 case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break;
308 case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
309 case tok::kw_static_cast: CastName = "static_cast"; break;
310 }
311
312 SourceLocation OpLoc = ConsumeToken();
313 SourceLocation LAngleBracketLoc = Tok.getLocation();
314
315 if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
Sebastian Redl20df9b72008-12-11 22:51:44 +0000316 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000317
Douglas Gregor809070a2009-02-18 17:45:20 +0000318 TypeResult CastTy = ParseTypeName();
Reid Spencer5f016e22007-07-11 17:01:13 +0000319 SourceLocation RAngleBracketLoc = Tok.getLocation();
320
Chris Lattner1ab3b962008-11-18 07:48:38 +0000321 if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
Sebastian Redl20df9b72008-12-11 22:51:44 +0000322 return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
Reid Spencer5f016e22007-07-11 17:01:13 +0000323
324 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
325
Argyrios Kyrtzidis21e7ad22009-05-22 10:23:16 +0000326 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName))
327 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000328
Argyrios Kyrtzidis21e7ad22009-05-22 10:23:16 +0000329 OwningExprResult Result = ParseExpression();
330
331 // Match the ')'.
332 if (Result.isInvalid())
333 SkipUntil(tok::r_paren);
334
335 if (Tok.is(tok::r_paren))
336 RParenLoc = ConsumeParen();
337 else
338 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000339
Douglas Gregor809070a2009-02-18 17:45:20 +0000340 if (!Result.isInvalid() && !CastTy.isInvalid())
Douglas Gregor49badde2008-10-27 19:41:14 +0000341 Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
Sebastian Redlf53597f2009-03-15 17:47:39 +0000342 LAngleBracketLoc, CastTy.get(),
Douglas Gregor809070a2009-02-18 17:45:20 +0000343 RAngleBracketLoc,
Sebastian Redlf53597f2009-03-15 17:47:39 +0000344 LParenLoc, move(Result), RParenLoc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000345
Sebastian Redl20df9b72008-12-11 22:51:44 +0000346 return move(Result);
Reid Spencer5f016e22007-07-11 17:01:13 +0000347}
348
Sebastian Redlc42e1182008-11-11 11:37:55 +0000349/// ParseCXXTypeid - This handles the C++ typeid expression.
350///
351/// postfix-expression: [C++ 5.2p1]
352/// 'typeid' '(' expression ')'
353/// 'typeid' '(' type-id ')'
354///
Sebastian Redl20df9b72008-12-11 22:51:44 +0000355Parser::OwningExprResult Parser::ParseCXXTypeid() {
Sebastian Redlc42e1182008-11-11 11:37:55 +0000356 assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
357
358 SourceLocation OpLoc = ConsumeToken();
359 SourceLocation LParenLoc = Tok.getLocation();
360 SourceLocation RParenLoc;
361
362 // typeid expressions are always parenthesized.
363 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
364 "typeid"))
Sebastian Redl20df9b72008-12-11 22:51:44 +0000365 return ExprError();
Sebastian Redlc42e1182008-11-11 11:37:55 +0000366
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000367 OwningExprResult Result(Actions);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000368
369 if (isTypeIdInParens()) {
Douglas Gregor809070a2009-02-18 17:45:20 +0000370 TypeResult Ty = ParseTypeName();
Sebastian Redlc42e1182008-11-11 11:37:55 +0000371
372 // Match the ')'.
373 MatchRHSPunctuation(tok::r_paren, LParenLoc);
374
Douglas Gregor809070a2009-02-18 17:45:20 +0000375 if (Ty.isInvalid())
Sebastian Redl20df9b72008-12-11 22:51:44 +0000376 return ExprError();
Sebastian Redlc42e1182008-11-11 11:37:55 +0000377
378 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
Douglas Gregor809070a2009-02-18 17:45:20 +0000379 Ty.get(), RParenLoc);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000380 } else {
Douglas Gregore0762c92009-06-19 23:52:42 +0000381 // C++0x [expr.typeid]p3:
382 // When typeid is applied to an expression other than an lvalue of a
383 // polymorphic class type [...] The expression is an unevaluated
384 // operand (Clause 5).
385 //
386 // Note that we can't tell whether the expression is an lvalue of a
387 // polymorphic class type until after we've parsed the expression, so
Douglas Gregorac7610d2009-06-22 20:57:11 +0000388 // we the expression is potentially potentially evaluated.
389 EnterExpressionEvaluationContext Unevaluated(Actions,
390 Action::PotentiallyPotentiallyEvaluated);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000391 Result = ParseExpression();
392
393 // Match the ')'.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000394 if (Result.isInvalid())
Sebastian Redlc42e1182008-11-11 11:37:55 +0000395 SkipUntil(tok::r_paren);
396 else {
397 MatchRHSPunctuation(tok::r_paren, LParenLoc);
398
399 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
Sebastian Redleffa8d12008-12-10 00:02:53 +0000400 Result.release(), RParenLoc);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000401 }
402 }
403
Sebastian Redl20df9b72008-12-11 22:51:44 +0000404 return move(Result);
Sebastian Redlc42e1182008-11-11 11:37:55 +0000405}
406
Reid Spencer5f016e22007-07-11 17:01:13 +0000407/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
408///
409/// boolean-literal: [C++ 2.13.5]
410/// 'true'
411/// 'false'
Sebastian Redl20df9b72008-12-11 22:51:44 +0000412Parser::OwningExprResult Parser::ParseCXXBoolLiteral() {
Reid Spencer5f016e22007-07-11 17:01:13 +0000413 tok::TokenKind Kind = Tok.getKind();
Sebastian Redlf53597f2009-03-15 17:47:39 +0000414 return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
Reid Spencer5f016e22007-07-11 17:01:13 +0000415}
Chris Lattner50dd2892008-02-26 00:51:44 +0000416
417/// ParseThrowExpression - This handles the C++ throw expression.
418///
419/// throw-expression: [C++ 15]
420/// 'throw' assignment-expression[opt]
Sebastian Redl20df9b72008-12-11 22:51:44 +0000421Parser::OwningExprResult Parser::ParseThrowExpression() {
Chris Lattner50dd2892008-02-26 00:51:44 +0000422 assert(Tok.is(tok::kw_throw) && "Not throw!");
Chris Lattner50dd2892008-02-26 00:51:44 +0000423 SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token.
Sebastian Redl20df9b72008-12-11 22:51:44 +0000424
Chris Lattner2a2819a2008-04-06 06:02:23 +0000425 // If the current token isn't the start of an assignment-expression,
426 // then the expression is not present. This handles things like:
427 // "C ? throw : (void)42", which is crazy but legal.
428 switch (Tok.getKind()) { // FIXME: move this predicate somewhere common.
429 case tok::semi:
430 case tok::r_paren:
431 case tok::r_square:
432 case tok::r_brace:
433 case tok::colon:
434 case tok::comma:
Sebastian Redlf53597f2009-03-15 17:47:39 +0000435 return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
Chris Lattner50dd2892008-02-26 00:51:44 +0000436
Chris Lattner2a2819a2008-04-06 06:02:23 +0000437 default:
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000438 OwningExprResult Expr(ParseAssignmentExpression());
Sebastian Redl20df9b72008-12-11 22:51:44 +0000439 if (Expr.isInvalid()) return move(Expr);
Sebastian Redlf53597f2009-03-15 17:47:39 +0000440 return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
Chris Lattner2a2819a2008-04-06 06:02:23 +0000441 }
Chris Lattner50dd2892008-02-26 00:51:44 +0000442}
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000443
444/// ParseCXXThis - This handles the C++ 'this' pointer.
445///
446/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
447/// a non-lvalue expression whose value is the address of the object for which
448/// the function is called.
Sebastian Redl20df9b72008-12-11 22:51:44 +0000449Parser::OwningExprResult Parser::ParseCXXThis() {
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000450 assert(Tok.is(tok::kw_this) && "Not 'this'!");
451 SourceLocation ThisLoc = ConsumeToken();
Sebastian Redlf53597f2009-03-15 17:47:39 +0000452 return Actions.ActOnCXXThis(ThisLoc);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000453}
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000454
455/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
456/// Can be interpreted either as function-style casting ("int(x)")
457/// or class type construction ("ClassType(x,y,z)")
458/// or creation of a value-initialized type ("int()").
459///
460/// postfix-expression: [C++ 5.2p1]
461/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
462/// typename-specifier '(' expression-list[opt] ')' [TODO]
463///
Sebastian Redl20df9b72008-12-11 22:51:44 +0000464Parser::OwningExprResult
465Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000466 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +0000467 TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000468
469 assert(Tok.is(tok::l_paren) && "Expected '('!");
470 SourceLocation LParenLoc = ConsumeParen();
471
Sebastian Redla55e52c2008-11-25 22:21:31 +0000472 ExprVector Exprs(Actions);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000473 CommaLocsTy CommaLocs;
474
475 if (Tok.isNot(tok::r_paren)) {
476 if (ParseExpressionList(Exprs, CommaLocs)) {
477 SkipUntil(tok::r_paren);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000478 return ExprError();
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000479 }
480 }
481
482 // Match the ')'.
483 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
484
485 assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
486 "Unexpected number of commas!");
Sebastian Redlf53597f2009-03-15 17:47:39 +0000487 return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
488 LParenLoc, move_arg(Exprs),
Jay Foadbeaaccd2009-05-21 09:52:38 +0000489 CommaLocs.data(), RParenLoc);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000490}
491
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000492/// ParseCXXCondition - if/switch/while/for condition expression.
493///
494/// condition:
495/// expression
496/// type-specifier-seq declarator '=' assignment-expression
497/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
498/// '=' assignment-expression
499///
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000500Parser::OwningExprResult Parser::ParseCXXCondition() {
Argyrios Kyrtzidisa8a45982008-10-05 15:03:47 +0000501 if (!isCXXConditionDeclaration())
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000502 return ParseExpression(); // expression
503
504 SourceLocation StartLoc = Tok.getLocation();
505
506 // type-specifier-seq
507 DeclSpec DS;
508 ParseSpecifierQualifierList(DS);
509
510 // declarator
511 Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
512 ParseDeclarator(DeclaratorInfo);
513
514 // simple-asm-expr[opt]
515 if (Tok.is(tok::kw_asm)) {
Sebastian Redlab197ba2009-02-09 18:23:29 +0000516 SourceLocation Loc;
517 OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000518 if (AsmLabel.isInvalid()) {
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000519 SkipUntil(tok::semi);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000520 return ExprError();
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000521 }
Sebastian Redleffa8d12008-12-10 00:02:53 +0000522 DeclaratorInfo.setAsmLabel(AsmLabel.release());
Sebastian Redlab197ba2009-02-09 18:23:29 +0000523 DeclaratorInfo.SetRangeEnd(Loc);
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000524 }
525
526 // If attributes are present, parse them.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000527 if (Tok.is(tok::kw___attribute)) {
528 SourceLocation Loc;
529 AttributeList *AttrList = ParseAttributes(&Loc);
530 DeclaratorInfo.AddAttributes(AttrList, Loc);
531 }
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000532
533 // '=' assignment-expression
534 if (Tok.isNot(tok::equal))
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000535 return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator));
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000536 SourceLocation EqualLoc = ConsumeToken();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000537 OwningExprResult AssignExpr(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000538 if (AssignExpr.isInvalid())
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000539 return ExprError();
540
Sebastian Redlf53597f2009-03-15 17:47:39 +0000541 return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
542 DeclaratorInfo,EqualLoc,
543 move(AssignExpr));
Argyrios Kyrtzidis71b914b2008-09-09 20:38:47 +0000544}
545
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000546/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
547/// This should only be called when the current token is known to be part of
548/// simple-type-specifier.
549///
550/// simple-type-specifier:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000551/// '::'[opt] nested-name-specifier[opt] type-name
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000552/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
553/// char
554/// wchar_t
555/// bool
556/// short
557/// int
558/// long
559/// signed
560/// unsigned
561/// float
562/// double
563/// void
564/// [GNU] typeof-specifier
565/// [C++0x] auto [TODO]
566///
567/// type-name:
568/// class-name
569/// enum-name
570/// typedef-name
571///
572void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
573 DS.SetRangeStart(Tok.getLocation());
574 const char *PrevSpec;
575 SourceLocation Loc = Tok.getLocation();
576
577 switch (Tok.getKind()) {
Chris Lattner55a7cef2009-01-05 00:13:00 +0000578 case tok::identifier: // foo::bar
579 case tok::coloncolon: // ::foo::bar
580 assert(0 && "Annotation token should already be formed!");
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000581 default:
582 assert(0 && "Not a simple-type-specifier token!");
583 abort();
Chris Lattner55a7cef2009-01-05 00:13:00 +0000584
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000585 // type-name
Chris Lattnerb31757b2009-01-06 05:06:21 +0000586 case tok::annot_typename: {
Douglas Gregor1a51b4a2009-02-09 15:09:02 +0000587 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000588 Tok.getAnnotationValue());
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000589 break;
590 }
591
592 // builtin types
593 case tok::kw_short:
594 DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
595 break;
596 case tok::kw_long:
597 DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
598 break;
599 case tok::kw_signed:
600 DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
601 break;
602 case tok::kw_unsigned:
603 DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
604 break;
605 case tok::kw_void:
606 DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
607 break;
608 case tok::kw_char:
609 DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
610 break;
611 case tok::kw_int:
612 DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
613 break;
614 case tok::kw_float:
615 DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
616 break;
617 case tok::kw_double:
618 DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
619 break;
620 case tok::kw_wchar_t:
621 DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
622 break;
623 case tok::kw_bool:
624 DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
625 break;
626
627 // GNU typeof support.
628 case tok::kw_typeof:
629 ParseTypeofSpecifier(DS);
Douglas Gregor9b3064b2009-04-01 22:41:11 +0000630 DS.Finish(Diags, PP);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000631 return;
632 }
Chris Lattnerb31757b2009-01-06 05:06:21 +0000633 if (Tok.is(tok::annot_typename))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000634 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
635 else
636 DS.SetRangeEnd(Tok.getLocation());
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000637 ConsumeToken();
Douglas Gregor9b3064b2009-04-01 22:41:11 +0000638 DS.Finish(Diags, PP);
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000639}
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000640
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000641/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
642/// [dcl.name]), which is a non-empty sequence of type-specifiers,
643/// e.g., "const short int". Note that the DeclSpec is *not* finished
644/// by parsing the type-specifier-seq, because these sequences are
645/// typically followed by some form of declarator. Returns true and
646/// emits diagnostics if this is not a type-specifier-seq, false
647/// otherwise.
648///
649/// type-specifier-seq: [C++ 8.1]
650/// type-specifier type-specifier-seq[opt]
651///
652bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
653 DS.SetRangeStart(Tok.getLocation());
654 const char *PrevSpec = 0;
655 int isInvalid = 0;
656
657 // Parse one or more of the type specifiers.
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000658 if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +0000659 Diag(Tok, diag::err_operator_missing_type_specifier);
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000660 return true;
661 }
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000662
Ted Kremenekb8006e52009-01-06 19:17:58 +0000663 while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) ;
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000664
665 return false;
666}
667
Douglas Gregor43c7bad2008-11-17 16:14:12 +0000668/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000669/// operator name (C++ [over.oper]). If successful, returns the
670/// predefined identifier that corresponds to that overloaded
671/// operator. Otherwise, returns NULL and does not consume any tokens.
672///
673/// operator-function-id: [C++ 13.5]
674/// 'operator' operator
675///
676/// operator: one of
677/// new delete new[] delete[]
678/// + - * / % ^ & | ~
679/// ! = < > += -= *= /= %=
680/// ^= &= |= << >> >>= <<= == !=
681/// <= >= && || ++ -- , ->* ->
682/// () []
Sebastian Redlab197ba2009-02-09 18:23:29 +0000683OverloadedOperatorKind
684Parser::TryParseOperatorFunctionId(SourceLocation *EndLoc) {
Argyrios Kyrtzidis9057a812008-11-07 15:54:02 +0000685 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
Sebastian Redlab197ba2009-02-09 18:23:29 +0000686 SourceLocation Loc;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000687
688 OverloadedOperatorKind Op = OO_None;
689 switch (NextToken().getKind()) {
690 case tok::kw_new:
691 ConsumeToken(); // 'operator'
Sebastian Redlab197ba2009-02-09 18:23:29 +0000692 Loc = ConsumeToken(); // 'new'
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000693 if (Tok.is(tok::l_square)) {
694 ConsumeBracket(); // '['
Sebastian Redlab197ba2009-02-09 18:23:29 +0000695 Loc = Tok.getLocation();
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000696 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
697 Op = OO_Array_New;
698 } else {
699 Op = OO_New;
700 }
Sebastian Redlab197ba2009-02-09 18:23:29 +0000701 if (EndLoc)
702 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000703 return Op;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000704
705 case tok::kw_delete:
706 ConsumeToken(); // 'operator'
Sebastian Redlab197ba2009-02-09 18:23:29 +0000707 Loc = ConsumeToken(); // 'delete'
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000708 if (Tok.is(tok::l_square)) {
709 ConsumeBracket(); // '['
Sebastian Redlab197ba2009-02-09 18:23:29 +0000710 Loc = Tok.getLocation();
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000711 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
712 Op = OO_Array_Delete;
713 } else {
714 Op = OO_Delete;
715 }
Sebastian Redlab197ba2009-02-09 18:23:29 +0000716 if (EndLoc)
717 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000718 return Op;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000719
Douglas Gregor02bcd4c2008-11-10 13:38:07 +0000720#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000721 case tok::Token: Op = OO_##Name; break;
Douglas Gregor02bcd4c2008-11-10 13:38:07 +0000722#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000723#include "clang/Basic/OperatorKinds.def"
724
725 case tok::l_paren:
726 ConsumeToken(); // 'operator'
727 ConsumeParen(); // '('
Sebastian Redlab197ba2009-02-09 18:23:29 +0000728 Loc = Tok.getLocation();
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000729 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
Sebastian Redlab197ba2009-02-09 18:23:29 +0000730 if (EndLoc)
731 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000732 return OO_Call;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000733
734 case tok::l_square:
735 ConsumeToken(); // 'operator'
736 ConsumeBracket(); // '['
Sebastian Redlab197ba2009-02-09 18:23:29 +0000737 Loc = Tok.getLocation();
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000738 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
Sebastian Redlab197ba2009-02-09 18:23:29 +0000739 if (EndLoc)
740 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000741 return OO_Subscript;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000742
743 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000744 return OO_None;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000745 }
746
Douglas Gregor43c7bad2008-11-17 16:14:12 +0000747 ConsumeToken(); // 'operator'
Sebastian Redlab197ba2009-02-09 18:23:29 +0000748 Loc = ConsumeAnyToken(); // the operator itself
749 if (EndLoc)
750 *EndLoc = Loc;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000751 return Op;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000752}
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000753
754/// ParseConversionFunctionId - Parse a C++ conversion-function-id,
755/// which expresses the name of a user-defined conversion operator
756/// (C++ [class.conv.fct]p1). Returns the type that this operator is
757/// specifying a conversion for, or NULL if there was an error.
758///
759/// conversion-function-id: [C++ 12.3.2]
760/// operator conversion-type-id
761///
762/// conversion-type-id:
763/// type-specifier-seq conversion-declarator[opt]
764///
765/// conversion-declarator:
766/// ptr-operator conversion-declarator[opt]
Sebastian Redlab197ba2009-02-09 18:23:29 +0000767Parser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) {
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000768 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
769 ConsumeToken(); // 'operator'
770
771 // Parse the type-specifier-seq.
772 DeclSpec DS;
773 if (ParseCXXTypeSpecifierSeq(DS))
774 return 0;
775
776 // Parse the conversion-declarator, which is merely a sequence of
777 // ptr-operators.
778 Declarator D(DS, Declarator::TypeNameContext);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000779 ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
Sebastian Redlab197ba2009-02-09 18:23:29 +0000780 if (EndLoc)
781 *EndLoc = D.getSourceRange().getEnd();
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000782
783 // Finish up the type.
784 Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +0000785 if (Result.isInvalid())
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000786 return 0;
787 else
Douglas Gregor5ac8aff2009-01-26 22:44:13 +0000788 return Result.get();
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000789}
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000790
791/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
792/// memory in a typesafe manner and call constructors.
Chris Lattner59232d32009-01-04 21:25:24 +0000793///
794/// This method is called to parse the new expression after the optional :: has
795/// been already parsed. If the :: was present, "UseGlobal" is true and "Start"
796/// is its location. Otherwise, "Start" is the location of the 'new' token.
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000797///
798/// new-expression:
799/// '::'[opt] 'new' new-placement[opt] new-type-id
800/// new-initializer[opt]
801/// '::'[opt] 'new' new-placement[opt] '(' type-id ')'
802/// new-initializer[opt]
803///
804/// new-placement:
805/// '(' expression-list ')'
806///
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000807/// new-type-id:
808/// type-specifier-seq new-declarator[opt]
809///
810/// new-declarator:
811/// ptr-operator new-declarator[opt]
812/// direct-new-declarator
813///
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000814/// new-initializer:
815/// '(' expression-list[opt] ')'
816/// [C++0x] braced-init-list [TODO]
817///
Chris Lattner59232d32009-01-04 21:25:24 +0000818Parser::OwningExprResult
819Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
820 assert(Tok.is(tok::kw_new) && "expected 'new' token");
821 ConsumeToken(); // Consume 'new'
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000822
823 // A '(' now can be a new-placement or the '(' wrapping the type-id in the
824 // second form of new-expression. It can't be a new-type-id.
825
Sebastian Redla55e52c2008-11-25 22:21:31 +0000826 ExprVector PlacementArgs(Actions);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000827 SourceLocation PlacementLParen, PlacementRParen;
828
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000829 bool ParenTypeId;
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000830 DeclSpec DS;
831 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000832 if (Tok.is(tok::l_paren)) {
833 // If it turns out to be a placement, we change the type location.
834 PlacementLParen = ConsumeParen();
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000835 if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
836 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000837 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000838 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000839
840 PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000841 if (PlacementRParen.isInvalid()) {
842 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000843 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000844 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000845
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000846 if (PlacementArgs.empty()) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000847 // Reset the placement locations. There was no placement.
848 PlacementLParen = PlacementRParen = SourceLocation();
849 ParenTypeId = true;
850 } else {
851 // We still need the type.
852 if (Tok.is(tok::l_paren)) {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000853 SourceLocation LParen = ConsumeParen();
854 ParseSpecifierQualifierList(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +0000855 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000856 ParseDeclarator(DeclaratorInfo);
857 MatchRHSPunctuation(tok::r_paren, LParen);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000858 ParenTypeId = true;
859 } else {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000860 if (ParseCXXTypeSpecifierSeq(DS))
861 DeclaratorInfo.setInvalidType(true);
Sebastian Redlab197ba2009-02-09 18:23:29 +0000862 else {
863 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000864 ParseDeclaratorInternal(DeclaratorInfo,
865 &Parser::ParseDirectNewDeclarator);
Sebastian Redlab197ba2009-02-09 18:23:29 +0000866 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000867 ParenTypeId = false;
868 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000869 }
870 } else {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000871 // A new-type-id is a simplified type-id, where essentially the
872 // direct-declarator is replaced by a direct-new-declarator.
873 if (ParseCXXTypeSpecifierSeq(DS))
874 DeclaratorInfo.setInvalidType(true);
Sebastian Redlab197ba2009-02-09 18:23:29 +0000875 else {
876 DeclaratorInfo.SetSourceRange(DS.getSourceRange());
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000877 ParseDeclaratorInternal(DeclaratorInfo,
878 &Parser::ParseDirectNewDeclarator);
Sebastian Redlab197ba2009-02-09 18:23:29 +0000879 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000880 ParenTypeId = false;
881 }
Chris Lattnereaaebc72009-04-25 08:06:05 +0000882 if (DeclaratorInfo.isInvalidType()) {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000883 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000884 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000885 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000886
Sebastian Redla55e52c2008-11-25 22:21:31 +0000887 ExprVector ConstructorArgs(Actions);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000888 SourceLocation ConstructorLParen, ConstructorRParen;
889
890 if (Tok.is(tok::l_paren)) {
891 ConstructorLParen = ConsumeParen();
892 if (Tok.isNot(tok::r_paren)) {
893 CommaLocsTy CommaLocs;
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000894 if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
895 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000896 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000897 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000898 }
899 ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000900 if (ConstructorRParen.isInvalid()) {
901 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
Sebastian Redl20df9b72008-12-11 22:51:44 +0000902 return ExprError();
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000903 }
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000904 }
905
Sebastian Redlf53597f2009-03-15 17:47:39 +0000906 return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
907 move_arg(PlacementArgs), PlacementRParen,
908 ParenTypeId, DeclaratorInfo, ConstructorLParen,
909 move_arg(ConstructorArgs), ConstructorRParen);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000910}
911
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000912/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
913/// passed to ParseDeclaratorInternal.
914///
915/// direct-new-declarator:
916/// '[' expression ']'
917/// direct-new-declarator '[' constant-expression ']'
918///
Chris Lattner59232d32009-01-04 21:25:24 +0000919void Parser::ParseDirectNewDeclarator(Declarator &D) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000920 // Parse the array dimensions.
921 bool first = true;
922 while (Tok.is(tok::l_square)) {
923 SourceLocation LLoc = ConsumeBracket();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000924 OwningExprResult Size(first ? ParseExpression()
925 : ParseConstantExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000926 if (Size.isInvalid()) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000927 // Recover
928 SkipUntil(tok::r_square);
929 return;
930 }
931 first = false;
932
Sebastian Redlab197ba2009-02-09 18:23:29 +0000933 SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000934 D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
Sebastian Redlab197ba2009-02-09 18:23:29 +0000935 Size.release(), LLoc),
936 RLoc);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000937
Sebastian Redlab197ba2009-02-09 18:23:29 +0000938 if (RLoc.isInvalid())
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000939 return;
940 }
941}
942
943/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
944/// This ambiguity appears in the syntax of the C++ new operator.
945///
946/// new-expression:
947/// '::'[opt] 'new' new-placement[opt] '(' type-id ')'
948/// new-initializer[opt]
949///
950/// new-placement:
951/// '(' expression-list ')'
952///
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000953bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
Chris Lattner59232d32009-01-04 21:25:24 +0000954 Declarator &D) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000955 // The '(' was already consumed.
956 if (isTypeIdInParens()) {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000957 ParseSpecifierQualifierList(D.getMutableDeclSpec());
Sebastian Redlab197ba2009-02-09 18:23:29 +0000958 D.SetSourceRange(D.getDeclSpec().getSourceRange());
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000959 ParseDeclarator(D);
Chris Lattnereaaebc72009-04-25 08:06:05 +0000960 return D.isInvalidType();
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000961 }
962
963 // It's not a type, it has to be an expression list.
964 // Discard the comma locations - ActOnCXXNew has enough parameters.
965 CommaLocsTy CommaLocs;
966 return ParseExpressionList(PlacementArgs, CommaLocs);
967}
968
969/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
970/// to free memory allocated by new.
971///
Chris Lattner59232d32009-01-04 21:25:24 +0000972/// This method is called to parse the 'delete' expression after the optional
973/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true
974/// and "Start" is its location. Otherwise, "Start" is the location of the
975/// 'delete' token.
976///
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000977/// delete-expression:
978/// '::'[opt] 'delete' cast-expression
979/// '::'[opt] 'delete' '[' ']' cast-expression
Chris Lattner59232d32009-01-04 21:25:24 +0000980Parser::OwningExprResult
981Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
982 assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
983 ConsumeToken(); // Consume 'delete'
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000984
985 // Array delete?
986 bool ArrayDelete = false;
987 if (Tok.is(tok::l_square)) {
988 ArrayDelete = true;
989 SourceLocation LHS = ConsumeBracket();
990 SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
991 if (RHS.isInvalid())
Sebastian Redl20df9b72008-12-11 22:51:44 +0000992 return ExprError();
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000993 }
994
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000995 OwningExprResult Operand(ParseCastExpression(false));
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000996 if (Operand.isInvalid())
Sebastian Redl20df9b72008-12-11 22:51:44 +0000997 return move(Operand);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000998
Sebastian Redlf53597f2009-03-15 17:47:39 +0000999 return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001000}
Sebastian Redl64b45f72009-01-05 20:52:13 +00001001
1002static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind)
1003{
1004 switch(kind) {
1005 default: assert(false && "Not a known unary type trait.");
1006 case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign;
1007 case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy;
1008 case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
1009 case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign;
1010 case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy;
1011 case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
1012 case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor;
1013 case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor;
1014 case tok::kw___is_abstract: return UTT_IsAbstract;
1015 case tok::kw___is_class: return UTT_IsClass;
1016 case tok::kw___is_empty: return UTT_IsEmpty;
1017 case tok::kw___is_enum: return UTT_IsEnum;
1018 case tok::kw___is_pod: return UTT_IsPOD;
1019 case tok::kw___is_polymorphic: return UTT_IsPolymorphic;
1020 case tok::kw___is_union: return UTT_IsUnion;
1021 }
1022}
1023
1024/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
1025/// pseudo-functions that allow implementation of the TR1/C++0x type traits
1026/// templates.
1027///
1028/// primary-expression:
1029/// [GNU] unary-type-trait '(' type-id ')'
1030///
1031Parser::OwningExprResult Parser::ParseUnaryTypeTrait()
1032{
1033 UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
1034 SourceLocation Loc = ConsumeToken();
1035
1036 SourceLocation LParen = Tok.getLocation();
1037 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
1038 return ExprError();
1039
1040 // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
1041 // there will be cryptic errors about mismatched parentheses and missing
1042 // specifiers.
Douglas Gregor809070a2009-02-18 17:45:20 +00001043 TypeResult Ty = ParseTypeName();
Sebastian Redl64b45f72009-01-05 20:52:13 +00001044
1045 SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
1046
Douglas Gregor809070a2009-02-18 17:45:20 +00001047 if (Ty.isInvalid())
1048 return ExprError();
1049
1050 return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
Sebastian Redl64b45f72009-01-05 20:52:13 +00001051}
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001052
1053/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
1054/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
1055/// based on the context past the parens.
1056Parser::OwningExprResult
1057Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
1058 TypeTy *&CastTy,
1059 SourceLocation LParenLoc,
1060 SourceLocation &RParenLoc) {
1061 assert(getLang().CPlusPlus && "Should only be called for C++!");
1062 assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
1063 assert(isTypeIdInParens() && "Not a type-id!");
1064
1065 OwningExprResult Result(Actions, true);
1066 CastTy = 0;
1067
1068 // We need to disambiguate a very ugly part of the C++ syntax:
1069 //
1070 // (T())x; - type-id
1071 // (T())*x; - type-id
1072 // (T())/x; - expression
1073 // (T()); - expression
1074 //
1075 // The bad news is that we cannot use the specialized tentative parser, since
1076 // it can only verify that the thing inside the parens can be parsed as
1077 // type-id, it is not useful for determining the context past the parens.
1078 //
1079 // The good news is that the parser can disambiguate this part without
Argyrios Kyrtzidisa558a892009-05-22 15:12:46 +00001080 // making any unnecessary Action calls.
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001081 //
1082 // It uses a scheme similar to parsing inline methods. The parenthesized
1083 // tokens are cached, the context that follows is determined (possibly by
1084 // parsing a cast-expression), and then we re-introduce the cached tokens
1085 // into the token stream and parse them appropriately.
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001086
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001087 ParenParseOption ParseAs;
1088 CachedTokens Toks;
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001089
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001090 // Store the tokens of the parentheses. We will parse them after we determine
1091 // the context that follows them.
1092 if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) {
1093 // We didn't find the ')' we expected.
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001094 MatchRHSPunctuation(tok::r_paren, LParenLoc);
1095 return ExprError();
1096 }
1097
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001098 if (Tok.is(tok::l_brace)) {
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001099 ParseAs = CompoundLiteral;
1100 } else {
1101 bool NotCastExpr;
Eli Friedmanb53f08a2009-05-25 19:41:42 +00001102 // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
1103 if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
1104 NotCastExpr = true;
1105 } else {
1106 // Try parsing the cast-expression that may follow.
1107 // If it is not a cast-expression, NotCastExpr will be true and no token
1108 // will be consumed.
1109 Result = ParseCastExpression(false/*isUnaryExpression*/,
1110 false/*isAddressofOperand*/,
1111 NotCastExpr);
1112 }
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001113
1114 // If we parsed a cast-expression, it's really a type-id, otherwise it's
1115 // an expression.
1116 ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001117 }
1118
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001119 // The current token should go after the cached tokens.
1120 Toks.push_back(Tok);
1121 // Re-enter the stored parenthesized tokens into the token stream, so we may
1122 // parse them now.
1123 PP.EnterTokenStream(Toks.data(), Toks.size(),
1124 true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
1125 // Drop the current token and bring the first cached one. It's the same token
1126 // as when we entered this function.
1127 ConsumeAnyToken();
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001128
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001129 if (ParseAs >= CompoundLiteral) {
1130 TypeResult Ty = ParseTypeName();
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001131
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001132 // Match the ')'.
1133 if (Tok.is(tok::r_paren))
1134 RParenLoc = ConsumeParen();
1135 else
1136 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001137
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001138 if (ParseAs == CompoundLiteral) {
1139 ExprType = CompoundLiteral;
1140 return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
1141 }
1142
1143 // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
1144 assert(ParseAs == CastExpr);
1145
1146 if (Ty.isInvalid())
1147 return ExprError();
1148
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001149 CastTy = Ty.get();
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001150
1151 // Result is what ParseCastExpression returned earlier.
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001152 if (!Result.isInvalid())
1153 Result = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc,move(Result));
1154 return move(Result);
1155 }
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001156
1157 // Not a compound literal, and not followed by a cast-expression.
1158 assert(ParseAs == SimpleExpr);
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001159
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001160 ExprType = SimpleExpr;
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001161 Result = ParseExpression();
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001162 if (!Result.isInvalid() && Tok.is(tok::r_paren))
1163 Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
1164
1165 // Match the ')'.
1166 if (Result.isInvalid()) {
1167 SkipUntil(tok::r_paren);
1168 return ExprError();
1169 }
Argyrios Kyrtzidisf40882a2009-05-22 21:09:47 +00001170
Argyrios Kyrtzidisf58f45e2009-05-22 10:24:42 +00001171 if (Tok.is(tok::r_paren))
1172 RParenLoc = ConsumeParen();
1173 else
1174 MatchRHSPunctuation(tok::r_paren, LParenLoc);
1175
1176 return move(Result);
1177}