blob: 9ef0aec9d903c18a143ae61f3cd00d9c10820f5f [file] [log] [blame]
Chris Lattnerc951dae2006-08-10 04:23:57 +00001//===--- Expression.cpp - Expression Parsing ------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Chris Lattnercde626a2006-08-12 08:13:25 +000010// 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
Chris Lattnerb7f1fc92006-08-12 16:45:01 +000016// operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are
Chris Lattnercde626a2006-08-12 08:13:25 +000017// handled by ParseCastExpression, the higher level pieces are handled by
18// ParseBinaryExpression.
Chris Lattnerc951dae2006-08-10 04:23:57 +000019//
20//===----------------------------------------------------------------------===//
21
22#include "clang/Parse/Parser.h"
23#include "clang/Basic/Diagnostic.h"
24using namespace llvm;
25using namespace clang;
26
Chris Lattnerb7f1fc92006-08-12 16:45:01 +000027/// PrecedenceLevels - These are precedences for the binary/ternary operators in
Chris Lattnercde626a2006-08-12 08:13:25 +000028/// the C99 grammar. These have been named to relate with the C99 grammar
29/// productions. Low precedences numbers bind more weakly than high numbers.
30namespace prec {
31 enum Level {
32 Unknown = 0, // Not binary operator.
33 Comma = 1, // ,
34 Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
35 Conditional = 3, // ?
36 LogicalOr = 4, // ||
37 LogicalAnd = 5, // &&
38 InclusiveOr = 6, // |
39 ExclusiveOr = 7, // ^
40 And = 8, // &
41 MinMax = 9, // <?, >? min, max (GCC extensions)
42 Equality = 10, // ==, !=
43 Relational = 11, // >=, <=, >, <
44 Shift = 12, // <<, >>
45 Additive = 13, // -, +
46 Multiplicative = 14 // *, /, %
47 };
48}
49
50
51/// getBinOpPrecedence - Return the precedence of the specified binary operator
52/// token. This returns:
53///
54static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
55 switch (Kind) {
56 default: return prec::Unknown;
57 case tok::comma: return prec::Comma;
58 case tok::equal:
59 case tok::starequal:
60 case tok::slashequal:
61 case tok::percentequal:
62 case tok::plusequal:
63 case tok::minusequal:
64 case tok::lesslessequal:
65 case tok::greatergreaterequal:
66 case tok::ampequal:
67 case tok::caretequal:
68 case tok::pipeequal: return prec::Assignment;
69 case tok::question: return prec::Conditional;
70 case tok::pipepipe: return prec::LogicalOr;
71 case tok::ampamp: return prec::LogicalAnd;
72 case tok::pipe: return prec::InclusiveOr;
73 case tok::caret: return prec::ExclusiveOr;
74 case tok::amp: return prec::And;
75 case tok::lessquestion:
76 case tok::greaterquestion: return prec::MinMax;
77 case tok::exclaimequal:
78 case tok::equalequal: return prec::Equality;
79 case tok::lessequal:
80 case tok::less:
81 case tok::greaterequal:
82 case tok::greater: return prec::Relational;
83 case tok::lessless:
84 case tok::greatergreater: return prec::Shift;
85 case tok::plus:
86 case tok::minus: return prec::Additive;
87 case tok::percent:
88 case tok::slash:
89 case tok::star: return prec::Multiplicative;
90 }
91}
92
93
Chris Lattnerce7e21d2006-08-12 17:22:40 +000094/// ParseExpression - Simple precedence-based parser for binary/ternary
Chris Lattnercde626a2006-08-12 08:13:25 +000095/// operators.
96///
Chris Lattnerb7f1fc92006-08-12 16:45:01 +000097/// Note: we diverge from the C99 grammar when parsing the assignment-expression
98/// production. C99 specifies that the LHS of an assignment operator should be
99/// parsed as a unary-expression, but consistency dictates that it be a
100/// conditional-expession. In practice, the important thing here is that the
101/// LHS of an assignment has to be an l-value, which productions between
102/// unary-expression and conditional-expression don't produce. Because we want
103/// consistency, we parse the LHS as a conditional-expression, then check for
104/// l-value-ness in semantic analysis stages.
105///
Chris Lattnercde626a2006-08-12 08:13:25 +0000106/// multiplicative-expression: [C99 6.5.5]
107/// cast-expression
108/// multiplicative-expression '*' cast-expression
109/// multiplicative-expression '/' cast-expression
110/// multiplicative-expression '%' cast-expression
111///
112/// additive-expression: [C99 6.5.6]
113/// multiplicative-expression
114/// additive-expression '+' multiplicative-expression
115/// additive-expression '-' multiplicative-expression
116///
117/// shift-expression: [C99 6.5.7]
118/// additive-expression
119/// shift-expression '<<' additive-expression
120/// shift-expression '>>' additive-expression
121///
122/// relational-expression: [C99 6.5.8]
123/// shift-expression
124/// relational-expression '<' shift-expression
125/// relational-expression '>' shift-expression
126/// relational-expression '<=' shift-expression
127/// relational-expression '>=' shift-expression
128///
129/// equality-expression: [C99 6.5.9]
130/// relational-expression
131/// equality-expression '==' relational-expression
132/// equality-expression '!=' relational-expression
133///
134/// AND-expression: [C99 6.5.10]
135/// equality-expression
136/// AND-expression '&' equality-expression
137///
138/// exclusive-OR-expression: [C99 6.5.11]
139/// AND-expression
140/// exclusive-OR-expression '^' AND-expression
141///
142/// inclusive-OR-expression: [C99 6.5.12]
143/// exclusive-OR-expression
144/// inclusive-OR-expression '|' exclusive-OR-expression
145///
146/// logical-AND-expression: [C99 6.5.13]
147/// inclusive-OR-expression
148/// logical-AND-expression '&&' inclusive-OR-expression
149///
150/// logical-OR-expression: [C99 6.5.14]
151/// logical-AND-expression
152/// logical-OR-expression '||' logical-AND-expression
153///
154/// conditional-expression: [C99 6.5.15]
155/// logical-OR-expression
156/// logical-OR-expression '?' expression ':' conditional-expression
157/// [GNU] logical-OR-expression '?' ':' conditional-expression
158///
159/// assignment-expression: [C99 6.5.16]
160/// conditional-expression
161/// unary-expression assignment-operator assignment-expression
162///
163/// assignment-operator: one of
164/// = *= /= %= += -= <<= >>= &= ^= |=
165///
166/// expression: [C99 6.5.17]
167/// assignment-expression
168/// expression ',' assignment-expression
169///
Chris Lattnerd35c34f2006-08-12 17:04:50 +0000170Parser::ExprResult Parser::ParseExpression() {
Chris Lattnercde626a2006-08-12 08:13:25 +0000171 ExprResult LHS = ParseCastExpression(false);
172 if (LHS.isInvalid) return LHS;
173
174 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
175}
176
Chris Lattner0c6c0342006-08-12 18:12:45 +0000177/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
178///
Chris Lattnerce7e21d2006-08-12 17:22:40 +0000179Parser::ExprResult Parser::ParseAssignmentExpression() {
180 ExprResult LHS = ParseCastExpression(false);
181 if (LHS.isInvalid) return LHS;
182
183 return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
184}
185
Chris Lattner3b561a32006-08-13 00:12:11 +0000186Parser::ExprResult Parser::ParseConstantExpression() {
187 ExprResult LHS = ParseCastExpression(false);
188 if (LHS.isInvalid) return LHS;
189
190 // TODO: Validate that this is a constant expr!
191 return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
192}
193
Chris Lattner0c6c0342006-08-12 18:12:45 +0000194/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
195/// in contexts where we have already consumed an identifier (which we saved in
196/// 'Tok'), then discovered that the identifier was really the leading token of
197/// part of an expression. For example, in "A[1]+B", we consumed "A" (which is
198/// now in 'Tok') and the current token is "[".
199Parser::ExprResult Parser::
200ParseExpressionWithLeadingIdentifier(const LexerToken &Tok) {
201 // We know that 'Tok' must correspond to this production:
202 // primary-expression: identifier
203
204 // TODO: Pass 'Tok' to the action.
205 ExprResult Res = ExprResult(false);
206
207 // Because we have to parse an entire cast-expression before starting the
208 // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
209 // need to handle the 'postfix-expression' rules. We do this by invoking
210 // ParsePostfixExpressionSuffix to consume any postfix-expression suffixes:
211 Res = ParsePostfixExpressionSuffix(Res);
212 if (Res.isInvalid) return Res;
213
214 // At this point, the "A[1]" part of "A[1]+B" has been consumed. Once this is
215 // done, we know we don't have to do anything for cast-expression, because the
216 // only non-postfix-expression production starts with a '(' token, and we know
217 // we have an identifier. As such, we can invoke ParseRHSOfBinaryExpression
218 // to consume any trailing operators (e.g. "+" in this example) and connected
219 // chunks of the expression.
220 return ParseRHSOfBinaryExpression(Res, prec::Comma);
221}
222
Chris Lattner8693a512006-08-13 21:54:02 +0000223/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
224/// in contexts where we have already consumed an identifier (which we saved in
225/// 'Tok'), then discovered that the identifier was really the leading token of
226/// part of an assignment-expression. For example, in "A[1]+B", we consumed "A"
227/// (which is now in 'Tok') and the current token is "[".
228Parser::ExprResult Parser::
229ParseAssignmentExprWithLeadingIdentifier(const LexerToken &Tok) {
230 // We know that 'Tok' must correspond to this production:
231 // primary-expression: identifier
232
233 // TODO: Pass 'Tok' to the action.
234 ExprResult Res = ExprResult(false);
235
236 // Because we have to parse an entire cast-expression before starting the
237 // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
238 // need to handle the 'postfix-expression' rules. We do this by invoking
239 // ParsePostfixExpressionSuffix to consume any postfix-expression suffixes:
240 Res = ParsePostfixExpressionSuffix(Res);
241 if (Res.isInvalid) return Res;
242
243 // At this point, the "A[1]" part of "A[1]+B" has been consumed. Once this is
244 // done, we know we don't have to do anything for cast-expression, because the
245 // only non-postfix-expression production starts with a '(' token, and we know
246 // we have an identifier. As such, we can invoke ParseRHSOfBinaryExpression
247 // to consume any trailing operators (e.g. "+" in this example) and connected
248 // chunks of the expression.
249 return ParseRHSOfBinaryExpression(Res, prec::Assignment);
250}
251
252
Chris Lattner62591722006-08-12 18:40:58 +0000253/// ParseAssignmentExpressionWithLeadingStar - This special purpose method is
254/// used in contexts where we have already consumed a '*' (which we saved in
255/// 'Tok'), then discovered that the '*' was really the leading token of an
256/// expression. For example, in "*(int*)P+B", we consumed "*" (which is
257/// now in 'Tok') and the current token is "(".
258Parser::ExprResult Parser::
259ParseAssignmentExpressionWithLeadingStar(const LexerToken &Tok) {
260 // We know that 'Tok' must correspond to this production:
261 // unary-expression: unary-operator cast-expression
262 // where 'unary-operator' is '*'.
263
264 // Parse the cast-expression that follows the '*'. This will parse the
265 // "*(int*)P" part of "*(int*)P+B".
266 ExprResult Res = ParseCastExpression(false);
267 if (Res.isInvalid) return Res;
268
269 // TODO: Combine Tok + Res to get the new AST.
270
271 // We have to parse an entire cast-expression before starting the
272 // ParseRHSOfBinaryExpression method (which parses any trailing binops). Since
273 // we know that the only production above us is the cast-expression
274 // production, and because the only alternative productions start with a '('
275 // token (we know we had a '*'), there is no work to do to get a whole
276 // cast-expression.
277
278 // At this point, the "*(int*)P" part of "*(int*)P+B" has been consumed. Once
279 // this is done, we can invoke ParseRHSOfBinaryExpression to consume any
280 // trailing operators (e.g. "+" in this example) and connected chunks of the
281 // assignment-expression.
282 return ParseRHSOfBinaryExpression(Res, prec::Assignment);
283}
284
285
Chris Lattnercde626a2006-08-12 08:13:25 +0000286/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
287/// LHS and has a precedence of at least MinPrec.
288Parser::ExprResult
289Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
290 unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
291
292 while (1) {
293 // If this token has a lower precedence than we are allowed to parse (e.g.
294 // because we are called recursively, or because the token is not a binop),
295 // then we are done!
296 if (NextTokPrec < MinPrec)
297 return LHS;
298
299 // Consume the operator, saving the operator token for error reporting.
300 LexerToken OpToken = Tok;
301 ConsumeToken();
302
Chris Lattner96c3deb2006-08-12 17:13:08 +0000303 // Special case handling for the ternary operator.
304 ExprResult TernaryMiddle;
305 if (NextTokPrec == prec::Conditional) {
306 if (Tok.getKind() != tok::colon) {
307 // Handle this production specially:
308 // logical-OR-expression '?' expression ':' conditional-expression
309 // In particular, the RHS of the '?' is 'expression', not
310 // 'logical-OR-expression' as we might expect.
311 TernaryMiddle = ParseExpression();
312 if (TernaryMiddle.isInvalid) return TernaryMiddle;
313 } else {
314 // Special case handling of "X ? Y : Z" where Y is empty:
315 // logical-OR-expression '?' ':' conditional-expression [GNU]
316 TernaryMiddle = ExprResult(false);
317 Diag(Tok, diag::ext_gnu_conditional_expr);
318 }
319
320 if (Tok.getKind() != tok::colon) {
321 Diag(Tok, diag::err_expected_colon);
322 Diag(OpToken, diag::err_matching, "?");
323 return ExprResult(true);
324 }
325
326 // Eat the colon.
327 ConsumeToken();
Chris Lattnercde626a2006-08-12 08:13:25 +0000328 }
Chris Lattner96c3deb2006-08-12 17:13:08 +0000329
330 // Parse another leaf here for the RHS of the operator.
331 ExprResult RHS = ParseCastExpression(false);
332 if (RHS.isInvalid) return RHS;
Chris Lattnercde626a2006-08-12 08:13:25 +0000333
334 // Remember the precedence of this operator and get the precedence of the
335 // operator immediately to the right of the RHS.
336 unsigned ThisPrec = NextTokPrec;
337 NextTokPrec = getBinOpPrecedence(Tok.getKind());
Chris Lattner89d53752006-08-12 17:18:19 +0000338
339 // Assignment and conditional expressions are right-associative.
340 bool isRightAssoc = NextTokPrec == prec::Conditional ||
341 NextTokPrec == prec::Assignment;
Chris Lattnercde626a2006-08-12 08:13:25 +0000342
343 // Get the precedence of the operator to the right of the RHS. If it binds
344 // more tightly with RHS than we do, evaluate it completely first.
Chris Lattnercde626a2006-08-12 08:13:25 +0000345 if (ThisPrec < NextTokPrec ||
346 (ThisPrec == NextTokPrec && isRightAssoc)) {
Chris Lattner89d53752006-08-12 17:18:19 +0000347 // If this is left-associative, only parse things on the RHS that bind
348 // more tightly than the current operator. If it is left-associative, it
349 // is okay, to bind exactly as tightly. For example, compile A=B=C=D as
350 // A=(B=(C=D)), where each paren is a level of recursion here.
351 RHS = ParseRHSOfBinaryExpression(RHS, ThisPrec + !isRightAssoc);
Chris Lattnercde626a2006-08-12 08:13:25 +0000352 if (RHS.isInvalid) return RHS;
353
354 NextTokPrec = getBinOpPrecedence(Tok.getKind());
355 }
356 assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
357
Chris Lattner96c3deb2006-08-12 17:13:08 +0000358 // TODO: combine the LHS and RHS into the LHS (e.g. build AST).
Chris Lattnercde626a2006-08-12 08:13:25 +0000359 }
360}
361
Chris Lattnereaf06592006-08-11 02:02:23 +0000362/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
363/// true, parse a unary-expression.
364///
Chris Lattner4564bc12006-08-10 23:14:52 +0000365/// cast-expression: [C99 6.5.4]
366/// unary-expression
367/// '(' type-name ')' cast-expression
Chris Lattner81b576e2006-08-11 02:13:20 +0000368///
Chris Lattnerc2dd85a2006-08-10 22:57:16 +0000369/// unary-expression: [C99 6.5.3]
370/// postfix-expression
371/// '++' unary-expression
372/// '--' unary-expression
373/// unary-operator cast-expression
374/// 'sizeof' unary-expression
375/// 'sizeof' '(' type-name ')'
376/// [GNU] '__alignof' unary-expression
377/// [GNU] '__alignof' '(' type-name ')'
378/// [GNU] '&&' identifier
Chris Lattner81b576e2006-08-11 02:13:20 +0000379///
Chris Lattnerc2dd85a2006-08-10 22:57:16 +0000380/// unary-operator: one of
381/// '&' '*' '+' '-' '~' '!'
382/// [GNU] '__extension__' '__real' '__imag'
383///
Chris Lattner52a99e52006-08-10 20:56:00 +0000384/// primary-expression: [C99 6.5.1]
Chris Lattnerc5e0d4a2006-08-10 19:06:03 +0000385/// identifier
386/// constant
387/// string-literal
388/// '(' expression ')'
Chris Lattner52a99e52006-08-10 20:56:00 +0000389/// '__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 ')'
398/// [OBC] '[' objc-receiver objc-message-args ']' [TODO]
399/// [OBC] '@selector' '(' objc-selector-arg ')' [TODO]
400/// [OBC] '@protocol' '(' identifier ')' [TODO]
401/// [OBC] '@encode' '(' type-name ')' [TODO]
402/// [OBC] objc-string-literal [TODO]
403///
404/// constant: [C99 6.4.4]
405/// integer-constant
406/// floating-constant
407/// enumeration-constant -> identifier
408/// character-constant
Chris Lattner52a99e52006-08-10 20:56:00 +0000409///
Chris Lattner89c50c62006-08-11 06:41:18 +0000410Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
411 ExprResult Res;
412
Chris Lattner81b576e2006-08-11 02:13:20 +0000413 // This handles all of cast-expression, unary-expression, postfix-expression,
414 // and primary-expression. We handle them together like this for efficiency
415 // and to simplify handling of an expression starting with a '(' token: which
416 // may be one of a parenthesized expression, cast-expression, compound literal
417 // expression, or statement expression.
418 //
419 // If the parsed tokens consist of a primary-expression, the cases below
Chris Lattner20c6a452006-08-12 17:40:43 +0000420 // call ParsePostfixExpressionSuffix to handle the postfix expression
421 // suffixes. Cases that cannot be followed by postfix exprs should
422 // return without invoking ParsePostfixExpressionSuffix.
Chris Lattner52a99e52006-08-10 20:56:00 +0000423 switch (Tok.getKind()) {
Chris Lattner81b576e2006-08-11 02:13:20 +0000424 case tok::l_paren:
425 // If this expression is limited to being a unary-expression, the parent can
426 // not start a cast expression.
427 ParenParseOption ParenExprType =
428 isUnaryExpression ? CompoundLiteral : CastExpr;
Chris Lattner89c50c62006-08-11 06:41:18 +0000429 Res = ParseParenExpression(ParenExprType);
430 if (Res.isInvalid) return Res;
431
Chris Lattner81b576e2006-08-11 02:13:20 +0000432 switch (ParenExprType) {
433 case SimpleExpr: break; // Nothing else to do.
434 case CompoundStmt: break; // Nothing else to do.
435 case CompoundLiteral:
436 // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of
437 // postfix-expression exist, parse them now.
438 break;
439 case CastExpr:
440 // We parsed '(' type-name ')' and the thing after it wasn't a '{'. Parse
441 // the cast-expression that follows it next.
Chris Lattner89c50c62006-08-11 06:41:18 +0000442 return ParseCastExpression(false);
Chris Lattner81b576e2006-08-11 02:13:20 +0000443 }
Chris Lattner20c6a452006-08-12 17:40:43 +0000444
445 // These can be followed by postfix-expr pieces.
446 return ParsePostfixExpressionSuffix(Res);
Chris Lattner89c50c62006-08-11 06:41:18 +0000447
Chris Lattner52a99e52006-08-10 20:56:00 +0000448 // primary-expression
449 case tok::identifier: // primary-expression: identifier
450 // constant: enumeration-constant
451 case tok::numeric_constant: // constant: integer-constant
452 // constant: floating-constant
453 case tok::char_constant: // constant: character-constant
454 case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
455 case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
456 case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
Chris Lattner20c6a452006-08-12 17:40:43 +0000457 Res = ExprResult(false);
Chris Lattner52a99e52006-08-10 20:56:00 +0000458 ConsumeToken();
Chris Lattner20c6a452006-08-12 17:40:43 +0000459 // These can be followed by postfix-expr pieces.
460 return ParsePostfixExpressionSuffix(Res);
Chris Lattner52a99e52006-08-10 20:56:00 +0000461 case tok::string_literal: // primary-expression: string-literal
Chris Lattner89c50c62006-08-11 06:41:18 +0000462 Res = ParseStringLiteralExpression();
463 if (Res.isInvalid) return Res;
Chris Lattner20c6a452006-08-12 17:40:43 +0000464 // This can be followed by postfix-expr pieces (e.g. "foo"[1]).
465 return ParsePostfixExpressionSuffix(Res);
Chris Lattnerf8339772006-08-10 22:01:51 +0000466 case tok::kw___builtin_va_arg:
467 case tok::kw___builtin_offsetof:
468 case tok::kw___builtin_choose_expr:
469 case tok::kw___builtin_types_compatible_p:
Chris Lattner11124352006-08-12 19:16:08 +0000470 return ParseBuiltinPrimaryExpression();
Chris Lattner81b576e2006-08-11 02:13:20 +0000471 case tok::plusplus: // unary-expression: '++' unary-expression
472 case tok::minusminus: // unary-expression: '--' unary-expression
473 ConsumeToken();
Chris Lattner89c50c62006-08-11 06:41:18 +0000474 return ParseCastExpression(true);
Chris Lattner81b576e2006-08-11 02:13:20 +0000475 case tok::amp: // unary-expression: '&' cast-expression
476 case tok::star: // unary-expression: '*' cast-expression
477 case tok::plus: // unary-expression: '+' cast-expression
478 case tok::minus: // unary-expression: '-' cast-expression
479 case tok::tilde: // unary-expression: '~' cast-expression
480 case tok::exclaim: // unary-expression: '!' cast-expression
481 case tok::kw___real: // unary-expression: '__real' cast-expression [GNU]
482 case tok::kw___imag: // unary-expression: '__real' cast-expression [GNU]
483 //case tok::kw__extension__: [TODO]
484 ConsumeToken();
Chris Lattner89c50c62006-08-11 06:41:18 +0000485 return ParseCastExpression(false);
Chris Lattner81b576e2006-08-11 02:13:20 +0000486
487 case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
488 // unary-expression: 'sizeof' '(' type-name ')'
489 case tok::kw___alignof: // unary-expression: '__alignof' unary-expression
490 // unary-expression: '__alignof' '(' type-name ')'
Chris Lattner89c50c62006-08-11 06:41:18 +0000491 return ParseSizeofAlignofExpression();
Chris Lattner81b576e2006-08-11 02:13:20 +0000492 case tok::ampamp: // unary-expression: '&&' identifier
493 Diag(Tok, diag::ext_gnu_address_of_label);
494 ConsumeToken();
495 if (Tok.getKind() == tok::identifier) {
496 ConsumeToken();
497 } else {
498 Diag(Tok, diag::err_expected_ident);
Chris Lattner89c50c62006-08-11 06:41:18 +0000499 return ExprResult(true);
Chris Lattner81b576e2006-08-11 02:13:20 +0000500 }
Chris Lattner89c50c62006-08-11 06:41:18 +0000501 return ExprResult(false);
Chris Lattner52a99e52006-08-10 20:56:00 +0000502 default:
503 Diag(Tok, diag::err_expected_expression);
Chris Lattner89c50c62006-08-11 06:41:18 +0000504 return ExprResult(true);
Chris Lattnerf8339772006-08-10 22:01:51 +0000505 }
506
Chris Lattner20c6a452006-08-12 17:40:43 +0000507 // unreachable.
508 abort();
509}
510
511/// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression
512/// is parsed, this method parses any suffixes that apply.
513///
514/// postfix-expression: [C99 6.5.2]
515/// primary-expression
516/// postfix-expression '[' expression ']'
517/// postfix-expression '(' argument-expression-list[opt] ')'
518/// postfix-expression '.' identifier
519/// postfix-expression '->' identifier
520/// postfix-expression '++'
521/// postfix-expression '--'
522/// '(' type-name ')' '{' initializer-list '}'
523/// '(' type-name ')' '{' initializer-list ',' '}'
524///
525/// argument-expression-list: [C99 6.5.2]
526/// argument-expression
527/// argument-expression-list ',' assignment-expression
528///
529Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
530 assert(!LHS.isInvalid && "LHS is invalid already!");
531
Chris Lattnerf8339772006-08-10 22:01:51 +0000532 // Now that the primary-expression piece of the postfix-expression has been
533 // parsed, see if there are any postfix-expression pieces here.
534 SourceLocation Loc;
535 while (1) {
536 switch (Tok.getKind()) {
Chris Lattner20c6a452006-08-12 17:40:43 +0000537 default: // Not a postfix-expression suffix.
538 return LHS;
Chris Lattner89c50c62006-08-11 06:41:18 +0000539 case tok::l_square: // postfix-expression: p-e '[' expression ']'
540 Loc = Tok.getLocation();
541 ConsumeBracket();
542 ParseExpression();
543 // Match the ']'.
Chris Lattner04f80192006-08-15 04:55:54 +0000544 MatchRHSPunctuation(tok::r_square, Loc);
Chris Lattner89c50c62006-08-11 06:41:18 +0000545 break;
546
547 case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')'
548 Loc = Tok.getLocation();
549 ConsumeParen();
550
Chris Lattner0c6c0342006-08-12 18:12:45 +0000551 if (Tok.getKind() != tok::r_paren) {
552 while (1) {
553 ParseAssignmentExpression();
554 if (Tok.getKind() != tok::comma)
555 break;
556 ConsumeToken(); // Next argument.
557 }
Chris Lattner89c50c62006-08-11 06:41:18 +0000558 }
Chris Lattner81b576e2006-08-11 02:13:20 +0000559
Chris Lattner89c50c62006-08-11 06:41:18 +0000560 // Match the ')'.
Chris Lattner04f80192006-08-15 04:55:54 +0000561 MatchRHSPunctuation(tok::r_paren, Loc);
Chris Lattner89c50c62006-08-11 06:41:18 +0000562 break;
563
564 case tok::arrow: // postfix-expression: p-e '->' identifier
565 case tok::period: // postfix-expression: p-e '.' identifier
566 ConsumeToken();
567 if (Tok.getKind() != tok::identifier) {
568 Diag(Tok, diag::err_expected_ident);
569 return ExprResult(true);
570 }
571 ConsumeToken();
572 break;
573
574 case tok::plusplus: // postfix-expression: postfix-expression '++'
575 case tok::minusminus: // postfix-expression: postfix-expression '--'
576 ConsumeToken();
577 break;
Chris Lattnerf8339772006-08-10 22:01:51 +0000578 }
579 }
Chris Lattner52a99e52006-08-10 20:56:00 +0000580}
581
Chris Lattner20c6a452006-08-12 17:40:43 +0000582
Chris Lattner81b576e2006-08-11 02:13:20 +0000583/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
584/// unary-expression: [C99 6.5.3]
585/// 'sizeof' unary-expression
586/// 'sizeof' '(' type-name ')'
587/// [GNU] '__alignof' unary-expression
588/// [GNU] '__alignof' '(' type-name ')'
Chris Lattner89c50c62006-08-11 06:41:18 +0000589Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
Chris Lattner81b576e2006-08-11 02:13:20 +0000590 assert((Tok.getKind() == tok::kw_sizeof ||
591 Tok.getKind() == tok::kw___alignof) &&
592 "Not a sizeof/alignof expression!");
593 ConsumeToken();
594
595 // If the operand doesn't start with an '(', it must be an expression.
Chris Lattner0be454e2006-08-12 19:30:51 +0000596 if (Tok.getKind() != tok::l_paren)
Chris Lattner89c50c62006-08-11 06:41:18 +0000597 return ParseCastExpression(true);
Chris Lattner81b576e2006-08-11 02:13:20 +0000598
599 // If it starts with a '(', we know that it is either a parenthesized
600 // type-name, or it is a unary-expression that starts with a compound literal,
601 // or starts with a primary-expression that is a parenthesized expression.
602 ParenParseOption ExprType = CastExpr;
Chris Lattner89c50c62006-08-11 06:41:18 +0000603 return ParseParenExpression(ExprType);
Chris Lattner81b576e2006-08-11 02:13:20 +0000604}
605
Chris Lattner11124352006-08-12 19:16:08 +0000606/// ParseBuiltinPrimaryExpression
607///
608/// primary-expression: [C99 6.5.1]
609/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
610/// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
611/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
612/// assign-expr ')'
613/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
614///
615/// [GNU] offsetof-member-designator:
616/// [GNU] identifier
617/// [GNU] offsetof-member-designator '.' identifier
618/// [GNU] offsetof-member-designator '[' expression ']'
619///
620Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
621 ExprResult Res(false);
622 SourceLocation StartLoc = Tok.getLocation();
623 const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
624
625 tok::TokenKind T = Tok.getKind();
626 ConsumeToken(); // Eat the builtin identifier.
627
628 // All of these start with an open paren.
629 if (Tok.getKind() != tok::l_paren) {
630 Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
631 return ExprResult(true);
632 }
633
634 SourceLocation LParenLoc = Tok.getLocation();
635 ConsumeParen();
636
637 switch (T) {
638 default: assert(0 && "Not a builtin primary expression!");
639 case tok::kw___builtin_va_arg:
640 Res = ParseAssignmentExpression();
641 if (Res.isInvalid) {
642 SkipUntil(tok::r_paren);
643 return Res;
644 }
Chris Lattner0be454e2006-08-12 19:30:51 +0000645
Chris Lattner6d7e6342006-08-15 03:41:14 +0000646 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Chris Lattner11124352006-08-12 19:16:08 +0000647 return ExprResult(true);
Chris Lattner0be454e2006-08-12 19:30:51 +0000648
Chris Lattner11124352006-08-12 19:16:08 +0000649 ParseTypeName();
650 break;
651
652 case tok::kw___builtin_offsetof:
653 ParseTypeName();
654
Chris Lattner6d7e6342006-08-15 03:41:14 +0000655 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Chris Lattner11124352006-08-12 19:16:08 +0000656 return ExprResult(true);
Chris Lattner11124352006-08-12 19:16:08 +0000657
658 // We must have at least one identifier here.
Chris Lattner6d7e6342006-08-15 03:41:14 +0000659 if (ExpectAndConsume(tok::identifier, diag::err_expected_ident, "",
Chris Lattnerdbb2a462006-08-12 19:26:13 +0000660 tok::r_paren))
Chris Lattner11124352006-08-12 19:16:08 +0000661 return ExprResult(true);
Chris Lattnerdbb2a462006-08-12 19:26:13 +0000662
Chris Lattner11124352006-08-12 19:16:08 +0000663 while (1) {
664 if (Tok.getKind() == tok::period) {
665 // offsetof-member-designator: offsetof-member-designator '.' identifier
666 ConsumeToken();
667
Chris Lattner6d7e6342006-08-15 03:41:14 +0000668 if (ExpectAndConsume(tok::identifier, diag::err_expected_ident, "",
Chris Lattnerdbb2a462006-08-12 19:26:13 +0000669 tok::r_paren))
Chris Lattner11124352006-08-12 19:16:08 +0000670 return ExprResult(true);
Chris Lattner11124352006-08-12 19:16:08 +0000671 } else if (Tok.getKind() == tok::l_square) {
672 // offsetof-member-designator: offsetof-member-design '[' expression ']'
673 SourceLocation LSquareLoc = Tok.getLocation();
674 ConsumeBracket();
675 Res = ParseExpression();
676 if (Res.isInvalid) {
677 SkipUntil(tok::r_paren);
678 return Res;
679 }
680
Chris Lattner04f80192006-08-15 04:55:54 +0000681 MatchRHSPunctuation(tok::r_square, LSquareLoc);
Chris Lattner11124352006-08-12 19:16:08 +0000682 } else {
683 break;
684 }
685 }
686 break;
687 case tok::kw___builtin_choose_expr:
688 Res = ParseAssignmentExpression();
689
Chris Lattner6d7e6342006-08-15 03:41:14 +0000690 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Chris Lattner11124352006-08-12 19:16:08 +0000691 return ExprResult(true);
Chris Lattner11124352006-08-12 19:16:08 +0000692
693 Res = ParseAssignmentExpression();
694
Chris Lattner6d7e6342006-08-15 03:41:14 +0000695 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Chris Lattner11124352006-08-12 19:16:08 +0000696 return ExprResult(true);
Chris Lattner11124352006-08-12 19:16:08 +0000697
698 Res = ParseAssignmentExpression();
699 break;
700 case tok::kw___builtin_types_compatible_p:
701 ParseTypeName();
702
Chris Lattner6d7e6342006-08-15 03:41:14 +0000703 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
Chris Lattner11124352006-08-12 19:16:08 +0000704 return ExprResult(true);
Chris Lattner11124352006-08-12 19:16:08 +0000705
706 ParseTypeName();
707 break;
708 }
709
Chris Lattner04f80192006-08-15 04:55:54 +0000710 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Chris Lattner11124352006-08-12 19:16:08 +0000711
712 // These can be followed by postfix-expr pieces because they are
713 // primary-expressions.
714 return ParsePostfixExpressionSuffix(Res);
715}
716
Chris Lattner52a99e52006-08-10 20:56:00 +0000717/// ParseStringLiteralExpression - This handles the various token types that
718/// form string literals, and also handles string concatenation [C99 5.1.1.2,
719/// translation phase #6].
720///
721/// primary-expression: [C99 6.5.1]
722/// string-literal
Chris Lattner89c50c62006-08-11 06:41:18 +0000723Parser::ExprResult Parser::ParseStringLiteralExpression() {
Chris Lattner4564bc12006-08-10 23:14:52 +0000724 assert(isTokenStringLiteral() && "Not a string literal!");
Chris Lattner52a99e52006-08-10 20:56:00 +0000725 ConsumeStringToken();
726
727 // String concat. Note that keywords like __func__ and __FUNCTION__ aren't
728 // considered to be strings.
Chris Lattner4564bc12006-08-10 23:14:52 +0000729 while (isTokenStringLiteral())
Chris Lattner52a99e52006-08-10 20:56:00 +0000730 ConsumeStringToken();
Chris Lattner89c50c62006-08-11 06:41:18 +0000731 return ExprResult(false);
Chris Lattner52a99e52006-08-10 20:56:00 +0000732}
Chris Lattnerc5e0d4a2006-08-10 19:06:03 +0000733
Chris Lattnerc951dae2006-08-10 04:23:57 +0000734
Chris Lattner4add4e62006-08-11 01:33:00 +0000735/// ParseParenExpression - This parses the unit that starts with a '(' token,
736/// based on what is allowed by ExprType. The actual thing parsed is returned
737/// in ExprType.
738///
739/// primary-expression: [C99 6.5.1]
Chris Lattnerc951dae2006-08-10 04:23:57 +0000740/// '(' expression ')'
Chris Lattnerf8339772006-08-10 22:01:51 +0000741/// [GNU] '(' compound-statement ')' (if !ParenExprOnly)
742/// postfix-expression: [C99 6.5.2]
743/// '(' type-name ')' '{' initializer-list '}'
744/// '(' type-name ')' '{' initializer-list ',' '}'
Chris Lattner4add4e62006-08-11 01:33:00 +0000745/// cast-expression: [C99 6.5.4]
746/// '(' type-name ')' cast-expression
Chris Lattnerf8339772006-08-10 22:01:51 +0000747///
Chris Lattner89c50c62006-08-11 06:41:18 +0000748Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType) {
Chris Lattnerc951dae2006-08-10 04:23:57 +0000749 assert(Tok.getKind() == tok::l_paren && "Not a paren expr!");
750 SourceLocation OpenLoc = Tok.getLocation();
751 ConsumeParen();
Chris Lattner89c50c62006-08-11 06:41:18 +0000752 ExprResult Result(false);
Chris Lattnerc951dae2006-08-10 04:23:57 +0000753
Chris Lattner4add4e62006-08-11 01:33:00 +0000754 if (ExprType >= CompoundStmt && Tok.getKind() == tok::l_brace &&
Chris Lattnerf8339772006-08-10 22:01:51 +0000755 !getLang().NoExtensions) {
756 Diag(Tok, diag::ext_gnu_statement_expr);
757 ParseCompoundStatement();
Chris Lattner4add4e62006-08-11 01:33:00 +0000758 ExprType = CompoundStmt;
759 } else if (ExprType >= CompoundLiteral && isTypeSpecifierQualifier()) {
Chris Lattner6c3f05d2006-08-12 16:54:25 +0000760 // Otherwise, this is a compound literal expression or cast expression.
Chris Lattnerf5fbd792006-08-10 23:56:11 +0000761 ParseTypeName();
762
763 // Match the ')'.
Chris Lattner04f80192006-08-15 04:55:54 +0000764 MatchRHSPunctuation(tok::r_paren, OpenLoc);
Chris Lattnerf5fbd792006-08-10 23:56:11 +0000765
Chris Lattner4add4e62006-08-11 01:33:00 +0000766 if (Tok.getKind() == tok::l_brace) {
Chris Lattner6c3f05d2006-08-12 16:54:25 +0000767 if (!getLang().C99) // Compound literals don't exist in C90.
768 Diag(OpenLoc, diag::ext_c99_compound_literal);
Chris Lattner89c50c62006-08-11 06:41:18 +0000769 Result = ParseInitializer();
Chris Lattner4add4e62006-08-11 01:33:00 +0000770 ExprType = CompoundLiteral;
771 } else if (ExprType == CastExpr) {
772 // Note that this doesn't parse the subsequence cast-expression.
773 ExprType = CastExpr;
774 } else {
Chris Lattnerf5fbd792006-08-10 23:56:11 +0000775 Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
Chris Lattner89c50c62006-08-11 06:41:18 +0000776 return ExprResult(true);
Chris Lattnerf5fbd792006-08-10 23:56:11 +0000777 }
Chris Lattner89c50c62006-08-11 06:41:18 +0000778 return Result;
Chris Lattner4add4e62006-08-11 01:33:00 +0000779 } else {
Chris Lattner89c50c62006-08-11 06:41:18 +0000780 Result = ParseExpression();
Chris Lattner4add4e62006-08-11 01:33:00 +0000781 ExprType = SimpleExpr;
Chris Lattnerf8339772006-08-10 22:01:51 +0000782 }
Chris Lattnerc951dae2006-08-10 04:23:57 +0000783
Chris Lattner4564bc12006-08-10 23:14:52 +0000784 // Match the ')'.
Chris Lattner89c50c62006-08-11 06:41:18 +0000785 if (Result.isInvalid)
786 SkipUntil(tok::r_paren);
787 else
Chris Lattner04f80192006-08-15 04:55:54 +0000788 MatchRHSPunctuation(tok::r_paren, OpenLoc);
Chris Lattner89c50c62006-08-11 06:41:18 +0000789 return Result;
Chris Lattnerc951dae2006-08-10 04:23:57 +0000790}