blob: 7c0b43923d60029e2568a1a1905accbfc54d366f [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- ParseExpr.cpp - 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. Expressions in
11// C99 basically consist of a bunch of binary operators with unary operators and
12// other random stuff at the leaves.
13//
14// In the C99 grammar, these unary operators bind tightest and are represented
15// as the 'cast-expression' production. Everything else is either a binary
16// operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are
17// handled by ParseCastExpression, the higher level pieces are handled by
18// ParseBinaryExpression.
19//
20//===----------------------------------------------------------------------===//
21
22#include "clang/Parse/Parser.h"
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000023#include "clang/Parse/DeclSpec.h"
Steve Naroff296e8d52008-08-28 19:20:44 +000024#include "clang/Parse/Scope.h"
Chris Lattnerc46d1a12008-10-20 06:45:43 +000025#include "ExtensionRAIIObject.h"
Sebastian Redla55e52c2008-11-25 22:21:31 +000026#include "AstGuard.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000027#include "llvm/ADT/SmallVector.h"
28#include "llvm/ADT/SmallString.h"
29using namespace clang;
30
31/// PrecedenceLevels - These are precedences for the binary/ternary operators in
32/// the C99 grammar. These have been named to relate with the C99 grammar
33/// productions. Low precedences numbers bind more weakly than high numbers.
34namespace prec {
35 enum Level {
Sebastian Redl22460502009-02-07 00:15:38 +000036 Unknown = 0, // Not binary operator.
37 Comma = 1, // ,
38 Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
39 Conditional = 3, // ?
40 LogicalOr = 4, // ||
41 LogicalAnd = 5, // &&
42 InclusiveOr = 6, // |
43 ExclusiveOr = 7, // ^
44 And = 8, // &
45 Equality = 9, // ==, !=
46 Relational = 10, // >=, <=, >, <
47 Shift = 11, // <<, >>
48 Additive = 12, // -, +
49 Multiplicative = 13, // *, /, %
50 PointerToMember = 14 // .*, ->*
Reid Spencer5f016e22007-07-11 17:01:13 +000051 };
52}
53
54
55/// getBinOpPrecedence - Return the precedence of the specified binary operator
56/// token. This returns:
57///
58static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
59 switch (Kind) {
60 default: return prec::Unknown;
61 case tok::comma: return prec::Comma;
62 case tok::equal:
63 case tok::starequal:
64 case tok::slashequal:
65 case tok::percentequal:
66 case tok::plusequal:
67 case tok::minusequal:
68 case tok::lesslessequal:
69 case tok::greatergreaterequal:
70 case tok::ampequal:
71 case tok::caretequal:
72 case tok::pipeequal: return prec::Assignment;
73 case tok::question: return prec::Conditional;
74 case tok::pipepipe: return prec::LogicalOr;
75 case tok::ampamp: return prec::LogicalAnd;
76 case tok::pipe: return prec::InclusiveOr;
77 case tok::caret: return prec::ExclusiveOr;
78 case tok::amp: return prec::And;
79 case tok::exclaimequal:
80 case tok::equalequal: return prec::Equality;
81 case tok::lessequal:
82 case tok::less:
83 case tok::greaterequal:
84 case tok::greater: return prec::Relational;
85 case tok::lessless:
86 case tok::greatergreater: return prec::Shift;
87 case tok::plus:
88 case tok::minus: return prec::Additive;
89 case tok::percent:
90 case tok::slash:
91 case tok::star: return prec::Multiplicative;
Sebastian Redl22460502009-02-07 00:15:38 +000092 case tok::periodstar:
93 case tok::arrowstar: return prec::PointerToMember;
Reid Spencer5f016e22007-07-11 17:01:13 +000094 }
95}
96
97
98/// ParseExpression - Simple precedence-based parser for binary/ternary
99/// operators.
100///
101/// Note: we diverge from the C99 grammar when parsing the assignment-expression
102/// production. C99 specifies that the LHS of an assignment operator should be
103/// parsed as a unary-expression, but consistency dictates that it be a
104/// conditional-expession. In practice, the important thing here is that the
105/// LHS of an assignment has to be an l-value, which productions between
106/// unary-expression and conditional-expression don't produce. Because we want
107/// consistency, we parse the LHS as a conditional-expression, then check for
108/// l-value-ness in semantic analysis stages.
109///
Sebastian Redl22460502009-02-07 00:15:38 +0000110/// pm-expression: [C++ 5.5]
111/// cast-expression
112/// pm-expression '.*' cast-expression
113/// pm-expression '->*' cast-expression
114///
Reid Spencer5f016e22007-07-11 17:01:13 +0000115/// multiplicative-expression: [C99 6.5.5]
Sebastian Redl22460502009-02-07 00:15:38 +0000116/// Note: in C++, apply pm-expression instead of cast-expression
Reid Spencer5f016e22007-07-11 17:01:13 +0000117/// cast-expression
118/// multiplicative-expression '*' cast-expression
119/// multiplicative-expression '/' cast-expression
120/// multiplicative-expression '%' cast-expression
121///
122/// additive-expression: [C99 6.5.6]
123/// multiplicative-expression
124/// additive-expression '+' multiplicative-expression
125/// additive-expression '-' multiplicative-expression
126///
127/// shift-expression: [C99 6.5.7]
128/// additive-expression
129/// shift-expression '<<' additive-expression
130/// shift-expression '>>' additive-expression
131///
132/// relational-expression: [C99 6.5.8]
133/// shift-expression
134/// relational-expression '<' shift-expression
135/// relational-expression '>' shift-expression
136/// relational-expression '<=' shift-expression
137/// relational-expression '>=' shift-expression
138///
139/// equality-expression: [C99 6.5.9]
140/// relational-expression
141/// equality-expression '==' relational-expression
142/// equality-expression '!=' relational-expression
143///
144/// AND-expression: [C99 6.5.10]
145/// equality-expression
146/// AND-expression '&' equality-expression
147///
148/// exclusive-OR-expression: [C99 6.5.11]
149/// AND-expression
150/// exclusive-OR-expression '^' AND-expression
151///
152/// inclusive-OR-expression: [C99 6.5.12]
153/// exclusive-OR-expression
154/// inclusive-OR-expression '|' exclusive-OR-expression
155///
156/// logical-AND-expression: [C99 6.5.13]
157/// inclusive-OR-expression
158/// logical-AND-expression '&&' inclusive-OR-expression
159///
160/// logical-OR-expression: [C99 6.5.14]
161/// logical-AND-expression
162/// logical-OR-expression '||' logical-AND-expression
163///
164/// conditional-expression: [C99 6.5.15]
165/// logical-OR-expression
166/// logical-OR-expression '?' expression ':' conditional-expression
167/// [GNU] logical-OR-expression '?' ':' conditional-expression
168///
169/// assignment-expression: [C99 6.5.16]
170/// conditional-expression
171/// unary-expression assignment-operator assignment-expression
Chris Lattner50dd2892008-02-26 00:51:44 +0000172/// [C++] throw-expression [C++ 15]
Reid Spencer5f016e22007-07-11 17:01:13 +0000173///
174/// assignment-operator: one of
175/// = *= /= %= += -= <<= >>= &= ^= |=
176///
177/// expression: [C99 6.5.17]
178/// assignment-expression
179/// expression ',' assignment-expression
180///
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000181Parser::OwningExprResult Parser::ParseExpression() {
Chris Lattner50dd2892008-02-26 00:51:44 +0000182 if (Tok.is(tok::kw_throw))
Sebastian Redl20df9b72008-12-11 22:51:44 +0000183 return ParseThrowExpression();
Chris Lattner50dd2892008-02-26 00:51:44 +0000184
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000185 OwningExprResult LHS(ParseCastExpression(false));
186 if (LHS.isInvalid()) return move(LHS);
187
Sebastian Redld8c4e152008-12-11 22:33:27 +0000188 return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
Reid Spencer5f016e22007-07-11 17:01:13 +0000189}
190
Fariborz Jahanian397fcc12007-09-19 19:14:32 +0000191/// This routine is called when the '@' is seen and consumed.
192/// Current token is an Identifier and is not a 'try'. This
Chris Lattnerc97c2042007-10-03 22:03:06 +0000193/// routine is necessary to disambiguate @try-statement from,
194/// for example, @encode-expression.
Fariborz Jahanian397fcc12007-09-19 19:14:32 +0000195///
Sebastian Redld8c4e152008-12-11 22:33:27 +0000196Parser::OwningExprResult
197Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
Sebastian Redl1d922962008-12-13 15:32:12 +0000198 OwningExprResult LHS(ParseObjCAtExpression(AtLoc));
Sebastian Redld8c4e152008-12-11 22:33:27 +0000199 if (LHS.isInvalid()) return move(LHS);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000200
Sebastian Redld8c4e152008-12-11 22:33:27 +0000201 return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
Fariborz Jahanian397fcc12007-09-19 19:14:32 +0000202}
203
Eli Friedmanadf077f2009-01-27 08:43:38 +0000204/// This routine is called when a leading '__extension__' is seen and
205/// consumed. This is necessary because the token gets consumed in the
206/// process of disambiguating between an expression and a declaration.
207Parser::OwningExprResult
208Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
209 // FIXME: The handling for throw is almost certainly wrong.
210 if (Tok.is(tok::kw_throw))
211 return ParseThrowExpression();
212
213 OwningExprResult LHS(ParseCastExpression(false));
214 if (LHS.isInvalid()) return move(LHS);
215
216 LHS = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__,
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000217 move(LHS));
Eli Friedmanadf077f2009-01-27 08:43:38 +0000218 if (LHS.isInvalid()) return move(LHS);
219
220 return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
221}
222
Reid Spencer5f016e22007-07-11 17:01:13 +0000223/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
224///
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000225Parser::OwningExprResult Parser::ParseAssignmentExpression() {
Chris Lattner50dd2892008-02-26 00:51:44 +0000226 if (Tok.is(tok::kw_throw))
Sebastian Redl20df9b72008-12-11 22:51:44 +0000227 return ParseThrowExpression();
Chris Lattner50dd2892008-02-26 00:51:44 +0000228
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000229 OwningExprResult LHS(ParseCastExpression(false));
230 if (LHS.isInvalid()) return move(LHS);
231
Sebastian Redld8c4e152008-12-11 22:33:27 +0000232 return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
Reid Spencer5f016e22007-07-11 17:01:13 +0000233}
234
Chris Lattnerb93fb492008-06-02 21:31:07 +0000235/// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
236/// where part of an objc message send has already been parsed. In this case
237/// LBracLoc indicates the location of the '[' of the message send, and either
238/// ReceiverName or ReceiverExpr is non-null indicating the receiver of the
239/// message.
240///
241/// Since this handles full assignment-expression's, it handles postfix
242/// expressions and other binary operators for these expressions as well.
Sebastian Redl1d922962008-12-13 15:32:12 +0000243Parser::OwningExprResult
Chris Lattnerb93fb492008-06-02 21:31:07 +0000244Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
Steve Naroff5cb93b82008-11-19 15:54:23 +0000245 SourceLocation NameLoc,
Chris Lattnerb93fb492008-06-02 21:31:07 +0000246 IdentifierInfo *ReceiverName,
Sebastian Redl1d922962008-12-13 15:32:12 +0000247 ExprArg ReceiverExpr) {
248 OwningExprResult R(ParseObjCMessageExpressionBody(LBracLoc, NameLoc,
249 ReceiverName,
250 move(ReceiverExpr)));
251 if (R.isInvalid()) return move(R);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000252 R = ParsePostfixExpressionSuffix(move(R));
Sebastian Redl1d922962008-12-13 15:32:12 +0000253 if (R.isInvalid()) return move(R);
254 return ParseRHSOfBinaryExpression(move(R), prec::Assignment);
Chris Lattnerb93fb492008-06-02 21:31:07 +0000255}
256
257
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000258Parser::OwningExprResult Parser::ParseConstantExpression() {
259 OwningExprResult LHS(ParseCastExpression(false));
260 if (LHS.isInvalid()) return move(LHS);
261
Sebastian Redld8c4e152008-12-11 22:33:27 +0000262 return ParseRHSOfBinaryExpression(move(LHS), prec::Conditional);
Reid Spencer5f016e22007-07-11 17:01:13 +0000263}
264
Reid Spencer5f016e22007-07-11 17:01:13 +0000265/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
266/// LHS and has a precedence of at least MinPrec.
Sebastian Redld8c4e152008-12-11 22:33:27 +0000267Parser::OwningExprResult
268Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000269 unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
270 SourceLocation ColonLoc;
271
272 while (1) {
273 // If this token has a lower precedence than we are allowed to parse (e.g.
274 // because we are called recursively, or because the token is not a binop),
275 // then we are done!
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000276 if (NextTokPrec < MinPrec)
Sebastian Redld8c4e152008-12-11 22:33:27 +0000277 return move(LHS);
Reid Spencer5f016e22007-07-11 17:01:13 +0000278
279 // Consume the operator, saving the operator token for error reporting.
Chris Lattnerd2177732007-07-20 16:59:19 +0000280 Token OpToken = Tok;
Reid Spencer5f016e22007-07-11 17:01:13 +0000281 ConsumeToken();
Sebastian Redl22460502009-02-07 00:15:38 +0000282
Reid Spencer5f016e22007-07-11 17:01:13 +0000283 // Special case handling for the ternary operator.
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000284 OwningExprResult TernaryMiddle(Actions, true);
Reid Spencer5f016e22007-07-11 17:01:13 +0000285 if (NextTokPrec == prec::Conditional) {
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000286 if (Tok.isNot(tok::colon)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000287 // Handle this production specially:
288 // logical-OR-expression '?' expression ':' conditional-expression
289 // In particular, the RHS of the '?' is 'expression', not
290 // 'logical-OR-expression' as we might expect.
291 TernaryMiddle = ParseExpression();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000292 if (TernaryMiddle.isInvalid())
Sebastian Redld8c4e152008-12-11 22:33:27 +0000293 return move(TernaryMiddle);
Reid Spencer5f016e22007-07-11 17:01:13 +0000294 } else {
295 // Special case handling of "X ? Y : Z" where Y is empty:
296 // logical-OR-expression '?' ':' conditional-expression [GNU]
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000297 TernaryMiddle = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000298 Diag(Tok, diag::ext_gnu_conditional_expr);
299 }
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000300
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000301 if (Tok.isNot(tok::colon)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000302 Diag(Tok, diag::err_expected_colon);
Chris Lattner28eb7e92008-11-23 23:17:07 +0000303 Diag(OpToken, diag::note_matching) << "?";
Sebastian Redld8c4e152008-12-11 22:33:27 +0000304 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000305 }
Sebastian Redld8c4e152008-12-11 22:33:27 +0000306
Reid Spencer5f016e22007-07-11 17:01:13 +0000307 // Eat the colon.
308 ColonLoc = ConsumeToken();
309 }
Sebastian Redld8c4e152008-12-11 22:33:27 +0000310
Reid Spencer5f016e22007-07-11 17:01:13 +0000311 // Parse another leaf here for the RHS of the operator.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000312 OwningExprResult RHS(ParseCastExpression(false));
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000313 if (RHS.isInvalid())
Sebastian Redld8c4e152008-12-11 22:33:27 +0000314 return move(RHS);
Reid Spencer5f016e22007-07-11 17:01:13 +0000315
316 // Remember the precedence of this operator and get the precedence of the
317 // operator immediately to the right of the RHS.
318 unsigned ThisPrec = NextTokPrec;
319 NextTokPrec = getBinOpPrecedence(Tok.getKind());
320
321 // Assignment and conditional expressions are right-associative.
Chris Lattnerd7d860d2007-12-18 06:06:23 +0000322 bool isRightAssoc = ThisPrec == prec::Conditional ||
323 ThisPrec == prec::Assignment;
Reid Spencer5f016e22007-07-11 17:01:13 +0000324
325 // Get the precedence of the operator to the right of the RHS. If it binds
326 // more tightly with RHS than we do, evaluate it completely first.
327 if (ThisPrec < NextTokPrec ||
328 (ThisPrec == NextTokPrec && isRightAssoc)) {
329 // If this is left-associative, only parse things on the RHS that bind
330 // more tightly than the current operator. If it is left-associative, it
331 // is okay, to bind exactly as tightly. For example, compile A=B=C=D as
332 // A=(B=(C=D)), where each paren is a level of recursion here.
Sebastian Redla55e52c2008-11-25 22:21:31 +0000333 // The function takes ownership of the RHS.
Sebastian Redld8c4e152008-12-11 22:33:27 +0000334 RHS = ParseRHSOfBinaryExpression(move(RHS), ThisPrec + !isRightAssoc);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000335 if (RHS.isInvalid())
Sebastian Redld8c4e152008-12-11 22:33:27 +0000336 return move(RHS);
Reid Spencer5f016e22007-07-11 17:01:13 +0000337
338 NextTokPrec = getBinOpPrecedence(Tok.getKind());
339 }
340 assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
Sebastian Redla55e52c2008-11-25 22:21:31 +0000341
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000342 if (!LHS.isInvalid()) {
Chris Lattnerd56d6b62007-08-31 05:01:50 +0000343 // Combine the LHS and RHS into the LHS (e.g. build AST).
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000344 if (TernaryMiddle.isInvalid())
Sebastian Redleffa8d12008-12-10 00:02:53 +0000345 LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(),
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000346 OpToken.getKind(), move(LHS), move(RHS));
Chris Lattnerd56d6b62007-08-31 05:01:50 +0000347 else
Steve Narofff69936d2007-09-16 03:34:24 +0000348 LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000349 move(LHS), move(TernaryMiddle),
350 move(RHS));
Chris Lattnerd56d6b62007-08-31 05:01:50 +0000351 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000352 }
353}
354
355/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
Sebastian Redlebc07d52009-02-03 20:19:35 +0000356/// true, parse a unary-expression. isAddressOfOperand exists because an
357/// id-expression that is the operand of address-of gets special treatment
358/// due to member pointers.
Reid Spencer5f016e22007-07-11 17:01:13 +0000359///
360/// cast-expression: [C99 6.5.4]
361/// unary-expression
362/// '(' type-name ')' cast-expression
363///
364/// unary-expression: [C99 6.5.3]
365/// postfix-expression
366/// '++' unary-expression
367/// '--' unary-expression
368/// unary-operator cast-expression
369/// 'sizeof' unary-expression
370/// 'sizeof' '(' type-name ')'
371/// [GNU] '__alignof' unary-expression
372/// [GNU] '__alignof' '(' type-name ')'
Douglas Gregor85bb3da2008-11-06 15:17:27 +0000373/// [C++0x] 'alignof' '(' type-id ')'
Reid Spencer5f016e22007-07-11 17:01:13 +0000374/// [GNU] '&&' identifier
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000375/// [C++] new-expression
376/// [C++] delete-expression
Reid Spencer5f016e22007-07-11 17:01:13 +0000377///
378/// unary-operator: one of
379/// '&' '*' '+' '-' '~' '!'
380/// [GNU] '__extension__' '__real' '__imag'
381///
382/// primary-expression: [C99 6.5.1]
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000383/// [C99] identifier
Sebastian Redlc42e1182008-11-11 11:37:55 +0000384/// [C++] id-expression
Reid Spencer5f016e22007-07-11 17:01:13 +0000385/// constant
386/// string-literal
387/// [C++] boolean-literal [C++ 2.13.5]
388/// '(' expression ')'
389/// '__func__' [C99 6.4.2.2]
390/// [GNU] '__FUNCTION__'
391/// [GNU] '__PRETTY_FUNCTION__'
392/// [GNU] '(' compound-statement ')'
393/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
394/// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
395/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
396/// assign-expr ')'
397/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
Douglas Gregor2d8b2732008-11-29 04:51:27 +0000398/// [GNU] '__null'
Fariborz Jahanian095ffca2007-09-26 17:03:44 +0000399/// [OBJC] '[' objc-message-expr ']'
Chris Lattner5ac87ed2008-01-25 18:58:06 +0000400/// [OBJC] '@selector' '(' objc-selector-arg ')'
Fariborz Jahanian095ffca2007-09-26 17:03:44 +0000401/// [OBJC] '@protocol' '(' identifier ')'
402/// [OBJC] '@encode' '(' type-name ')'
Fariborz Jahanian0ccb27d2007-09-05 19:52:07 +0000403/// [OBJC] objc-string-literal
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000404/// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
405/// [C++] typename-specifier '(' expression-list[opt] ')' [TODO]
Reid Spencer5f016e22007-07-11 17:01:13 +0000406/// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
407/// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
408/// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
409/// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
Sebastian Redlc42e1182008-11-11 11:37:55 +0000410/// [C++] 'typeid' '(' expression ')' [C++ 5.2p1]
411/// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1]
Argyrios Kyrtzidisd7464be2008-07-16 07:23:27 +0000412/// [C++] 'this' [C++ 9.3.2]
Sebastian Redl64b45f72009-01-05 20:52:13 +0000413/// [G++] unary-type-trait '(' type-id ')'
414/// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO]
Steve Naroff296e8d52008-08-28 19:20:44 +0000415/// [clang] '^' block-literal
Reid Spencer5f016e22007-07-11 17:01:13 +0000416///
417/// constant: [C99 6.4.4]
418/// integer-constant
419/// floating-constant
420/// enumeration-constant -> identifier
421/// character-constant
422///
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000423/// id-expression: [C++ 5.1]
424/// unqualified-id
425/// qualified-id [TODO]
426///
427/// unqualified-id: [C++ 5.1]
428/// identifier
429/// operator-function-id
430/// conversion-function-id [TODO]
431/// '~' class-name [TODO]
432/// template-id [TODO]
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000433///
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000434/// new-expression: [C++ 5.3.4]
435/// '::'[opt] 'new' new-placement[opt] new-type-id
436/// new-initializer[opt]
437/// '::'[opt] 'new' new-placement[opt] '(' type-id ')'
438/// new-initializer[opt]
439///
440/// delete-expression: [C++ 5.3.5]
441/// '::'[opt] 'delete' cast-expression
442/// '::'[opt] 'delete' '[' ']' cast-expression
443///
Sebastian Redl64b45f72009-01-05 20:52:13 +0000444/// [GNU] unary-type-trait:
445/// '__has_nothrow_assign' [TODO]
446/// '__has_nothrow_copy' [TODO]
447/// '__has_nothrow_constructor' [TODO]
448/// '__has_trivial_assign' [TODO]
449/// '__has_trivial_copy' [TODO]
450/// '__has_trivial_constructor' [TODO]
451/// '__has_trivial_destructor' [TODO]
452/// '__has_virtual_destructor' [TODO]
453/// '__is_abstract' [TODO]
454/// '__is_class'
455/// '__is_empty' [TODO]
456/// '__is_enum'
457/// '__is_pod'
458/// '__is_polymorphic'
459/// '__is_union'
460///
461/// [GNU] binary-type-trait:
462/// '__is_base_of' [TODO]
463///
Sebastian Redlebc07d52009-02-03 20:19:35 +0000464Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
465 bool isAddressOfOperand) {
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000466 OwningExprResult Res(Actions);
Reid Spencer5f016e22007-07-11 17:01:13 +0000467 tok::TokenKind SavedKind = Tok.getKind();
468
469 // This handles all of cast-expression, unary-expression, postfix-expression,
470 // and primary-expression. We handle them together like this for efficiency
471 // and to simplify handling of an expression starting with a '(' token: which
472 // may be one of a parenthesized expression, cast-expression, compound literal
473 // expression, or statement expression.
474 //
475 // If the parsed tokens consist of a primary-expression, the cases below
476 // call ParsePostfixExpressionSuffix to handle the postfix expression
477 // suffixes. Cases that cannot be followed by postfix exprs should
478 // return without invoking ParsePostfixExpressionSuffix.
479 switch (SavedKind) {
480 case tok::l_paren: {
481 // If this expression is limited to being a unary-expression, the parent can
482 // not start a cast expression.
483 ParenParseOption ParenExprType =
484 isUnaryExpression ? CompoundLiteral : CastExpr;
485 TypeTy *CastTy;
486 SourceLocation LParenLoc = Tok.getLocation();
487 SourceLocation RParenLoc;
488 Res = ParseParenExpression(ParenExprType, CastTy, RParenLoc);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000489 if (Res.isInvalid()) return move(Res);
Reid Spencer5f016e22007-07-11 17:01:13 +0000490
491 switch (ParenExprType) {
492 case SimpleExpr: break; // Nothing else to do.
493 case CompoundStmt: break; // Nothing else to do.
494 case CompoundLiteral:
495 // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of
496 // postfix-expression exist, parse them now.
497 break;
498 case CastExpr:
499 // We parsed '(' type-name ')' and the thing after it wasn't a '{'. Parse
500 // the cast-expression that follows it next.
501 // TODO: For cast expression with CastTy.
502 Res = ParseCastExpression(false);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000503 if (!Res.isInvalid())
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000504 Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, move(Res));
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000505 return move(Res);
Reid Spencer5f016e22007-07-11 17:01:13 +0000506 }
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000507
Reid Spencer5f016e22007-07-11 17:01:13 +0000508 // These can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000509 return ParsePostfixExpressionSuffix(move(Res));
Reid Spencer5f016e22007-07-11 17:01:13 +0000510 }
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000511
Reid Spencer5f016e22007-07-11 17:01:13 +0000512 // primary-expression
513 case tok::numeric_constant:
514 // constant: integer-constant
515 // constant: floating-constant
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000516
Steve Narofff69936d2007-09-16 03:34:24 +0000517 Res = Actions.ActOnNumericConstant(Tok);
Reid Spencer5f016e22007-07-11 17:01:13 +0000518 ConsumeToken();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000519
Reid Spencer5f016e22007-07-11 17:01:13 +0000520 // These can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000521 return ParsePostfixExpressionSuffix(move(Res));
Reid Spencer5f016e22007-07-11 17:01:13 +0000522
523 case tok::kw_true:
524 case tok::kw_false:
Sebastian Redl20df9b72008-12-11 22:51:44 +0000525 return ParseCXXBoolLiteral();
Reid Spencer5f016e22007-07-11 17:01:13 +0000526
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000527 case tok::identifier: { // primary-expression: identifier
528 // unqualified-id: identifier
529 // constant: enumeration-constant
Chris Lattnerb31757b2009-01-06 05:06:21 +0000530 // Turn a potentially qualified name into a annot_typename or
Chris Lattner74ba4102009-01-04 22:52:14 +0000531 // annot_cxxscope if it would be valid. This handles things like x::y, etc.
Chris Lattnera7bc7c82009-01-04 23:23:14 +0000532 if (getLang().CPlusPlus) {
Chris Lattnere26ff022009-01-04 23:46:59 +0000533 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
534 if (TryAnnotateTypeOrScopeToken())
Sebastian Redlebc07d52009-02-03 20:19:35 +0000535 return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
Chris Lattnera7bc7c82009-01-04 23:23:14 +0000536 }
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000537
Reid Spencer5f016e22007-07-11 17:01:13 +0000538 // Consume the identifier so that we can see if it is followed by a '('.
539 // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
540 // need to know whether or not this identifier is a function designator or
541 // not.
542 IdentifierInfo &II = *Tok.getIdentifierInfo();
543 SourceLocation L = ConsumeToken();
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000544 Res = Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren));
Reid Spencer5f016e22007-07-11 17:01:13 +0000545 // These can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000546 return ParsePostfixExpressionSuffix(move(Res));
Reid Spencer5f016e22007-07-11 17:01:13 +0000547 }
548 case tok::char_constant: // constant: character-constant
Steve Narofff69936d2007-09-16 03:34:24 +0000549 Res = Actions.ActOnCharacterConstant(Tok);
Reid Spencer5f016e22007-07-11 17:01:13 +0000550 ConsumeToken();
551 // These can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000552 return ParsePostfixExpressionSuffix(move(Res));
Reid Spencer5f016e22007-07-11 17:01:13 +0000553 case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
554 case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
555 case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
Chris Lattnerd9f69102008-08-10 01:53:14 +0000556 Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
Reid Spencer5f016e22007-07-11 17:01:13 +0000557 ConsumeToken();
558 // These can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000559 return ParsePostfixExpressionSuffix(move(Res));
Reid Spencer5f016e22007-07-11 17:01:13 +0000560 case tok::string_literal: // primary-expression: string-literal
561 case tok::wide_string_literal:
562 Res = ParseStringLiteralExpression();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000563 if (Res.isInvalid()) return move(Res);
Reid Spencer5f016e22007-07-11 17:01:13 +0000564 // This can be followed by postfix-expr pieces (e.g. "foo"[1]).
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000565 return ParsePostfixExpressionSuffix(move(Res));
Reid Spencer5f016e22007-07-11 17:01:13 +0000566 case tok::kw___builtin_va_arg:
567 case tok::kw___builtin_offsetof:
568 case tok::kw___builtin_choose_expr:
Nate Begemane2ce1d92008-01-17 17:46:27 +0000569 case tok::kw___builtin_overload:
Reid Spencer5f016e22007-07-11 17:01:13 +0000570 case tok::kw___builtin_types_compatible_p:
Sebastian Redld8c4e152008-12-11 22:33:27 +0000571 return ParseBuiltinPrimaryExpression();
Douglas Gregor2d8b2732008-11-29 04:51:27 +0000572 case tok::kw___null:
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000573 return Owned(Actions.ActOnGNUNullExpr(ConsumeToken()));
Douglas Gregor2d8b2732008-11-29 04:51:27 +0000574 break;
Reid Spencer5f016e22007-07-11 17:01:13 +0000575 case tok::plusplus: // unary-expression: '++' unary-expression
576 case tok::minusminus: { // unary-expression: '--' unary-expression
577 SourceLocation SavedLoc = ConsumeToken();
578 Res = ParseCastExpression(true);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000579 if (!Res.isInvalid())
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000580 Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000581 return move(Res);
Reid Spencer5f016e22007-07-11 17:01:13 +0000582 }
Sebastian Redlebc07d52009-02-03 20:19:35 +0000583 case tok::amp: { // unary-expression: '&' cast-expression
584 // Special treatment because of member pointers
585 SourceLocation SavedLoc = ConsumeToken();
586 Res = ParseCastExpression(false, true);
587 if (!Res.isInvalid())
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000588 Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
Sebastian Redlebc07d52009-02-03 20:19:35 +0000589 return move(Res);
590 }
591
Reid Spencer5f016e22007-07-11 17:01:13 +0000592 case tok::star: // unary-expression: '*' cast-expression
593 case tok::plus: // unary-expression: '+' cast-expression
594 case tok::minus: // unary-expression: '-' cast-expression
595 case tok::tilde: // unary-expression: '~' cast-expression
596 case tok::exclaim: // unary-expression: '!' cast-expression
597 case tok::kw___real: // unary-expression: '__real' cast-expression [GNU]
Chris Lattner35080842008-02-02 20:20:10 +0000598 case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
Reid Spencer5f016e22007-07-11 17:01:13 +0000599 SourceLocation SavedLoc = ConsumeToken();
600 Res = ParseCastExpression(false);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000601 if (!Res.isInvalid())
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000602 Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000603 return move(Res);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000604 }
605
Chris Lattner35080842008-02-02 20:20:10 +0000606 case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
607 // __extension__ silences extension warnings in the subexpression.
Chris Lattnerc46d1a12008-10-20 06:45:43 +0000608 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Chris Lattner35080842008-02-02 20:20:10 +0000609 SourceLocation SavedLoc = ConsumeToken();
610 Res = ParseCastExpression(false);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000611 if (!Res.isInvalid())
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000612 Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000613 return move(Res);
Reid Spencer5f016e22007-07-11 17:01:13 +0000614 }
615 case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
616 // unary-expression: 'sizeof' '(' type-name ')'
Douglas Gregor85bb3da2008-11-06 15:17:27 +0000617 case tok::kw_alignof:
Reid Spencer5f016e22007-07-11 17:01:13 +0000618 case tok::kw___alignof: // unary-expression: '__alignof' unary-expression
619 // unary-expression: '__alignof' '(' type-name ')'
Douglas Gregor85bb3da2008-11-06 15:17:27 +0000620 // unary-expression: 'alignof' '(' type-id ')'
Sebastian Redld8c4e152008-12-11 22:33:27 +0000621 return ParseSizeofAlignofExpression();
Reid Spencer5f016e22007-07-11 17:01:13 +0000622 case tok::ampamp: { // unary-expression: '&&' identifier
623 SourceLocation AmpAmpLoc = ConsumeToken();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000624 if (Tok.isNot(tok::identifier))
625 return ExprError(Diag(Tok, diag::err_expected_ident));
Sebastian Redleffa8d12008-12-10 00:02:53 +0000626
Reid Spencer5f016e22007-07-11 17:01:13 +0000627 Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
Steve Naroff1b273c42007-09-16 14:56:35 +0000628 Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
Reid Spencer5f016e22007-07-11 17:01:13 +0000629 Tok.getIdentifierInfo());
630 ConsumeToken();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000631 return move(Res);
Reid Spencer5f016e22007-07-11 17:01:13 +0000632 }
633 case tok::kw_const_cast:
634 case tok::kw_dynamic_cast:
635 case tok::kw_reinterpret_cast:
636 case tok::kw_static_cast:
Argyrios Kyrtzidisb348b812008-08-16 19:45:32 +0000637 Res = ParseCXXCasts();
638 // These can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000639 return ParsePostfixExpressionSuffix(move(Res));
Sebastian Redlc42e1182008-11-11 11:37:55 +0000640 case tok::kw_typeid:
641 Res = ParseCXXTypeid();
642 // This can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000643 return ParsePostfixExpressionSuffix(move(Res));
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000644 case tok::kw_this:
Argyrios Kyrtzidis289d7732008-08-16 19:34:46 +0000645 Res = ParseCXXThis();
646 // This can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000647 return ParsePostfixExpressionSuffix(move(Res));
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000648
649 case tok::kw_char:
650 case tok::kw_wchar_t:
651 case tok::kw_bool:
652 case tok::kw_short:
653 case tok::kw_int:
654 case tok::kw_long:
655 case tok::kw_signed:
656 case tok::kw_unsigned:
657 case tok::kw_float:
658 case tok::kw_double:
659 case tok::kw_void:
Chris Lattner2dcaab32009-01-04 22:28:21 +0000660 case tok::kw_typeof:
Chris Lattnerb31757b2009-01-06 05:06:21 +0000661 case tok::annot_typename: {
Chris Lattner2dcaab32009-01-04 22:28:21 +0000662 if (!getLang().CPlusPlus) {
663 Diag(Tok, diag::err_expected_expression);
664 return ExprError();
665 }
666
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000667 // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
668 //
669 DeclSpec DS;
670 ParseCXXSimpleTypeSpecifier(DS);
671 if (Tok.isNot(tok::l_paren))
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000672 return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
673 << DS.getSourceRange());
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000674
675 Res = ParseCXXTypeConstructExpression(DS);
676 // This can be followed by postfix-expr pieces.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000677 return ParsePostfixExpressionSuffix(move(Res));
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +0000678 }
679
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000680 case tok::annot_cxxscope: // [C++] id-expression: qualified-id
681 case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
682 // template-id
Sebastian Redlebc07d52009-02-03 20:19:35 +0000683 Res = ParseCXXIdExpression(isAddressOfOperand);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000684 return ParsePostfixExpressionSuffix(move(Res));
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +0000685
Chris Lattner74ba4102009-01-04 22:52:14 +0000686 case tok::coloncolon: {
Chris Lattner5b454732009-01-05 03:55:46 +0000687 // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken
688 // annotates the token, tail recurse.
689 if (TryAnnotateTypeOrScopeToken())
Sebastian Redlebc07d52009-02-03 20:19:35 +0000690 return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
691
Chris Lattner74ba4102009-01-04 22:52:14 +0000692 // ::new -> [C++] new-expression
693 // ::delete -> [C++] delete-expression
Chris Lattner5b454732009-01-05 03:55:46 +0000694 SourceLocation CCLoc = ConsumeToken();
Chris Lattner59232d32009-01-04 21:25:24 +0000695 if (Tok.is(tok::kw_new))
Chris Lattner5b454732009-01-05 03:55:46 +0000696 return ParseCXXNewExpression(true, CCLoc);
Chris Lattner74ba4102009-01-04 22:52:14 +0000697 if (Tok.is(tok::kw_delete))
Chris Lattner5b454732009-01-05 03:55:46 +0000698 return ParseCXXDeleteExpression(true, CCLoc);
699
Chris Lattnera7bc7c82009-01-04 23:23:14 +0000700 // This is not a type name or scope specifier, it is an invalid expression.
Chris Lattner5b454732009-01-05 03:55:46 +0000701 Diag(CCLoc, diag::err_expected_expression);
Chris Lattnera7bc7c82009-01-04 23:23:14 +0000702 return ExprError();
Chris Lattner59232d32009-01-04 21:25:24 +0000703 }
Sebastian Redlfb4ccd72008-12-02 16:35:44 +0000704
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000705 case tok::kw_new: // [C++] new-expression
Chris Lattner59232d32009-01-04 21:25:24 +0000706 return ParseCXXNewExpression(false, Tok.getLocation());
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000707
708 case tok::kw_delete: // [C++] delete-expression
Chris Lattner59232d32009-01-04 21:25:24 +0000709 return ParseCXXDeleteExpression(false, Tok.getLocation());
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000710
Sebastian Redl64b45f72009-01-05 20:52:13 +0000711 case tok::kw___is_pod: // [GNU] unary-type-trait
712 case tok::kw___is_class:
713 case tok::kw___is_enum:
714 case tok::kw___is_union:
715 case tok::kw___is_polymorphic:
716 return ParseUnaryTypeTrait();
717
Chris Lattnerc97c2042007-10-03 22:03:06 +0000718 case tok::at: {
719 SourceLocation AtLoc = ConsumeToken();
Sebastian Redl1d922962008-12-13 15:32:12 +0000720 return ParseObjCAtExpression(AtLoc);
Chris Lattnerc97c2042007-10-03 22:03:06 +0000721 }
Steve Naroff296e8d52008-08-28 19:20:44 +0000722 case tok::caret:
723 if (getLang().Blocks)
Sebastian Redl1d922962008-12-13 15:32:12 +0000724 return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression());
Steve Naroff296e8d52008-08-28 19:20:44 +0000725 Diag(Tok, diag::err_expected_expression);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000726 return ExprError();
Chris Lattnerfdb548e2008-12-12 19:20:14 +0000727 case tok::l_square:
728 // These can be followed by postfix-expr pieces.
729 if (getLang().ObjC1)
Sebastian Redl1d922962008-12-13 15:32:12 +0000730 return ParsePostfixExpressionSuffix(ParseObjCMessageExpression());
Chris Lattner2dcaab32009-01-04 22:28:21 +0000731 // FALL THROUGH.
Reid Spencer5f016e22007-07-11 17:01:13 +0000732 default:
733 Diag(Tok, diag::err_expected_expression);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000734 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000735 }
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000736
Reid Spencer5f016e22007-07-11 17:01:13 +0000737 // unreachable.
738 abort();
739}
740
741/// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression
742/// is parsed, this method parses any suffixes that apply.
743///
744/// postfix-expression: [C99 6.5.2]
745/// primary-expression
746/// postfix-expression '[' expression ']'
747/// postfix-expression '(' argument-expression-list[opt] ')'
748/// postfix-expression '.' identifier
749/// postfix-expression '->' identifier
750/// postfix-expression '++'
751/// postfix-expression '--'
752/// '(' type-name ')' '{' initializer-list '}'
753/// '(' type-name ')' '{' initializer-list ',' '}'
754///
755/// argument-expression-list: [C99 6.5.2]
756/// argument-expression
757/// argument-expression-list ',' assignment-expression
758///
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000759Parser::OwningExprResult
760Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000761 // Now that the primary-expression piece of the postfix-expression has been
762 // parsed, see if there are any postfix-expression pieces here.
763 SourceLocation Loc;
764 while (1) {
765 switch (Tok.getKind()) {
766 default: // Not a postfix-expression suffix.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000767 return move(LHS);
Reid Spencer5f016e22007-07-11 17:01:13 +0000768 case tok::l_square: { // postfix-expression: p-e '[' expression ']'
769 Loc = ConsumeBracket();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000770 OwningExprResult Idx(ParseExpression());
Sebastian Redla55e52c2008-11-25 22:21:31 +0000771
Reid Spencer5f016e22007-07-11 17:01:13 +0000772 SourceLocation RLoc = Tok.getLocation();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000773
774 if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) {
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000775 LHS = Actions.ActOnArraySubscriptExpr(CurScope, move(LHS), Loc,
776 move(Idx), RLoc);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000777 } else
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000778 LHS = ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000779
780 // Match the ']'.
781 MatchRHSPunctuation(tok::r_square, Loc);
782 break;
783 }
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000784
Reid Spencer5f016e22007-07-11 17:01:13 +0000785 case tok::l_paren: { // p-e: p-e '(' argument-expression-list[opt] ')'
Sebastian Redla55e52c2008-11-25 22:21:31 +0000786 ExprVector ArgExprs(Actions);
Argyrios Kyrtzidis0cd5b422008-08-16 20:03:01 +0000787 CommaLocsTy CommaLocs;
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000788
Reid Spencer5f016e22007-07-11 17:01:13 +0000789 Loc = ConsumeParen();
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000790
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000791 if (Tok.isNot(tok::r_paren)) {
Argyrios Kyrtzidis0cd5b422008-08-16 20:03:01 +0000792 if (ParseExpressionList(ArgExprs, CommaLocs)) {
793 SkipUntil(tok::r_paren);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000794 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000795 }
796 }
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000797
Reid Spencer5f016e22007-07-11 17:01:13 +0000798 // Match the ')'.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000799 if (!LHS.isInvalid() && Tok.is(tok::r_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000800 assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
801 "Unexpected number of commas!");
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000802 LHS = Actions.ActOnCallExpr(CurScope, move(LHS), Loc,
Sebastian Redl0eb23302009-01-19 00:08:26 +0000803 move_arg(ArgExprs), &CommaLocs[0],
Sebastian Redla55e52c2008-11-25 22:21:31 +0000804 Tok.getLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +0000805 }
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000806
Chris Lattner2ff54262007-07-21 05:18:12 +0000807 MatchRHSPunctuation(tok::r_paren, Loc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000808 break;
809 }
810 case tok::arrow: // postfix-expression: p-e '->' identifier
811 case tok::period: { // postfix-expression: p-e '.' identifier
812 tok::TokenKind OpKind = Tok.getKind();
813 SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000814
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000815 if (Tok.isNot(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000816 Diag(Tok, diag::err_expected_ident);
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000817 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000818 }
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000819
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000820 if (!LHS.isInvalid()) {
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000821 LHS = Actions.ActOnMemberReferenceExpr(CurScope, move(LHS), OpLoc,
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000822 OpKind, Tok.getLocation(),
Reid Spencer5f016e22007-07-11 17:01:13 +0000823 *Tok.getIdentifierInfo());
Sebastian Redla55e52c2008-11-25 22:21:31 +0000824 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000825 ConsumeToken();
826 break;
827 }
828 case tok::plusplus: // postfix-expression: postfix-expression '++'
829 case tok::minusminus: // postfix-expression: postfix-expression '--'
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000830 if (!LHS.isInvalid()) {
Douglas Gregor74253732008-11-19 15:42:04 +0000831 LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(),
Sebastian Redl76ad2e82009-02-05 15:02:23 +0000832 Tok.getKind(), move(LHS));
Sebastian Redla55e52c2008-11-25 22:21:31 +0000833 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000834 ConsumeToken();
835 break;
836 }
837 }
838}
839
840
841/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
842/// unary-expression: [C99 6.5.3]
843/// 'sizeof' unary-expression
844/// 'sizeof' '(' type-name ')'
845/// [GNU] '__alignof' unary-expression
846/// [GNU] '__alignof' '(' type-name ')'
Douglas Gregor85bb3da2008-11-06 15:17:27 +0000847/// [C++0x] 'alignof' '(' type-id ')'
Sebastian Redld8c4e152008-12-11 22:33:27 +0000848Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
Douglas Gregor85bb3da2008-11-06 15:17:27 +0000849 assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)
850 || Tok.is(tok::kw_alignof)) &&
Reid Spencer5f016e22007-07-11 17:01:13 +0000851 "Not a sizeof/alignof expression!");
Chris Lattnerd2177732007-07-20 16:59:19 +0000852 Token OpTok = Tok;
Reid Spencer5f016e22007-07-11 17:01:13 +0000853 ConsumeToken();
854
855 // If the operand doesn't start with an '(', it must be an expression.
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000856 OwningExprResult Operand(Actions);
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000857 if (Tok.isNot(tok::l_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000858 Operand = ParseCastExpression(true);
859 } else {
860 // If it starts with a '(', we know that it is either a parenthesized
861 // type-name, or it is a unary-expression that starts with a compound
862 // literal, or starts with a primary-expression that is a parenthesized
863 // expression.
864 ParenParseOption ExprType = CastExpr;
865 TypeTy *CastTy;
866 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
867 Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
Sebastian Redld8c4e152008-12-11 22:33:27 +0000868
Reid Spencer5f016e22007-07-11 17:01:13 +0000869 // If ParseParenExpression parsed a '(typename)' sequence only, the this is
870 // sizeof/alignof a type. Otherwise, it is sizeof/alignof an expression.
Chris Lattner4c1a2a92007-11-13 20:50:37 +0000871 if (ExprType == CastExpr)
Sebastian Redl0eb23302009-01-19 00:08:26 +0000872 return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
Sebastian Redl05189992008-11-11 17:56:53 +0000873 OpTok.is(tok::kw_sizeof),
874 /*isType=*/true, CastTy,
Sebastian Redl0eb23302009-01-19 00:08:26 +0000875 SourceRange(LParenLoc, RParenLoc));
Sebastian Redld8c4e152008-12-11 22:33:27 +0000876
Chris Lattner4c1a2a92007-11-13 20:50:37 +0000877 // If this is a parenthesized expression, it is the start of a
878 // unary-expression, but doesn't include any postfix pieces. Parse these
879 // now if present.
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000880 Operand = ParsePostfixExpressionSuffix(move(Operand));
Reid Spencer5f016e22007-07-11 17:01:13 +0000881 }
Sebastian Redld8c4e152008-12-11 22:33:27 +0000882
Reid Spencer5f016e22007-07-11 17:01:13 +0000883 // If we get here, the operand to the sizeof/alignof was an expresion.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000884 if (!Operand.isInvalid())
Sebastian Redl05189992008-11-11 17:56:53 +0000885 Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
886 OpTok.is(tok::kw_sizeof),
Sebastian Redleffa8d12008-12-10 00:02:53 +0000887 /*isType=*/false,
888 Operand.release(), SourceRange());
Sebastian Redld8c4e152008-12-11 22:33:27 +0000889 return move(Operand);
Reid Spencer5f016e22007-07-11 17:01:13 +0000890}
891
892/// ParseBuiltinPrimaryExpression
893///
894/// primary-expression: [C99 6.5.1]
895/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
896/// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
897/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
898/// assign-expr ')'
899/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
Nate Begemane2ce1d92008-01-17 17:46:27 +0000900/// [CLANG] '__builtin_overload' '(' expr (',' expr)* ')'
Reid Spencer5f016e22007-07-11 17:01:13 +0000901///
902/// [GNU] offsetof-member-designator:
903/// [GNU] identifier
904/// [GNU] offsetof-member-designator '.' identifier
905/// [GNU] offsetof-member-designator '[' expression ']'
906///
Sebastian Redld8c4e152008-12-11 22:33:27 +0000907Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000908 OwningExprResult Res(Actions);
Reid Spencer5f016e22007-07-11 17:01:13 +0000909 const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
910
911 tok::TokenKind T = Tok.getKind();
912 SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier.
913
914 // All of these start with an open paren.
Sebastian Redld8c4e152008-12-11 22:33:27 +0000915 if (Tok.isNot(tok::l_paren))
916 return ExprError(Diag(Tok, diag::err_expected_lparen_after_id)
917 << BuiltinII);
918
Reid Spencer5f016e22007-07-11 17:01:13 +0000919 SourceLocation LParenLoc = ConsumeParen();
920 // TODO: Build AST.
921
922 switch (T) {
923 default: assert(0 && "Not a builtin primary expression!");
Anders Carlsson7c50aca2007-10-15 20:28:48 +0000924 case tok::kw___builtin_va_arg: {
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000925 OwningExprResult Expr(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000926 if (Expr.isInvalid()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000927 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +0000928 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000929 }
930
931 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Sebastian Redld8c4e152008-12-11 22:33:27 +0000932 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +0000933
Anders Carlsson7c50aca2007-10-15 20:28:48 +0000934 TypeTy *Ty = ParseTypeName();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000935
Anders Carlsson7c50aca2007-10-15 20:28:48 +0000936 if (Tok.isNot(tok::r_paren)) {
937 Diag(Tok, diag::err_expected_rparen);
Sebastian Redld8c4e152008-12-11 22:33:27 +0000938 return ExprError();
Anders Carlsson7c50aca2007-10-15 20:28:48 +0000939 }
Sebastian Redleffa8d12008-12-10 00:02:53 +0000940 Res = Actions.ActOnVAArg(StartLoc, Expr.release(), Ty, ConsumeParen());
Reid Spencer5f016e22007-07-11 17:01:13 +0000941 break;
Anders Carlsson7c50aca2007-10-15 20:28:48 +0000942 }
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000943 case tok::kw___builtin_offsetof: {
Chris Lattner9fddf0a2007-08-30 17:08:45 +0000944 SourceLocation TypeLoc = Tok.getLocation();
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000945 TypeTy *Ty = ParseTypeName();
Reid Spencer5f016e22007-07-11 17:01:13 +0000946
947 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Sebastian Redld8c4e152008-12-11 22:33:27 +0000948 return ExprError();
949
Reid Spencer5f016e22007-07-11 17:01:13 +0000950 // We must have at least one identifier here.
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000951 if (Tok.isNot(tok::identifier)) {
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000952 Diag(Tok, diag::err_expected_ident);
953 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +0000954 return ExprError();
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000955 }
Sebastian Redld8c4e152008-12-11 22:33:27 +0000956
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000957 // Keep track of the various subcomponents we see.
958 llvm::SmallVector<Action::OffsetOfComponent, 4> Comps;
Sebastian Redld8c4e152008-12-11 22:33:27 +0000959
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000960 Comps.push_back(Action::OffsetOfComponent());
961 Comps.back().isBrackets = false;
962 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
963 Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +0000964
Sebastian Redla55e52c2008-11-25 22:21:31 +0000965 // FIXME: This loop leaks the index expressions on error.
Reid Spencer5f016e22007-07-11 17:01:13 +0000966 while (1) {
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000967 if (Tok.is(tok::period)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000968 // offsetof-member-designator: offsetof-member-designator '.' identifier
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000969 Comps.push_back(Action::OffsetOfComponent());
970 Comps.back().isBrackets = false;
971 Comps.back().LocStart = ConsumeToken();
Sebastian Redld8c4e152008-12-11 22:33:27 +0000972
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000973 if (Tok.isNot(tok::identifier)) {
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000974 Diag(Tok, diag::err_expected_ident);
975 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +0000976 return ExprError();
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000977 }
978 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
979 Comps.back().LocEnd = ConsumeToken();
Sebastian Redld8c4e152008-12-11 22:33:27 +0000980
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000981 } else if (Tok.is(tok::l_square)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000982 // offsetof-member-designator: offsetof-member-design '[' expression ']'
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000983 Comps.push_back(Action::OffsetOfComponent());
984 Comps.back().isBrackets = true;
985 Comps.back().LocStart = ConsumeBracket();
Reid Spencer5f016e22007-07-11 17:01:13 +0000986 Res = ParseExpression();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000987 if (Res.isInvalid()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000988 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +0000989 return move(Res);
Reid Spencer5f016e22007-07-11 17:01:13 +0000990 }
Sebastian Redleffa8d12008-12-10 00:02:53 +0000991 Comps.back().U.E = Res.release();
Reid Spencer5f016e22007-07-11 17:01:13 +0000992
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +0000993 Comps.back().LocEnd =
994 MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
Chris Lattner4e1d99a2007-10-09 17:41:39 +0000995 } else if (Tok.is(tok::r_paren)) {
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000996 Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc, Ty,
997 &Comps[0], Comps.size(),
998 ConsumeParen());
Chris Lattner6eb21092007-08-30 15:52:49 +0000999 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00001000 } else {
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +00001001 // Error occurred.
Sebastian Redld8c4e152008-12-11 22:33:27 +00001002 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +00001003 }
1004 }
1005 break;
Chris Lattnerf9aa3cb2007-08-30 15:51:11 +00001006 }
Steve Naroffd04fdd52007-08-03 21:21:27 +00001007 case tok::kw___builtin_choose_expr: {
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001008 OwningExprResult Cond(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001009 if (Cond.isInvalid()) {
Steve Naroffd04fdd52007-08-03 21:21:27 +00001010 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001011 return move(Cond);
Steve Naroffd04fdd52007-08-03 21:21:27 +00001012 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001013 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Sebastian Redld8c4e152008-12-11 22:33:27 +00001014 return ExprError();
1015
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001016 OwningExprResult Expr1(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001017 if (Expr1.isInvalid()) {
Steve Naroffd04fdd52007-08-03 21:21:27 +00001018 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001019 return move(Expr1);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001020 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001021 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Sebastian Redld8c4e152008-12-11 22:33:27 +00001022 return ExprError();
1023
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001024 OwningExprResult Expr2(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001025 if (Expr2.isInvalid()) {
Steve Naroffd04fdd52007-08-03 21:21:27 +00001026 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001027 return move(Expr2);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001028 }
Chris Lattner4e1d99a2007-10-09 17:41:39 +00001029 if (Tok.isNot(tok::r_paren)) {
Steve Naroffd04fdd52007-08-03 21:21:27 +00001030 Diag(Tok, diag::err_expected_rparen);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001031 return ExprError();
Steve Naroffd04fdd52007-08-03 21:21:27 +00001032 }
Sebastian Redleffa8d12008-12-10 00:02:53 +00001033 Res = Actions.ActOnChooseExpr(StartLoc, Cond.release(), Expr1.release(),
1034 Expr2.release(), ConsumeParen());
Chris Lattner6eb21092007-08-30 15:52:49 +00001035 break;
Steve Naroffd04fdd52007-08-03 21:21:27 +00001036 }
Nate Begemane2ce1d92008-01-17 17:46:27 +00001037 case tok::kw___builtin_overload: {
Sebastian Redla55e52c2008-11-25 22:21:31 +00001038 ExprVector ArgExprs(Actions);
Nate Begemane2ce1d92008-01-17 17:46:27 +00001039 llvm::SmallVector<SourceLocation, 8> CommaLocs;
1040
1041 // For each iteration through the loop look for assign-expr followed by a
1042 // comma. If there is no comma, break and attempt to match r-paren.
1043 if (Tok.isNot(tok::r_paren)) {
1044 while (1) {
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001045 OwningExprResult ArgExpr(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001046 if (ArgExpr.isInvalid()) {
Nate Begemane2ce1d92008-01-17 17:46:27 +00001047 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001048 return ExprError();
Nate Begemane2ce1d92008-01-17 17:46:27 +00001049 } else
Sebastian Redleffa8d12008-12-10 00:02:53 +00001050 ArgExprs.push_back(ArgExpr.release());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001051
Nate Begemane2ce1d92008-01-17 17:46:27 +00001052 if (Tok.isNot(tok::comma))
1053 break;
1054 // Move to the next argument, remember where the comma was.
1055 CommaLocs.push_back(ConsumeToken());
1056 }
1057 }
Sebastian Redld8c4e152008-12-11 22:33:27 +00001058
Nate Begemane2ce1d92008-01-17 17:46:27 +00001059 // Attempt to consume the r-paren
1060 if (Tok.isNot(tok::r_paren)) {
1061 Diag(Tok, diag::err_expected_rparen);
1062 SkipUntil(tok::r_paren);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001063 return ExprError();
Nate Begemane2ce1d92008-01-17 17:46:27 +00001064 }
Sebastian Redld8c4e152008-12-11 22:33:27 +00001065 Res = Actions.ActOnOverloadExpr(ArgExprs.take(), ArgExprs.size(),
Nate Begemane2ce1d92008-01-17 17:46:27 +00001066 &CommaLocs[0], StartLoc, ConsumeParen());
1067 break;
1068 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001069 case tok::kw___builtin_types_compatible_p:
Steve Naroff363bcff2007-08-01 23:45:51 +00001070 TypeTy *Ty1 = ParseTypeName();
Sebastian Redld8c4e152008-12-11 22:33:27 +00001071
Reid Spencer5f016e22007-07-11 17:01:13 +00001072 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Sebastian Redld8c4e152008-12-11 22:33:27 +00001073 return ExprError();
1074
Steve Naroff363bcff2007-08-01 23:45:51 +00001075 TypeTy *Ty2 = ParseTypeName();
Sebastian Redld8c4e152008-12-11 22:33:27 +00001076
Chris Lattner4e1d99a2007-10-09 17:41:39 +00001077 if (Tok.isNot(tok::r_paren)) {
Steve Naroff363bcff2007-08-01 23:45:51 +00001078 Diag(Tok, diag::err_expected_rparen);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001079 return ExprError();
Steve Naroff363bcff2007-08-01 23:45:51 +00001080 }
Steve Naroff1b273c42007-09-16 14:56:35 +00001081 Res = Actions.ActOnTypesCompatibleExpr(StartLoc, Ty1, Ty2, ConsumeParen());
Chris Lattner6eb21092007-08-30 15:52:49 +00001082 break;
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001083 }
1084
Reid Spencer5f016e22007-07-11 17:01:13 +00001085 // These can be followed by postfix-expr pieces because they are
1086 // primary-expressions.
Sebastian Redld8c4e152008-12-11 22:33:27 +00001087 return ParsePostfixExpressionSuffix(move(Res));
Reid Spencer5f016e22007-07-11 17:01:13 +00001088}
1089
1090/// ParseParenExpression - This parses the unit that starts with a '(' token,
1091/// based on what is allowed by ExprType. The actual thing parsed is returned
1092/// in ExprType.
1093///
1094/// primary-expression: [C99 6.5.1]
1095/// '(' expression ')'
1096/// [GNU] '(' compound-statement ')' (if !ParenExprOnly)
1097/// postfix-expression: [C99 6.5.2]
1098/// '(' type-name ')' '{' initializer-list '}'
1099/// '(' type-name ')' '{' initializer-list ',' '}'
1100/// cast-expression: [C99 6.5.4]
1101/// '(' type-name ')' cast-expression
1102///
Sebastian Redld8c4e152008-12-11 22:33:27 +00001103Parser::OwningExprResult
1104Parser::ParseParenExpression(ParenParseOption &ExprType,
1105 TypeTy *&CastTy, SourceLocation &RParenLoc) {
Chris Lattner4e1d99a2007-10-09 17:41:39 +00001106 assert(Tok.is(tok::l_paren) && "Not a paren expr!");
Reid Spencer5f016e22007-07-11 17:01:13 +00001107 SourceLocation OpenLoc = ConsumeParen();
Sebastian Redl15faa7f2008-12-09 20:22:58 +00001108 OwningExprResult Result(Actions, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00001109 CastTy = 0;
Sebastian Redld8c4e152008-12-11 22:33:27 +00001110
Chris Lattner4e1d99a2007-10-09 17:41:39 +00001111 if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001112 Diag(Tok, diag::ext_gnu_statement_expr);
Sebastian Redl61364dd2008-12-11 19:30:53 +00001113 OwningStmtResult Stmt(ParseCompoundStatement(true));
Reid Spencer5f016e22007-07-11 17:01:13 +00001114 ExprType = CompoundStmt;
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001115
Chris Lattnerab18c4c2007-07-24 16:58:17 +00001116 // If the substmt parsed correctly, build the AST node.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001117 if (!Stmt.isInvalid() && Tok.is(tok::r_paren))
1118 Result = Actions.ActOnStmtExpr(
Sebastian Redleffa8d12008-12-10 00:02:53 +00001119 OpenLoc, Stmt.release(), Tok.getLocation());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001120
Argyrios Kyrtzidis78c8d802008-10-05 19:56:22 +00001121 } else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001122 // Otherwise, this is a compound literal expression or cast expression.
1123 TypeTy *Ty = ParseTypeName();
1124
1125 // Match the ')'.
Chris Lattner4e1d99a2007-10-09 17:41:39 +00001126 if (Tok.is(tok::r_paren))
Reid Spencer5f016e22007-07-11 17:01:13 +00001127 RParenLoc = ConsumeParen();
1128 else
1129 MatchRHSPunctuation(tok::r_paren, OpenLoc);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001130
Chris Lattner4e1d99a2007-10-09 17:41:39 +00001131 if (Tok.is(tok::l_brace)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001132 if (!getLang().C99) // Compound literals don't exist in C90.
1133 Diag(OpenLoc, diag::ext_c99_compound_literal);
1134 Result = ParseInitializer();
1135 ExprType = CompoundLiteral;
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001136 if (!Result.isInvalid())
Sebastian Redlb8a6aca2009-01-19 22:31:54 +00001137 return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc,
Sebastian Redl76ad2e82009-02-05 15:02:23 +00001138 move(Result));
Chris Lattner42ece642008-12-12 06:00:12 +00001139 return move(Result);
1140 }
Sebastian Redlb8a6aca2009-01-19 22:31:54 +00001141
Chris Lattner42ece642008-12-12 06:00:12 +00001142 if (ExprType == CastExpr) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001143 // Note that this doesn't parse the subsequence cast-expression, it just
1144 // returns the parsed type to the callee.
1145 ExprType = CastExpr;
1146 CastTy = Ty;
Sebastian Redld8c4e152008-12-11 22:33:27 +00001147 return OwningExprResult(Actions);
Reid Spencer5f016e22007-07-11 17:01:13 +00001148 }
Sebastian Redlb8a6aca2009-01-19 22:31:54 +00001149
Chris Lattner42ece642008-12-12 06:00:12 +00001150 Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
1151 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +00001152 } else {
1153 Result = ParseExpression();
1154 ExprType = SimpleExpr;
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001155 if (!Result.isInvalid() && Tok.is(tok::r_paren))
Sebastian Redl76ad2e82009-02-05 15:02:23 +00001156 Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), move(Result));
Reid Spencer5f016e22007-07-11 17:01:13 +00001157 }
Sebastian Redld8c4e152008-12-11 22:33:27 +00001158
Reid Spencer5f016e22007-07-11 17:01:13 +00001159 // Match the ')'.
Chris Lattner42ece642008-12-12 06:00:12 +00001160 if (Result.isInvalid()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001161 SkipUntil(tok::r_paren);
Chris Lattner42ece642008-12-12 06:00:12 +00001162 return ExprError();
Reid Spencer5f016e22007-07-11 17:01:13 +00001163 }
Chris Lattner42ece642008-12-12 06:00:12 +00001164
1165 if (Tok.is(tok::r_paren))
1166 RParenLoc = ConsumeParen();
1167 else
1168 MatchRHSPunctuation(tok::r_paren, OpenLoc);
Sebastian Redld8c4e152008-12-11 22:33:27 +00001169
1170 return move(Result);
Reid Spencer5f016e22007-07-11 17:01:13 +00001171}
1172
1173/// ParseStringLiteralExpression - This handles the various token types that
1174/// form string literals, and also handles string concatenation [C99 5.1.1.2,
1175/// translation phase #6].
1176///
1177/// primary-expression: [C99 6.5.1]
1178/// string-literal
Sebastian Redl20df9b72008-12-11 22:51:44 +00001179Parser::OwningExprResult Parser::ParseStringLiteralExpression() {
Reid Spencer5f016e22007-07-11 17:01:13 +00001180 assert(isTokenStringLiteral() && "Not a string literal!");
Sebastian Redl20df9b72008-12-11 22:51:44 +00001181
Reid Spencer5f016e22007-07-11 17:01:13 +00001182 // String concat. Note that keywords like __func__ and __FUNCTION__ are not
1183 // considered to be strings for concatenation purposes.
Chris Lattnerd2177732007-07-20 16:59:19 +00001184 llvm::SmallVector<Token, 4> StringToks;
Sebastian Redl20df9b72008-12-11 22:51:44 +00001185
Reid Spencer5f016e22007-07-11 17:01:13 +00001186 do {
1187 StringToks.push_back(Tok);
1188 ConsumeStringToken();
1189 } while (isTokenStringLiteral());
1190
1191 // Pass the set of string tokens, ready for concatenation, to the actions.
Sebastian Redlcd965b92009-01-18 18:53:16 +00001192 return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size());
Reid Spencer5f016e22007-07-11 17:01:13 +00001193}
Argyrios Kyrtzidis0cd5b422008-08-16 20:03:01 +00001194
1195/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
1196///
1197/// argument-expression-list:
1198/// assignment-expression
1199/// argument-expression-list , assignment-expression
1200///
1201/// [C++] expression-list:
1202/// [C++] assignment-expression
1203/// [C++] expression-list , assignment-expression
1204///
1205bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
1206 while (1) {
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001207 OwningExprResult Expr(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001208 if (Expr.isInvalid())
Argyrios Kyrtzidis0cd5b422008-08-16 20:03:01 +00001209 return true;
Argyrios Kyrtzidis4fdc1ca2008-08-18 22:49:40 +00001210
Sebastian Redleffa8d12008-12-10 00:02:53 +00001211 Exprs.push_back(Expr.release());
Argyrios Kyrtzidis0cd5b422008-08-16 20:03:01 +00001212
1213 if (Tok.isNot(tok::comma))
1214 return false;
1215 // Move to the next argument, remember where the comma was.
1216 CommaLocs.push_back(ConsumeToken());
1217 }
1218}
Steve Naroff296e8d52008-08-28 19:20:44 +00001219
Mike Stump98eb8a72009-02-04 22:31:32 +00001220/// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
1221///
1222/// [clang] block-id:
1223/// [clang] specifier-qualifier-list block-declarator
1224///
1225void Parser::ParseBlockId() {
1226 // Parse the specifier-qualifier-list piece.
1227 DeclSpec DS;
1228 ParseSpecifierQualifierList(DS);
1229
1230 // Parse the block-declarator.
1231 Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
1232 ParseDeclarator(DeclaratorInfo);
1233 // Inform sema that we are starting a block.
1234 Actions.ActOnBlockArguments(DeclaratorInfo, CurScope);
1235}
1236
Steve Naroff296e8d52008-08-28 19:20:44 +00001237/// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
Steve Naroff17dab4f2008-09-16 23:11:46 +00001238/// like ^(int x){ return x+1; }
Steve Naroff296e8d52008-08-28 19:20:44 +00001239///
1240/// block-literal:
1241/// [clang] '^' block-args[opt] compound-statement
Mike Stump98eb8a72009-02-04 22:31:32 +00001242/// [clang] '^' block-id compound-statement
Steve Naroff296e8d52008-08-28 19:20:44 +00001243/// [clang] block-args:
1244/// [clang] '(' parameter-list ')'
1245///
Sebastian Redl1d922962008-12-13 15:32:12 +00001246Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
Steve Naroff296e8d52008-08-28 19:20:44 +00001247 assert(Tok.is(tok::caret) && "block literal starts with ^");
1248 SourceLocation CaretLoc = ConsumeToken();
Sebastian Redl1d922962008-12-13 15:32:12 +00001249
Steve Naroff296e8d52008-08-28 19:20:44 +00001250 // Enter a scope to hold everything within the block. This includes the
1251 // argument decls, decls within the compound expression, etc. This also
1252 // allows determining whether a variable reference inside the block is
1253 // within or outside of the block.
Douglas Gregor8935b8b2008-12-10 06:34:36 +00001254 ParseScope BlockScope(this, Scope::BlockScope|Scope::FnScope|Scope::BreakScope|
1255 Scope::ContinueScope|Scope::DeclScope);
Steve Naroff090276f2008-10-10 01:28:17 +00001256
1257 // Inform sema that we are starting a block.
1258 Actions.ActOnBlockStart(CaretLoc, CurScope);
Sebastian Redl1d922962008-12-13 15:32:12 +00001259
Steve Naroff296e8d52008-08-28 19:20:44 +00001260 // Parse the return type if present.
1261 DeclSpec DS;
Mike Stump98eb8a72009-02-04 22:31:32 +00001262 Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
Sebastian Redl1d922962008-12-13 15:32:12 +00001263
Steve Naroff296e8d52008-08-28 19:20:44 +00001264 // If this block has arguments, parse them. There is no ambiguity here with
1265 // the expression case, because the expression case requires a parameter list.
1266 if (Tok.is(tok::l_paren)) {
1267 ParseParenDeclarator(ParamInfo);
1268 // Parse the pieces after the identifier as if we had "int(...)".
1269 ParamInfo.SetIdentifier(0, CaretLoc);
1270 if (ParamInfo.getInvalidType()) {
Mike Stump98eb8a72009-02-04 22:31:32 +00001271 // If there was an error parsing the arguments, they may have
1272 // tried to use ^(x+y) which requires an argument list. Just
1273 // skip the whole block literal.
Sebastian Redl1d922962008-12-13 15:32:12 +00001274 return ExprError();
Steve Naroff296e8d52008-08-28 19:20:44 +00001275 }
Mike Stump98eb8a72009-02-04 22:31:32 +00001276 // Inform sema that we are starting a block.
1277 Actions.ActOnBlockArguments(ParamInfo, CurScope);
1278 } else if (! Tok.is(tok::l_brace)) {
1279 ParseBlockId();
Steve Naroff296e8d52008-08-28 19:20:44 +00001280 } else {
1281 // Otherwise, pretend we saw (void).
1282 ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
Chris Lattner5af2f352009-01-20 19:11:22 +00001283 0, 0, 0, CaretLoc,
1284 ParamInfo));
Mike Stump98eb8a72009-02-04 22:31:32 +00001285 // Inform sema that we are starting a block.
1286 Actions.ActOnBlockArguments(ParamInfo, CurScope);
Steve Naroff296e8d52008-08-28 19:20:44 +00001287 }
1288
Sebastian Redl1d922962008-12-13 15:32:12 +00001289
Sebastian Redl15faa7f2008-12-09 20:22:58 +00001290 OwningExprResult Result(Actions, true);
Steve Naroff296e8d52008-08-28 19:20:44 +00001291 if (Tok.is(tok::l_brace)) {
Sebastian Redl61364dd2008-12-11 19:30:53 +00001292 OwningStmtResult Stmt(ParseCompoundStatementBody());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001293 if (!Stmt.isInvalid()) {
Sebastian Redleffa8d12008-12-10 00:02:53 +00001294 Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.release(), CurScope);
Steve Naroff296e8d52008-08-28 19:20:44 +00001295 } else {
1296 Actions.ActOnBlockError(CaretLoc, CurScope);
Steve Naroff296e8d52008-08-28 19:20:44 +00001297 }
Mike Stump281481d2009-02-02 23:46:21 +00001298 } else {
Fariborz Jahanianff03fbb2009-01-14 19:39:53 +00001299 // Saw something like: ^expr
1300 Diag(Tok, diag::err_expected_expression);
1301 return ExprError();
1302 }
Sebastian Redl1d922962008-12-13 15:32:12 +00001303 return move(Result);
Steve Naroff296e8d52008-08-28 19:20:44 +00001304}
1305